[372] in linux-net channel archive

home help back first fref pref prev next nref lref last post

RTF_BLOCK patch

daemon@ATHENA.MIT.EDU (ukd1@rz.uni-karlsruhe.de)
Wed May 24 20:47:35 1995

From: ukd1@rz.uni-karlsruhe.de
To: linux-kernel@vger.rutgers.edu, linux-net@vger.rutgers.edu
Followup-To: comp.os.linux.development.system
Date: 24 May 1995 21:52:11 GMT

I have written some small Kernelpatches to enable the metric field in the
Kernel-Routing Table, an additional Flag for automatically generated routes
by routing daemons a flag for setting up 'blocking' routes (dead routes) and
some more support for usermode routing daemons. See the README for
clearification.

The Patches, the Readme and the additional Programs can be found on

http://www.inka.de/sites/lina/linux/route/ or
ftp://ftp.inka.de/sites/lina/linux/route/

If you are a Developer give me some Feedback (especially about the
implementation).

Included after the Readme is _only_ route1.patch, see the above location for
the suplemental stuff.


BEGIN README ----------------------------------------------------------------

                                 route patch
                                 -----------

INSTALL
-------

route1.patch - apply this to 1.2.8 Kernel with

   cd /usr/src
   patch -p0 < route1.patch

   cd linux ; make zLilo           # recompile Kernel

   to add two new Flags for SIOCADDRT ioctl call (add route). And to add an
   additional IOCTL SIOCSLEEPRT. The Metric field in the Kernel routing 
   table will get accesable, too.

route2.patch - apply this to nettools-1.2.0.tar.gz with

   cd /usr/src/net
   patch -p0 < route2.patch

   make install                    # recompile binary

   to add support for the new routing Flags.


DESCRIPTION (the main purpose of this patch is metric and RTF_BLOCK)
-----------

RTF_AUTO - is a Flag, which will be set from a user-mode program to indicate
   that the new route is set from a routing daemon and not 'manually' on
   bootup or dialin. The Kernel saves the flag but does not query it. This
   is only for the usermode to mark dynamic routes (like RTF_DYNAMIC for
   ICMP redirects). Non RTF_AUTO routes should not be changed from an
   routing daemon. (It is possible to set the auto flag with the modified
   route command (route2.patch), but this is only for batch or debugging
   usage.

metric - The Metric Value provided by SIOCADDRT will now be stored in the
   kernel routing table. This value isnt used by the Kernel, its for
   usermode only. 

SIOCSLEEPRT - IOCTL to allow a usermode program to sleep until there is a 
   modification at the routing table. (by SIOC*RT or ICMP redirets)

RTF_BLOCK - This allows to install a (net)'route' which will make the
   lookup for a route fail. This is used to notify the sender that the
   destination is unreachable. This is at the curent implementation not
   possible, if there is a default Gateway (which is very common on Systems
   with access to the Internet).

   RTF_BLOCK is not primary for Firewalling (use IP_FIREWALL, ipfwadm
   instead) but to allow Linux to generate probably error Messages instead
   of Timeouts for unreachable (site-local) hosts.

   Example

-----------------------------------------
Kernel routing table
Destination     Gateway         Genmask         Flags MSS    Window Use Iface
localhost.      *               255.255.255.255 UH    1936   0        7 lo
host1.doma.in	*		255.255.255.255 UH    1436   0       10 eth0
host2.doma.in   *               255.255.255.255 UH    1436   0       12 eth0
host3.doma.in   host2.doma.in   255.255.255.255 UHGA  1436   0        1 eth0
doma-in-net     *               255.255.255.0   UB    1436   0        1 eth0
default         host1.doma.in   *               UG    1436   0      100 eth0
-----------------------------------------

   This Table is an example. localhost, host1 and host2 are set manually.
   host3 is set by some user-mode routing daemon and doma-in-net is a
   blocking route installed with:

   route add -net doma-in-net dev eth0 block

   In this example this particular hosts only routes packets to host1 host2
   and host3 of the domai-in-net. The World is still reachable. If the
   blocking route is missing all acces to unknown hosts of the local net
   will be routed to the default gateway.

   An other Example:

-----------------------------------------
Kernel routing table
Destination     Gateway         Genmask         Flags MSS    Window Use Iface
localhost.      *               255.255.255.255 UH    1936   0        7 lo
host1.doma.in	*		255.255.255.255 UHB   1436   0       10 eth0
doma-in-net     *               255.255.255.0   U     1436   0        1 eth0
-----------------------------------------

   In this case a packet to host1 will be rejected with a 'now route to
   host' but all other hosts from the Class-C Network attached to the eth0
   can be accessed if present. If they are not present it ony will generate
   a timeout.

bernd.eckenfels@inka.de

END   README ----------------------------------------------------------------


BEGIN route1.patch -----------------------------------------------------------

Patch to add RTF_AUTO, RTF_BLOCK, metric and SIOCSLEEPRT Support to Kernel.
This should cleanly patch at least against 1.2.8.

diff -u --recursive --new-file linux/include/linux/route.h.org linux/include/linux/route.h
--- route.c.org	Sun May  7 19:47:06 1995
+++ route.c	Sun May 21 07:15:04 1995
@@ -24,6 +24,7 @@
  *		Alan Cox	: 	MSS actually. Also added the window
  *					clamper.
  *		Sam Lantinga	:	Fixed route matching in rt_del()
+ *		Bernd Eckenfels :	Metric and RTF_BLOCK support
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -65,6 +66,15 @@
 static struct rtable *rt_loopback = NULL;
 
 /*
+ *      Waitqueue and Version for table changes
+ */
+
+static struct wait_queue * rt_change_wait = NULL;
+static unsigned rt_version=0;
+
+#define rt_change_wakeup() rt_version++; wake_up_interruptible(&rt_change_wait);
+ 
+/*
  *	Remove a routing table entry.
  */
 
@@ -72,8 +82,10 @@
 {
 	struct rtable *r, **rp;
 	unsigned long flags;
+ 	short changed;
 
 	rp = &rt_base;
+	changed = 0;
 	
 	/*
 	 *	This must be done with interrupts off because we could take
@@ -92,6 +104,7 @@
 			continue;
 		}
 		*rp = r->rt_next;
+		changed = 1;
 		
 		/*
 		 *	If we delete the loopback route update its pointer.
@@ -102,6 +115,8 @@
 		kfree_s(r, sizeof(struct rtable));
 	} 
 	restore_flags(flags);
+	if (changed)
+		rt_change_wakeup();
 }
 
 
@@ -115,8 +130,10 @@
 	struct rtable *r;
 	struct rtable **rp;
 	unsigned long flags;
+	short changed;
 
 	rp = &rt_base;
+	changed = 0;
 	save_flags(flags);
 	cli();
 	while ((r = *rp) != NULL) {
@@ -125,11 +142,14 @@
 			continue;
 		}
 		*rp = r->rt_next;
+		changed = 1;
 		if (rt_loopback == r)
 			rt_loopback = NULL;
 		kfree_s(r, sizeof(struct rtable));
 	} 
 	restore_flags(flags);
+	if (changed)
+		rt_change_wakeup();
 }
 
 /*
@@ -201,7 +221,8 @@
  */
  
 void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
-	unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window)
+	unsigned long gw, struct device *dev, unsigned short mtu, 
+	unsigned long window, short metric)
 {
 	struct rtable *r, *rt;
 	struct rtable **rp;
@@ -273,6 +294,7 @@
 	rt->rt_dev = dev;
 	rt->rt_gateway = gw;
 	rt->rt_mask = mask;
+	rt->rt_metric = metric;
 	rt->rt_mss = dev->mtu - HEADER_SIZE;
 	rt->rt_window = 0;	/* Default is no clamping */
 
@@ -338,6 +360,7 @@
 	 */
 	 
 	restore_flags(cpuflags);
+	rt_change_wakeup();
 	return;
 }
 
@@ -460,7 +483,8 @@
 	 *	Add the route
 	 */
 	 
-	ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window);
+	ip_rt_add(flags, daddr, mask, gw, dev, 
+	          r->rt_mss, r->rt_window, r->rt_metric);
 	return 0;
 }
 
@@ -511,7 +535,7 @@
 	 
 	for (r = rt_base; r != NULL; r = r->rt_next) 
 	{
-        	size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\t%d\t%lu\n",
+        	size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%04X\t%d\t%lu\t%d\t%08lX\t%d\t%lu\n",
 			r->rt_dev->name, r->rt_dst, r->rt_gateway,
 			r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
 			r->rt_mask, (int)r->rt_mss, r->rt_window);
@@ -564,6 +588,8 @@
 			break;
 	}
 	
+	if (rt->rt_flags & RTF_BLOCK)
+	        goto no_route;
 	if(src_addr!=NULL)
 		*src_addr= rt->rt_dev->pa_addr;
 		
@@ -645,6 +671,7 @@
 {
 	int err;
 	struct rtentry rt;
+	unsigned tmp_rt_version;
 
 	switch(cmd) 
 	{
@@ -666,7 +693,16 @@
 				return err;
 			memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
 			return (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
-	}
 
+		case SIOCSLEEPRT:    /* Sleep for routing table modification */
+			tmp_rt_version = rt_version;
+			while(tmp_rt_version == rt_version) {
+			
+				interruptible_sleep_on(&rt_change_wait);
+				
+				if (current->signal & ~current->blocked)
+					return(-EINTR);
+			}
+	}
 	return -EINVAL;
 }

END   route1.patch -----------------------------------------------------------

-- __
  (OO)      --  Bernd_Eckenfels@Wittumstrasse13.76646Bruchsal.de  --
 ( .. ) +4972573817  ecki@lina.{inka.de,ka.sub.org}  ukd1@rz.uni.karlsruhe.de
  o--o           *QUAK* Jetzt auch mit Plueschtier in der .Sig!
(O____O)   <A href=http://rzstud1.rz.uni-karlsruhe.de/~ukd1/>Eckes@IRC</A>

home help back first fref pref prev next nref lref last post