[comp.protocols.tcp-ip] SubSubNets ???

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);
  }
  
  /*