Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147298185
D33274.id99624.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D33274.id99624.diff
View Options
Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -114,11 +114,88 @@
#define V_ipsendredirects VNET(ipsendredirects)
static struct mbuf *
-ip_redir_alloc(struct mbuf *m, struct nhop_object *nh,
- struct ip *ip, in_addr_t *addr)
+ip_redir_alloc(struct mbuf *m, struct nhop_object *nh, u_short ip_len,
+ struct in_addr *osrc, struct in_addr *newgw)
{
- struct mbuf *mcopy = m_gethdr(M_NOWAIT, m->m_type);
+ struct nhop_object *snh;
+ struct in_ifaddr *nh_ia, *snh_ia;
+ struct mbuf *mcopy;
+ KASSERT(nh != NULL, ("%s: m %p nh is NULL\n", __func__, m));
+
+ /*
+ * Only send a redirect if:
+ * - Redirects are not disabled (must be checked by caller),
+ * - Neither a MCAST or BCAST packet (must be checked by caller)
+ * [RFC1009 Appendix A.2].
+ * - The packet does not do IP source routing or having any other
+ * IP options (this case was handled already by ip_input() calling
+ * ip_dooptions() [RFC792, p13],
+ */
+
+ /*
+ * The packet is being forwarded out the same physical interface
+ * that it was received from [RFC1812, 5.2.7.2].
+ * XXX note that this is flawed in a multi-interface or in ROUTE_MPATH
+ * these days.
+ */
+ if (nh->nh_ifp != m->m_pkthdr.rcvif)
+ return (NULL);
+
+ /*
+ * - The forwarding route was not created by a redirect
+ * [RFC1812, 5.2.7.2], or
+ * if it was to follow a default route (see below).
+ * - The next-hop is reachable by us [RFC1009 Appendix A.2].
+ */
+ if ((nh->nh_flags & (NHF_DEFAULT | NHF_REDIRECT |
+ NHF_BLACKHOLE | NHF_REJECT)) != 0)
+ return (NULL);
+
+ /* Get the new gateway. */
+ if ((nh->nh_flags & NHF_GATEWAY) == 0 || nh->gw_sa.sa_family != PF_INET)
+ return (NULL);
+ newgw->s_addr = nh->gw4_sa.sin_addr.s_addr;
+
+ /*
+ * - The resulting forwarding destination is not "This host on this
+ * network" [RFC1122, Section 3.2.1.3] (default route check above).
+ */
+ if (newgw->s_addr == 0)
+ return (NULL);
+
+ /*
+ * - We know how to reach the sender and the source address is
+ * directly connected to us [RFC792, p13].
+ */
+ /*
+ * We do a lookup here as the incoming and outgoing interface
+ * do not have to be the same (as assumed in the past).
+ * NB: we do this extra lookup as late as possible.
+ */
+ snh = fib4_lookup(M_GETFIB(m), *osrc, 0, NHR_NONE, m->m_pkthdr.flowid);
+ if (snh == NULL || (snh->nh_flags & NHF_GATEWAY) != 0)
+ return (NULL);
+
+ /*
+ * - The new gateway address and the source address are on the same
+ * subnet [RFC1009 Appendix A.2, RFC1122 3.2.2.2, RFC1812, 5.2.7.2].
+ * NB: if you think multiple logical subnets on the same wire should
+ * receive redirects read [RFC1812, APPENDIX C (15)].
+ */
+ nh_ia = (struct in_ifaddr *)nh->nh_ifa;
+ snh_ia = (struct in_ifaddr *)snh->nh_ifa;
+ if (nh_ia->ia_subnet != snh_ia->ia_subnet ||
+ nh_ia->ia_subnetmask != snh_ia->ia_subnetmask)
+ return (NULL);
+
+ /* Prepare for sending the redirect. */
+
+ /*
+ * Make a copy of as much as we need of the packet as the original
+ * one will be forwarded but we need (a portion) for icmp_error().
+ */
+ mcopy = m_gethdr(M_NOWAIT, m->m_type);
if (mcopy == NULL)
return (NULL);
@@ -132,23 +209,10 @@
m_free(mcopy);
return (NULL);
}
- mcopy->m_len = min(ntohs(ip->ip_len), M_TRAILINGSPACE(mcopy));
+ mcopy->m_len = min(ip_len, M_TRAILINGSPACE(mcopy));
mcopy->m_pkthdr.len = mcopy->m_len;
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
- 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);
-
- if (nh_ia != NULL &&
- (src & nh_ia->ia_subnetmask) == nh_ia->ia_subnet) {
- if (nh->nh_flags & NHF_GATEWAY)
- *addr = nh->gw4_sa.sin_addr.s_addr;
- else
- *addr = ip->ip_dst.s_addr;
- }
- }
return (mcopy);
}
@@ -202,7 +266,7 @@
struct route ro;
struct sockaddr_in *dst;
const struct sockaddr *gw;
- struct in_addr dest, odest, rtdest;
+ struct in_addr dest, odest, rtdest, osrc;
uint16_t ip_len, ip_off;
int error = 0;
struct m_tag *fwd_tag = NULL;
@@ -274,6 +338,7 @@
*/
odest.s_addr = dest.s_addr = ip->ip_dst.s_addr;
+ osrc.s_addr = ip->ip_src.s_addr;
/*
* Run through list of ipfilter hooks for input packets
@@ -434,13 +499,10 @@
} else
gw = (const struct sockaddr *)dst;
- /*
- * Handle redirect case.
- */
+ /* Handle redirect case. */
redest.s_addr = 0;
- if (V_ipsendredirects && (nh->nh_ifp == m->m_pkthdr.rcvif) &&
- gw->sa_family == AF_INET)
- mcopy = ip_redir_alloc(m, nh, ip, &redest.s_addr);
+ if (V_ipsendredirects)
+ mcopy = ip_redir_alloc(m, nh, ip_len, &osrc, &redest);
/*
* Check if packet fits MTU or if hardware will fragment for us
@@ -514,7 +576,7 @@
/* Send required redirect */
if (mcopy != NULL) {
icmp_error(mcopy, ICMP_REDIRECT, ICMP_REDIRECT_HOST, redest.s_addr, 0);
- mcopy = NULL; /* Freed by caller */
+ mcopy = NULL; /* Was consumed by callee. */
}
consumed:
Index: sys/netinet/ip_input.c
===================================================================
--- sys/netinet/ip_input.c
+++ sys/netinet/ip_input.c
@@ -560,8 +560,9 @@
/*
* Try to forward the packet, but if we fail continue.
- * ip_tryforward() does not generate redirects, so fall
- * through to normal processing if redirects are required.
+ * ip_tryforward() may generate redirects these days.
+ * XXX the logic below falling through to normal processing
+ * if redirects are required should be revisited as well.
* ip_tryforward() does inbound and outbound packet firewall
* processing. If firewall has decided that destination becomes
* our local address, it sets M_FASTFWD_OURS flag. In this
@@ -574,6 +575,10 @@
IPSEC_CAPS(ipv4, m, IPSEC_CAP_OPERABLE) == 0)
#endif
) {
+ /*
+ * ip_dooptions() was run so we can ignore the source route (or
+ * any IP options case) case for redirects in ip_tryforward().
+ */
if ((m = ip_tryforward(m)) == NULL)
return;
if (m->m_flags & M_FASTFWD_OURS) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 10, 7:01 PM (13 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29476643
Default Alt Text
D33274.id99624.diff (6 KB)
Attached To
Mode
D33274: IPv4: fix redirect sending conditions
Attached
Detach File
Event Timeline
Log In to Comment