Page MenuHomeFreeBSD

D33274.id99484.diff
No OneTemporary

D33274.id99484.diff

Index: sys/netinet/ip_fastfwd.c
===================================================================
--- sys/netinet/ip_fastfwd.c
+++ sys/netinet/ip_fastfwd.c
@@ -136,6 +136,10 @@
mcopy->m_pkthdr.len = mcopy->m_len;
m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
+ /*
+ * XXX A lot of this should be a pre-condition of whether to send
+ * a redirect in first place and not how to send it.
+ */
if (nh != NULL &&
((nh->nh_flags & (NHF_REDIRECT|NHF_DEFAULT)) == 0)) {
struct in_ifaddr *nh_ia = (struct in_ifaddr *)(nh->nh_ifa);
@@ -198,7 +202,7 @@
{
struct ip *ip;
struct mbuf *m0 = NULL;
- struct nhop_object *nh = NULL;
+ struct nhop_object *nh = NULL, *onh;
struct route ro;
struct sockaddr_in *dst;
const struct sockaddr *gw;
@@ -435,12 +439,33 @@
gw = (const struct sockaddr *)dst;
/*
- * Handle redirect case.
+ * Handle redirect case. Only send a redirect if:
+ * (a) redirects are not disabled,
+ * (b) packet goes out the same interface (partially flawed in case
+ * of ROUTE_MPATH and having multiple addresses of the same subnet
+ * on multiple interfaces but good enough as an abstraction),
+ * (c) we know how to reach the sender and the source address is
+ * directly connected to us [RFC792, p13],
+ * (d) the forwarding route was not created by a redirect,
+ * (e) 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],
+ * (f) the resulting forwarding destination is not "This host on this
+ * network" [RFC1122, Section 3.2.1.3].
*/
redest.s_addr = 0;
+ onh = fib4_lookup(M_GETFIB(m), ip->ip_src, 0, NHR_NONE, m->m_pkthdr.flowid);
if (V_ipsendredirects && (nh->nh_ifp == m->m_pkthdr.rcvif) &&
- gw->sa_family == AF_INET)
+ onh != NULL && (onh->nh_flags & NHF_GATEWAY) == 0 &&
+ (nh->nh_flags & NHF_REDIRECT) == 0 &&
+ gw->sa_family == AF_INET) {
mcopy = ip_redir_alloc(m, nh, ip, &redest.s_addr);
+ if (mcopy != NULL && redest.s_addr == 0) {
+ /* Do not redirect to 0.0.0.0. */
+ m_freem(mcopy);
+ mcopy = NULL;
+ }
+ }
/*
* Check if packet fits MTU or if hardware will fragment for us
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

Mime Type
text/plain
Expires
Fri, Aug 28, 6:52 PM (9 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37477279
Default Alt Text
D33274.id99484.diff (3 KB)

Event Timeline