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