summaryrefslogtreecommitdiff
path: root/sys/netinet6/nd6_nbr.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-18 13:58:03 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-18 13:58:03 +0000
commit1b5b0a48a70bb823fa605244f12bac59c59ba29c (patch)
treea7301d7733650b513f5a1517159f605dfdaf339c /sys/netinet6/nd6_nbr.c
parent349255e55fb00e0ec1720b2775d046471821a9f4 (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.c32
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);
+}