This is basically a rewrite of in6_ifpprefix() in a more generic
fashion.  The idea is to get rid of rt_ifp.  I'm also introducing
if_isconnected() because I want to use it in ARP.

ok?

Index: netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.178
diff -u -p -r1.178 in6.c
--- netinet6/in6.c      2 Nov 2015 15:05:23 -0000       1.178
+++ netinet6/in6.c      12 Nov 2015 10:33:30 -0000
@@ -61,7 +61,6 @@
  *     @(#)in.c        8.2 (Berkeley) 11/15/93
  */
 
-#include "bridge.h"
 #include "carp.h"
 
 #include <sys/param.h>
@@ -84,9 +83,6 @@
 
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
-#if NBRIDGE > 0
-#include <net/if_bridge.h>
-#endif
 
 #include <netinet6/in6_var.h>
 #include <netinet/ip6.h>
@@ -1448,44 +1444,6 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, st
        }
 
        return (ifatoia6(ifa));
-}
-
-/*
- * Check whether an interface has a prefix by looking up the cloning route.
- */
-int
-in6_ifpprefix(const struct ifnet *ifp, const struct in6_addr *addr)
-{
-       struct sockaddr_in6 dst;
-       struct rtentry *rt;
-       u_int tableid = ifp->if_rdomain;
-
-       bzero(&dst, sizeof(dst));
-       dst.sin6_len = sizeof(struct sockaddr_in6);
-       dst.sin6_family = AF_INET6;
-       dst.sin6_addr = *addr;
-       rt = rtalloc(sin6tosa(&dst), 0, tableid);
-
-       if (rt == NULL)
-               return (0);
-       if ((rt->rt_flags & (RTF_CLONING | RTF_CLONED)) == 0 ||
-           (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
-           1)) {
-               rtfree(rt);
-               return (0);
-       }
-
-       rtfree(rt);
-       return (1);
 }
 
 /*
Index: netinet6/in6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_var.h,v
retrieving revision 1.57
diff -u -p -r1.57 in6_var.h
--- netinet6/in6_var.h  5 Oct 2015 01:22:34 -0000       1.57
+++ netinet6/in6_var.h  12 Nov 2015 10:14:21 -0000
@@ -506,7 +506,6 @@ void        *in6_domifattach(struct ifnet *);
 void   in6_domifdetach(struct ifnet *, void *);
 struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int);
 struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *);
-int    in6_ifpprefix(const struct ifnet *, const struct in6_addr *);
 int    in6_addr2scopeid(unsigned int, struct in6_addr *);
 int    in6_matchlen(struct in6_addr *, struct in6_addr *);
 int    in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int);
Index: netinet6/nd6_nbr.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v
retrieving revision 1.99
diff -u -p -r1.99 nd6_nbr.c
--- netinet6/nd6_nbr.c  2 Nov 2015 15:05:23 -0000       1.99
+++ netinet6/nd6_nbr.c  12 Nov 2015 10:36:56 -0000
@@ -81,6 +81,8 @@ void nd6_dad_ns_output(struct dadq *, st
 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, in
                /*
                 * 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, in
        /*
         * 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;
@@ -1405,4 +1407,28 @@ nd6_dad_ns_input(struct ifaddr *ifa)
                if (dp)
                        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);
 }
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.405
diff -u -p -r1.405 if.c
--- net/if.c    11 Nov 2015 10:23:23 -0000      1.405
+++ net/if.c    12 Nov 2015 10:34:37 -0000
@@ -945,6 +945,36 @@ if_detach(struct ifnet *ifp)
 }
 
 /*
+ * Returns true if ``ifp0'' is connected to the interface with index ``ifidx''.
+ */
+int
+if_isconnected(const struct ifnet *ifp0, unsigned int ifidx)
+{
+       struct ifnet *ifp;
+       int connected = 0;
+
+       ifp = if_get(ifidx);
+       if (ifp == NULL)
+               return (0);
+
+       if (ifp0->if_index == ifp->if_index)
+               connected = 1;
+
+#if NBRIDGE > 0
+       if (SAME_BRIDGE(ifp0->if_bridgeport, ifp->if_bridgeport))
+               connected = 1;
+#endif
+#if NCARP > 0
+       if ((ifp0->if_type == IFT_CARP && ifp0->if_carpdev == ifp) ||
+           (ifp->if_type == IFT_CARP && ifp->if_carpdev == ifp0))
+               connected = 1;
+#endif
+
+       if_put(ifp);
+       return (connected);
+}
+
+/*
  * Create a clone network interface.
  */
 int
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.52
diff -u -p -r1.52 if_var.h
--- net/if_var.h        11 Nov 2015 10:23:23 -0000      1.52
+++ net/if_var.h        12 Nov 2015 10:31:29 -0000
@@ -426,6 +426,8 @@ struct      ifaddr *ifa_ifwithnet(struct sock
 struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
 void   ifafree(struct ifaddr *);
 
+int    if_isconnected(const struct ifnet *, unsigned int);
+
 void   if_clone_attach(struct if_clone *);
 void   if_clone_detach(struct if_clone *);
 

Reply via email to