Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 May 1999 17:07:14 -0700 (PDT)
From:      Dean Gaudet <dgaudet-list-freebsd-net@arctic.org>
To:        freebsd-net@FreeBSD.ORG
Subject:   cidr aliases
Message-ID:  <Pine.LNX.3.96dg4.990506170025.9393R-100000@twinlark.arctic.org>

next in thread | raw e-mail | index | archive | help
We have an application which requires a godawfully large number of aliases
on one box.  The linear list used to handle this stuff in 2.2.x (and 3.1.x
from what I can tell) just isn't cutting it.  (16ms localnet ping times
for some of the higher numbered aliases... bandwidth drops off from
8Mbyte/s down to 160kbyte/s due to the high cost of receiving packets...) 

We essentially allocate entire CIDR blocks to a single box.  So naturally
it'd be cool if we could just alias the entire CIDR block in one fell
swoop... this would reduce the kernel structures down to the minimum. 

I hacked together the patch included below against 2.2.8, which seems to
be a reasonable start.  It's not clean... but I was wondering if someone
else with more knowledge of the stack has a few moments to say "you're on
crack, do it this way" or "you're heading the right way, here's a few
tweaks". 

A better solution would actually set some bit on a per-alias basis to
indicate if it is a CIDR-alias or a regular host-alias.  But for now I'm
happy if all aliases are CIDR-aliases... and I totally cheat by using the
netmask to indicate what the CIDR block is. 

This patch works fine when accessed from other boxes -- I can set up TCP
connections to any of the addresses in the CIDR block.  But the localhost
can't ping itself on any of the addresses. 

Dean

--- ./net/if.c.orig	Wed May  5 10:46:01 1999
+++ ./net/if.c	Wed May  5 10:46:06 1999
@@ -186,6 +186,9 @@
 		    equal(ifa->ifa_broadaddr, addr))
 			return (ifa);
 	}
+	/* pretend that aliases consume their entire subnet */
+	if ((ifa = ifa_ifwithnet(addr)) && (ifa->ifa_flags & IFA_ALIAS))
+		return (ifa);
 	return ((struct ifaddr *)0);
 }
 /*
--- ./net/if.h.orig	Mon Jul  6 22:24:08 1998
+++ ./net/if.h	Wed May  5 10:54:16 1999
@@ -321,6 +321,7 @@
 
 };
 #define	IFA_ROUTE	RTF_UP		/* route installed */
+#define IFA_ALIAS	0x80		/* this is unused by RTF flags... */
 
 /*
  * Message format for use in obtaining information about interfaces
--- ./netinet/ip_input.c.orig	Wed May  5 10:46:01 1999
+++ ./netinet/ip_input.c	Wed May  5 10:46:06 1999
@@ -435,6 +435,16 @@
 			if (ip->ip_dst.s_addr == ia->ia_netbroadcast.s_addr)
 				goto ours;
 		}
+		/* if it's not the first address on the interface it
+		 * is an alias -- in that case consider all addresses
+		 * under the aliased netmask to be ours... that is,
+		 * pretend an entire CIDR block is aliased to us.
+		 */
+		if (ia->ia_ifa.ifa_flags & IFA_ALIAS) {
+			if ((ntohl(ip->ip_dst.s_addr) & ia->ia_subnetmask)
+			      == ia->ia_subnet)
+			  	goto ours;
+		}
 	}
 	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
 		struct in_multi *inm;
--- ./netinet/ip_icmp.c.orig	Wed May  5 10:46:01 1999
+++ ./netinet/ip_icmp.c	Wed May  5 10:55:22 1999
@@ -529,6 +529,10 @@
 		if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) &&
 		    t.s_addr == satosin(&ia->ia_broadaddr)->sin_addr.s_addr)
 			break;
+		if (ia->ia_ifa.ifa_flags & IFA_ALIAS)
+			if ((ntohl(ip->ip_dst.s_addr) & ia->ia_subnetmask)
+			    == ia->ia_subnet)
+				break;
 	}
 	icmpdst.sin_addr = t;
 	if ((ia == (struct in_ifaddr *)0) && m->m_pkthdr.rcvif)
--- ./netinet/in.c.orig	Wed May  5 10:47:02 1999
+++ ./netinet/in.c	Wed May  5 10:52:57 1999
@@ -327,6 +327,7 @@
 		break;
 
 	case SIOCAIFADDR:
+		ia->ia_ifa.ifa_flags |= IFA_ALIAS;
 		maskIsNew = 0;
 		hostIsNew = 1;
 		error = 0;




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.3.96dg4.990506170025.9393R-100000>