From b122449be225e53cbcd5c449aa1f3fe7a4735352 Mon Sep 17 00:00:00 2001 From: roy Date: Wed, 15 Jan 2014 10:25:04 +0000 Subject: [PATCH] If the address matches a cloning route, it is also a neighbor. This allows us to use prefixes which userland may have added. --- sys/netinet6/nd6.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 3fe58e0d105e..88739675f47d 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.c,v 1.146 2013/12/17 20:25:00 martin Exp $ */ +/* $NetBSD: nd6.c,v 1.147 2014/01/15 10:25:04 roy Exp $ */ /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.146 2013/12/17 20:25:00 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.147 2014/01/15 10:25:04 roy Exp $"); #include "opt_ipsec.h" @@ -818,8 +818,9 @@ nd6_purge(struct ifnet *ifp) } } -struct rtentry * -nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp) +static struct rtentry * +nd6_lookup1(const struct in6_addr *addr6, int create, struct ifnet *ifp, + int cloning) { struct rtentry *rt; struct sockaddr_in6 sin6; @@ -883,6 +884,27 @@ nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp) } else return NULL; rt->rt_refcnt--; + + /* + * Check for a cloning route to match the address. + * This should only be set from in6_is_addr_neighbor so we avoid + * a potentially expensive second call to rtalloc1. + */ + if (cloning && + rt->rt_flags & (RTF_CLONING | RTF_CLONED) && + (rt->rt_ifp == ifp +#if NBRIDGE > 0 + || SAME_BRIDGE(rt->rt_ifp->if_bridgeport, ifp->if_bridgeport) +#endif +#if NCARP > 0 + || (ifp->if_type == IFT_CARP && rt->rt_ifp == ifp->if_carpdev) || + (rt->rt_ifp->if_type == IFT_CARP && rt->rt_ifp->if_carpdev == ifp)|| + (ifp->if_type == IFT_CARP && rt->rt_ifp->if_type == IFT_CARP && + rt->rt_ifp->if_carpdev == ifp->if_carpdev) +#endif + )) + return rt; + /* * Validation for the entry. * Note that the check for rt_llinfo is necessary because a cloned @@ -913,6 +935,13 @@ nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp) return rt; } +struct rtentry * +nd6_lookup(const struct in6_addr *addr6, int create, struct ifnet *ifp) +{ + + return nd6_lookup1(addr6, create, ifp, 0); +} + /* * Detect if a given IPv6 address identifies a neighbor on a given link. * XXX: should take care of the destination of a p2p link? @@ -973,10 +1002,10 @@ nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) } /* - * Even if the address matches none of our addresses, it might be - * in the neighbor cache. + * Even if the address matches none of our addresses, it might match + * a cloning route or be in the neighbor cache. */ - if (nd6_lookup(&addr->sin6_addr, 0, ifp) != NULL) + if (nd6_lookup1(&addr->sin6_addr, 0, ifp, 1) != NULL) return 1; return 0;