From owner-freebsd-net Thu May 6 17: 7:40 1999 Delivered-To: freebsd-net@freebsd.org Received: from twinlark.arctic.org (twinlark.arctic.org [204.107.140.52]) by hub.freebsd.org (Postfix) with SMTP id E388814BF4 for ; Thu, 6 May 1999 17:07:36 -0700 (PDT) (envelope-from dgaudet-list-freebsd-net@arctic.org) Received: (qmail 25576 invoked by uid 500); 7 May 1999 00:07:14 -0000 Date: Thu, 6 May 1999 17:07:14 -0700 (PDT) From: Dean Gaudet To: freebsd-net@FreeBSD.ORG Subject: cidr aliases Message-ID: X-Comment: Visit http://www.arctic.org/~dgaudet/legal for information regarding copyright and disclaimer. MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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