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); }