kern/120958: no response to ICMP traffic on interface
configured with a link-local address
James Snow
snow at teardrop.org
Thu Mar 13 17:40:03 PDT 2008
The following reply was made to PR kern/120958; it has been noted by GNATS.
From: James Snow <snow at teardrop.org>
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/120958: no response to ICMP traffic on interface configured with a link-local address
Date: Thu, 13 Mar 2008 20:23:55 -0400
--IS0zKkzwUGydFO0o
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Attached is a patch that reworks the problematic if statement in
sys/netinet/ip_icmp.c and adds two new macros to sys/netinet/in.h.
This fixes the problem, and eliminates a duplicate check for loopback
addresses. (Although it introduces some redundant ntohl() calls.)
-Snow
--IS0zKkzwUGydFO0o
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="link-local-icmp.patch"
diff -ru /usr/src/sys/netinet/in.h /usr/src.new/sys/netinet/in.h
--- /usr/src/sys/netinet/in.h 2007-06-12 16:24:53.000000000 +0000
+++ /usr/src.new/sys/netinet/in.h 2008-03-13 10:44:29.000000000 +0000
@@ -379,6 +379,8 @@
#define IN_BADCLASS(i) (((u_int32_t)(i) & 0xf0000000) == 0xf0000000)
#define IN_LINKLOCAL(i) (((u_int32_t)(i) & 0xffff0000) == 0xa9fe0000)
+#define IN_LOOPBACK(i) (((u_int32_t)(i) & 0xff000000) == 0x7f000000)
+#define IN_ZERONET(i) (((u_int32_t)(i) & 0xff000000) == 0)
#define IN_PRIVATE(i) ((((u_int32_t)(i) & 0xff000000) == 0x0a000000) || \
(((u_int32_t)(i) & 0xfff00000) == 0xac100000) || \
diff -ru /usr/src/sys/netinet/ip_icmp.c /usr/src.new/sys/netinet/ip_icmp.c
--- /usr/src/sys/netinet/ip_icmp.c 2007-10-07 20:44:23.000000000 +0000
+++ /usr/src.new/sys/netinet/ip_icmp.c 2008-03-13 11:03:44.000000000 +0000
@@ -622,13 +622,14 @@
struct mbuf *opts = 0;
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
- if (!in_canforward(ip->ip_src) &&
- ((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
- (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))) {
+ if (IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
+ IN_EXPERIMENTAL(ntohl(ip->ip_src.s_addr)) ||
+ IN_ZERONET(ntohl(ip->ip_src.s_addr)) ) {
m_freem(m); /* Bad return address */
icmpstat.icps_badaddr++;
goto done; /* Ip_output() will check for broadcast */
}
+
t = ip->ip_dst;
ip->ip_dst = ip->ip_src;
--IS0zKkzwUGydFO0o--
More information about the freebsd-net
mailing list