Some if_get() love in icmp6.
ok?
Index: netinet6/icmp6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/icmp6.c,v
retrieving revision 1.177
diff -u -p -r1.177 icmp6.c
--- netinet6/icmp6.c 3 Nov 2015 21:39:34 -0000 1.177
+++ netinet6/icmp6.c 20 Nov 2015 13:33:10 -0000
@@ -1018,16 +1018,19 @@ icmp6_mtudisc_update(struct ip6ctlparam
rt = icmp6_mtudisc_clone(sin6tosa(&sin6), m->m_pkthdr.ph_rtableid);
- if (rt && (rt->rt_flags & RTF_HOST) &&
+ if (rt != NULL && ISSET(rt->rt_flags, RTF_HOST) &&
!(rt->rt_rmx.rmx_locks & RTV_MTU) &&
(rt->rt_rmx.rmx_mtu > mtu || rt->rt_rmx.rmx_mtu == 0)) {
- if (mtu < rt->rt_ifp->if_mtu) {
+ struct ifnet *ifp;
+
+ ifp = if_get(rt->rt_ifidx);
+ if (ifp != NULL && mtu < ifp->if_mtu) {
icmp6stat.icp6s_pmtuchg++;
rt->rt_rmx.rmx_mtu = mtu;
}
+ if_put(ifp);
}
- if (rt)
- rtfree(rt);
+ rtfree(rt);
/*
* Notify protocols that the MTU for this destination
@@ -1549,7 +1552,7 @@ icmp6_redirect_input(struct mbuf *m, int
void
icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
{
- struct ifnet *ifp; /* my outgoing interface */
+ struct ifnet *ifp = NULL;
struct in6_addr *ifp_ll6;
struct in6_addr *nexthop;
struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */
@@ -1569,7 +1572,10 @@ icmp6_redirect_output(struct mbuf *m0, s
/* sanity check */
if (m0 == NULL || !rtisvalid(rt))
goto fail;
- ifp = rt->rt_ifp;
+
+ ifp = if_get(rt->rt_ifidx);
+ if (ifp == NULL)
+ goto fail;
/*
* Address check:
@@ -1795,9 +1801,11 @@ noredhdropt:
icmp6stat.icp6s_outhist[ND_REDIRECT]++;
+ if_put(ifp);
return;
fail:
+ if_put(ifp);
m_freem(m);
m_freem(m0);
}