diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-11-18 13:58:03 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-11-18 13:58:03 +0000 |
commit | 1b5b0a48a70bb823fa605244f12bac59c59ba29c (patch) | |
tree | a7301d7733650b513f5a1517159f605dfdaf339c /sys/netinet6/nd6_nbr.c | |
parent | 349255e55fb00e0ec1720b2775d046471821a9f4 (diff) |
Factorize the bits to check if a L2 route is connected, wether it is
attached to a carp(4) or bridge(4) member, to not dereference rt_ifp
directly.
ok visa@
Diffstat (limited to 'sys/netinet6/nd6_nbr.c')
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index e138d21dcf6..168de6e8a4d 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_nbr.c,v 1.99 2015/11/02 15:05:23 mpi Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.100 2015/11/18 13:58:02 mpi Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -81,6 +81,8 @@ void nd6_dad_ns_output(struct dadq *, struct ifaddr *); void nd6_dad_ns_input(struct ifaddr *); void nd6_dad_duplicated(struct dadq *); +int nd6_isneighbor(const struct ifnet *, const struct in6_addr *); + static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ /* @@ -149,7 +151,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) /* * Make sure the source address is from a neighbor's address. */ - if (!in6_ifpprefix(ifp, &saddr6)) { + if (!nd6_isneighbor(ifp, &saddr6)) { nd6log((LOG_INFO, "nd6_ns_input: " "NS packet from non-neighbor\n")); goto bad; @@ -684,7 +686,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) /* * Make sure the source address is from a neighbor's address. */ - if (!in6_ifpprefix(ifp, &saddr6)) { + if (!nd6_isneighbor(ifp, &saddr6)) { nd6log((LOG_INFO, "nd6_na_input: " "ND packet from non-neighbor\n")); goto bad; @@ -1406,3 +1408,27 @@ nd6_dad_ns_input(struct ifaddr *ifa) dp->dad_ns_icount++; } } + +/* + * Check whether ``addr'' is a neighbor address connected to ``ifp''. + */ +int +nd6_isneighbor(const struct ifnet *ifp, const struct in6_addr *addr) +{ + struct rtentry *rt; + struct sockaddr_in6 sin6; + unsigned int tableid = ifp->if_rdomain; + int rv = 0; + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = *addr; + rt = rtalloc(sin6tosa(&sin6), 0, tableid); + + if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_CLONING|RTF_CLONED)) + rv = if_isconnected(ifp, rt->rt_ifidx); + + rtfree(rt); + return (rv); +} |