Instead of rtfree(9)ing the cached route after using it, if it is a
multipath one, free it before.
Ok?
Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.269
diff -u -p -r1.269 ip_input.c
--- netinet/ip_input.c 29 Mar 2016 10:34:42 -0000 1.269
+++ netinet/ip_input.c 11 Apr 2016 13:21:44 -0000
@@ -1422,8 +1422,9 @@ ip_forward(struct mbuf *m, struct ifnet
rtableid = m->m_pkthdr.ph_rtableid;
+ rt = ipforward_rt.ro_rt;
sin = satosin(&ipforward_rt.ro_dst);
- if ((rt = ipforward_rt.ro_rt) == NULL ||
+ if (rt == NULL || ISSET(rt->rt_flags, RTF_MPATH) ||
ip->ip_dst.s_addr != sin->sin_addr.s_addr ||
rtableid != ipforward_rt.ro_tableid) {
if (ipforward_rt.ro_rt) {
@@ -1506,7 +1507,7 @@ ip_forward(struct mbuf *m, struct ifnet
goto freecopy;
}
if (!fake)
- goto freert;
+ return;
switch (error) {
@@ -1528,9 +1529,7 @@ ip_forward(struct mbuf *m, struct ifnet
code = ICMP_UNREACH_NEEDFRAG;
#ifdef IPSEC
- if (ipforward_rt.ro_rt) {
- struct rtentry *rt = ipforward_rt.ro_rt;
-
+ if (rt != NULL) {
if (rt->rt_rmx.rmx_mtu)
destmtu = rt->rt_rmx.rmx_mtu;
else {
@@ -1569,15 +1568,6 @@ ip_forward(struct mbuf *m, struct ifnet
freecopy:
if (fake)
m_tag_delete_chain(&mfake);
- freert:
-#ifndef SMALL_KERNEL
- if (ipmultipath && ipforward_rt.ro_rt &&
- (ipforward_rt.ro_rt->rt_flags & RTF_MPATH)) {
- rtfree(ipforward_rt.ro_rt);
- ipforward_rt.ro_rt = NULL;
- }
-#endif
- return;
}
int
Index: netinet6/ip6_forward.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_forward.c,v
retrieving revision 1.87
diff -u -p -r1.87 ip6_forward.c
--- netinet6/ip6_forward.c 29 Mar 2016 11:57:51 -0000 1.87
+++ netinet6/ip6_forward.c 11 Apr 2016 13:21:45 -0000
@@ -225,6 +225,7 @@ reroute:
* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst
*/
if (!rtisvalid(ip6_forward_rt.ro_rt) ||
+ ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) ||
ip6_forward_rt.ro_tableid != rtableid) {
if (ip6_forward_rt.ro_rt) {
rtfree(ip6_forward_rt.ro_rt);
@@ -248,6 +249,7 @@ reroute:
return;
}
} else if (!rtisvalid(ip6_forward_rt.ro_rt) ||
+ ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) ||
!IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr) ||
ip6_forward_rt.ro_tableid != rtableid) {
if (ip6_forward_rt.ro_rt) {
@@ -303,7 +305,7 @@ reroute:
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
m_freem(m);
- goto freert;
+ goto out;
}
#ifdef IPSEC
@@ -346,7 +348,7 @@ reroute:
/* Callee frees mbuf */
error = ipsp_process_packet(m, tdb, AF_INET6, 0);
m_freem(mcopy);
- goto freert;
+ goto out;
}
#endif /* IPSEC */
@@ -387,7 +389,7 @@ reroute:
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_ADDR, 0);
m_freem(m);
- goto freert;
+ goto out;
}
type = ND_REDIRECT;
}
@@ -434,7 +436,7 @@ reroute:
icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0,
ifp->if_mtu);
m_freem(m);
- goto freert;
+ goto out;
}
error = nd6_output(ifp, m, dst, rt);
@@ -454,12 +456,12 @@ reroute:
senderr:
#endif
if (mcopy == NULL)
- goto freert;
+ goto out;
switch (error) {
case 0:
if (type == ND_REDIRECT) {
icmp6_redirect_output(mcopy, rt);
- goto freert;
+ goto out;
}
goto freecopy;
@@ -481,17 +483,10 @@ senderr:
break;
}
icmp6_error(mcopy, type, code, 0);
- goto freert;
+ goto out;
- freecopy:
+freecopy:
m_freem(mcopy);
- freert:
-#ifndef SMALL_KERNEL
- if (ip6_multipath && ip6_forward_rt.ro_rt &&
- (ip6_forward_rt.ro_rt->rt_flags & RTF_MPATH)) {
- rtfree(ip6_forward_rt.ro_rt);
- ip6_forward_rt.ro_rt = NULL;
- }
-#endif
+out:
if_put(ifp);
}
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.157
diff -u -p -r1.157 ip6_input.c
--- netinet6/ip6_input.c 11 Apr 2016 13:02:35 -0000 1.157
+++ netinet6/ip6_input.c 11 Apr 2016 13:21:45 -0000
@@ -422,6 +422,7 @@ ip6_input(struct mbuf *m)
* Unicast check
*/
if (rtisvalid(ip6_forward_rt.ro_rt) &&
+ !ISSET(ip6_forward_rt.ro_rt->rt_flags, RTF_MPATH) &&
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
&ip6_forward_rt.ro_dst.sin6_addr) &&
rtableid == ip6_forward_rt.ro_tableid)