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

* [PATCH] [RESEND] ROUTE target
  2003-06-24 14:42 [PATCH] ROUTE target Cedric de Launois
@ 2003-07-18  8:37 ` Cedric de Launois
  2003-07-20 18:15   ` Martin Josefsson
  0 siblings, 1 reply; 8+ messages in thread
From: Cedric de Launois @ 2003-07-18  8:37 UTC (permalink / raw)
  To: Harald Welte, Netfilter Development Mailinglist

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

This is a resend of the ROUTE patch I sent nearly one month ago.
Please apply or give me comments.

Cedric

Le mar 24/06/2003 à 16:42, Cedric de Launois a écrit :
> 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

* Re: [PATCH] [RESEND] ROUTE target
  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
  0 siblings, 2 replies; 8+ messages in thread
From: Martin Josefsson @ 2003-07-20 18:15 UTC (permalink / raw)
  To: Cedric de Launois; +Cc: Harald Welte, Netfilter Development Mailinglist

On Fri, 2003-07-18 at 10:37, Cedric de Launois wrote:
> This is a resend of the ROUTE patch I sent nearly one month ago.
> Please apply or give me comments.
> 
> Cedric
> 
> Le mar 24/06/2003 à 16:42, Cedric de Launois a écrit :
> > 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).

My concern is that even though this target isn't included in the kernel
it's a bad idea to change the current behaviour if it can be avoidable.
I mean this target has existed in pom for quite some time (just over 1
year) and if the behaviour changes it might make for some surprises for
its users. Sure the options has changed names over time but that's the
sort of change that users notice quite easily. A subtle change that
suddenly continues traversing rules might lead to weird things.

It's your target but I'd like you to think about this and maybe rename
the new option and leave the default as is.

-- 
/Martin

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

* Re: [PATCH] [RESEND] ROUTE target
  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
  1 sibling, 0 replies; 8+ messages in thread
From: Cedric de Launois @ 2003-07-21  8:25 UTC (permalink / raw)
  To: Martin Josefsson; +Cc: Netfilter Development Mailinglist

Le dim 20/07/2003 à 20:15, Martin Josefsson a écrit :
> On Fri, 2003-07-18 at 10:37, Cedric de Launois wrote:
> > This is a resend of the ROUTE patch I sent nearly one month ago.
> > Please apply or give me comments.
> > 
> > Cedric
> > 
> > Le mar 24/06/2003 à 16:42, Cedric de Launois a écrit :
> > > 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).
> 
> My concern is that even though this target isn't included in the kernel
> it's a bad idea to change the current behaviour if it can be avoidable.
> I mean this target has existed in pom for quite some time (just over 1
> year) and if the behaviour changes it might make for some surprises for
> its users. Sure the options has changed names over time but that's the
> sort of change that users notice quite easily. A subtle change that
> suddenly continues traversing rules might lead to weird things.
> 
> It's your target but I'd like you to think about this and maybe rename
> the new option and leave the default as is.

My concern is that the current behaviour is perhaps not the most logical
one. But you're certainly right. I'll submit a modified patch later.

Thanks for your comment.

Cedric

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

* [PATCH] corrected ROUTE target
  2003-07-20 18:15   ` Martin Josefsson
  2003-07-21  8:25     ` Cedric de Launois
@ 2003-07-25  9:43     ` Cedric de Launois
  2003-07-25 11:36       ` Martin Josefsson
  1 sibling, 1 reply; 8+ messages in thread
From: Cedric de Launois @ 2003-07-25  9:43 UTC (permalink / raw)
  To: Martin Josefsson; +Cc: Netfilter Development Mailinglist

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

Le dim 20/07/2003 à 20:15, Martin Josefsson a écrit :
> > Le mar 24/06/2003 à 16:42, Cedric de Launois a écrit :
> > > 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).
> 
> My concern is that even though this target isn't included in the kernel
> it's a bad idea to change the current behaviour if it can be avoidable.
> I mean this target has existed in pom for quite some time (just over 1
> year) and if the behaviour changes it might make for some surprises for
> its users. Sure the options has changed names over time but that's the
> sort of change that users notice quite easily. A subtle change that
> suddenly continues traversing rules might lead to weird things.
> 
> It's your target but I'd like you to think about this and maybe rename
> the new option and leave the default as is.

Ok. So here is the ROUTE patch that preserves the old behaviour.
The new option is called --continue. When using it, the packet is routed
and then continues travering the rules. If the option is not used, the
behaviour is as before (i.e. the packet is sent).

The patch is against current cvs.

Cedric


[-- Attachment #2: ROUTE.cvs.patch --]
[-- Type: text/x-patch, Size: 13444 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-07-25 10:38:03.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch	2003-07-25 11:37:50.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-07-25 11:05:27.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_CONTINUE        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-07-25 11:07:47.000000000 +0200
+@@ -0,0 +1,369 @@
 +/*
 + * 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/07/25
 + *
 + * 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,69 @@
 +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);
-+
++	switch (route(skb, ifindex, route_info)) {
++	case 1:
 +		dev_put(dev_out);
++		if (route_info->flags & IPT_ROUTE_CONTINUE)
++			return IPT_CONTINUE;
++
 +		ip_direct_send(skb);
 +		return NF_STOLEN;
-+	}
 +
-+	if (err) {
-+		dev_put(dev_out);
-+		return NF_DROP;
-+	}
-+
-+	/* Failed to send to oif. Trying the hard way */
-+
-+	DEBUGP(KERN_DEBUG "HARD ROUTING\n");
++	case 0:
++		/* Failed to send to oif. Trying the hard way */
++		if (route_info->flags & IPT_ROUTE_CONTINUE)
++			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 +239,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,11 +262,10 @@
 +	if (route(skb, 0, route_info)!=1)
 +		return NF_DROP;
 +
-+	DEBUGP(KERN_DEBUG "ROUTE gw ok, skb->dev->index=%i\n",
-+	       skb->dev->ifindex);
++	if (route_info->flags & IPT_ROUTE_CONTINUE)
++		return IPT_CONTINUE;
 +
 +	ip_direct_send(skb);
-+
 +	return NF_STOLEN;
 +}
 +
@@ -308,12 +318,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_CONTINUE)) {
++		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 +336,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/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-07-25 11:24:35.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,20 @@
 {
 	printf(
 "ROUTE target v%s options:\n"
-"  --oif   \tifname \t\tSend the packet out using `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"
+"    --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"
+"    --continue\t     \t\tRoute the packet and continue traversing the\n"
+"            \t       \t\trules. Not valid with --iif.\n"
 "\n",
-IPTABLES_VERSION);
+"1.8");
 }
 
 static struct option opts[] = {
 	{ "oif", 1, 0, '1' },
 	{ "iif", 1, 0, '2' },
 	{ "gw", 1, 0, '3' },
+	{ "continue", 0, 0, '4' },
 	{ 0 }
 };
 
@@ -44,11 +48,14 @@
 	route_info->oif[0] = '\0';
 	route_info->iif[0] = '\0';
 	route_info->gw = 0;
+	route_info->flags = 0;
 }
 
 
-#define IPT_ROUTE_OPT_IF       0x01
-#define IPT_ROUTE_OPT_GW       0x02
+#define IPT_ROUTE_OPT_OIF      0x01
+#define IPT_ROUTE_OPT_IIF      0x02
+#define IPT_ROUTE_OPT_GW       0x04
+#define IPT_ROUTE_OPT_CONTINUE 0x08
 
 /* Function which parses command options; returns true if it
    ate an option */
@@ -62,9 +69,13 @@
 
 	switch (c) {
 	case '1':
-		if (*flags & IPT_ROUTE_OPT_IF)
+		if (*flags & IPT_ROUTE_OPT_OIF)
 			exit_error(PARAMETER_PROBLEM,
-				   "Can't specify --oif twice or --oif with --iif");
+				   "Can't specify --oif twice");
+
+		if (*flags & IPT_ROUTE_OPT_IIF)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't use --oif and --iif together");
 
 		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
@@ -76,13 +87,17 @@
 				   sizeof(route_info->oif) - 1);
 
 		strcpy(route_info->oif, optarg);
-		*flags |= IPT_ROUTE_OPT_IF;
+		*flags |= IPT_ROUTE_OPT_OIF;
 		break;
 
 	case '2':
-		if (*flags & IPT_ROUTE_OPT_IF)
+		if (*flags & IPT_ROUTE_OPT_IIF)
 			exit_error(PARAMETER_PROBLEM,
-				   "Can't specify --iif twice or --iif with --oif");
+				   "Can't specify --iif twice");
+
+		if (*flags & IPT_ROUTE_OPT_OIF)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't use --iif and --oif together");
 
 		if (check_inverse(optarg, &invert, NULL, 0))
 			exit_error(PARAMETER_PROBLEM,
@@ -94,7 +109,7 @@
 				   sizeof(route_info->iif) - 1);
 
 		strcpy(route_info->iif, optarg);
-		*flags |= IPT_ROUTE_OPT_IF;
+		*flags |= IPT_ROUTE_OPT_IIF;
 		break;
 
 	case '3':
@@ -102,6 +117,10 @@
 			exit_error(PARAMETER_PROBLEM,
 				   "Can't specify --gw twice");
 
+		if (check_inverse(optarg, &invert, NULL, 0))
+			exit_error(PARAMETER_PROBLEM,
+				   "Unexpected `!' after --gw");
+
 		if (!inet_aton(optarg, (struct in_addr*)&route_info->gw)) {
 			exit_error(PARAMETER_PROBLEM,
 				   "Invalid IP address %s",
@@ -111,6 +130,16 @@
 		*flags |= IPT_ROUTE_OPT_GW;
 		break;
 
+	case '4':
+		if (*flags & IPT_ROUTE_OPT_CONTINUE)
+			exit_error(PARAMETER_PROBLEM,
+				   "Can't specify --continue twice");
+
+		route_info->flags |= IPT_ROUTE_CONTINUE;
+		*flags |= IPT_ROUTE_OPT_CONTINUE;
+
+		break;
+
 	default:
 		return 0;
 	}
@@ -124,7 +153,11 @@
 {
 	if (!flags)
 		exit_error(PARAMETER_PROBLEM,
-		           "ROUTE target: one parameter is required");
+		           "ROUTE target: oif, iif or gw option required");
+
+	if ((flags & IPT_ROUTE_OPT_CONTINUE) && (flags & IPT_ROUTE_OPT_IIF))
+		exit_error(PARAMETER_PROBLEM,
+			   "ROUTE target: can't continue traversing the rules with iif option");
 }
 
 
@@ -140,15 +173,19 @@
 	printf("ROUTE ");
 
 	if (route_info->oif[0])
-		printf("oif %s ", route_info->oif);
+		printf("oif:%s ", route_info->oif);
 
 	if (route_info->iif[0])
-		printf("iif %s ", route_info->iif);
+		printf("iif:%s ", route_info->iif);
 
 	if (route_info->gw) {
 		struct in_addr ip = { route_info->gw };
-		printf("gw %s ", inet_ntoa(ip));
+		printf("gw:%s ", inet_ntoa(ip));
 	}
+
+	if (route_info->flags & IPT_ROUTE_CONTINUE)
+		printf("continue");
+
 }
 
 
@@ -168,6 +205,9 @@
 		struct in_addr ip = { route_info->gw };
 		printf("--gw %s ", inet_ntoa(ip));
 	}
+
+	if (route_info->flags & IPT_ROUTE_CONTINUE)
+		printf("--continue ");
 }
 
 

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

* Re: [PATCH] corrected ROUTE target
  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
  0 siblings, 1 reply; 8+ messages in thread
From: Martin Josefsson @ 2003-07-25 11:36 UTC (permalink / raw)
  To: Cedric de Launois; +Cc: Netfilter Development Mailinglist

On Fri, 25 Jul 2003, Cedric de Launois wrote:

> Ok. So here is the ROUTE patch that preserves the old behaviour.
> The new option is called --continue. When using it, the packet is routed
> and then continues travering the rules. If the option is not used, the
> behaviour is as before (i.e. the packet is sent).
>
> The patch is against current cvs.

Applied, thanks

/Martin

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

* [PATCH] update to ROUTE target
  2003-07-25 11:36       ` Martin Josefsson
@ 2003-07-25 13:16         ` Cedric de Launois
  2003-07-25 15:27           ` Martin Josefsson
  0 siblings, 1 reply; 8+ messages in thread
From: Cedric de Launois @ 2003-07-25 13:16 UTC (permalink / raw)
  To: Martin Josefsson; +Cc: Netfilter Development Mailinglist

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

Hi again,

Oops, I forgot to also submit changes to the ROUTE.patch.configure.help
and ROUTE.patch.help files to update the descriptions of the target.

I also modified ROUTE.patch.configure.in in order to make the ROUTE
target dependent of the CONFIG_IP_NF_MANGLE kernel option (since the
ROUTE target must be used inside the mangle table).

The patch is still against the very current cvs.

Thanks for applying it.

Cédric


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

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-07-25 14:30:09.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.config.in	2003-07-25 14:10:49.000000000 +0200
@@ -1,2 +1,3 @@
-  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
+ 
\ Pas de fin de ligne à la fin du fichier.
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-07-25 14:30:09.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.configure.help	2003-07-25 14:15:05.000000000 +0200
@@ -1,16 +1,14 @@
-CONFIG_IP_NF_TARGET_LOG
+CONFIG_IP_NF_TARGET_MARK
 ROUTE target support
 CONFIG_IP_NF_TARGET_ROUTE
   This option adds a `ROUTE' target, which enables you to setup unusual
-  routes not supported by the standard kernel routing table.
-  For example, the ROUTE lets you directly route a received packet through 
+  routes. For example, the ROUTE lets you route a received packet through 
   an interface or towards a host, even if the regular destination of the 
   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. It has to be used inside the 
+  mangle table.
   
   If you want to compile it as a module, say M here and read
   Documentation/modules.txt.  The module will be called ipt_ROUTE.o.
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-07-25 14:30:09.000000000 +0200
+++ netfilter/patch-o-matic/extra/ROUTE.patch.help	2003-07-25 14:51:25.000000000 +0200
@@ -1,32 +1,37 @@
 Author: Cédric de Launois <delaunois@info.ucl.ac.be>
-Status: In Development/Works for me
+Status: Experimental
   
   This option adds a `ROUTE' target, which enables you to setup unusual
-  routes not supported by the standard kernel routing table.
-  For example, the ROUTE lets you directly route a received packet through 
+  routes. For example, the ROUTE lets you route a received packet through 
   an interface or towards a host, even if the regular destination of the 
   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. It has to be used inside the 
+  mangle table.
 
   ROUTE target options:
-    --oif   ifname    Send the packet out using `ifname' network interface.
-    --iif   ifname    Change the packet's incoming interface to `ifname'.
-    --gw    ip        Route the packet via this gateway.
+  --oif   ifname    Send the packet out using `ifname' network interface.
+  --iif   ifname    Change the packet's incoming interface to `ifname'.
+  --gw    ip        Route the packet via this gateway.
+  --continue        Route the packet and continue traversing the rules.
 
-  Examples :
-
-  To redirect all outgoing icmp packet to the eth1 interface :
-  # iptables -A POSTROUTING -t mangle -p icmp -j ROUTE --oif eth1
+  Note that --iif and --continue can't be used together.
 
-  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
+  Examples :
 
-  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
+  # 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
  
+  # To tunnel outgoing http packets and continue traversing the rules :
+  iptables -A POSTROUTING -t mangle -p tcp --dport 80 -j ROUTE --oif tunl1 --continue
+ 
+  # To forward all ssh packets to gateway w.x.y.z, and continue traversing
+  # the rules :
+  iptables -A POSTROUTING -t mangle -p tcp --dport 22 -j ROUTE --gw w.x.y.z --continue
+ 
+  # To change the incoming network interface from eth0 to eth1 for all icmp
+  # packets (final target) :
+  iptables -A PREROUTING -t mangle -p icmp -i eth0 -j ROUTE --iif eth1
+

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

* Re: [PATCH] update to ROUTE target
  2003-07-25 13:16         ` [PATCH] update to " Cedric de Launois
@ 2003-07-25 15:27           ` Martin Josefsson
  0 siblings, 0 replies; 8+ messages in thread
From: Martin Josefsson @ 2003-07-25 15:27 UTC (permalink / raw)
  To: Cedric de Launois; +Cc: Netfilter Development Mailinglist

On Fri, 2003-07-25 at 15:16, Cedric de Launois wrote:
> Hi again,
> 
> Oops, I forgot to also submit changes to the ROUTE.patch.configure.help
> and ROUTE.patch.help files to update the descriptions of the target.
> 
> I also modified ROUTE.patch.configure.in in order to make the ROUTE
> target dependent of the CONFIG_IP_NF_MANGLE kernel option (since the
> ROUTE target must be used inside the mangle table).
> 
> The patch is still against the very current cvs.
> 
> Thanks for applying it.

Applied

-- 
/Martin

^ 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.