All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ROUTE target
@ 2003-06-24 14:42 Cedric de Launois
  2003-07-18  8:37 ` [PATCH] [RESEND] " Cedric de Launois
  0 siblings, 1 reply; 8+ messages in thread
From: Cedric de Launois @ 2003-06-24 14:42 UTC (permalink / raw)
  To: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 758 bytes --]

Hi !

Here is a new version of the ROUTE target. Following discussions,
it seems that there is a need to make the ROUTE target also a
non-final target. So I added a new option --force. When not using
this option, the behaviour is to set the route and continue traversal.
When using this option, the behaviour is as before, i.e. the packet
is sent and the packet is stolen. This remains useful when we have
to force the use of an interface (rather unfrequent).

Changes :
- ipt_ROUTE.c : 
     added --force option
     cosmetic changes
- ipt_ROUTE.h : added --force option
- libipt_ROUTE.c : added --force option
- ROUTE.patch.config.in : target kernel option now depends on
     CONFIG_IP_NF_MANGLE kernel option

The patch is against current cvs.

Cedric


[-- Attachment #2: ROUTE.cvs.patch --]
[-- Type: text/x-patch, Size: 14268 bytes --]

diff -Nru netfilter.orig/patch-o-matic/extra/ROUTE.patch netfilter/patch-o-matic/extra/ROUTE.patch
--- netfilter.orig/patch-o-matic/extra/ROUTE.patch	2003-06-24 15:10:12.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch	2003-06-24 15:22:19.000000000 +0200
@@ -1,7 +1,7 @@
 diff -Nru linux.orig/include/linux/netfilter_ipv4/ipt_ROUTE.h linux/include/linux/netfilter_ipv4/ipt_ROUTE.h
---- linux.orig/include/linux/netfilter_ipv4/ipt_ROUTE.h	Thu Jan  1 01:00:00 1970
-+++ linux/include/linux/netfilter_ipv4/ipt_ROUTE.h	Tue Dec 17 16:49:04 2002
-@@ -0,0 +1,18 @@
+--- linux.orig/include/linux/netfilter_ipv4/ipt_ROUTE.h	1970-01-01 01:00:00.000000000 +0100
++++ linux/include/linux/netfilter_ipv4/ipt_ROUTE.h	2003-06-24 10:40:54.000000000 +0200
+@@ -0,0 +1,22 @@
 +/* Header file for iptables ipt_ROUTE target
 + *
 + * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
@@ -14,23 +14,27 @@
 +#define IPT_ROUTE_IFNAMSIZ 16
 +
 +struct ipt_route_target_info {
-+	char oif[IPT_ROUTE_IFNAMSIZ];
-+	char iif[IPT_ROUTE_IFNAMSIZ];
-+	unsigned int gw;
++	char      oif[IPT_ROUTE_IFNAMSIZ];      /* Output Interface Name */
++	char      iif[IPT_ROUTE_IFNAMSIZ];      /* Input Interface Name  */
++	u_int32_t gw;                           /* IP address of gateway */
++	u_int8_t  flags;
 +};
 +
++/* Values for "flags" field */
++#define IPT_ROUTE_FORCE        0x01
++
 +#endif /*_IPT_ROUTE_H_target*/
 diff -Nru linux.orig/net/ipv4/netfilter/ipt_ROUTE.c linux/net/ipv4/netfilter/ipt_ROUTE.c
---- linux.orig/net/ipv4/netfilter/ipt_ROUTE.c	Thu Jan  1 01:00:00 1970
-+++ linux/net/ipv4/netfilter/ipt_ROUTE.c	Wed Feb 26 17:25:39 2003
-@@ -0,0 +1,359 @@
+--- linux.orig/net/ipv4/netfilter/ipt_ROUTE.c	1970-01-01 01:00:00.000000000 +0100
++++ linux/net/ipv4/netfilter/ipt_ROUTE.c	2003-06-24 15:19:15.000000000 +0200
+@@ -0,0 +1,370 @@
 +/*
 + * This implements the ROUTE target, which enables you to setup unusual
 + * routes not supported by the standard kernel routing table.
 + *
 + * Copyright (C) 2002 Cedric de Launois <delaunois@info.ucl.ac.be>
 + *
-+ * v 1.6 2003/02/26
++ * v 1.8 2003/06/24
 + *
 + * This software is distributed under GNU GPL v2, 1991
 + */
@@ -56,7 +60,7 @@
 +/* Try to route the packet according to the routing keys specified in
 + * route_info. Keys are :
 + *  - ifindex : 
-+ *      0 if no oif prefered, 
++ *      0 if no oif preferred, 
 + *      otherwise set to the index of the desired oif
 + *  - route_info->gw :
 + *      0 if no gateway specified,
@@ -88,9 +92,10 @@
 +	if (route_info->gw)
 +		key.dst = route_info->gw;
 +	
-+	/* Trying to route the packet with the standard routing table. */
++	/* Trying to route the packet using the standard routing table. */
 +	if ((err = ip_route_output_key(&rt, &key))) {
-+		DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
++		if (net_ratelimit()) 
++			DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
 +		return -1;
 +	}
 +	
@@ -101,7 +106,6 @@
 +	/* Success if no oif specified or if the oif correspond to the 
 +	 * one desired */
 +	if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
-+		/* Drop old route. */
 +		skb->dst = &rt->u.dst;
 +		skb->dev = skb->dst->dev;
 +		return 1;
@@ -111,8 +115,9 @@
 +	 * specified by the user. This may happen because the dst address
 +	 * is one of our own addresses.
 +	 */
-+	DEBUGP("ipt_ROUTE: failed to route as desired (oif: %i)", 
-+	       rt->u.dst.dev->ifindex);
++	if (net_ratelimit()) 
++		DEBUGP("ipt_ROUTE: failed to route as desired gw=%u.%u.%u.%u oif=%i (got oif=%i)\n", 
++		       NIPQUAD(route_info->gw), ifindex, rt->u.dst.dev->ifindex);
 +	
 +	return 0;
 +}
@@ -159,64 +164,70 @@
 +static unsigned int route_oif(const struct ipt_route_target_info *route_info,
 +			      struct sk_buff *skb) 
 +{
-+	int err;
 +	unsigned int ifindex = 0;
 +	struct net_device *dev_out = NULL;
 +
 +	/* The user set the interface name to use.
 +	 * Getting the current interface index.
 +	 */
-+	if ((dev_out = dev_get_by_name(route_info->oif)))
++	if ((dev_out = dev_get_by_name(route_info->oif))) {
 +		ifindex = dev_out->ifindex;
-+	else 
++	} else {
 +		/* Unknown interface name : packet dropped */
++		if (net_ratelimit()) 
++			DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
 +		return NF_DROP;
-+	
-+	DEBUGP(KERN_DEBUG "oif index of %s is %i\n", route_info->oif, ifindex);
-+
-+
-+	/* Trying the standard way of routing packets */
-+	err = route(skb, ifindex, route_info);
-+	if (err==1) {
-+		DEBUGP(KERN_DEBUG "ROUTE oif ok, skb->dev->index=%i\n",
-+		       skb->dev->ifindex);
-+
-+		dev_put(dev_out);
-+		ip_direct_send(skb);
-+		return NF_STOLEN;
 +	}
 +
-+	if (err) {
++	/* Trying the standard way of routing packets */
++	switch (route(skb, ifindex, route_info)) {
++	case 1:
 +		dev_put(dev_out);
-+		return NF_DROP;
-+	}
++		if (route_info->flags & IPT_ROUTE_FORCE) {
++			ip_direct_send(skb);
++			return NF_STOLEN;
++		}
 +
-+	/* Failed to send to oif. Trying the hard way */
++		return IPT_CONTINUE;
 +
-+	DEBUGP(KERN_DEBUG "HARD ROUTING\n");
++	case 0:
++		/* Failed to send to oif. Trying the hard way */
++		if (!(route_info->flags & IPT_ROUTE_FORCE))
++			return NF_DROP;
 +
-+	/* We have to force the use of an interface.
-+	 * This interface must be a tunnel interface since
-+	 * otherwise we can't guess the hw address for
-+	 * the packet. For a tunnel interface, no hw address
-+	 * is needed.
-+	 */
-+	if ((dev_out->type != ARPHRD_TUNNEL)
-+	    && (dev_out->type != ARPHRD_IPGRE)) {
-+		DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
++		if (net_ratelimit()) 
++			DEBUGP("ipt_ROUTE: forcing the use of %i\n",
++			       ifindex);
++
++		/* We have to force the use of an interface.
++		 * This interface must be a tunnel interface since
++		 * otherwise we can't guess the hw address for
++		 * the packet. For a tunnel interface, no hw address
++		 * is needed.
++		 */
++		if ((dev_out->type != ARPHRD_TUNNEL)
++		    && (dev_out->type != ARPHRD_IPGRE)) {
++			if (net_ratelimit()) 
++				DEBUGP("ipt_ROUTE: can't guess the hw addr !\n");
++			dev_put(dev_out);
++			return NF_DROP;
++		}
++	
++		/* Send the packet. This will also free skb
++		 * Do not go through the POST_ROUTING hook because 
++		 * skb->dst is not set and because it will probably
++		 * get confused by the destination IP address.
++		 */
++		skb->dev = dev_out;
++		dev_direct_send(skb);
++		dev_put(dev_out);
++		return NF_STOLEN;
++		
++	default:
++		/* Unexpected error */
 +		dev_put(dev_out);
 +		return NF_DROP;
 +	}
-+	
-+	/* Send the packet. This will also free skb
-+	 * Do not go through the POST_ROUTING hook because 
-+	 * skb->dst is not set and because it will probably
-+	 * get confused by the destination IP address.
-+	 */
-+	skb->dev = dev_out;
-+	dev_direct_send(skb);
-+	dev_put(dev_out);
-+	return NF_STOLEN;
 +}
 +
 +
@@ -229,11 +240,12 @@
 +	/* Getting the current interface index. */
 +	if ((dev_out = dev_get_by_name(route_info->iif)))
 +		ifindex = dev_out->ifindex;
-+	else 
++	else {
 +		/* Unknown interface name : packet dropped */
++		if (net_ratelimit()) 
++			DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->oif);
 +		return NF_DROP;
-+
-+	DEBUGP(KERN_DEBUG "iif index of %s is %i\n", route_info->iif, ifindex);
++	}
 +
 +	skb->dev = dev_out;
 +	dst_release(skb->dst);
@@ -251,12 +263,11 @@
 +	if (route(skb, 0, route_info)!=1)
 +		return NF_DROP;
 +
-+	DEBUGP(KERN_DEBUG "ROUTE gw ok, skb->dev->index=%i\n",
-+	       skb->dev->ifindex);
-+
-+	ip_direct_send(skb);
-+
-+	return NF_STOLEN;
++	if (route_info->flags & IPT_ROUTE_FORCE) {
++		ip_direct_send(skb);
++		return NF_STOLEN;
++	} else
++		return IPT_CONTINUE;
 +}
 +
 +
@@ -308,12 +319,14 @@
 +	 * when a packet is leaving with dst address == our address.
 +	 * Good idea ? Dunno. Need advice.
 +	 */
-+	nf_conntrack_put(skb->nfct);
-+	skb->nfct = NULL;
-+	skb->nfcache = 0;
++	if (route_info->flags & IPT_ROUTE_FORCE) {
++		nf_conntrack_put(skb->nfct);
++		skb->nfct = NULL;
++		skb->nfcache = 0;
 +#ifdef CONFIG_NETFILTER_DEBUG
-+	skb->nf_debug = 0;
++		skb->nf_debug = 0;
 +#endif
++	}
 +
 +	if (route_info->oif[0]) 
 +		return route_oif(route_info, *pskb);
@@ -324,8 +337,10 @@
 +	if (route_info->gw) 
 +		return route_gw(route_info, *pskb);
 +
-+	DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
-+	return NF_ACCEPT;
++	if (net_ratelimit()) 
++		DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
++
++	return IPT_CONTINUE;
 +}
 +
 +
diff -Nru netfilter.orig/patch-o-matic/extra/ROUTE.patch.config.in netfilter/patch-o-matic/extra/ROUTE.patch.config.in
--- netfilter.orig/patch-o-matic/extra/ROUTE.patch.config.in	2003-06-24 15:10:12.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.config.in	2003-06-24 12:46:28.000000000 +0200
@@ -1,2 +1,2 @@
-  dep_tristate '  LOG target support' CONFIG_IP_NF_TARGET_LOG $CONFIG_IP_NF_IPTABLES
-  dep_tristate '  ROUTE target support' CONFIG_IP_NF_TARGET_ROUTE $CONFIG_IP_NF_IPTABLES
+    dep_tristate '    MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE
+    dep_tristate '    ROUTE target support' CONFIG_IP_NF_TARGET_ROUTE $CONFIG_IP_NF_MANGLE
diff -Nru netfilter.orig/patch-o-matic/extra/ROUTE.patch.configure.help netfilter/patch-o-matic/extra/ROUTE.patch.configure.help
--- netfilter.orig/patch-o-matic/extra/ROUTE.patch.configure.help	2003-06-24 15:10:12.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.configure.help	2003-06-24 11:33:25.000000000 +0200
@@ -8,8 +8,8 @@
   packet is the router itself. The ROUTE target is also able to change the 
   incoming interface of a packet.
 
-  This target does never modify the packet and is a final target.
-  It has to be used inside the mangle table.
+  The target can be or not a final target and has to be used inside the 
+  mangle table.
 
   
   If you want to compile it as a module, say M here and read
diff -Nru netfilter.orig/patch-o-matic/extra/ROUTE.patch.help netfilter/patch-o-matic/extra/ROUTE.patch.help
--- netfilter.orig/patch-o-matic/extra/ROUTE.patch.help	2003-06-24 15:10:12.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.help	2003-06-24 12:35:59.000000000 +0200
@@ -8,24 +8,29 @@
   packet is the router itself. The ROUTE target is also able to change the 
   incoming interface of a packet.
 
-  This target does never modify the packet and is a final target.
-  It has to be used inside the mangle table.
+  The target has to be used inside the mangle table.
 
   ROUTE target options:
-    --oif   ifname    Send the packet out using `ifname' network interface.
+    --oif   ifname    Route the packet through `ifname' network interface
     --iif   ifname    Change the packet's incoming interface to `ifname'.
     --gw    ip        Route the packet via this gateway.
+    --force           Force the use of the interface and send the packet.
+
+  The --force option can be used together with --oif or --gw. When using
+  this option, the target becomes a final target. Otherwise, the route
+  is simply set for the packet.
 
   Examples :
 
-  To redirect all outgoing icmp packet to the eth1 interface :
-  # iptables -A POSTROUTING -t mangle -p icmp -j ROUTE --oif eth1
+  To force all outgoing icmp packet to go through the eth1 interface 
+  (final target) :
+  # iptables -A POSTROUTING -t mangle -p icmp -j ROUTE --oif eth1 --force
 
   To tunnel all incoming http packets :
   # iptables -A PREROUTING -t mangle -p tcp --dport 80 -j ROUTE --oif tunl1
 
-  To force the next-hop used for ssh packets :
-  # iptables -A PREROUTING -t mangle -p tcp --dport 22 -j ROUTE --gw w.x.y.z
+  To change the the next-hop used for ssh packets :
+  # iptables -A POSTROUTING -t mangle -p tcp --dport 22 -j ROUTE --gw w.x.y.z
 
   To change the incoming network interface from eth0 to eth1 for icmp packets :
   # iptables -A PREROUTING -t mangle -p icmp -i eth0 -j ROUTE --iif eth1
diff -Nru netfilter.orig/userspace/extensions/libipt_ROUTE.c netfilter/userspace/extensions/libipt_ROUTE.c
--- netfilter.orig/userspace/extensions/libipt_ROUTE.c	2003-06-24 15:10:12.000000000 +0200
+++ netfilter/userspace/extensions/libipt_ROUTE.c	2003-06-24 15:19:48.000000000 +0200
@@ -1,5 +1,6 @@
 /* Shared library add-on to iptables to add ROUTE target support.
- * Author : Cédric de Launois, <delaunois@info.ucl.ac.be>
+ * Author : Cedric de Launois, <delaunois@info.ucl.ac.be>
+ * v 1.8 2003/06/24
  */
 
 #include <stdio.h>
@@ -20,17 +21,19 @@
 {
 	printf(
 "ROUTE target v%s options:\n"
-"  --oif   \tifname \t\tSend the packet out using `ifname' network interface\n"
+"  --oif   \tifname \t\tRoute the packet through `ifname' network interface\n"
 "  --iif   \tifname \t\tChange the packet's incoming interface to `ifname'\n"
 "  --gw    \tip     \t\tRoute the packet via this gateway\n"
+"  --force \t       \t\tForce the use of the interface and send the packet\n"
 "\n",
-IPTABLES_VERSION);
+"1.8");
 }
 
 static struct option opts[] = {
 	{ "oif", 1, 0, '1' },
 	{ "iif", 1, 0, '2' },
 	{ "gw", 1, 0, '3' },
+	{ "force", 0, 0, '4' },
 	{ 0 }
 };
 
@@ -44,6 +47,7 @@
 	route_info->oif[0] = '\0';
 	route_info->iif[0] = '\0';
 	route_info->gw = 0;
+	route_info->flags = 0;
 }
 
 
@@ -111,6 +115,10 @@
 		*flags |= IPT_ROUTE_OPT_GW;
 		break;
 
+	case '4':
+		route_info->flags |= IPT_ROUTE_FORCE;
+		break;
+
 	default:
 		return 0;
 	}
@@ -124,7 +132,7 @@
 {
 	if (!flags)
 		exit_error(PARAMETER_PROBLEM,
-		           "ROUTE target: one parameter is required");
+		           "ROUTE target: a oif, iif or gw parameter is required");
 }
 
 
@@ -149,6 +157,10 @@
 		struct in_addr ip = { route_info->gw };
 		printf("gw %s ", inet_ntoa(ip));
 	}
+
+	if (route_info->flags & IPT_ROUTE_FORCE)
+		printf("force");
+
 }
 
 
@@ -168,6 +180,9 @@
 		struct in_addr ip = { route_info->gw };
 		printf("--gw %s ", inet_ntoa(ip));
 	}
+
+	if (route_info->flags & IPT_ROUTE_FORCE)
+		printf("--force ");
 }
 
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2003-07-25 15:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-24 14:42 [PATCH] ROUTE target Cedric de Launois
2003-07-18  8:37 ` [PATCH] [RESEND] " Cedric de Launois
2003-07-20 18:15   ` Martin Josefsson
2003-07-21  8:25     ` Cedric de Launois
2003-07-25  9:43     ` [PATCH] corrected " Cedric de Launois
2003-07-25 11:36       ` Martin Josefsson
2003-07-25 13:16         ` [PATCH] update to " Cedric de Launois
2003-07-25 15:27           ` Martin Josefsson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.