Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Oct 2011 18:41:26 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r226402 - head/sys/netinet
Message-ID:  <201110151841.p9FIfQLE025750@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Sat Oct 15 18:41:25 2011
New Revision: 226402
URL: http://svn.freebsd.org/changeset/base/226402

Log:
  Add support for IPv4 /31 prefixes, as described in RFC3021.
  
  To run a /31 network, participating hosts MUST drop support
  for directed broadcasts, and treat the first and last addresses
  on subnet as unicast. The broadcast address for the prefix
  should be the link local broadcast address, INADDR_BROADCAST.

Modified:
  head/sys/netinet/in.c
  head/sys/netinet/in.h

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Sat Oct 15 16:28:06 2011	(r226401)
+++ head/sys/netinet/in.c	Sat Oct 15 18:41:25 2011	(r226402)
@@ -897,8 +897,11 @@ in_ifinit(struct ifnet *ifp, struct in_i
 	 */
 	ia->ia_ifa.ifa_metric = ifp->if_metric;
 	if (ifp->if_flags & IFF_BROADCAST) {
-		ia->ia_broadaddr.sin_addr.s_addr =
-			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
+		if (ia->ia_subnetmask == IN_RFC3021_MASK)
+			ia->ia_broadaddr.sin_addr.s_addr = INADDR_BROADCAST;
+		else
+			ia->ia_broadaddr.sin_addr.s_addr =
+			    htonl(ia->ia_subnet | ~ia->ia_subnetmask);
 	} else if (ifp->if_flags & IFF_LOOPBACK) {
 		ia->ia_dstaddr = ia->ia_addr;
 		flags |= RTF_HOST;
@@ -1230,9 +1233,11 @@ in_broadcast(struct in_addr in, struct i
 		if (ifa->ifa_addr->sa_family == AF_INET &&
 		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
 		     /*
-		      * Check for old-style (host 0) broadcast.
+		      * Check for old-style (host 0) broadcast, but
+		      * taking into account that RFC 3021 obsoletes it.
 		      */
-		     t == ia->ia_subnet) &&
+		     (ia->ia_subnetmask != IN_RFC3021_MASK &&
+		     t == ia->ia_subnet)) &&
 		     /*
 		      * Check for an all one subnetmask. These
 		      * only exist when an interface gets a secondary

Modified: head/sys/netinet/in.h
==============================================================================
--- head/sys/netinet/in.h	Sat Oct 15 16:28:06 2011	(r226401)
+++ head/sys/netinet/in.h	Sat Oct 15 18:41:25 2011	(r226402)
@@ -392,6 +392,8 @@ __END_DECLS
 
 #define	IN_LOOPBACKNET		127			/* official! */
 
+#define	IN_RFC3021_MASK		(u_int32_t)0xfffffffe
+
 /*
  * Options for use with [gs]etsockopt at the IP level.
  * First word of comment is data type; bool is stored in int.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110151841.p9FIfQLE025750>