From 331b4363053aa0348db11124ffb4bbe57f433a8a Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 6 Jul 2011 01:57:38 +0000 Subject: allow /31s on broadcast interfaces (eg ethernet) to work as per rfc3021. the issue in our kernel was the broadcast address calculated on the /31 caused a ton of checks for use of broadcast addresses to kick in and prevent one of the two addresses on the /31 from being used. this diff basically detects if a /31 has been configured and doesnt configure a broadcast address for it, which makes the ips usable for normal traffic. i wrote this so i could interoperate with "carrier" network gear better, and sthen wants it so he can conserve address space use. the further special casing of broadcast address handling was from claudio@ ok claudio@ markus@ sthen@ henning@ --- sys/netinet/in.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sys/netinet/in.c') diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 5ac859edea9..9167486dd95 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in.c,v 1.67 2011/07/03 06:24:13 dlg Exp $ */ +/* $OpenBSD: in.c,v 1.68 2011/07/06 01:57:37 dlg Exp $ */ /* $NetBSD: in.c,v 1.26 1996/02/13 23:41:39 christos Exp $ */ /* @@ -700,8 +700,12 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, */ ia->ia_ifa.ifa_metric = ifp->if_metric; if (ifp->if_flags & IFF_BROADCAST) { - ia->ia_broadaddr.sin_addr.s_addr = - ia->ia_net | ~ia->ia_netmask; + if (IN_RFC3021_SUBNET(ia->ia_netmask)) + ia->ia_broadaddr.sin_addr.s_addr = 0; + else { + ia->ia_broadaddr.sin_addr.s_addr = + ia->ia_net | ~ia->ia_netmask; + } } else if (ifp->if_flags & IFF_LOOPBACK) { ia->ia_dstaddr = ia->ia_addr; flags |= RTF_HOST; -- cgit v1.2.3