Diff below removes the 'struct route_in6' argument from in6_selectsrc().

It is only used by in6_pcbselsrc() so move the code there.  This reduces
differences with IPv4 and help me to get rid of 'struct route*'.

ok?

Index: net/if_vxlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vxlan.c,v
retrieving revision 1.52
diff -u -p -r1.52 if_vxlan.c
--- net/if_vxlan.c      29 Nov 2016 10:09:57 -0000      1.52
+++ net/if_vxlan.c      29 Nov 2016 15:52:41 -0000
@@ -768,7 +768,7 @@ vxlan_encap6(struct ifnet *ifp, struct m
                ip6->ip6_hlim = ip6_defhlim;
 
        if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)) {
-               error = in6_selectsrc(&in6a, satosin6(dst), NULL, NULL,
+               error = in6_selectsrc(&in6a, satosin6(dst), NULL,
                    sc->sc_rdomain);
                if (error != 0) {
                        m_freem(m);
Index: netinet6/in6_src.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_src.c,v
retrieving revision 1.80
diff -u -p -r1.80 in6_src.c
--- netinet6/in6_src.c  2 Sep 2016 13:53:44 -0000       1.80
+++ netinet6/in6_src.c  29 Nov 2016 15:56:56 -0000
@@ -99,7 +99,6 @@ in6_pcbselsrc(struct in6_addr **in6src, 
        struct route_in6 *ro = &inp->inp_route6;
        struct in6_addr *laddr = &inp->inp_laddr6;
        u_int rtableid = inp->inp_rtableid;
-
        struct ifnet *ifp = NULL;
        struct in6_addr *dst;
        struct in6_ifaddr *ia6 = NULL;
@@ -172,7 +171,55 @@ in6_pcbselsrc(struct in6_addr **in6src, 
                return (0);
        }
 
-       return in6_selectsrc(in6src, dstsock, mopts, ro, rtableid);
+       error = in6_selectsrc(in6src, dstsock, mopts, rtableid);
+       if (error != EADDRNOTAVAIL)
+               return (error);
+
+       /*
+        * If route is known or can be allocated now,
+        * our src addr is taken from the i/f, else punt.
+        */
+       if (!rtisvalid(ro->ro_rt) || (ro->ro_tableid != rtableid) ||
+           !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst)) {
+               rtfree(ro->ro_rt);
+               ro->ro_rt = NULL;
+       }
+       if (ro->ro_rt == NULL) {
+               struct sockaddr_in6 *sa6;
+
+               /* No route yet, so try to acquire one */
+               bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
+               ro->ro_tableid = rtableid;
+               sa6 = &ro->ro_dst;
+               sa6->sin6_family = AF_INET6;
+               sa6->sin6_len = sizeof(struct sockaddr_in6);
+               sa6->sin6_addr = *dst;
+               sa6->sin6_scope_id = dstsock->sin6_scope_id;
+               ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst),
+                   RT_RESOLVE, ro->ro_tableid);
+       }
+
+       /*
+        * in_pcbconnect() checks out IFF_LOOPBACK to skip using
+        * the address. But we don't know why it does so.
+        * It is necessary to ensure the scope even for lo0
+        * so doesn't check out IFF_LOOPBACK.
+        */
+
+       if (ro->ro_rt) {
+               ifp = if_get(ro->ro_rt->rt_ifidx);
+               if (ifp != NULL) {
+                       ia6 = in6_ifawithscope(ifp, dst, rtableid);
+                       if_put(ifp);
+               }
+               if (ia6 == NULL) /* xxx scope error ?*/
+                       ia6 = ifatoia6(ro->ro_rt->rt_ifa);
+       }
+       if (ia6 == NULL)
+               return (EHOSTUNREACH);  /* no route */
+
+       *in6src = &ia6->ia_addr.sin6_addr;
+       return (0);
 }
 
 /*
@@ -183,7 +230,7 @@ in6_pcbselsrc(struct in6_addr **in6src, 
  */
 int
 in6_selectsrc(struct in6_addr **in6src, struct sockaddr_in6 *dstsock,
-    struct ip6_moptions *mopts, struct route_in6 *ro, u_int rtableid)
+    struct ip6_moptions *mopts, unsigned int rtableid)
 {
        struct ifnet *ifp = NULL;
        struct in6_addr *dst;
@@ -239,54 +286,6 @@ in6_selectsrc(struct in6_addr **in6src, 
                        *in6src = &ia6->ia_addr.sin6_addr;
                        return (0);
                }
-       }
-
-       /*
-        * If route is known or can be allocated now,
-        * our src addr is taken from the i/f, else punt.
-        */
-       if (ro) {
-               if (!rtisvalid(ro->ro_rt) || (ro->ro_tableid != rtableid) ||
-                   !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst)) {
-                       rtfree(ro->ro_rt);
-                       ro->ro_rt = NULL;
-               }
-               if (ro->ro_rt == NULL) {
-                       struct sockaddr_in6 *sa6;
-
-                       /* No route yet, so try to acquire one */
-                       bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
-                       ro->ro_tableid = rtableid;
-                       sa6 = &ro->ro_dst;
-                       sa6->sin6_family = AF_INET6;
-                       sa6->sin6_len = sizeof(struct sockaddr_in6);
-                       sa6->sin6_addr = *dst;
-                       sa6->sin6_scope_id = dstsock->sin6_scope_id;
-                       ro->ro_rt = rtalloc(sin6tosa(&ro->ro_dst),
-                           RT_RESOLVE, ro->ro_tableid);
-               }
-
-               /*
-                * in_pcbconnect() checks out IFF_LOOPBACK to skip using
-                * the address. But we don't know why it does so.
-                * It is necessary to ensure the scope even for lo0
-                * so doesn't check out IFF_LOOPBACK.
-                */
-
-               if (ro->ro_rt) {
-                       ifp = if_get(ro->ro_rt->rt_ifidx);
-                       if (ifp != NULL) {
-                               ia6 = in6_ifawithscope(ifp, dst, rtableid);
-                               if_put(ifp);
-                       }
-                       if (ia6 == NULL) /* xxx scope error ?*/
-                               ia6 = ifatoia6(ro->ro_rt->rt_ifa);
-               }
-               if (ia6 == NULL)
-                       return (EHOSTUNREACH);  /* no route */
-
-               *in6src = &ia6->ia_addr.sin6_addr;
-               return (0);
        }
 
        return (EADDRNOTAVAIL);
Index: netinet6/ip6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.64
diff -u -p -r1.64 ip6_var.h
--- netinet6/ip6_var.h  24 Aug 2016 09:41:12 -0000      1.64
+++ netinet6/ip6_var.h  29 Nov 2016 15:58:04 -0000
@@ -297,7 +297,7 @@ int none_input(struct mbuf **, int *, in
 int    in6_pcbselsrc(struct in6_addr **, struct sockaddr_in6 *,
            struct inpcb *, struct ip6_pktopts *);
 int    in6_selectsrc(struct in6_addr **, struct sockaddr_in6 *,
-           struct ip6_moptions *, struct route_in6 *, u_int);
+           struct ip6_moptions *, unsigned int);
 struct rtentry *in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
            struct route_in6 *, unsigned int rtableid);
 

Reply via email to