summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorgnn <gnn@FreeBSD.org>2016-03-24 07:54:56 +0000
committergnn <gnn@FreeBSD.org>2016-03-24 07:54:56 +0000
commitc3d5404bbe9b51c8373832a220b2568fc8b806fe (patch)
treee930aaa09aa8f724ba7ca61b6ec317d3c5bf9cee /sys/netinet6
parenta9f48f4d565cc70d5eb24a4b37b79b0f870226de (diff)
downloadFreeBSD-src-c3d5404bbe9b51c8373832a220b2568fc8b806fe.zip
FreeBSD-src-c3d5404bbe9b51c8373832a220b2568fc8b806fe.tar.gz
FreeBSD previously provided route caching for TCP (and UDP). Re-add
route caching for TCP, with some improvements. In particular, invalidate the route cache if a new route is added, which might be a better match. The cache is automatically invalidated if the old route is deleted. Submitted by: Mike Karels Reviewed by: gnn Differential Revision: https://reviews.freebsd.org/D4306
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6_pcb.c15
-rw-r--r--sys/netinet6/ip6_output.c19
-rw-r--r--sys/netinet6/udp6_usrreq.c4
3 files changed, 27 insertions, 11 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index a779b8d..98f4cd3 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -827,9 +827,10 @@ void
in6_losing(struct inpcb *in6p)
{
- /*
- * We don't store route pointers in the routing table anymore
- */
+ if (in6p->inp_route6.ro_rt) {
+ RTFREE(in6p->inp_route6.ro_rt);
+ in6p->inp_route6.ro_rt = (struct rtentry *)NULL;
+ }
return;
}
@@ -840,9 +841,11 @@ in6_losing(struct inpcb *in6p)
struct inpcb *
in6_rtchange(struct inpcb *inp, int errno)
{
- /*
- * We don't store route pointers in the routing table anymore
- */
+
+ if (inp->inp_route6.ro_rt) {
+ RTFREE(inp->inp_route6.ro_rt);
+ inp->inp_route6.ro_rt = (struct rtentry *)NULL;
+ }
return inp;
}
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 3a47285..7895139 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -546,7 +546,18 @@ again:
/* adjust pointer */
ip6 = mtod(m, struct ip6_hdr *);
- if (ro->ro_rt && fwd_tag == NULL) {
+ /*
+ * Validate route against routing table additions;
+ * a better/more specific route might have been added.
+ * Make sure address family is set in route.
+ */
+ if (inp) {
+ ro->ro_dst.sin6_family = AF_INET6;
+ RT_VALIDATE((struct route *)ro, &inp->inp_rt_cookie, fibnum);
+ }
+ if (ro->ro_rt && fwd_tag == NULL && (ro->ro_rt->rt_flags & RTF_UP) &&
+ ro->ro_dst.sin6_family == AF_INET6 &&
+ IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, &ip6->ip6_dst)) {
rt = ro->ro_rt;
ifp = ro->ro_rt->rt_ifp;
} else {
@@ -939,7 +950,8 @@ passout:
m->m_pkthdr.len);
ifa_free(&ia6->ia_ifa);
}
- error = nd6_output_ifp(ifp, origifp, m, dst, NULL);
+ error = nd6_output_ifp(ifp, origifp, m, dst,
+ (struct route *)ro);
goto done;
}
@@ -1038,7 +1050,8 @@ sendorfree:
counter_u64_add(ia->ia_ifa.ifa_obytes,
m->m_pkthdr.len);
}
- error = nd6_output_ifp(ifp, origifp, m, dst, NULL);
+ error = nd6_output_ifp(ifp, origifp, m, dst,
+ (struct route *)ro);
} else
m_freem(m);
}
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 9768df5..ebcf6d6 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -876,8 +876,8 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
UDP_PROBE(send, NULL, inp, ip6, inp, udp6);
UDPSTAT_INC(udps_opackets);
- error = ip6_output(m, optp, NULL, flags, inp->in6p_moptions,
- NULL, inp);
+ error = ip6_output(m, optp, &inp->inp_route6, flags,
+ inp->in6p_moptions, NULL, inp);
break;
case AF_INET:
error = EAFNOSUPPORT;
OpenPOWER on IntegriCloud