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>
