Page MenuHomeFreeBSD

D61385.1794420214.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D61385.1794420214.diff

diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -62,6 +62,7 @@
#include <net/pfil.h>
#include <net/route.h>
#include <net/route/nhop.h>
+#include <net/route/route_var.h>
#include <net/netisr.h>
#include <net/rss_config.h>
#include <net/vnet.h>
@@ -936,6 +937,7 @@
struct ip *ip = mtod(m, struct ip *);
struct in_ifaddr *ia;
struct mbuf *mcopy;
+ struct nhop_object *nh;
struct sockaddr_in *sin;
struct in_addr dest;
struct route ro;
@@ -964,21 +966,19 @@
sin->sin_len = sizeof(*sin);
sin->sin_addr = ip->ip_dst;
flowid = m->m_pkthdr.flowid;
- ro.ro_nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_REF, flowid);
- if (ro.ro_nh != NULL) {
- if (ro.ro_nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) {
+ nh = fib4_lookup(M_GETFIB(m), ip->ip_dst, 0, NHR_NONE, flowid);
+ if (nh != NULL) {
+ if (nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) {
IPSTAT_INC(ips_cantforward);
m_freem(m);
- NH_FREE(ro.ro_nh);
return;
}
- if (ro.ro_nh->nh_flags & NHF_REJECT) {
+ if (nh->nh_flags & NHF_REJECT) {
IPSTAT_INC(ips_cantforward);
- NH_FREE(ro.ro_nh);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
return;
}
- ia = ifatoia(ro.ro_nh->nh_ifa);
+ ia = ifatoia(nh->nh_ifa);
} else
ia = NULL;
/*
@@ -1021,7 +1021,6 @@
if (IPSEC_ENABLED(ipv4)) {
if ((error = IPSEC_FORWARD(ipv4, m)) != 0) {
/* mbuf consumed by IPsec */
- RO_NHFREE(&ro);
m_freem(mcopy);
if (error != EINPROGRESS)
IPSTAT_INC(ips_cantforward);
@@ -1041,10 +1040,6 @@
dest.s_addr = 0;
if (!srcrt && V_ipsendredirects &&
ia != NULL && ia->ia_ifp == m->m_pkthdr.rcvif) {
- struct nhop_object *nh;
-
- nh = ro.ro_nh;
-
if (nh != NULL && ((nh->nh_flags & (NHF_REDIRECT|NHF_DEFAULT)) == 0)) {
struct in_ifaddr *nh_ia = (struct in_ifaddr *)(nh->nh_ifa);
u_long src = ntohl(ip->ip_src.s_addr);
@@ -1065,6 +1060,14 @@
}
}
+ /*
+ * ip_output() may release and replace the nexthop of the route it is
+ * given, and the route is released below, so it needs a reference of
+ * its own. If the nexthop is being destroyed, ip_output() looks the
+ * route up again.
+ */
+ if (nh != NULL && nhop_try_ref_object(nh))
+ ro.ro_nh = nh;
error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL, NULL);
if (error == EMSGSIZE && ro.ro_nh)

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 11, 6:03 PM (2 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41659030
Default Alt Text
D61385.1794420214.diff (2 KB)

Event Timeline