X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/7e834d66daf58ac5f02719defdeb7ee46238dec2..8a27f1c965140ec72dd069582960c64ba9ecf534:/sys/netinet6/in6.c diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index c29085b845..ef148f6fe7 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/netinet6/in6.c,v 1.7.2.9 2002/04/28 05:40:26 suz Exp $ */ -/* $DragonFly: src/sys/netinet6/in6.c,v 1.29 2008/04/20 13:44:26 swildner Exp $ */ +/* $DragonFly: src/sys/netinet6/in6.c,v 1.30 2008/10/03 07:59:20 hasso Exp $ */ /* $KAME: in6.c,v 1.259 2002/01/21 11:37:50 keiichi Exp $ */ /* @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -385,7 +386,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, int error; privileged = 0; - if (suser(td) == 0) + if (priv_check(td, PRIV_ROOT) == 0) privileged++; switch (cmd) { @@ -394,6 +395,14 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, return (mrt6_ioctl(cmd, data)); } + switch(cmd) { + case SIOCAADDRCTL_POLICY: + case SIOCDADDRCTL_POLICY: + if (!privileged) + return (EPERM); + return (in6_src_ioctl(cmd, data)); + } + if (ifp == NULL) return (EOPNOTSUPP); @@ -611,9 +620,14 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, case SIOCAIFADDR_IN6: { - int i, error = 0; + int i, error = 0, iaIsNew; struct nd_prefix pr0, *pr; + if (ia != NULL) + iaIsNew = 0; + else + iaIsNew = 1; + /* * first, make or update the interface address structure, * and link it to the list. @@ -708,8 +722,11 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, */ pfxlist_onlink_check(); } - if (error == 0 && ia) - EVENTHANDLER_INVOKE(ifaddr_event, ifp); + if (error == 0 && ia) { + EVENTHANDLER_INVOKE(ifaddr_event, ifp, + iaIsNew ? IFADDR_EVENT_ADD : IFADDR_EVENT_CHANGE, + &ia->ia_ifa); + } break; } @@ -755,9 +772,10 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, pr->ndpr_expire = 1; /* XXX: just for expiration */ } - purgeaddr: +purgeaddr: + EVENTHANDLER_INVOKE(ifaddr_event, ifp, IFADDR_EVENT_DELETE, + &ia->ia_ifa); in6_purgeaddr(&ia->ia_ifa); - EVENTHANDLER_INVOKE(ifaddr_event, ifp); break; } @@ -1783,6 +1801,34 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr) return (NULL); } +/* + * find the internet address on a given interface corresponding to a neighbor's + * address. + */ +struct in6_ifaddr * +in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr) +{ + struct ifaddr *ifa; + struct in6_ifaddr *ia; + struct ifaddr_container *ifac; + + TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { + ifa = ifac->ifa; + + if (ifa->ifa_addr == NULL) + continue; /* just for safety */ + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + ia = (struct in6_ifaddr *)ifa; + if (IN6_ARE_MASKED_ADDR_EQUAL(addr, + &ia->ia_addr.sin6_addr, + &ia->ia_prefixmask.sin6_addr)) + return ia; + } + + return NULL; +} + /* * Convert IP6 address to printable (loggable) representation. */