Like for IPv4, I'd like to get rid of this global list.  The reason is
that having fewer global data structures means fewer locking.

Here's a trivial conversion to use the routing table in ICMPv6 echo
reply code.  Note that it is safe to dereference ``rt->rt_ifa'' before
calling rtfree(9).

ok?

Index: netinet6/icmp6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/icmp6.c,v
retrieving revision 1.201
diff -u -p -r1.201 icmp6.c
--- netinet6/icmp6.c    9 Feb 2017 20:31:29 -0000       1.201
+++ netinet6/icmp6.c    1 Mar 2017 11:25:46 -0000
@@ -1158,7 +1158,6 @@ icmp6_reflect(struct mbuf *m, size_t off
        struct rtentry *rt = NULL;
        struct ip6_hdr *ip6;
        struct icmp6_hdr *icmp6;
-       struct in6_ifaddr *ia6;
        struct in6_addr t, *src = NULL;
        struct sockaddr_in6 sa6_src, sa6_dst;
 
@@ -1231,26 +1230,30 @@ icmp6_reflect(struct mbuf *m, size_t off
        in6_embedscope(&t, &sa6_dst, NULL);
 
        /*
+        * This is the case if the dst is our link-local address
+        * and the sender is also ourselves.
+        */
+       if (IN6_IS_ADDR_LINKLOCAL(&t) && (m->m_flags & M_LOOP))
+               src = &t;
+
+       /*
         * If the incoming packet was addressed directly to us (i.e. unicast),
         * use dst as the src for the reply.
         * The IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED case would be VERY rare,
         * but is possible (for example) when we encounter an error while
         * forwarding procedure destined to a duplicated address of ours.
         */
-       TAILQ_FOREACH(ia6, &in6_ifaddr, ia_list)
-               if (IN6_ARE_ADDR_EQUAL(&t, &ia6->ia_addr.sin6_addr) &&
-                   (ia6->ia6_flags & (IN6_IFF_ANYCAST|IN6_IFF_TENTATIVE|
-                   IN6_IFF_DUPLICATED)) == 0) {
+       if (src == NULL) {
+               rt = rtalloc(sin6tosa(&sa6_dst), 0, m->m_pkthdr.ph_rtableid);
+               if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) &&
+                   !ISSET(ifatoia6(rt->rt_ifa)->ia6_flags,
+                   IN6_IFF_ANYCAST|IN6_IFF_TENTATIVE|IN6_IFF_DUPLICATED)) {
                        src = &t;
-                       break;
                }
-       if (ia6 == NULL && IN6_IS_ADDR_LINKLOCAL(&t) && (m->m_flags & M_LOOP)) {
-               /*
-                * This is the case if the dst is our link-local address
-                * and the sender is also ourselves.
-                */
-               src = &t;
+               rtfree(rt);
+               rt = NULL;
        }
+
 
        if (src == NULL) {
                /*

Reply via email to