viktor@phoenix.Princeton.EDU (Viktor Dukhovni) (08/18/89)
Consider following topology: .... The universe | | G0 | | ==Net 1=============================== Subnetted Class B net | with say 6 subnet bits | G1 | | ===Net 2============================== Same Class B net with 9 | | subnet bits ??? G2 G3 | | =====Net 3===== =====Net 4==== Both have 9 subnet bits. Still same class B net??? Usually one would assign Class C addresses to nets 3 & 4, not subsubnet, and advertise routing information for both. Instead it is tempting to hide the interior topology from the rest of the world, by having different netmasks on the two interfaces of G1. This should cause no problem for G0 which should perceive the network behind G1 as being flat, also G2 & G3 are ok since they can simply "route add default G1". All the potential trouble arises on G1, which no longer has a clear notion of the correct subnet mask for the class B net in question. And yet I think that there is a natural scheme for allowing this new behaviour. Rule: ----- Given an address X, whose standard network part (Y) matches the standard network part of a non zero number of interfaces on a host, consider the network part of that address to be: 1) X & IPNETMASK(i), if (X & IPNETMASK(i)) == (IPADDR(i) & IPNETMASK(i)) for some interface i. That is, if X is an address of a host on the network connected to interface i [ Or we think is so anyway, this network could be further subsubnetted, but what we don't know can't hurt us, right??? After all we are tryin to play hide redundant information! ] or 2) X & Intersection(IPNETMASK(i)) if none of the interfaces are directly std(i)=Y connected to X. The motivation behind part 2, is that in a sub-subnet situation addresses not on one of the "would be Class C" nets, must be on the other side of G1, and so should use the coarser netmask. The host part of the address should then be X & ~(IN_NETOF(X)). Such schemes are not supported by the current sys/netinet/in.c code. Here is a proposed change to in_netof(), that would implement part of this policy. I would like to solicit comments on the folly/wisdom of this analysis. -- Viktor Dukhovni <viktor%math@Princeton.EDU> : ARPA <...!princeton!math!viktor> : UUCP ------- in.c ------- *** /tmp/da2073 Fri Aug 18 02:26:12 1989 --- sys/netinet/in.c Fri Aug 18 02:25:58 1989 *************** *** 78,83 **** --- 78,84 ---- { register u_long i = ntohl(in.s_addr); register u_long net; + register u_long mask = ~0L ; register struct in_ifaddr *ia; if (IN_CLASSA(i)) *************** *** 90,102 **** return (0); /* ! * Check whether network is a subnet; ! * if so, return subnet number. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) ! if (net == ia->ia_net) ! return (i & ia->ia_subnetmask); ! return (net); } /* --- 91,112 ---- return (0); /* ! * Check whether network is subnetted; ! * Allow a subnet gateway to SUBSUBNET! ! * This means that the subnet mask is ! * The smallest is no interface matches, ! * or the subnet mask for a particular interface ! * if that interface matches. ! * Note that this code reduces to the usual case ! * if all the netmasks are the same. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) ! if ( net == ia->ia_net ) { ! if ( (i & ia->ia_subnetmask) == ia->ia_subnet ) ! return(ia->ia_subnet) ; ! mask &= ia->ia_subnetmask ; ! } ! return (~mask ? mask&i : net); } /*
viktor@MATH.PRINCETON.EDU (Viktor Dukhovni) (08/24/89)
Consider following topology: .... The universe | | G0 | | ==Net 1=============================== Subnetted Class B net | with say 6 subnet bits | G1 | | ===Net 2============================== Same Class B net with 9 | | subnet bits ??? G2 G3 | | =====Net 3===== =====Net 4==== Both have 9 subnet bits. Still same class B net??? Usually one would assign Class C addresses to nets 3 & 4, not subsubnet, and advertise routing information for both. Instead it is tempting to hide the interior topology from the rest of the world, by having different netmasks on the two interfaces of G1. This should cause no problem for G0 which should perceive the network behind G1 as being flat, also G2 & G3 are ok since they can simply "route add default G1". All the potential trouble arises on G1, which no longer has a clear notion of the correct subnet mask for the class B net in question. And yet I think that there is a natural scheme for allowing this new behaviour. Rule: ----- Given an address X, whose standard network part (Y) matches the standard network part of a non zero number of interfaces on a host, consider the network part of that address to be: 1) X & IPNETMASK(i), if (X & IPNETMASK(i)) == (IPADDR(i) & IPNETMASK(i)) for some interface i. That is, if X is an address of a host on the network connected to interface i [ Or we think is so anyway, this network could be further subsubnetted, but what we don't know can't hurt us, right??? After all we are tryin to play hide redundant information! ] or 2) X & Intersection(IPNETMASK(i)) if none of the interfaces are directly std(i)=Y connected to X. The motivation behind part 2, is that in a sub-subnet situation addresses not on one of the "would be Class C" nets, must be on the other side of G1, and so should use the coarser netmask. The host part of the address should then be X & ~(IN_NETOF(X)). Such schemes are not supported by the current sys/netinet/in.c code. Here is a proposed change to in_netof(), that would implement part of this policy. I would like to solicit comments on the folly/wisdom of this analysis. -- Viktor Dukhovni <viktor@math.princeton.edu> : ARPA <...!uunet!princeton!math!viktor> : UUCP +1-(609)-452-5792 : VOICE ------- in.c ------- *** /tmp/da2073 Fri Aug 18 02:26:12 1989 --- sys/netinet/in.c Fri Aug 18 02:25:58 1989 *************** *** 78,83 **** --- 78,84 ---- { register u_long i = ntohl(in.s_addr); register u_long net; + register u_long mask = ~0L ; register struct in_ifaddr *ia; if (IN_CLASSA(i)) *************** *** 90,102 **** return (0); /* ! * Check whether network is a subnet; ! * if so, return subnet number. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) ! if (net == ia->ia_net) ! return (i & ia->ia_subnetmask); ! return (net); } /* --- 91,112 ---- return (0); /* ! * Check whether network is subnetted; ! * Allow a subnet gateway to SUBSUBNET! ! * This means that the subnet mask is ! * The smallest is no interface matches, ! * or the subnet mask for a particular interface ! * if that interface matches. ! * Note that this code reduces to the usual case ! * if all the netmasks are the same. */ for (ia = in_ifaddr; ia; ia = ia->ia_next) ! if ( net == ia->ia_net ) { ! if ( (i & ia->ia_subnetmask) == ia->ia_subnet ) ! return(ia->ia_subnet) ; ! mask &= ia->ia_subnetmask ; ! } ! return (~mask ? mask&i : net); } /*