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) {
/*