* [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x
@ 2004-04-21 8:16 Cedric de Launois
2004-04-24 23:03 ` Patrick McHardy
0 siblings, 1 reply; 6+ messages in thread
From: Cedric de Launois @ 2004-04-21 8:16 UTC (permalink / raw)
To: Netfilter Development Mailinglist
[-- Attachment #1: Type: text/plain, Size: 252 bytes --]
Hi,
Here is a patch to convert the ROUTE target to the new pom-ng.
This patch also contains a corrected version of the ROUTE target
for kernels 2.6.x.
Other fixes for the ROUTE target will follow.
The patch is against the current cvs tree.
Cedric
[-- Attachment #2: ROUTE.pom-ng.patch --]
[-- Type: text/x-patch, Size: 64672 bytes --]
diff -Nru ROUTE.orig/info ROUTE/info
--- ROUTE.orig/info 2004-02-20 00:11:50.000000000 +0100
+++ ROUTE/info 2004-03-08 14:19:22.000000000 +0100
@@ -1,4 +1,5 @@
Author: Cédric de Launois <delaunois@info.ucl.ac.be>
Status: Experimental
Repository: extra
-Requires: linux < 2.6.0
+Recompile: netfilter
+Recompile: iptables
diff -Nru ROUTE.orig/linux/Documentation/Configure.help.ladd ROUTE/linux/Documentation/Configure.help.ladd
--- ROUTE.orig/linux/Documentation/Configure.help.ladd 2004-02-19 12:30:08.000000000 +0100
+++ ROUTE/linux/Documentation/Configure.help.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,16 +0,0 @@
-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. 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.
-
- 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.
- If unsure, say `N'.
-
diff -Nru ROUTE.orig/linux/Documentation/Configure.help.ladd_2 ROUTE/linux/Documentation/Configure.help.ladd_2
--- ROUTE.orig/linux/Documentation/Configure.help.ladd_2 2004-03-05 10:30:26.000000000 +0100
+++ ROUTE/linux/Documentation/Configure.help.ladd_2 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-CONFIG_IP6_NF_TARGET_MARK
-ROUTE target support
-CONFIG_IP6_NF_TARGET_ROUTE
- This option adds a `ROUTE' target, which enables you to setup unusual
- routes. The ROUTE target is also able to change the incoming interface
- of a packet.
-
- The target can be or not a final target. It has to be used inside the
- mangle table.
-
- Not working as a module.
-
diff -Nru ROUTE.orig/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h ROUTE/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h
--- ROUTE.orig/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100
+++ ROUTE/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-/* Header file for iptables ipt_ROUTE target
- *
- * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
- *
- * This software is distributed under GNU GPL v2, 1991
- */
-#ifndef _IPT_ROUTE_H_target
-#define _IPT_ROUTE_H_target
-
-#define IPT_ROUTE_IFNAMSIZ 16
-
-struct ipt_route_target_info {
- 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 ROUTE.orig/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h ROUTE/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h
--- ROUTE.orig/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100
+++ ROUTE/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-/* Header file for iptables ip6t_ROUTE target
- *
- * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
- *
- * This software is distributed under GNU GPL v2, 1991
- */
-#ifndef _IPT_ROUTE_H_target
-#define _IPT_ROUTE_H_target
-
-#define IP6T_ROUTE_IFNAMSIZ 16
-
-struct ip6t_route_target_info {
- char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
- char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
- u_int32_t gw[4]; /* IPv6 address of gateway */
- u_int8_t flags;
-};
-
-/* Values for "flags" field */
-#define IP6T_ROUTE_CONTINUE 0x01
-
-#endif /*_IP6T_ROUTE_H_target*/
diff -Nru ROUTE.orig/linux/net/ipv4/netfilter/Config.in.ladd ROUTE/linux/net/ipv4/netfilter/Config.in.ladd
--- ROUTE.orig/linux/net/ipv4/netfilter/Config.in.ladd 2003-12-18 19:47:54.000000000 +0100
+++ ROUTE/linux/net/ipv4/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
- 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 ROUTE.orig/linux/net/ipv4/netfilter/ipt_ROUTE.c ROUTE/linux/net/ipv4/netfilter/ipt_ROUTE.c
--- ROUTE.orig/linux/net/ipv4/netfilter/ipt_ROUTE.c 2003-12-18 19:47:54.000000000 +0100
+++ ROUTE/linux/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,369 +0,0 @@
-/*
- * 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.8 2003/07/25
- *
- * This software is distributed under GNU GPL v2, 1991
- */
-
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ipt_ROUTE.h>
-#include <linux/netdevice.h>
-#include <linux/route.h>
-#include <net/ip.h>
-#include <net/route.h>
-#include <net/icmp.h>
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-
-/* Try to route the packet according to the routing keys specified in
- * route_info. Keys are :
- * - ifindex :
- * 0 if no oif preferred,
- * otherwise set to the index of the desired oif
- * - route_info->gw :
- * 0 if no gateway specified,
- * otherwise set to the next host to which the pkt must be routed
- * If success, skb->dev is the output device to which the packet must
- * be sent and skb->dst is not NULL
- *
- * RETURN: -1 if an error occured
- * 1 if the packet was succesfully routed to the
- * destination desired
- * 0 if the kernel routing table could not route the packet
- * according to the keys specified
- */
-static int route(struct sk_buff *skb,
- unsigned int ifindex,
- const struct ipt_route_target_info *route_info)
-{
- int err;
- struct rtable *rt;
- struct iphdr *iph = skb->nh.iph;
- struct rt_key key = {
- dst:iph->daddr,
- src:0,
- oif:ifindex,
- tos:RT_TOS(iph->tos)
- };
-
- /* The destination address may be overloaded by the target */
- if (route_info->gw)
- key.dst = route_info->gw;
-
- /* Trying to route the packet using the standard routing table. */
- if ((err = ip_route_output_key(&rt, &key))) {
- if (net_ratelimit())
- DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
- return -1;
- }
-
- /* Drop old route. */
- dst_release(skb->dst);
- skb->dst = NULL;
-
- /* Success if no oif specified or if the oif correspond to the
- * one desired */
- if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
- skb->dst = &rt->u.dst;
- skb->dev = skb->dst->dev;
- return 1;
- }
-
- /* The interface selected by the routing table is not the one
- * specified by the user. This may happen because the dst address
- * is one of our own addresses.
- */
- 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;
-}
-
-
-/* Stolen from ip_finish_output2
- * PRE : skb->dev is set to the device we are leaving by
- * skb->dst is not NULL
- * POST: the packet is sent with the link layer header pushed
- * the packet is destroyed
- */
-static void ip_direct_send(struct sk_buff *skb)
-{
- struct dst_entry *dst = skb->dst;
- struct hh_cache *hh = dst->hh;
-
- if (hh) {
- read_lock_bh(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
- read_unlock_bh(&hh->hh_lock);
- skb_push(skb, hh->hh_len);
- hh->hh_output(skb);
- } else if (dst->neighbour)
- dst->neighbour->output(skb);
- else {
- if (net_ratelimit())
- DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
- kfree_skb(skb);
- }
-}
-
-
-/* PRE : skb->dev is set to the device we are leaving by
- * POST: - the packet is directly sent to the skb->dev device, without
- * pushing the link layer header.
- * - the packet is destroyed
- */
-static inline int dev_direct_send(struct sk_buff *skb)
-{
- return dev_queue_xmit(skb);
-}
-
-
-static unsigned int route_oif(const struct ipt_route_target_info *route_info,
- struct sk_buff *skb)
-{
- 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))) {
- ifindex = dev_out->ifindex;
- } else {
- /* Unknown interface name : packet dropped */
- if (net_ratelimit())
- DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
- return NF_DROP;
- }
-
- /* Trying the standard way of routing packets */
- 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;
-
- case 0:
- /* Failed to send to oif. Trying the hard way */
- if (route_info->flags & IPT_ROUTE_CONTINUE)
- return NF_DROP;
-
- 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;
- }
-}
-
-
-static unsigned int route_iif(const struct ipt_route_target_info *route_info,
- struct sk_buff *skb)
-{
- struct net_device *dev_out = NULL;
- unsigned int ifindex = 0;
-
- /* Getting the current interface index. */
- if ((dev_out = dev_get_by_name(route_info->iif)))
- ifindex = dev_out->ifindex;
- else {
- /* Unknown interface name : packet dropped */
- if (net_ratelimit())
- DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->oif);
- return NF_DROP;
- }
-
- skb->dev = dev_out;
- dst_release(skb->dst);
- skb->dst = NULL;
-
- netif_rx(skb);
-
- return NF_STOLEN;
-}
-
-
-static unsigned int route_gw(const struct ipt_route_target_info *route_info,
- struct sk_buff *skb)
-{
- if (route(skb, 0, route_info)!=1)
- return NF_DROP;
-
- if (route_info->flags & IPT_ROUTE_CONTINUE)
- return IPT_CONTINUE;
-
- ip_direct_send(skb);
- return NF_STOLEN;
-}
-
-
-static unsigned int ipt_route_target(struct sk_buff **pskb,
- unsigned int hooknum,
- const struct net_device *in,
- const struct net_device *out,
- const void *targinfo,
- void *userinfo)
-{
- const struct ipt_route_target_info *route_info = targinfo;
- struct sk_buff *skb = *pskb;
-
- /* If we are at PREROUTING or INPUT hook
- * the TTL isn't decreased by the IP stack
- */
- if (hooknum == NF_IP_PRE_ROUTING ||
- hooknum == NF_IP_LOCAL_IN) {
-
- struct iphdr *iph = skb->nh.iph;
-
- if (iph->ttl <= 1) {
- struct rtable *rt;
-
- if (ip_route_output(&rt, iph->saddr, iph->daddr,
- RT_TOS(iph->tos) | RTO_CONN,
- 0)) {
- return NF_DROP;
- }
-
- if (skb->dev == rt->u.dst.dev) {
- /* Drop old route. */
- dst_release(skb->dst);
- skb->dst = &rt->u.dst;
-
- /* this will traverse normal stack, and
- * thus call conntrack on the icmp packet */
- icmp_send(skb, ICMP_TIME_EXCEEDED,
- ICMP_EXC_TTL, 0);
- }
-
- return NF_DROP;
- }
-
- ip_decrease_ttl(iph);
- }
-
- /* Tell conntrack to forget this packet since it may get confused
- * when a packet is leaving with dst address == our address.
- * Good idea ? Dunno. Need advice.
- */
- 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;
-#endif
- }
-
- if (route_info->oif[0])
- return route_oif(route_info, *pskb);
-
- if (route_info->iif[0])
- return route_iif(route_info, *pskb);
-
- if (route_info->gw)
- return route_gw(route_info, *pskb);
-
- if (net_ratelimit())
- DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
-
- return IPT_CONTINUE;
-}
-
-
-static int ipt_route_checkentry(const char *tablename,
- const struct ipt_entry *e,
- void *targinfo,
- unsigned int targinfosize,
- unsigned int hook_mask)
-{
- if (strcmp(tablename, "mangle") != 0) {
- printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
- tablename);
- return 0;
- }
-
- if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
- | (1 << NF_IP_LOCAL_IN)
- | (1 << NF_IP_FORWARD)
- | (1 << NF_IP_LOCAL_OUT)
- | (1 << NF_IP_POST_ROUTING))) {
- printk("ipt_ROUTE: bad hook\n");
- return 0;
- }
-
- if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
- printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
- targinfosize,
- IPT_ALIGN(sizeof(struct ipt_route_target_info)));
- return 0;
- }
-
- return 1;
-}
-
-
-static struct ipt_target ipt_route_reg
-= { { NULL, NULL }, "ROUTE", ipt_route_target, ipt_route_checkentry, NULL,
- THIS_MODULE };
-
-
-static int __init init(void)
-{
- if (ipt_register_target(&ipt_route_reg))
- return -EINVAL;
-
- return 0;
-}
-
-
-static void __exit fini(void)
-{
- ipt_unregister_target(&ipt_route_reg);
-}
-
-module_init(init);
-module_exit(fini);
-MODULE_LICENSE("GPL");
diff -Nru ROUTE.orig/linux/net/ipv4/netfilter/Kconfig.ladd ROUTE/linux/net/ipv4/netfilter/Kconfig.ladd
--- ROUTE.orig/linux/net/ipv4/netfilter/Kconfig.ladd 2003-12-21 21:09:27.000000000 +0100
+++ ROUTE/linux/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-config IP_NF_TARGET_ROUTE
- tristate 'ROUTE target support'
- depends on IP_NF_MANGLE
diff -Nru ROUTE.orig/linux/net/ipv4/netfilter/Makefile.ladd ROUTE/linux/net/ipv4/netfilter/Makefile.ladd
--- ROUTE.orig/linux/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100
+++ ROUTE/linux/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
-obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
diff -Nru ROUTE.orig/linux/net/ipv6/netfilter/Config.in.ladd ROUTE/linux/net/ipv6/netfilter/Config.in.ladd
--- ROUTE.orig/linux/net/ipv6/netfilter/Config.in.ladd 2003-12-20 17:43:09.000000000 +0100
+++ ROUTE/linux/net/ipv6/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
- dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE
- dep_mbool ' ROUTE target support' CONFIG_IP6_NF_TARGET_ROUTE $CONFIG_IP6_NF_MANGLE
\ Pas de fin de ligne à la fin du fichier.
diff -Nru ROUTE.orig/linux/net/ipv6/netfilter/ip6t_ROUTE.c ROUTE/linux/net/ipv6/netfilter/ip6t_ROUTE.c
--- ROUTE.orig/linux/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100
+++ ROUTE/linux/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,289 +0,0 @@
-/*
- * This implements the ROUTE v6 target, which enables you to setup unusual
- * routes not supported by the standard kernel routing table.
- *
- * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
- *
- * v 1.0 2003/08/05
- *
- * This software is distributed under GNU GPL v2, 1991
- */
-
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/ipv6.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
-#include <linux/netdevice.h>
-#include <net/ipv6.h>
-#include <net/ndisc.h>
-#include <net/ip6_route.h>
-#include <linux/icmpv6.h>
-
-#if 1
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
-#define NIP6(addr) \
- ntohs((addr).s6_addr16[0]), \
- ntohs((addr).s6_addr16[1]), \
- ntohs((addr).s6_addr16[2]), \
- ntohs((addr).s6_addr16[3]), \
- ntohs((addr).s6_addr16[4]), \
- ntohs((addr).s6_addr16[5]), \
- ntohs((addr).s6_addr16[6]), \
- ntohs((addr).s6_addr16[7])
-
-/* Route the packet according to the routing keys specified in
- * route_info. Keys are :
- * - ifindex :
- * 0 if no oif preferred,
- * otherwise set to the index of the desired oif
- * - route_info->gw :
- * 0 if no gateway specified,
- * otherwise set to the next host to which the pkt must be routed
- * If success, skb->dev is the output device to which the packet must
- * be sent and skb->dst is not NULL
- *
- * RETURN: 1 if the packet was succesfully routed to the
- * destination desired
- * 0 if the kernel routing table could not route the packet
- * according to the keys specified
- */
-static int
-route6(struct sk_buff *skb,
- unsigned int ifindex,
- const struct ip6t_route_target_info *route_info)
-{
- struct rt6_info *rt = NULL;
- struct ipv6hdr *ipv6h = skb->nh.ipv6h;
- struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
-
- DEBUGP("ip6t_ROUTE: called with: ");
- DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
- DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
- DEBUGP("OUT=%s\n", route_info->oif);
-
- if (ipv6_addr_any(gw))
- rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
- else
- rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
-
- if (!rt)
- goto no_route;
-
- DEBUGP("ip6t_ROUTE: routing gives: ");
- DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
- DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
- DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
-
- if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
- goto wrong_route;
-
- if (!rt->rt6i_nexthop) {
- DEBUGP("ip6t_ROUTE: discovering neighbour\n");
- rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
- }
-
- /* Drop old route. */
- dst_release(skb->dst);
- skb->dst = &rt->u.dst;
- skb->dev = rt->rt6i_dev;
- return 1;
-
- wrong_route:
- dst_release(&rt->u.dst);
- no_route:
- if (!net_ratelimit())
- return 0;
-
- printk("ip6t_ROUTE: no explicit route found ");
- if (ifindex)
- printk("via interface %s ", route_info->oif);
- if (!ipv6_addr_any(gw))
- printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
- printk("\n");
- return 0;
-}
-
-
-/* Stolen from ip6_output_finish
- * PRE : skb->dev is set to the device we are leaving by
- * skb->dst is not NULL
- * POST: the packet is sent with the link layer header pushed
- * the packet is destroyed
- */
-static void ip_direct_send(struct sk_buff *skb)
-{
- struct dst_entry *dst = skb->dst;
- struct hh_cache *hh = dst->hh;
-
- if (hh) {
- read_lock_bh(&hh->hh_lock);
- memcpy(skb->data - 16, hh->hh_data, 16);
- read_unlock_bh(&hh->hh_lock);
- skb_push(skb, hh->hh_len);
- hh->hh_output(skb);
- } else if (dst->neighbour)
- dst->neighbour->output(skb);
- else {
- if (net_ratelimit())
- DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
- kfree_skb(skb);
- }
-}
-
-
-static unsigned int
-route6_oif(const struct ip6t_route_target_info *route_info,
- struct sk_buff *skb)
-{
- 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))) {
- ifindex = dev_out->ifindex;
- } else {
- /* Unknown interface name : packet dropped */
- if (net_ratelimit())
- DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
-
- if (route_info->flags & IP6T_ROUTE_CONTINUE)
- return IP6T_CONTINUE;
- else
- return NF_DROP;
- }
-
- /* Trying the standard way of routing packets */
- if (route6(skb, ifindex, route_info)) {
- dev_put(dev_out);
- if (route_info->flags & IP6T_ROUTE_CONTINUE)
- return IP6T_CONTINUE;
-
- ip_direct_send(skb);
- return NF_STOLEN;
- } else
- return NF_DROP;
-}
-
-
-static unsigned int
-route6_gw(const struct ip6t_route_target_info *route_info,
- struct sk_buff *skb)
-{
- if (route6(skb, 0, route_info)) {
- if (route_info->flags & IP6T_ROUTE_CONTINUE)
- return IP6T_CONTINUE;
-
- ip_direct_send(skb);
- return NF_STOLEN;
- } else
- return NF_DROP;
-}
-
-
-static unsigned int
-ip6t_route_target(struct sk_buff **pskb,
- unsigned int hooknum,
- const struct net_device *in,
- const struct net_device *out,
- const void *targinfo,
- void *userinfo)
-{
- const struct ip6t_route_target_info *route_info = targinfo;
- struct sk_buff *skb = *pskb;
- struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
-
- if (route_info->flags & IP6T_ROUTE_CONTINUE)
- goto do_it;
-
- /* If we are at PREROUTING or INPUT hook
- * the TTL isn't decreased by the IP stack
- */
- if (hooknum == NF_IP6_PRE_ROUTING ||
- hooknum == NF_IP6_LOCAL_IN) {
-
- struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-
- if (ipv6h->hop_limit <= 1) {
- /* Force OUTPUT device used as source address */
- skb->dev = skb->dst->dev;
-
- icmpv6_send(skb, ICMPV6_TIME_EXCEED,
- ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
-
- return NF_DROP;
- }
-
- ipv6h->hop_limit--;
- }
-
-
- do_it:
- if (route_info->oif[0])
- return route6_oif(route_info, *pskb);
-
- if (!ipv6_addr_any(gw))
- return route6_gw(route_info, *pskb);
-
- if (net_ratelimit())
- DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
-
- return IP6T_CONTINUE;
-}
-
-
-static int
-ip6t_route_checkentry(const char *tablename,
- const struct ip6t_entry *e,
- void *targinfo,
- unsigned int targinfosize,
- unsigned int hook_mask)
-{
- if (strcmp(tablename, "mangle") != 0) {
- printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
- return 0;
- }
-
- if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
- printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
- targinfosize,
- IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
- return 0;
- }
-
- return 1;
-}
-
-
-static struct ip6t_target ip6t_route_reg = {
- .name = "ROUTE",
- .target = ip6t_route_target,
- .checkentry = ip6t_route_checkentry,
- .me = THIS_MODULE
-};
-
-
-static int __init init(void)
-{
- printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
- if (ip6t_register_target(&ip6t_route_reg))
- return -EINVAL;
-
- return 0;
-}
-
-
-static void __exit fini(void)
-{
- ip6t_unregister_target(&ip6t_route_reg);
-}
-
-module_init(init);
-module_exit(fini);
-MODULE_LICENSE("GPL");
diff -Nru ROUTE.orig/linux/net/ipv6/netfilter/Kconfig.ladd ROUTE/linux/net/ipv6/netfilter/Kconfig.ladd
--- ROUTE.orig/linux/net/ipv6/netfilter/Kconfig.ladd 2003-12-23 12:41:11.000000000 +0100
+++ ROUTE/linux/net/ipv6/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,3 +0,0 @@
-config IP6_NF_TARGET_ROUTE
- tristate ' ROUTE target support'
- depends on IP6_NF_MANGLE
diff -Nru ROUTE.orig/linux/net/ipv6/netfilter/Makefile.ladd ROUTE/linux/net/ipv6/netfilter/Makefile.ladd
--- ROUTE.orig/linux/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100
+++ ROUTE/linux/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
@@ -1,2 +0,0 @@
-obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
-obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
diff -Nru ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd ROUTE/linux-2.4/Documentation/Configure.help.ladd
--- ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/Documentation/Configure.help.ladd 2004-02-19 12:30:08.000000000 +0100
@@ -0,0 +1,16 @@
+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. 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.
+
+ 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.
+ If unsure, say `N'.
+
diff -Nru ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd_2 ROUTE/linux-2.4/Documentation/Configure.help.ladd_2
--- ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd_2 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/Documentation/Configure.help.ladd_2 2004-03-05 10:30:26.000000000 +0100
@@ -0,0 +1,12 @@
+CONFIG_IP6_NF_TARGET_MARK
+ROUTE target support
+CONFIG_IP6_NF_TARGET_ROUTE
+ This option adds a `ROUTE' target, which enables you to setup unusual
+ routes. The ROUTE target is also able to change the incoming interface
+ of a packet.
+
+ The target can be or not a final target. It has to be used inside the
+ mangle table.
+
+ Not working as a module.
+
diff -Nru ROUTE.orig/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h ROUTE/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h
--- ROUTE.orig/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100
@@ -0,0 +1,22 @@
+/* Header file for iptables ipt_ROUTE target
+ *
+ * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+#ifndef _IPT_ROUTE_H_target
+#define _IPT_ROUTE_H_target
+
+#define IPT_ROUTE_IFNAMSIZ 16
+
+struct ipt_route_target_info {
+ 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 ROUTE.orig/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h ROUTE/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h
--- ROUTE.orig/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,22 @@
+/* Header file for iptables ip6t_ROUTE target
+ *
+ * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+#ifndef _IPT_ROUTE_H_target
+#define _IPT_ROUTE_H_target
+
+#define IP6T_ROUTE_IFNAMSIZ 16
+
+struct ip6t_route_target_info {
+ char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
+ char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
+ u_int32_t gw[4]; /* IPv6 address of gateway */
+ u_int8_t flags;
+};
+
+/* Values for "flags" field */
+#define IP6T_ROUTE_CONTINUE 0x01
+
+#endif /*_IP6T_ROUTE_H_target*/
diff -Nru ROUTE.orig/linux-2.4/net/ipv4/netfilter/Config.in.ladd ROUTE/linux-2.4/net/ipv4/netfilter/Config.in.ladd
--- ROUTE.orig/linux-2.4/net/ipv4/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv4/netfilter/Config.in.ladd 2003-12-18 19:47:54.000000000 +0100
@@ -0,0 +1,3 @@
+ 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 ROUTE.orig/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c ROUTE/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c
--- ROUTE.orig/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c 2003-12-18 19:47:54.000000000 +0100
@@ -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.8 2003/07/25
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_ROUTE.h>
+#include <linux/netdevice.h>
+#include <linux/route.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <net/icmp.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+
+/* Try to route the packet according to the routing keys specified in
+ * route_info. Keys are :
+ * - ifindex :
+ * 0 if no oif preferred,
+ * otherwise set to the index of the desired oif
+ * - route_info->gw :
+ * 0 if no gateway specified,
+ * otherwise set to the next host to which the pkt must be routed
+ * If success, skb->dev is the output device to which the packet must
+ * be sent and skb->dst is not NULL
+ *
+ * RETURN: -1 if an error occured
+ * 1 if the packet was succesfully routed to the
+ * destination desired
+ * 0 if the kernel routing table could not route the packet
+ * according to the keys specified
+ */
+static int route(struct sk_buff *skb,
+ unsigned int ifindex,
+ const struct ipt_route_target_info *route_info)
+{
+ int err;
+ struct rtable *rt;
+ struct iphdr *iph = skb->nh.iph;
+ struct rt_key key = {
+ dst:iph->daddr,
+ src:0,
+ oif:ifindex,
+ tos:RT_TOS(iph->tos)
+ };
+
+ /* The destination address may be overloaded by the target */
+ if (route_info->gw)
+ key.dst = route_info->gw;
+
+ /* Trying to route the packet using the standard routing table. */
+ if ((err = ip_route_output_key(&rt, &key))) {
+ if (net_ratelimit())
+ DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
+ return -1;
+ }
+
+ /* Drop old route. */
+ dst_release(skb->dst);
+ skb->dst = NULL;
+
+ /* Success if no oif specified or if the oif correspond to the
+ * one desired */
+ if (!ifindex || rt->u.dst.dev->ifindex == ifindex) {
+ skb->dst = &rt->u.dst;
+ skb->dev = skb->dst->dev;
+ return 1;
+ }
+
+ /* The interface selected by the routing table is not the one
+ * specified by the user. This may happen because the dst address
+ * is one of our own addresses.
+ */
+ 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;
+}
+
+
+/* Stolen from ip_finish_output2
+ * PRE : skb->dev is set to the device we are leaving by
+ * skb->dst is not NULL
+ * POST: the packet is sent with the link layer header pushed
+ * the packet is destroyed
+ */
+static void ip_direct_send(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb->dst;
+ struct hh_cache *hh = dst->hh;
+
+ if (hh) {
+ read_lock_bh(&hh->hh_lock);
+ memcpy(skb->data - 16, hh->hh_data, 16);
+ read_unlock_bh(&hh->hh_lock);
+ skb_push(skb, hh->hh_len);
+ hh->hh_output(skb);
+ } else if (dst->neighbour)
+ dst->neighbour->output(skb);
+ else {
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
+ kfree_skb(skb);
+ }
+}
+
+
+/* PRE : skb->dev is set to the device we are leaving by
+ * POST: - the packet is directly sent to the skb->dev device, without
+ * pushing the link layer header.
+ * - the packet is destroyed
+ */
+static inline int dev_direct_send(struct sk_buff *skb)
+{
+ return dev_queue_xmit(skb);
+}
+
+
+static unsigned int route_oif(const struct ipt_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ 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))) {
+ ifindex = dev_out->ifindex;
+ } else {
+ /* Unknown interface name : packet dropped */
+ if (net_ratelimit())
+ DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif);
+ return NF_DROP;
+ }
+
+ /* Trying the standard way of routing packets */
+ 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;
+
+ case 0:
+ /* Failed to send to oif. Trying the hard way */
+ if (route_info->flags & IPT_ROUTE_CONTINUE)
+ return NF_DROP;
+
+ 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;
+ }
+}
+
+
+static unsigned int route_iif(const struct ipt_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ struct net_device *dev_out = NULL;
+ unsigned int ifindex = 0;
+
+ /* Getting the current interface index. */
+ if ((dev_out = dev_get_by_name(route_info->iif)))
+ ifindex = dev_out->ifindex;
+ else {
+ /* Unknown interface name : packet dropped */
+ if (net_ratelimit())
+ DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->oif);
+ return NF_DROP;
+ }
+
+ skb->dev = dev_out;
+ dst_release(skb->dst);
+ skb->dst = NULL;
+
+ netif_rx(skb);
+
+ return NF_STOLEN;
+}
+
+
+static unsigned int route_gw(const struct ipt_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ if (route(skb, 0, route_info)!=1)
+ return NF_DROP;
+
+ if (route_info->flags & IPT_ROUTE_CONTINUE)
+ return IPT_CONTINUE;
+
+ ip_direct_send(skb);
+ return NF_STOLEN;
+}
+
+
+static unsigned int ipt_route_target(struct sk_buff **pskb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo,
+ void *userinfo)
+{
+ const struct ipt_route_target_info *route_info = targinfo;
+ struct sk_buff *skb = *pskb;
+
+ /* If we are at PREROUTING or INPUT hook
+ * the TTL isn't decreased by the IP stack
+ */
+ if (hooknum == NF_IP_PRE_ROUTING ||
+ hooknum == NF_IP_LOCAL_IN) {
+
+ struct iphdr *iph = skb->nh.iph;
+
+ if (iph->ttl <= 1) {
+ struct rtable *rt;
+
+ if (ip_route_output(&rt, iph->saddr, iph->daddr,
+ RT_TOS(iph->tos) | RTO_CONN,
+ 0)) {
+ return NF_DROP;
+ }
+
+ if (skb->dev == rt->u.dst.dev) {
+ /* Drop old route. */
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
+
+ /* this will traverse normal stack, and
+ * thus call conntrack on the icmp packet */
+ icmp_send(skb, ICMP_TIME_EXCEEDED,
+ ICMP_EXC_TTL, 0);
+ }
+
+ return NF_DROP;
+ }
+
+ ip_decrease_ttl(iph);
+ }
+
+ /* Tell conntrack to forget this packet since it may get confused
+ * when a packet is leaving with dst address == our address.
+ * Good idea ? Dunno. Need advice.
+ */
+ 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;
+#endif
+ }
+
+ if (route_info->oif[0])
+ return route_oif(route_info, *pskb);
+
+ if (route_info->iif[0])
+ return route_iif(route_info, *pskb);
+
+ if (route_info->gw)
+ return route_gw(route_info, *pskb);
+
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n");
+
+ return IPT_CONTINUE;
+}
+
+
+static int ipt_route_checkentry(const char *tablename,
+ const struct ipt_entry *e,
+ void *targinfo,
+ unsigned int targinfosize,
+ unsigned int hook_mask)
+{
+ if (strcmp(tablename, "mangle") != 0) {
+ printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n",
+ tablename);
+ return 0;
+ }
+
+ if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING)
+ | (1 << NF_IP_LOCAL_IN)
+ | (1 << NF_IP_FORWARD)
+ | (1 << NF_IP_LOCAL_OUT)
+ | (1 << NF_IP_POST_ROUTING))) {
+ printk("ipt_ROUTE: bad hook\n");
+ return 0;
+ }
+
+ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) {
+ printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n",
+ targinfosize,
+ IPT_ALIGN(sizeof(struct ipt_route_target_info)));
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static struct ipt_target ipt_route_reg
+= { { NULL, NULL }, "ROUTE", ipt_route_target, ipt_route_checkentry, NULL,
+ THIS_MODULE };
+
+
+static int __init init(void)
+{
+ if (ipt_register_target(&ipt_route_reg))
+ return -EINVAL;
+
+ return 0;
+}
+
+
+static void __exit fini(void)
+{
+ ipt_unregister_target(&ipt_route_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -Nru ROUTE.orig/linux-2.4/net/ipv4/netfilter/Makefile.ladd ROUTE/linux-2.4/net/ipv4/netfilter/Makefile.ladd
--- ROUTE.orig/linux-2.4/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/Config.in.ladd ROUTE/linux-2.4/net/ipv6/netfilter/Config.in.ladd
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/Config.in.ladd 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,2 @@
+ dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE
+ dep_mbool ' ROUTE target support' CONFIG_IP6_NF_TARGET_ROUTE $CONFIG_IP6_NF_MANGLE
\ Pas de fin de ligne à la fin du fichier.
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries 2004-03-08 10:06:41.000000000 +0100
@@ -0,0 +1,5 @@
+/Config.in.ladd/1.1/Sat Dec 20 16:43:09 2003//
+/Kconfig.ladd/1.1/Tue Dec 23 11:41:11 2003//
+/Makefile.ladd/1.1/Sat Dec 20 16:43:09 2003//
+/ip6t_ROUTE.c/1.1/Sat Dec 20 16:43:09 2003//
+D
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository 2004-03-08 10:06:41.000000000 +0100
@@ -0,0 +1 @@
+patch-o-matic-ng/ROUTE/linux/net/ipv6/netfilter
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root 2004-03-08 10:06:41.000000000 +0100
@@ -0,0 +1 @@
+:pserver:cvs:cvs@pserver.netfilter.org:/cvspublic
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c ROUTE/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,289 @@
+/*
+ * This implements the ROUTE v6 target, which enables you to setup unusual
+ * routes not supported by the standard kernel routing table.
+ *
+ * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * v 1.0 2003/08/05
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
+#include <linux/netdevice.h>
+#include <net/ipv6.h>
+#include <net/ndisc.h>
+#include <net/ip6_route.h>
+#include <linux/icmpv6.h>
+
+#if 1
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+
+/* Route the packet according to the routing keys specified in
+ * route_info. Keys are :
+ * - ifindex :
+ * 0 if no oif preferred,
+ * otherwise set to the index of the desired oif
+ * - route_info->gw :
+ * 0 if no gateway specified,
+ * otherwise set to the next host to which the pkt must be routed
+ * If success, skb->dev is the output device to which the packet must
+ * be sent and skb->dst is not NULL
+ *
+ * RETURN: 1 if the packet was succesfully routed to the
+ * destination desired
+ * 0 if the kernel routing table could not route the packet
+ * according to the keys specified
+ */
+static int
+route6(struct sk_buff *skb,
+ unsigned int ifindex,
+ const struct ip6t_route_target_info *route_info)
+{
+ struct rt6_info *rt = NULL;
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
+
+ DEBUGP("ip6t_ROUTE: called with: ");
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
+ DEBUGP("OUT=%s\n", route_info->oif);
+
+ if (ipv6_addr_any(gw))
+ rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
+ else
+ rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
+
+ if (!rt)
+ goto no_route;
+
+ DEBUGP("ip6t_ROUTE: routing gives: ");
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
+ DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
+
+ if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
+ goto wrong_route;
+
+ if (!rt->rt6i_nexthop) {
+ DEBUGP("ip6t_ROUTE: discovering neighbour\n");
+ rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
+ }
+
+ /* Drop old route. */
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
+ skb->dev = rt->rt6i_dev;
+ return 1;
+
+ wrong_route:
+ dst_release(&rt->u.dst);
+ no_route:
+ if (!net_ratelimit())
+ return 0;
+
+ printk("ip6t_ROUTE: no explicit route found ");
+ if (ifindex)
+ printk("via interface %s ", route_info->oif);
+ if (!ipv6_addr_any(gw))
+ printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
+ printk("\n");
+ return 0;
+}
+
+
+/* Stolen from ip6_output_finish
+ * PRE : skb->dev is set to the device we are leaving by
+ * skb->dst is not NULL
+ * POST: the packet is sent with the link layer header pushed
+ * the packet is destroyed
+ */
+static void ip_direct_send(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb->dst;
+ struct hh_cache *hh = dst->hh;
+
+ if (hh) {
+ read_lock_bh(&hh->hh_lock);
+ memcpy(skb->data - 16, hh->hh_data, 16);
+ read_unlock_bh(&hh->hh_lock);
+ skb_push(skb, hh->hh_len);
+ hh->hh_output(skb);
+ } else if (dst->neighbour)
+ dst->neighbour->output(skb);
+ else {
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
+ kfree_skb(skb);
+ }
+}
+
+
+static unsigned int
+route6_oif(const struct ip6t_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ 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))) {
+ ifindex = dev_out->ifindex;
+ } else {
+ /* Unknown interface name : packet dropped */
+ if (net_ratelimit())
+ DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
+
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+ else
+ return NF_DROP;
+ }
+
+ /* Trying the standard way of routing packets */
+ if (route6(skb, ifindex, route_info)) {
+ dev_put(dev_out);
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+
+ ip_direct_send(skb);
+ return NF_STOLEN;
+ } else
+ return NF_DROP;
+}
+
+
+static unsigned int
+route6_gw(const struct ip6t_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ if (route6(skb, 0, route_info)) {
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+
+ ip_direct_send(skb);
+ return NF_STOLEN;
+ } else
+ return NF_DROP;
+}
+
+
+static unsigned int
+ip6t_route_target(struct sk_buff **pskb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo,
+ void *userinfo)
+{
+ const struct ip6t_route_target_info *route_info = targinfo;
+ struct sk_buff *skb = *pskb;
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
+
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ goto do_it;
+
+ /* If we are at PREROUTING or INPUT hook
+ * the TTL isn't decreased by the IP stack
+ */
+ if (hooknum == NF_IP6_PRE_ROUTING ||
+ hooknum == NF_IP6_LOCAL_IN) {
+
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+
+ if (ipv6h->hop_limit <= 1) {
+ /* Force OUTPUT device used as source address */
+ skb->dev = skb->dst->dev;
+
+ icmpv6_send(skb, ICMPV6_TIME_EXCEED,
+ ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
+
+ return NF_DROP;
+ }
+
+ ipv6h->hop_limit--;
+ }
+
+
+ do_it:
+ if (route_info->oif[0])
+ return route6_oif(route_info, *pskb);
+
+ if (!ipv6_addr_any(gw))
+ return route6_gw(route_info, *pskb);
+
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
+
+ return IP6T_CONTINUE;
+}
+
+
+static int
+ip6t_route_checkentry(const char *tablename,
+ const struct ip6t_entry *e,
+ void *targinfo,
+ unsigned int targinfosize,
+ unsigned int hook_mask)
+{
+ if (strcmp(tablename, "mangle") != 0) {
+ printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
+ return 0;
+ }
+
+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
+ printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
+ targinfosize,
+ IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static struct ip6t_target ip6t_route_reg = {
+ .name = "ROUTE",
+ .target = ip6t_route_target,
+ .checkentry = ip6t_route_checkentry,
+ .me = THIS_MODULE
+};
+
+
+static int __init init(void)
+{
+ printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
+ if (ip6t_register_target(&ip6t_route_reg))
+ return -EINVAL;
+
+ return 0;
+}
+
+
+static void __exit fini(void)
+{
+ ip6t_unregister_target(&ip6t_route_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/Makefile.ladd ROUTE/linux-2.4/net/ipv6/netfilter/Makefile.ladd
--- ROUTE.orig/linux-2.4/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.4/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
+obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
diff -Nru ROUTE.orig/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h ROUTE/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h
--- ROUTE.orig/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100
@@ -0,0 +1,22 @@
+/* Header file for iptables ipt_ROUTE target
+ *
+ * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+#ifndef _IPT_ROUTE_H_target
+#define _IPT_ROUTE_H_target
+
+#define IPT_ROUTE_IFNAMSIZ 16
+
+struct ipt_route_target_info {
+ 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 ROUTE.orig/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h ROUTE/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h
--- ROUTE.orig/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,22 @@
+/* Header file for iptables ip6t_ROUTE target
+ *
+ * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+#ifndef _IPT_ROUTE_H_target
+#define _IPT_ROUTE_H_target
+
+#define IP6T_ROUTE_IFNAMSIZ 16
+
+struct ip6t_route_target_info {
+ char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */
+ char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */
+ u_int32_t gw[4]; /* IPv6 address of gateway */
+ u_int8_t flags;
+};
+
+/* Values for "flags" field */
+#define IP6T_ROUTE_CONTINUE 0x01
+
+#endif /*_IP6T_ROUTE_H_target*/
diff -Nru ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c
--- ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-02-22 18:29:10.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-03-08 15:19:07.000000000 +0100
@@ -19,6 +19,7 @@
#include <net/ip.h>
#include <net/route.h>
#include <net/icmp.h>
+#include <net/checksum.h>
#if 0
#define DEBUGP printk
@@ -28,6 +29,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>");
+MODULE_DESCRIPTION("iptables ROUTE target module");
/* Try to route the packet according to the routing keys specified in
* route_info. Keys are :
@@ -53,19 +55,24 @@
int err;
struct rtable *rt;
struct iphdr *iph = skb->nh.iph;
- struct rt_key key = {
- dst:iph->daddr,
- src:0,
- oif:ifindex,
- tos:RT_TOS(iph->tos)
+ struct flowi fl = {
+ .oif = ifindex,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = 0,
+ .tos = RT_TOS(iph->tos),
+ .scope = RT_SCOPE_UNIVERSE,
+ }
+ }
};
/* The destination address may be overloaded by the target */
if (route_info->gw)
- key.dst = route_info->gw;
+ fl.fld_dst = route_info->gw;
/* Trying to route the packet using the standard routing table. */
- if ((err = ip_route_output_key(&rt, &key))) {
+ if ((err = ip_route_output_key(&rt, &fl))) {
if (net_ratelimit())
DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err);
return -1;
@@ -262,10 +269,21 @@
if (iph->ttl <= 1) {
struct rtable *rt;
+ struct flowi fl = {
+ .oif = 0,
+ .nl_u = {
+ .ip4_u = {
+ .daddr = iph->daddr,
+ .saddr = iph->saddr,
+ .tos = RT_TOS(iph->tos),
+ .scope = ((iph->tos & RTO_ONLINK) ?
+ RT_SCOPE_LINK :
+ RT_SCOPE_UNIVERSE)
+ }
+ }
+ };
- if (ip_route_output(&rt, iph->saddr, iph->daddr,
- RT_TOS(iph->tos) | RTO_CONN,
- 0)) {
+ if (ip_route_output_key(&rt, &fl)) {
return NF_DROP;
}
@@ -284,6 +302,7 @@
}
ip_decrease_ttl(iph);
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
}
/* Tell conntrack to forget this packet since it may get confused
diff -Nru ROUTE.orig/linux-2.6/net/ipv4/netfilter/Kconfig.ladd ROUTE/linux-2.6/net/ipv4/netfilter/Kconfig.ladd
--- ROUTE.orig/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 2004-03-08 14:02:45.000000000 +0100
@@ -0,0 +1,16 @@
+config IP_NF_TARGET_ROUTE
+ tristate 'ROUTE target support'
+ depends on IP_NF_MANGLE
+ help
+ This option adds a `ROUTE' target, which enables you to setup unusual
+ 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.
+
+ 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.
+ If unsure, say `N'.
diff -Nru ROUTE.orig/linux-2.6/net/ipv4/netfilter/Makefile.ladd ROUTE/linux-2.6/net/ipv4/netfilter/Makefile.ladd
--- ROUTE.orig/linux-2.6/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
+obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o
diff -Nru ROUTE.orig/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c ROUTE/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c
--- ROUTE.orig/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,289 @@
+/*
+ * This implements the ROUTE v6 target, which enables you to setup unusual
+ * routes not supported by the standard kernel routing table.
+ *
+ * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be>
+ *
+ * v 1.0 2003/08/05
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_ROUTE.h>
+#include <linux/netdevice.h>
+#include <net/ipv6.h>
+#include <net/ndisc.h>
+#include <net/ip6_route.h>
+#include <linux/icmpv6.h>
+
+#if 1
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+
+/* Route the packet according to the routing keys specified in
+ * route_info. Keys are :
+ * - ifindex :
+ * 0 if no oif preferred,
+ * otherwise set to the index of the desired oif
+ * - route_info->gw :
+ * 0 if no gateway specified,
+ * otherwise set to the next host to which the pkt must be routed
+ * If success, skb->dev is the output device to which the packet must
+ * be sent and skb->dst is not NULL
+ *
+ * RETURN: 1 if the packet was succesfully routed to the
+ * destination desired
+ * 0 if the kernel routing table could not route the packet
+ * according to the keys specified
+ */
+static int
+route6(struct sk_buff *skb,
+ unsigned int ifindex,
+ const struct ip6t_route_target_info *route_info)
+{
+ struct rt6_info *rt = NULL;
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
+
+ DEBUGP("ip6t_ROUTE: called with: ");
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr));
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw));
+ DEBUGP("OUT=%s\n", route_info->oif);
+
+ if (ipv6_addr_any(gw))
+ rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1);
+ else
+ rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1);
+
+ if (!rt)
+ goto no_route;
+
+ DEBUGP("ip6t_ROUTE: routing gives: ");
+ DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr));
+ DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway));
+ DEBUGP("OUT=%s\n", rt->rt6i_dev->name);
+
+ if (ifindex && rt->rt6i_dev->ifindex!=ifindex)
+ goto wrong_route;
+
+ if (!rt->rt6i_nexthop) {
+ DEBUGP("ip6t_ROUTE: discovering neighbour\n");
+ rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr);
+ }
+
+ /* Drop old route. */
+ dst_release(skb->dst);
+ skb->dst = &rt->u.dst;
+ skb->dev = rt->rt6i_dev;
+ return 1;
+
+ wrong_route:
+ dst_release(&rt->u.dst);
+ no_route:
+ if (!net_ratelimit())
+ return 0;
+
+ printk("ip6t_ROUTE: no explicit route found ");
+ if (ifindex)
+ printk("via interface %s ", route_info->oif);
+ if (!ipv6_addr_any(gw))
+ printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw));
+ printk("\n");
+ return 0;
+}
+
+
+/* Stolen from ip6_output_finish
+ * PRE : skb->dev is set to the device we are leaving by
+ * skb->dst is not NULL
+ * POST: the packet is sent with the link layer header pushed
+ * the packet is destroyed
+ */
+static void ip_direct_send(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb->dst;
+ struct hh_cache *hh = dst->hh;
+
+ if (hh) {
+ read_lock_bh(&hh->hh_lock);
+ memcpy(skb->data - 16, hh->hh_data, 16);
+ read_unlock_bh(&hh->hh_lock);
+ skb_push(skb, hh->hh_len);
+ hh->hh_output(skb);
+ } else if (dst->neighbour)
+ dst->neighbour->output(skb);
+ else {
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n");
+ kfree_skb(skb);
+ }
+}
+
+
+static unsigned int
+route6_oif(const struct ip6t_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ 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))) {
+ ifindex = dev_out->ifindex;
+ } else {
+ /* Unknown interface name : packet dropped */
+ if (net_ratelimit())
+ DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif);
+
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+ else
+ return NF_DROP;
+ }
+
+ /* Trying the standard way of routing packets */
+ if (route6(skb, ifindex, route_info)) {
+ dev_put(dev_out);
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+
+ ip_direct_send(skb);
+ return NF_STOLEN;
+ } else
+ return NF_DROP;
+}
+
+
+static unsigned int
+route6_gw(const struct ip6t_route_target_info *route_info,
+ struct sk_buff *skb)
+{
+ if (route6(skb, 0, route_info)) {
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ return IP6T_CONTINUE;
+
+ ip_direct_send(skb);
+ return NF_STOLEN;
+ } else
+ return NF_DROP;
+}
+
+
+static unsigned int
+ip6t_route_target(struct sk_buff **pskb,
+ unsigned int hooknum,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *targinfo,
+ void *userinfo)
+{
+ const struct ip6t_route_target_info *route_info = targinfo;
+ struct sk_buff *skb = *pskb;
+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;
+
+ if (route_info->flags & IP6T_ROUTE_CONTINUE)
+ goto do_it;
+
+ /* If we are at PREROUTING or INPUT hook
+ * the TTL isn't decreased by the IP stack
+ */
+ if (hooknum == NF_IP6_PRE_ROUTING ||
+ hooknum == NF_IP6_LOCAL_IN) {
+
+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
+
+ if (ipv6h->hop_limit <= 1) {
+ /* Force OUTPUT device used as source address */
+ skb->dev = skb->dst->dev;
+
+ icmpv6_send(skb, ICMPV6_TIME_EXCEED,
+ ICMPV6_EXC_HOPLIMIT, 0, skb->dev);
+
+ return NF_DROP;
+ }
+
+ ipv6h->hop_limit--;
+ }
+
+
+ do_it:
+ if (route_info->oif[0])
+ return route6_oif(route_info, *pskb);
+
+ if (!ipv6_addr_any(gw))
+ return route6_gw(route_info, *pskb);
+
+ if (net_ratelimit())
+ DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");
+
+ return IP6T_CONTINUE;
+}
+
+
+static int
+ip6t_route_checkentry(const char *tablename,
+ const struct ip6t_entry *e,
+ void *targinfo,
+ unsigned int targinfosize,
+ unsigned int hook_mask)
+{
+ if (strcmp(tablename, "mangle") != 0) {
+ printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");
+ return 0;
+ }
+
+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) {
+ printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n",
+ targinfosize,
+ IP6T_ALIGN(sizeof(struct ip6t_route_target_info)));
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static struct ip6t_target ip6t_route_reg = {
+ .name = "ROUTE",
+ .target = ip6t_route_target,
+ .checkentry = ip6t_route_checkentry,
+ .me = THIS_MODULE
+};
+
+
+static int __init init(void)
+{
+ printk(KERN_DEBUG "registering ipv6 ROUTE target\n");
+ if (ip6t_register_target(&ip6t_route_reg))
+ return -EINVAL;
+
+ return 0;
+}
+
+
+static void __exit fini(void)
+{
+ ip6t_unregister_target(&ip6t_route_reg);
+}
+
+module_init(init);
+module_exit(fini);
+MODULE_LICENSE("GPL");
diff -Nru ROUTE.orig/linux-2.6/net/ipv6/netfilter/Kconfig.ladd ROUTE/linux-2.6/net/ipv6/netfilter/Kconfig.ladd
--- ROUTE.orig/linux-2.6/net/ipv6/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv6/netfilter/Kconfig.ladd 2004-03-08 15:06:42.000000000 +0100
@@ -0,0 +1,11 @@
+config IP6_NF_TARGET_ROUTE
+ tristate ' ROUTE target support'
+ depends on IP6_NF_MANGLE
+ help
+ This option adds a `ROUTE' target, which enables you to setup unusual
+ routes. The ROUTE target is also able to change the incoming interface
+ of a packet.
+
+ The target can be or not a final target. It has to be used inside the
+ mangle table.
+
diff -Nru ROUTE.orig/linux-2.6/net/ipv6/netfilter/Makefile.ladd ROUTE/linux-2.6/net/ipv6/netfilter/Makefile.ladd
--- ROUTE.orig/linux-2.6/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100
+++ ROUTE/linux-2.6/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
+obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x 2004-04-21 8:16 [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x Cedric de Launois @ 2004-04-24 23:03 ` Patrick McHardy 2004-04-25 0:01 ` Esteban Ribicic 2004-04-28 15:25 ` Cedric de Launois 0 siblings, 2 replies; 6+ messages in thread From: Patrick McHardy @ 2004-04-24 23:03 UTC (permalink / raw) To: Cedric de Launois; +Cc: Netfilter Development Mailinglist Cedric de Launois wrote: > Here is a patch to convert the ROUTE target to the new pom-ng. > This patch also contains a corrected version of the ROUTE target > for kernels 2.6.x. Please make sure your patch doesn't contain changes to CVS directories. Regards Patrick > > Cedric > > > > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries 1970-01-01 01:00:00.000000000 +0100 > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries 2004-03-08 10:06:41.000000000 +0100 > @@ -0,0 +1,5 @@ > +/Config.in.ladd/1.1/Sat Dec 20 16:43:09 2003// > +/Kconfig.ladd/1.1/Tue Dec 23 11:41:11 2003// > +/Makefile.ladd/1.1/Sat Dec 20 16:43:09 2003// > +/ip6t_ROUTE.c/1.1/Sat Dec 20 16:43:09 2003// > +D > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository 1970-01-01 01:00:00.000000000 +0100 > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository 2004-03-08 10:06:41.000000000 +0100 > @@ -0,0 +1 @@ > +patch-o-matic-ng/ROUTE/linux/net/ipv6/netfilter > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root 1970-01-01 01:00:00.000000000 +0100 > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root 2004-03-08 10:06:41.000000000 +0100 > @@ -0,0 +1 @@ > +:pserver:cvs:cvs@pserver.netfilter.org:/cvspublic ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x 2004-04-24 23:03 ` Patrick McHardy @ 2004-04-25 0:01 ` Esteban Ribicic 2004-04-26 4:46 ` Henrik Nordstrom 2004-04-28 15:25 ` Cedric de Launois 1 sibling, 1 reply; 6+ messages in thread From: Esteban Ribicic @ 2004-04-25 0:01 UTC (permalink / raw) To: netfilter-devel Content-Transfer-Encoding: 7bit hi im trying to match all recent ip_conntrak connections from my network im using this algortithm: # does not concern ESTA connections.. # udp 17 59 src=10.0.3.75 dst=62.215.85.173 sport=26097 dport=19210 src=62.215.85.173 dst=200.69.147.80 sport=19210 dport=26097 [ASSURED] use=1 mark=0 $timeout=300; if ($_=~/\w+\s+\d+\s(\d+)\s+src=/) { if ($1<$timeout) { $counter++; } } where $timeout is the max timeout of the connection. now, what i notice is that ESTABLISHED connections are rarely under 2000 seconds? isnt it rare? lp:~/codigos/conntrack# cat /proc/net/ip_conntrack | grep ESTABLISHED | awk '{print $3}' | sort -n | head -n 5 870 938 1106 1977 1990 ...(the list is realy extensive) Its obvious im thinking something woron..maybe $1 is not a timeout and less is seconds? thanks for the help Steve On Sun, 25 Apr 2004 01:03:24 +0200 Patrick McHardy <kaber@trash.net> wrote: > Cedric de Launois wrote: > > Here is a patch to convert the ROUTE target to the new pom-ng. > > This patch also contains a corrected version of the ROUTE target > > for kernels 2.6.x. > > Please make sure your patch doesn't contain changes to CVS directories. > > Regards > Patrick > > > > > Cedric > > > > > > > > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries > > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Entries 1970-01-01 01:00:00.000000000 +0100 > > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Entries 2004-03-08 10:06:41.000000000 +0100 > > @@ -0,0 +1,5 @@ > > +/Config.in.ladd/1.1/Sat Dec 20 16:43:09 2003// > > +/Kconfig.ladd/1.1/Tue Dec 23 11:41:11 2003// > > +/Makefile.ladd/1.1/Sat Dec 20 16:43:09 2003// > > +/ip6t_ROUTE.c/1.1/Sat Dec 20 16:43:09 2003// > > +D > > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository > > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Repository 1970-01-01 01:00:00.000000000 +0100 > > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Repository 2004-03-08 10:06:41.000000000 +0100 > > @@ -0,0 +1 @@ > > +patch-o-matic-ng/ROUTE/linux/net/ipv6/netfilter > > diff -Nru ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root > > --- ROUTE.orig/linux-2.4/net/ipv6/netfilter/CVS/Root 1970-01-01 01:00:00.000000000 +0100 > > +++ ROUTE/linux-2.4/net/ipv6/netfilter/CVS/Root 2004-03-08 10:06:41.000000000 +0100 > > @@ -0,0 +1 @@ > > +:pserver:cvs:cvs@pserver.netfilter.org:/cvspublic > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x 2004-04-25 0:01 ` Esteban Ribicic @ 2004-04-26 4:46 ` Henrik Nordstrom 0 siblings, 0 replies; 6+ messages in thread From: Henrik Nordstrom @ 2004-04-26 4:46 UTC (permalink / raw) To: Esteban Ribicic; +Cc: netfilter-devel On Sat, 24 Apr 2004, Esteban Ribicic wrote: > now, what i notice is that ESTABLISHED connections are rarely under 2000 seconds? isnt it rare? The timeout of a ESTABLISHED TCP is 5 days (432000 seconds).. A ESTABLISHED connecting with a timeout under 2000 seconds needs to have been idle in almost 5 days.. TCP state timeouts from ip_conntrack_proto_tcp: unsigned long ip_ct_tcp_timeout_syn_sent = 2 MINS; unsigned long ip_ct_tcp_timeout_syn_recv = 60 SECS; unsigned long ip_ct_tcp_timeout_established = 5 DAYS; unsigned long ip_ct_tcp_timeout_fin_wait = 2 MINS; unsigned long ip_ct_tcp_timeout_close_wait = 60 SECS; unsigned long ip_ct_tcp_timeout_last_ack = 30 SECS; unsigned long ip_ct_tcp_timeout_time_wait = 2 MINS; unsigned long ip_ct_tcp_timeout_close = 10 SECS; Each packet while the TCP is in the given state extends the timeout. On UDP the timeouts is much smaller due to the stateless nature of the protocol unsigned long ip_ct_udp_timeout = 30*HZ; unsigned long ip_ct_udp_timeout_stream = 180*HZ; 30 seconds for traffic in only one direction, 180 if traffic has been seen in both directions. Regards Henrik ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x 2004-04-24 23:03 ` Patrick McHardy 2004-04-25 0:01 ` Esteban Ribicic @ 2004-04-28 15:25 ` Cedric de Launois 2004-04-29 16:45 ` Patrick McHardy 1 sibling, 1 reply; 6+ messages in thread From: Cedric de Launois @ 2004-04-28 15:25 UTC (permalink / raw) To: Patrick McHardy; +Cc: Netfilter Development Mailinglist [-- Attachment #1: Type: text/plain, Size: 392 bytes --] Le dim 25/04/2004 à 01:03, Patrick McHardy a écrit : > Cedric de Launois wrote: > > Here is a patch to convert the ROUTE target to the new pom-ng. > > This patch also contains a corrected version of the ROUTE target > > for kernels 2.6.x. > > Please make sure your patch doesn't contain changes to CVS directories. Oops, sorry. This patch should be better. Regards, Cedric [-- Attachment #2: ROUTE.pom-ng.patch --] [-- Type: text/x-patch, Size: 66675 bytes --] diff -Nru ./ROUTE.orig/info ./ROUTE/info --- ./ROUTE.orig/info 2004-02-20 00:11:50.000000000 +0100 +++ ./ROUTE/info 2004-03-08 14:19:22.000000000 +0100 @@ -1,4 +1,5 @@ Author: Cédric de Launois <delaunois@info.ucl.ac.be> Status: Experimental Repository: extra -Requires: linux < 2.6.0 +Recompile: netfilter +Recompile: iptables diff -Nru ./ROUTE.orig/linux/Documentation/Configure.help.ladd ./ROUTE/linux/Documentation/Configure.help.ladd --- ./ROUTE.orig/linux/Documentation/Configure.help.ladd 2004-02-19 12:30:08.000000000 +0100 +++ ./ROUTE/linux/Documentation/Configure.help.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,16 +0,0 @@ -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. 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. - - 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. - If unsure, say `N'. - diff -Nru ./ROUTE.orig/linux/Documentation/Configure.help.ladd_2 ./ROUTE/linux/Documentation/Configure.help.ladd_2 --- ./ROUTE.orig/linux/Documentation/Configure.help.ladd_2 2004-03-05 10:30:26.000000000 +0100 +++ ./ROUTE/linux/Documentation/Configure.help.ladd_2 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -CONFIG_IP6_NF_TARGET_MARK -ROUTE target support -CONFIG_IP6_NF_TARGET_ROUTE - This option adds a `ROUTE' target, which enables you to setup unusual - routes. The ROUTE target is also able to change the incoming interface - of a packet. - - The target can be or not a final target. It has to be used inside the - mangle table. - - Not working as a module. - diff -Nru ./ROUTE.orig/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h ./ROUTE/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h --- ./ROUTE.orig/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100 +++ ./ROUTE/linux/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -/* Header file for iptables ipt_ROUTE target - * - * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be> - * - * This software is distributed under GNU GPL v2, 1991 - */ -#ifndef _IPT_ROUTE_H_target -#define _IPT_ROUTE_H_target - -#define IPT_ROUTE_IFNAMSIZ 16 - -struct ipt_route_target_info { - 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 ./ROUTE.orig/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h ./ROUTE/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h --- ./ROUTE.orig/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100 +++ ./ROUTE/linux/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -/* Header file for iptables ip6t_ROUTE target - * - * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be> - * - * This software is distributed under GNU GPL v2, 1991 - */ -#ifndef _IPT_ROUTE_H_target -#define _IPT_ROUTE_H_target - -#define IP6T_ROUTE_IFNAMSIZ 16 - -struct ip6t_route_target_info { - char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */ - char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */ - u_int32_t gw[4]; /* IPv6 address of gateway */ - u_int8_t flags; -}; - -/* Values for "flags" field */ -#define IP6T_ROUTE_CONTINUE 0x01 - -#endif /*_IP6T_ROUTE_H_target*/ diff -Nru ./ROUTE.orig/linux/net/ipv4/netfilter/Config.in.ladd ./ROUTE/linux/net/ipv4/netfilter/Config.in.ladd --- ./ROUTE.orig/linux/net/ipv4/netfilter/Config.in.ladd 2003-12-18 19:47:54.000000000 +0100 +++ ./ROUTE/linux/net/ipv4/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ - 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 ./ROUTE.orig/linux/net/ipv4/netfilter/ipt_ROUTE.c ./ROUTE/linux/net/ipv4/netfilter/ipt_ROUTE.c --- ./ROUTE.orig/linux/net/ipv4/netfilter/ipt_ROUTE.c 2003-12-18 19:47:54.000000000 +0100 +++ ./ROUTE/linux/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,369 +0,0 @@ -/* - * 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.8 2003/07/25 - * - * This software is distributed under GNU GPL v2, 1991 - */ - -#include <linux/module.h> -#include <linux/skbuff.h> -#include <linux/ip.h> -#include <linux/netfilter_ipv4/ip_tables.h> -#include <linux/netfilter_ipv4/ipt_ROUTE.h> -#include <linux/netdevice.h> -#include <linux/route.h> -#include <net/ip.h> -#include <net/route.h> -#include <net/icmp.h> - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - - -/* Try to route the packet according to the routing keys specified in - * route_info. Keys are : - * - ifindex : - * 0 if no oif preferred, - * otherwise set to the index of the desired oif - * - route_info->gw : - * 0 if no gateway specified, - * otherwise set to the next host to which the pkt must be routed - * If success, skb->dev is the output device to which the packet must - * be sent and skb->dst is not NULL - * - * RETURN: -1 if an error occured - * 1 if the packet was succesfully routed to the - * destination desired - * 0 if the kernel routing table could not route the packet - * according to the keys specified - */ -static int route(struct sk_buff *skb, - unsigned int ifindex, - const struct ipt_route_target_info *route_info) -{ - int err; - struct rtable *rt; - struct iphdr *iph = skb->nh.iph; - struct rt_key key = { - dst:iph->daddr, - src:0, - oif:ifindex, - tos:RT_TOS(iph->tos) - }; - - /* The destination address may be overloaded by the target */ - if (route_info->gw) - key.dst = route_info->gw; - - /* Trying to route the packet using the standard routing table. */ - if ((err = ip_route_output_key(&rt, &key))) { - if (net_ratelimit()) - DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err); - return -1; - } - - /* Drop old route. */ - dst_release(skb->dst); - skb->dst = NULL; - - /* Success if no oif specified or if the oif correspond to the - * one desired */ - if (!ifindex || rt->u.dst.dev->ifindex == ifindex) { - skb->dst = &rt->u.dst; - skb->dev = skb->dst->dev; - return 1; - } - - /* The interface selected by the routing table is not the one - * specified by the user. This may happen because the dst address - * is one of our own addresses. - */ - 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; -} - - -/* Stolen from ip_finish_output2 - * PRE : skb->dev is set to the device we are leaving by - * skb->dst is not NULL - * POST: the packet is sent with the link layer header pushed - * the packet is destroyed - */ -static void ip_direct_send(struct sk_buff *skb) -{ - struct dst_entry *dst = skb->dst; - struct hh_cache *hh = dst->hh; - - if (hh) { - read_lock_bh(&hh->hh_lock); - memcpy(skb->data - 16, hh->hh_data, 16); - read_unlock_bh(&hh->hh_lock); - skb_push(skb, hh->hh_len); - hh->hh_output(skb); - } else if (dst->neighbour) - dst->neighbour->output(skb); - else { - if (net_ratelimit()) - DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n"); - kfree_skb(skb); - } -} - - -/* PRE : skb->dev is set to the device we are leaving by - * POST: - the packet is directly sent to the skb->dev device, without - * pushing the link layer header. - * - the packet is destroyed - */ -static inline int dev_direct_send(struct sk_buff *skb) -{ - return dev_queue_xmit(skb); -} - - -static unsigned int route_oif(const struct ipt_route_target_info *route_info, - struct sk_buff *skb) -{ - 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))) { - ifindex = dev_out->ifindex; - } else { - /* Unknown interface name : packet dropped */ - if (net_ratelimit()) - DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif); - return NF_DROP; - } - - /* Trying the standard way of routing packets */ - 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; - - case 0: - /* Failed to send to oif. Trying the hard way */ - if (route_info->flags & IPT_ROUTE_CONTINUE) - return NF_DROP; - - 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; - } -} - - -static unsigned int route_iif(const struct ipt_route_target_info *route_info, - struct sk_buff *skb) -{ - struct net_device *dev_out = NULL; - unsigned int ifindex = 0; - - /* Getting the current interface index. */ - if ((dev_out = dev_get_by_name(route_info->iif))) - ifindex = dev_out->ifindex; - else { - /* Unknown interface name : packet dropped */ - if (net_ratelimit()) - DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->oif); - return NF_DROP; - } - - skb->dev = dev_out; - dst_release(skb->dst); - skb->dst = NULL; - - netif_rx(skb); - - return NF_STOLEN; -} - - -static unsigned int route_gw(const struct ipt_route_target_info *route_info, - struct sk_buff *skb) -{ - if (route(skb, 0, route_info)!=1) - return NF_DROP; - - if (route_info->flags & IPT_ROUTE_CONTINUE) - return IPT_CONTINUE; - - ip_direct_send(skb); - return NF_STOLEN; -} - - -static unsigned int ipt_route_target(struct sk_buff **pskb, - unsigned int hooknum, - const struct net_device *in, - const struct net_device *out, - const void *targinfo, - void *userinfo) -{ - const struct ipt_route_target_info *route_info = targinfo; - struct sk_buff *skb = *pskb; - - /* If we are at PREROUTING or INPUT hook - * the TTL isn't decreased by the IP stack - */ - if (hooknum == NF_IP_PRE_ROUTING || - hooknum == NF_IP_LOCAL_IN) { - - struct iphdr *iph = skb->nh.iph; - - if (iph->ttl <= 1) { - struct rtable *rt; - - if (ip_route_output(&rt, iph->saddr, iph->daddr, - RT_TOS(iph->tos) | RTO_CONN, - 0)) { - return NF_DROP; - } - - if (skb->dev == rt->u.dst.dev) { - /* Drop old route. */ - dst_release(skb->dst); - skb->dst = &rt->u.dst; - - /* this will traverse normal stack, and - * thus call conntrack on the icmp packet */ - icmp_send(skb, ICMP_TIME_EXCEEDED, - ICMP_EXC_TTL, 0); - } - - return NF_DROP; - } - - ip_decrease_ttl(iph); - } - - /* Tell conntrack to forget this packet since it may get confused - * when a packet is leaving with dst address == our address. - * Good idea ? Dunno. Need advice. - */ - 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; -#endif - } - - if (route_info->oif[0]) - return route_oif(route_info, *pskb); - - if (route_info->iif[0]) - return route_iif(route_info, *pskb); - - if (route_info->gw) - return route_gw(route_info, *pskb); - - if (net_ratelimit()) - DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n"); - - return IPT_CONTINUE; -} - - -static int ipt_route_checkentry(const char *tablename, - const struct ipt_entry *e, - void *targinfo, - unsigned int targinfosize, - unsigned int hook_mask) -{ - if (strcmp(tablename, "mangle") != 0) { - printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n", - tablename); - return 0; - } - - if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING) - | (1 << NF_IP_LOCAL_IN) - | (1 << NF_IP_FORWARD) - | (1 << NF_IP_LOCAL_OUT) - | (1 << NF_IP_POST_ROUTING))) { - printk("ipt_ROUTE: bad hook\n"); - return 0; - } - - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) { - printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n", - targinfosize, - IPT_ALIGN(sizeof(struct ipt_route_target_info))); - return 0; - } - - return 1; -} - - -static struct ipt_target ipt_route_reg -= { { NULL, NULL }, "ROUTE", ipt_route_target, ipt_route_checkentry, NULL, - THIS_MODULE }; - - -static int __init init(void) -{ - if (ipt_register_target(&ipt_route_reg)) - return -EINVAL; - - return 0; -} - - -static void __exit fini(void) -{ - ipt_unregister_target(&ipt_route_reg); -} - -module_init(init); -module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru ./ROUTE.orig/linux/net/ipv4/netfilter/Kconfig.ladd ./ROUTE/linux/net/ipv4/netfilter/Kconfig.ladd --- ./ROUTE.orig/linux/net/ipv4/netfilter/Kconfig.ladd 2003-12-21 21:09:27.000000000 +0100 +++ ./ROUTE/linux/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -config IP_NF_TARGET_ROUTE - tristate 'ROUTE target support' - depends on IP_NF_MANGLE diff -Nru ./ROUTE.orig/linux/net/ipv4/netfilter/Makefile.ladd ./ROUTE/linux/net/ipv4/netfilter/Makefile.ladd --- ./ROUTE.orig/linux/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100 +++ ./ROUTE/linux/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o -obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o diff -Nru ./ROUTE.orig/linux/net/ipv6/netfilter/Config.in.ladd ./ROUTE/linux/net/ipv6/netfilter/Config.in.ladd --- ./ROUTE.orig/linux/net/ipv6/netfilter/Config.in.ladd 2003-12-20 17:43:09.000000000 +0100 +++ ./ROUTE/linux/net/ipv6/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ - dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE - dep_mbool ' ROUTE target support' CONFIG_IP6_NF_TARGET_ROUTE $CONFIG_IP6_NF_MANGLE \ Pas de fin de ligne à la fin du fichier. diff -Nru ./ROUTE.orig/linux/net/ipv6/netfilter/ip6t_ROUTE.c ./ROUTE/linux/net/ipv6/netfilter/ip6t_ROUTE.c --- ./ROUTE.orig/linux/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100 +++ ./ROUTE/linux/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,289 +0,0 @@ -/* - * This implements the ROUTE v6 target, which enables you to setup unusual - * routes not supported by the standard kernel routing table. - * - * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be> - * - * v 1.0 2003/08/05 - * - * This software is distributed under GNU GPL v2, 1991 - */ - -#include <linux/module.h> -#include <linux/skbuff.h> -#include <linux/ipv6.h> -#include <linux/netfilter_ipv6/ip6_tables.h> -#include <linux/netfilter_ipv6/ip6t_ROUTE.h> -#include <linux/netdevice.h> -#include <net/ipv6.h> -#include <net/ndisc.h> -#include <net/ip6_route.h> -#include <linux/icmpv6.h> - -#if 1 -#define DEBUGP printk -#else -#define DEBUGP(format, args...) -#endif - -#define NIP6(addr) \ - ntohs((addr).s6_addr16[0]), \ - ntohs((addr).s6_addr16[1]), \ - ntohs((addr).s6_addr16[2]), \ - ntohs((addr).s6_addr16[3]), \ - ntohs((addr).s6_addr16[4]), \ - ntohs((addr).s6_addr16[5]), \ - ntohs((addr).s6_addr16[6]), \ - ntohs((addr).s6_addr16[7]) - -/* Route the packet according to the routing keys specified in - * route_info. Keys are : - * - ifindex : - * 0 if no oif preferred, - * otherwise set to the index of the desired oif - * - route_info->gw : - * 0 if no gateway specified, - * otherwise set to the next host to which the pkt must be routed - * If success, skb->dev is the output device to which the packet must - * be sent and skb->dst is not NULL - * - * RETURN: 1 if the packet was succesfully routed to the - * destination desired - * 0 if the kernel routing table could not route the packet - * according to the keys specified - */ -static int -route6(struct sk_buff *skb, - unsigned int ifindex, - const struct ip6t_route_target_info *route_info) -{ - struct rt6_info *rt = NULL; - struct ipv6hdr *ipv6h = skb->nh.ipv6h; - struct in6_addr *gw = (struct in6_addr*)&route_info->gw; - - DEBUGP("ip6t_ROUTE: called with: "); - DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr)); - DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw)); - DEBUGP("OUT=%s\n", route_info->oif); - - if (ipv6_addr_any(gw)) - rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1); - else - rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1); - - if (!rt) - goto no_route; - - DEBUGP("ip6t_ROUTE: routing gives: "); - DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr)); - DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway)); - DEBUGP("OUT=%s\n", rt->rt6i_dev->name); - - if (ifindex && rt->rt6i_dev->ifindex!=ifindex) - goto wrong_route; - - if (!rt->rt6i_nexthop) { - DEBUGP("ip6t_ROUTE: discovering neighbour\n"); - rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr); - } - - /* Drop old route. */ - dst_release(skb->dst); - skb->dst = &rt->u.dst; - skb->dev = rt->rt6i_dev; - return 1; - - wrong_route: - dst_release(&rt->u.dst); - no_route: - if (!net_ratelimit()) - return 0; - - printk("ip6t_ROUTE: no explicit route found "); - if (ifindex) - printk("via interface %s ", route_info->oif); - if (!ipv6_addr_any(gw)) - printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw)); - printk("\n"); - return 0; -} - - -/* Stolen from ip6_output_finish - * PRE : skb->dev is set to the device we are leaving by - * skb->dst is not NULL - * POST: the packet is sent with the link layer header pushed - * the packet is destroyed - */ -static void ip_direct_send(struct sk_buff *skb) -{ - struct dst_entry *dst = skb->dst; - struct hh_cache *hh = dst->hh; - - if (hh) { - read_lock_bh(&hh->hh_lock); - memcpy(skb->data - 16, hh->hh_data, 16); - read_unlock_bh(&hh->hh_lock); - skb_push(skb, hh->hh_len); - hh->hh_output(skb); - } else if (dst->neighbour) - dst->neighbour->output(skb); - else { - if (net_ratelimit()) - DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n"); - kfree_skb(skb); - } -} - - -static unsigned int -route6_oif(const struct ip6t_route_target_info *route_info, - struct sk_buff *skb) -{ - 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))) { - ifindex = dev_out->ifindex; - } else { - /* Unknown interface name : packet dropped */ - if (net_ratelimit()) - DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif); - - if (route_info->flags & IP6T_ROUTE_CONTINUE) - return IP6T_CONTINUE; - else - return NF_DROP; - } - - /* Trying the standard way of routing packets */ - if (route6(skb, ifindex, route_info)) { - dev_put(dev_out); - if (route_info->flags & IP6T_ROUTE_CONTINUE) - return IP6T_CONTINUE; - - ip_direct_send(skb); - return NF_STOLEN; - } else - return NF_DROP; -} - - -static unsigned int -route6_gw(const struct ip6t_route_target_info *route_info, - struct sk_buff *skb) -{ - if (route6(skb, 0, route_info)) { - if (route_info->flags & IP6T_ROUTE_CONTINUE) - return IP6T_CONTINUE; - - ip_direct_send(skb); - return NF_STOLEN; - } else - return NF_DROP; -} - - -static unsigned int -ip6t_route_target(struct sk_buff **pskb, - unsigned int hooknum, - const struct net_device *in, - const struct net_device *out, - const void *targinfo, - void *userinfo) -{ - const struct ip6t_route_target_info *route_info = targinfo; - struct sk_buff *skb = *pskb; - struct in6_addr *gw = (struct in6_addr*)&route_info->gw; - - if (route_info->flags & IP6T_ROUTE_CONTINUE) - goto do_it; - - /* If we are at PREROUTING or INPUT hook - * the TTL isn't decreased by the IP stack - */ - if (hooknum == NF_IP6_PRE_ROUTING || - hooknum == NF_IP6_LOCAL_IN) { - - struct ipv6hdr *ipv6h = skb->nh.ipv6h; - - if (ipv6h->hop_limit <= 1) { - /* Force OUTPUT device used as source address */ - skb->dev = skb->dst->dev; - - icmpv6_send(skb, ICMPV6_TIME_EXCEED, - ICMPV6_EXC_HOPLIMIT, 0, skb->dev); - - return NF_DROP; - } - - ipv6h->hop_limit--; - } - - - do_it: - if (route_info->oif[0]) - return route6_oif(route_info, *pskb); - - if (!ipv6_addr_any(gw)) - return route6_gw(route_info, *pskb); - - if (net_ratelimit()) - DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n"); - - return IP6T_CONTINUE; -} - - -static int -ip6t_route_checkentry(const char *tablename, - const struct ip6t_entry *e, - void *targinfo, - unsigned int targinfosize, - unsigned int hook_mask) -{ - if (strcmp(tablename, "mangle") != 0) { - printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n"); - return 0; - } - - if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) { - printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n", - targinfosize, - IP6T_ALIGN(sizeof(struct ip6t_route_target_info))); - return 0; - } - - return 1; -} - - -static struct ip6t_target ip6t_route_reg = { - .name = "ROUTE", - .target = ip6t_route_target, - .checkentry = ip6t_route_checkentry, - .me = THIS_MODULE -}; - - -static int __init init(void) -{ - printk(KERN_DEBUG "registering ipv6 ROUTE target\n"); - if (ip6t_register_target(&ip6t_route_reg)) - return -EINVAL; - - return 0; -} - - -static void __exit fini(void) -{ - ip6t_unregister_target(&ip6t_route_reg); -} - -module_init(init); -module_exit(fini); -MODULE_LICENSE("GPL"); diff -Nru ./ROUTE.orig/linux/net/ipv6/netfilter/Kconfig.ladd ./ROUTE/linux/net/ipv6/netfilter/Kconfig.ladd --- ./ROUTE.orig/linux/net/ipv6/netfilter/Kconfig.ladd 2003-12-23 12:41:11.000000000 +0100 +++ ./ROUTE/linux/net/ipv6/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,3 +0,0 @@ -config IP6_NF_TARGET_ROUTE - tristate ' ROUTE target support' - depends on IP6_NF_MANGLE diff -Nru ./ROUTE.orig/linux/net/ipv6/netfilter/Makefile.ladd ./ROUTE/linux/net/ipv6/netfilter/Makefile.ladd --- ./ROUTE.orig/linux/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100 +++ ./ROUTE/linux/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o -obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o diff -Nru ./ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd ./ROUTE/linux-2.4/Documentation/Configure.help.ladd --- ./ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/Documentation/Configure.help.ladd 2004-02-19 12:30:08.000000000 +0100 @@ -0,0 +1,16 @@ +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. 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. + + 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. + If unsure, say `N'. + diff -Nru ./ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd_2 ./ROUTE/linux-2.4/Documentation/Configure.help.ladd_2 --- ./ROUTE.orig/linux-2.4/Documentation/Configure.help.ladd_2 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/Documentation/Configure.help.ladd_2 2004-03-05 10:30:26.000000000 +0100 @@ -0,0 +1,12 @@ +CONFIG_IP6_NF_TARGET_MARK +ROUTE target support +CONFIG_IP6_NF_TARGET_ROUTE + This option adds a `ROUTE' target, which enables you to setup unusual + routes. The ROUTE target is also able to change the incoming interface + of a packet. + + The target can be or not a final target. It has to be used inside the + mangle table. + + Not working as a module. + diff -Nru ./ROUTE.orig/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h ./ROUTE/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h --- ./ROUTE.orig/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100 @@ -0,0 +1,22 @@ +/* Header file for iptables ipt_ROUTE target + * + * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be> + * + * This software is distributed under GNU GPL v2, 1991 + */ +#ifndef _IPT_ROUTE_H_target +#define _IPT_ROUTE_H_target + +#define IPT_ROUTE_IFNAMSIZ 16 + +struct ipt_route_target_info { + 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 ./ROUTE.orig/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h ./ROUTE/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h --- ./ROUTE.orig/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,22 @@ +/* Header file for iptables ip6t_ROUTE target + * + * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be> + * + * This software is distributed under GNU GPL v2, 1991 + */ +#ifndef _IPT_ROUTE_H_target +#define _IPT_ROUTE_H_target + +#define IP6T_ROUTE_IFNAMSIZ 16 + +struct ip6t_route_target_info { + char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */ + char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */ + u_int32_t gw[4]; /* IPv6 address of gateway */ + u_int8_t flags; +}; + +/* Values for "flags" field */ +#define IP6T_ROUTE_CONTINUE 0x01 + +#endif /*_IP6T_ROUTE_H_target*/ diff -Nru ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Config.in.ladd ./ROUTE/linux-2.4/net/ipv4/netfilter/Config.in.ladd --- ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv4/netfilter/Config.in.ladd 2003-12-18 19:47:54.000000000 +0100 @@ -0,0 +1,3 @@ + 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 ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c ./ROUTE/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c --- ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv4/netfilter/ipt_ROUTE.c 2004-04-21 09:47:08.000000000 +0200 @@ -0,0 +1,401 @@ +/* + * 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.10 2004/04/21 + * + * This software is distributed under GNU GPL v2, 1991 + * + * 30 Dec 2003: Rickard Molin <rickard.molin@businessecurity.com> + * - recalculate checksum at INPUT chain after ttl is decreased + * 21 Apr 2004: Bill Rugolsky Jr. <brugolsky@telemetry-investments.com> + * - fix missing dev_put() in route_iif() + */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/ip.h> +#include <linux/netfilter_ipv4/ip_tables.h> +#include <linux/netfilter_ipv4/ipt_ROUTE.h> +#include <linux/netdevice.h> +#include <linux/route.h> +#include <net/ip.h> +#include <net/route.h> +#include <net/icmp.h> +#include <net/checksum.h> + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + + +/* Try to route the packet according to the routing keys specified in + * route_info. Keys are : + * - ifindex : + * 0 if no oif preferred, + * otherwise set to the index of the desired oif + * - route_info->gw : + * 0 if no gateway specified, + * otherwise set to the next host to which the pkt must be routed + * If success, skb->dev is the output device to which the packet must + * be sent and skb->dst is not NULL + * + * RETURN: -1 if an error occured + * 1 if the packet was succesfully routed to the + * destination desired + * 0 if the kernel routing table could not route the packet + * according to the keys specified + */ +static int route(struct sk_buff *skb, + unsigned int ifindex, + const struct ipt_route_target_info *route_info) +{ + int err; + struct rtable *rt; + struct iphdr *iph = skb->nh.iph; + struct rt_key key = { + dst:iph->daddr, + src:0, + oif:ifindex, + tos:RT_TOS(iph->tos) + }; + + /* The destination address may be overloaded by the target */ + if (route_info->gw) + key.dst = route_info->gw; + + /* Trying to route the packet using the standard routing table. */ + if ((err = ip_route_output_key(&rt, &key))) { + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err); + return -1; + } + + /* Drop old route. */ + dst_release(skb->dst); + skb->dst = NULL; + + /* Success if no oif specified or if the oif correspond to the + * one desired */ + if (!ifindex || rt->u.dst.dev->ifindex == ifindex) { + skb->dst = &rt->u.dst; + skb->dev = skb->dst->dev; + return 1; + } + + /* The interface selected by the routing table is not the one + * specified by the user. This may happen because the dst address + * is one of our own addresses. + */ + 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; +} + + +/* Stolen from ip_finish_output2 + * PRE : skb->dev is set to the device we are leaving by + * skb->dst is not NULL + * POST: the packet is sent with the link layer header pushed + * the packet is destroyed + */ +static void ip_direct_send(struct sk_buff *skb) +{ + struct dst_entry *dst = skb->dst; + struct hh_cache *hh = dst->hh; + + if (hh) { + read_lock_bh(&hh->hh_lock); + memcpy(skb->data - 16, hh->hh_data, 16); + read_unlock_bh(&hh->hh_lock); + skb_push(skb, hh->hh_len); + hh->hh_output(skb); + } else if (dst->neighbour) + dst->neighbour->output(skb); + else { + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n"); + kfree_skb(skb); + } +} + + +/* PRE : skb->dev is set to the device we are leaving by + * POST: - the packet is directly sent to the skb->dev device, without + * pushing the link layer header. + * - the packet is destroyed + */ +static inline int dev_direct_send(struct sk_buff *skb) +{ + return dev_queue_xmit(skb); +} + + +static void ip_tunnel_send(struct sk_buff *skb) +{ + memset(skb->data - 16, 0, 16); + skb_push(skb, skb->dev->hard_header_len); + dev_direct_send(skb); +} + + +static unsigned int route_oif(const struct ipt_route_target_info *route_info, + struct sk_buff *skb) +{ + 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))) { + ifindex = dev_out->ifindex; + } else { + /* Unknown interface name : packet dropped */ + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif); + + if (route_info->flags & IPT_ROUTE_CONTINUE) + return IPT_CONTINUE; + else + return NF_DROP; + } + + /* Trying the standard way of routing packets */ + 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; + + case 0: + /* Failed to send to oif. Trying the hard way */ + if (route_info->flags & IPT_ROUTE_CONTINUE) { + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: can't force the use of %s with --continue\n", + route_info->oif); + return IPT_CONTINUE; + } + + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: forcing the use of %s\n", + route_info->oif); + + /* 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; + ip_tunnel_send(skb); + dev_put(dev_out); + return NF_STOLEN; + + default: + /* Unexpected error */ + dev_put(dev_out); + return NF_DROP; + } +} + + +static unsigned int route_iif(const struct ipt_route_target_info *route_info, + struct sk_buff *skb) +{ + struct net_device *dev_in = NULL; + + if (!(dev_in = dev_get_by_name(route_info->iif))) { + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif); + return NF_DROP; + } + + skb->dev = dev_in; + dst_release(skb->dst); + skb->dst = NULL; + + netif_rx(skb); + + dev_put(dev_in); + return NF_STOLEN; +} + + +static unsigned int route_gw(const struct ipt_route_target_info *route_info, + struct sk_buff *skb) +{ + if (route(skb, 0, route_info)!=1) + if (!(route_info->flags & IPT_ROUTE_CONTINUE)) + return NF_DROP; + + if (route_info->flags & IPT_ROUTE_CONTINUE) + return IPT_CONTINUE; + + ip_direct_send(skb); + return NF_STOLEN; +} + + +static unsigned int ipt_route_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ipt_route_target_info *route_info = targinfo; + struct sk_buff *skb = *pskb; + + if (route_info->flags & IPT_ROUTE_CONTINUE) + goto do_it; + + /* If we are at PREROUTING or INPUT hook + * the TTL isn't decreased by the IP stack + */ + if (hooknum == NF_IP_PRE_ROUTING || + hooknum == NF_IP_LOCAL_IN) { + + struct iphdr *iph = skb->nh.iph; + + if (iph->ttl <= 1) { + struct rtable *rt; + + if (ip_route_output(&rt, iph->saddr, iph->daddr, + RT_TOS(iph->tos) | RTO_CONN, + 0)) { + return NF_DROP; + } + + if (skb->dev == rt->u.dst.dev) { + /* Drop old route. */ + dst_release(skb->dst); + skb->dst = &rt->u.dst; + + /* this will traverse normal stack, and + * thus call conntrack on the icmp packet */ + icmp_send(skb, ICMP_TIME_EXCEEDED, + ICMP_EXC_TTL, 0); + } + + return NF_DROP; + } + + /* + * If we are at INPUT the checksum must be recalculated since + * the length could change as the result of a defragmentation. + */ + if(hooknum == NF_IP_LOCAL_IN) { + iph->ttl = iph->ttl - 1; + iph->check = 0; + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } else { + ip_decrease_ttl(iph); + } + } + + /* Tell conntrack to forget this packet since it may get confused + * 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; +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif + + + do_it: + if (route_info->oif[0]) + return route_oif(route_info, *pskb); + + if (route_info->iif[0]) + return route_iif(route_info, *pskb); + + if (route_info->gw) + return route_gw(route_info, *pskb); + + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ipt_ROUTE: no parameter !\n"); + + return IPT_CONTINUE; +} + + +static int ipt_route_checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (strcmp(tablename, "mangle") != 0) { + printk("ipt_ROUTE: bad table `%s', use the `mangle' table.\n", + tablename); + return 0; + } + + if (hook_mask & ~( (1 << NF_IP_PRE_ROUTING) + | (1 << NF_IP_LOCAL_IN) + | (1 << NF_IP_FORWARD) + | (1 << NF_IP_LOCAL_OUT) + | (1 << NF_IP_POST_ROUTING))) { + printk("ipt_ROUTE: bad hook\n"); + return 0; + } + + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_route_target_info))) { + printk(KERN_WARNING "ipt_ROUTE: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_route_target_info))); + return 0; + } + + return 1; +} + + +static struct ipt_target ipt_route_reg += { { NULL, NULL }, "ROUTE", ipt_route_target, ipt_route_checkentry, NULL, + THIS_MODULE }; + + +static int __init init(void) +{ + if (ipt_register_target(&ipt_route_reg)) + return -EINVAL; + + return 0; +} + + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_route_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Kconfig.ladd ./ROUTE/linux-2.4/net/ipv4/netfilter/Kconfig.ladd --- ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv4/netfilter/Kconfig.ladd 2003-12-21 21:09:27.000000000 +0100 @@ -0,0 +1,3 @@ +config IP_NF_TARGET_ROUTE + tristate 'ROUTE target support' + depends on IP_NF_MANGLE diff -Nru ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Makefile.ladd ./ROUTE/linux-2.4/net/ipv4/netfilter/Makefile.ladd --- ./ROUTE.orig/linux-2.4/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100 @@ -0,0 +1,2 @@ +obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o +obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o diff -Nru ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/Config.in.ladd ./ROUTE/linux-2.4/net/ipv6/netfilter/Config.in.ladd --- ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/Config.in.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv6/netfilter/Config.in.ladd 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,2 @@ + dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE + dep_mbool ' ROUTE target support' CONFIG_IP6_NF_TARGET_ROUTE $CONFIG_IP6_NF_MANGLE \ Pas de fin de ligne à la fin du fichier. diff -Nru ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c ./ROUTE/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c --- ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,289 @@ +/* + * This implements the ROUTE v6 target, which enables you to setup unusual + * routes not supported by the standard kernel routing table. + * + * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be> + * + * v 1.0 2003/08/05 + * + * This software is distributed under GNU GPL v2, 1991 + */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/ipv6.h> +#include <linux/netfilter_ipv6/ip6_tables.h> +#include <linux/netfilter_ipv6/ip6t_ROUTE.h> +#include <linux/netdevice.h> +#include <net/ipv6.h> +#include <net/ndisc.h> +#include <net/ip6_route.h> +#include <linux/icmpv6.h> + +#if 1 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +#define NIP6(addr) \ + ntohs((addr).s6_addr16[0]), \ + ntohs((addr).s6_addr16[1]), \ + ntohs((addr).s6_addr16[2]), \ + ntohs((addr).s6_addr16[3]), \ + ntohs((addr).s6_addr16[4]), \ + ntohs((addr).s6_addr16[5]), \ + ntohs((addr).s6_addr16[6]), \ + ntohs((addr).s6_addr16[7]) + +/* Route the packet according to the routing keys specified in + * route_info. Keys are : + * - ifindex : + * 0 if no oif preferred, + * otherwise set to the index of the desired oif + * - route_info->gw : + * 0 if no gateway specified, + * otherwise set to the next host to which the pkt must be routed + * If success, skb->dev is the output device to which the packet must + * be sent and skb->dst is not NULL + * + * RETURN: 1 if the packet was succesfully routed to the + * destination desired + * 0 if the kernel routing table could not route the packet + * according to the keys specified + */ +static int +route6(struct sk_buff *skb, + unsigned int ifindex, + const struct ip6t_route_target_info *route_info) +{ + struct rt6_info *rt = NULL; + struct ipv6hdr *ipv6h = skb->nh.ipv6h; + struct in6_addr *gw = (struct in6_addr*)&route_info->gw; + + DEBUGP("ip6t_ROUTE: called with: "); + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr)); + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw)); + DEBUGP("OUT=%s\n", route_info->oif); + + if (ipv6_addr_any(gw)) + rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1); + else + rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1); + + if (!rt) + goto no_route; + + DEBUGP("ip6t_ROUTE: routing gives: "); + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr)); + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway)); + DEBUGP("OUT=%s\n", rt->rt6i_dev->name); + + if (ifindex && rt->rt6i_dev->ifindex!=ifindex) + goto wrong_route; + + if (!rt->rt6i_nexthop) { + DEBUGP("ip6t_ROUTE: discovering neighbour\n"); + rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr); + } + + /* Drop old route. */ + dst_release(skb->dst); + skb->dst = &rt->u.dst; + skb->dev = rt->rt6i_dev; + return 1; + + wrong_route: + dst_release(&rt->u.dst); + no_route: + if (!net_ratelimit()) + return 0; + + printk("ip6t_ROUTE: no explicit route found "); + if (ifindex) + printk("via interface %s ", route_info->oif); + if (!ipv6_addr_any(gw)) + printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw)); + printk("\n"); + return 0; +} + + +/* Stolen from ip6_output_finish + * PRE : skb->dev is set to the device we are leaving by + * skb->dst is not NULL + * POST: the packet is sent with the link layer header pushed + * the packet is destroyed + */ +static void ip_direct_send(struct sk_buff *skb) +{ + struct dst_entry *dst = skb->dst; + struct hh_cache *hh = dst->hh; + + if (hh) { + read_lock_bh(&hh->hh_lock); + memcpy(skb->data - 16, hh->hh_data, 16); + read_unlock_bh(&hh->hh_lock); + skb_push(skb, hh->hh_len); + hh->hh_output(skb); + } else if (dst->neighbour) + dst->neighbour->output(skb); + else { + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n"); + kfree_skb(skb); + } +} + + +static unsigned int +route6_oif(const struct ip6t_route_target_info *route_info, + struct sk_buff *skb) +{ + 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))) { + ifindex = dev_out->ifindex; + } else { + /* Unknown interface name : packet dropped */ + if (net_ratelimit()) + DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif); + + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + else + return NF_DROP; + } + + /* Trying the standard way of routing packets */ + if (route6(skb, ifindex, route_info)) { + dev_put(dev_out); + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + + ip_direct_send(skb); + return NF_STOLEN; + } else + return NF_DROP; +} + + +static unsigned int +route6_gw(const struct ip6t_route_target_info *route_info, + struct sk_buff *skb) +{ + if (route6(skb, 0, route_info)) { + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + + ip_direct_send(skb); + return NF_STOLEN; + } else + return NF_DROP; +} + + +static unsigned int +ip6t_route_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_route_target_info *route_info = targinfo; + struct sk_buff *skb = *pskb; + struct in6_addr *gw = (struct in6_addr*)&route_info->gw; + + if (route_info->flags & IP6T_ROUTE_CONTINUE) + goto do_it; + + /* If we are at PREROUTING or INPUT hook + * the TTL isn't decreased by the IP stack + */ + if (hooknum == NF_IP6_PRE_ROUTING || + hooknum == NF_IP6_LOCAL_IN) { + + struct ipv6hdr *ipv6h = skb->nh.ipv6h; + + if (ipv6h->hop_limit <= 1) { + /* Force OUTPUT device used as source address */ + skb->dev = skb->dst->dev; + + icmpv6_send(skb, ICMPV6_TIME_EXCEED, + ICMPV6_EXC_HOPLIMIT, 0, skb->dev); + + return NF_DROP; + } + + ipv6h->hop_limit--; + } + + + do_it: + if (route_info->oif[0]) + return route6_oif(route_info, *pskb); + + if (!ipv6_addr_any(gw)) + return route6_gw(route_info, *pskb); + + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n"); + + return IP6T_CONTINUE; +} + + +static int +ip6t_route_checkentry(const char *tablename, + const struct ip6t_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (strcmp(tablename, "mangle") != 0) { + printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n"); + return 0; + } + + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) { + printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n", + targinfosize, + IP6T_ALIGN(sizeof(struct ip6t_route_target_info))); + return 0; + } + + return 1; +} + + +static struct ip6t_target ip6t_route_reg = { + .name = "ROUTE", + .target = ip6t_route_target, + .checkentry = ip6t_route_checkentry, + .me = THIS_MODULE +}; + + +static int __init init(void) +{ + printk(KERN_DEBUG "registering ipv6 ROUTE target\n"); + if (ip6t_register_target(&ip6t_route_reg)) + return -EINVAL; + + return 0; +} + + +static void __exit fini(void) +{ + ip6t_unregister_target(&ip6t_route_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/Makefile.ladd ./ROUTE/linux-2.4/net/ipv6/netfilter/Makefile.ladd --- ./ROUTE.orig/linux-2.4/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.4/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,2 @@ +obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o +obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o diff -Nru ./ROUTE.orig/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h ./ROUTE/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h --- ./ROUTE.orig/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/include/linux/netfilter_ipv4/ipt_ROUTE.h 2003-12-18 19:47:54.000000000 +0100 @@ -0,0 +1,22 @@ +/* Header file for iptables ipt_ROUTE target + * + * (C) 2002 by Cédric de Launois <delaunois@info.ucl.ac.be> + * + * This software is distributed under GNU GPL v2, 1991 + */ +#ifndef _IPT_ROUTE_H_target +#define _IPT_ROUTE_H_target + +#define IPT_ROUTE_IFNAMSIZ 16 + +struct ipt_route_target_info { + 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 ./ROUTE.orig/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h ./ROUTE/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h --- ./ROUTE.orig/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/include/linux/netfilter_ipv6/ip6t_ROUTE.h 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,22 @@ +/* Header file for iptables ip6t_ROUTE target + * + * (C) 2003 by Cédric de Launois <delaunois@info.ucl.ac.be> + * + * This software is distributed under GNU GPL v2, 1991 + */ +#ifndef _IPT_ROUTE_H_target +#define _IPT_ROUTE_H_target + +#define IP6T_ROUTE_IFNAMSIZ 16 + +struct ip6t_route_target_info { + char oif[IP6T_ROUTE_IFNAMSIZ]; /* Output Interface Name */ + char iif[IP6T_ROUTE_IFNAMSIZ]; /* Input Interface Name */ + u_int32_t gw[4]; /* IPv6 address of gateway */ + u_int8_t flags; +}; + +/* Values for "flags" field */ +#define IP6T_ROUTE_CONTINUE 0x01 + +#endif /*_IP6T_ROUTE_H_target*/ diff -Nru ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c ./ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c --- ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-02-22 18:29:10.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-04-21 10:17:44.000000000 +0200 @@ -19,6 +19,7 @@ #include <net/ip.h> #include <net/route.h> #include <net/icmp.h> +#include <net/checksum.h> #if 0 #define DEBUGP printk @@ -28,6 +29,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Cedric de Launois <delaunois@info.ucl.ac.be>"); +MODULE_DESCRIPTION("iptables ROUTE target module"); /* Try to route the packet according to the routing keys specified in * route_info. Keys are : @@ -53,19 +55,24 @@ int err; struct rtable *rt; struct iphdr *iph = skb->nh.iph; - struct rt_key key = { - dst:iph->daddr, - src:0, - oif:ifindex, - tos:RT_TOS(iph->tos) + struct flowi fl = { + .oif = ifindex, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = 0, + .tos = RT_TOS(iph->tos), + .scope = RT_SCOPE_UNIVERSE, + } + } }; /* The destination address may be overloaded by the target */ if (route_info->gw) - key.dst = route_info->gw; + fl.fld_dst = route_info->gw; /* Trying to route the packet using the standard routing table. */ - if ((err = ip_route_output_key(&rt, &key))) { + if ((err = ip_route_output_key(&rt, &fl))) { if (net_ratelimit()) DEBUGP("ipt_ROUTE: couldn't route pkt (err: %i)",err); return -1; @@ -205,25 +212,21 @@ static unsigned int route_iif(const struct ipt_route_target_info *route_info, struct sk_buff *skb) { - struct net_device *dev_out = NULL; - unsigned int ifindex = 0; + struct net_device *dev_in = NULL; - /* Getting the current interface index. */ - if ((dev_out = dev_get_by_name(route_info->iif))) - ifindex = dev_out->ifindex; - else { - /* Unknown interface name : packet dropped */ - if (net_ratelimit()) - DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->oif); + if (!(dev_in = dev_get_by_name(route_info->iif))) { + if (net_ratelimit()) + DEBUGP("ipt_ROUTE: iif interface %s not found\n", route_info->iif); return NF_DROP; } - skb->dev = dev_out; + skb->dev = dev_in; dst_release(skb->dst); skb->dst = NULL; - + netif_rx(skb); + dev_put(dev_in); return NF_STOLEN; } @@ -252,6 +255,9 @@ const struct ipt_route_target_info *route_info = targinfo; struct sk_buff *skb = *pskb; + if (route_info->flags & IPT_ROUTE_CONTINUE) + goto do_it; + /* If we are at PREROUTING or INPUT hook * the TTL isn't decreased by the IP stack */ @@ -262,10 +268,21 @@ if (iph->ttl <= 1) { struct rtable *rt; + struct flowi fl = { + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos), + .scope = ((iph->tos & RTO_ONLINK) ? + RT_SCOPE_LINK : + RT_SCOPE_UNIVERSE) + } + } + }; - if (ip_route_output(&rt, iph->saddr, iph->daddr, - RT_TOS(iph->tos) | RTO_CONN, - 0)) { + if (ip_route_output_key(&rt, &fl)) { return NF_DROP; } @@ -283,7 +300,17 @@ return NF_DROP; } - ip_decrease_ttl(iph); + /* + * If we are at INPUT the checksum must be recalculated since + * the length could change as the result of a defragmentation. + */ + if(hooknum == NF_IP_LOCAL_IN) { + iph->ttl = iph->ttl - 1; + iph->check = 0; + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } else { + ip_decrease_ttl(iph); + } } /* Tell conntrack to forget this packet since it may get confused @@ -299,6 +326,7 @@ #endif } + do_it: if (route_info->oif[0]) return route_oif(route_info, *pskb); diff -Nru ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/Kconfig.ladd ./ROUTE/linux-2.6/net/ipv4/netfilter/Kconfig.ladd --- ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 2004-03-08 14:02:45.000000000 +0100 @@ -0,0 +1,16 @@ +config IP_NF_TARGET_ROUTE + tristate 'ROUTE target support' + depends on IP_NF_MANGLE + help + This option adds a `ROUTE' target, which enables you to setup unusual + 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. + + 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. + If unsure, say `N'. diff -Nru ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/Makefile.ladd ./ROUTE/linux-2.6/net/ipv4/netfilter/Makefile.ladd --- ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv4/netfilter/Makefile.ladd 2003-12-18 19:47:54.000000000 +0100 @@ -0,0 +1,2 @@ +obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o +obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o diff -Nru ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c ./ROUTE/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c --- ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv6/netfilter/ip6t_ROUTE.c 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,289 @@ +/* + * This implements the ROUTE v6 target, which enables you to setup unusual + * routes not supported by the standard kernel routing table. + * + * Copyright (C) 2003 Cedric de Launois <delaunois@info.ucl.ac.be> + * + * v 1.0 2003/08/05 + * + * This software is distributed under GNU GPL v2, 1991 + */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/ipv6.h> +#include <linux/netfilter_ipv6/ip6_tables.h> +#include <linux/netfilter_ipv6/ip6t_ROUTE.h> +#include <linux/netdevice.h> +#include <net/ipv6.h> +#include <net/ndisc.h> +#include <net/ip6_route.h> +#include <linux/icmpv6.h> + +#if 1 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +#define NIP6(addr) \ + ntohs((addr).s6_addr16[0]), \ + ntohs((addr).s6_addr16[1]), \ + ntohs((addr).s6_addr16[2]), \ + ntohs((addr).s6_addr16[3]), \ + ntohs((addr).s6_addr16[4]), \ + ntohs((addr).s6_addr16[5]), \ + ntohs((addr).s6_addr16[6]), \ + ntohs((addr).s6_addr16[7]) + +/* Route the packet according to the routing keys specified in + * route_info. Keys are : + * - ifindex : + * 0 if no oif preferred, + * otherwise set to the index of the desired oif + * - route_info->gw : + * 0 if no gateway specified, + * otherwise set to the next host to which the pkt must be routed + * If success, skb->dev is the output device to which the packet must + * be sent and skb->dst is not NULL + * + * RETURN: 1 if the packet was succesfully routed to the + * destination desired + * 0 if the kernel routing table could not route the packet + * according to the keys specified + */ +static int +route6(struct sk_buff *skb, + unsigned int ifindex, + const struct ip6t_route_target_info *route_info) +{ + struct rt6_info *rt = NULL; + struct ipv6hdr *ipv6h = skb->nh.ipv6h; + struct in6_addr *gw = (struct in6_addr*)&route_info->gw; + + DEBUGP("ip6t_ROUTE: called with: "); + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ipv6h->daddr)); + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(*gw)); + DEBUGP("OUT=%s\n", route_info->oif); + + if (ipv6_addr_any(gw)) + rt = rt6_lookup(&ipv6h->daddr, &ipv6h->saddr, ifindex, 1); + else + rt = rt6_lookup(gw, &ipv6h->saddr, ifindex, 1); + + if (!rt) + goto no_route; + + DEBUGP("ip6t_ROUTE: routing gives: "); + DEBUGP("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_dst.addr)); + DEBUGP("GATEWAY=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(rt->rt6i_gateway)); + DEBUGP("OUT=%s\n", rt->rt6i_dev->name); + + if (ifindex && rt->rt6i_dev->ifindex!=ifindex) + goto wrong_route; + + if (!rt->rt6i_nexthop) { + DEBUGP("ip6t_ROUTE: discovering neighbour\n"); + rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_dst.addr); + } + + /* Drop old route. */ + dst_release(skb->dst); + skb->dst = &rt->u.dst; + skb->dev = rt->rt6i_dev; + return 1; + + wrong_route: + dst_release(&rt->u.dst); + no_route: + if (!net_ratelimit()) + return 0; + + printk("ip6t_ROUTE: no explicit route found "); + if (ifindex) + printk("via interface %s ", route_info->oif); + if (!ipv6_addr_any(gw)) + printk("via gateway %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", NIP6(*gw)); + printk("\n"); + return 0; +} + + +/* Stolen from ip6_output_finish + * PRE : skb->dev is set to the device we are leaving by + * skb->dst is not NULL + * POST: the packet is sent with the link layer header pushed + * the packet is destroyed + */ +static void ip_direct_send(struct sk_buff *skb) +{ + struct dst_entry *dst = skb->dst; + struct hh_cache *hh = dst->hh; + + if (hh) { + read_lock_bh(&hh->hh_lock); + memcpy(skb->data - 16, hh->hh_data, 16); + read_unlock_bh(&hh->hh_lock); + skb_push(skb, hh->hh_len); + hh->hh_output(skb); + } else if (dst->neighbour) + dst->neighbour->output(skb); + else { + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no hdr & no neighbour cache!\n"); + kfree_skb(skb); + } +} + + +static unsigned int +route6_oif(const struct ip6t_route_target_info *route_info, + struct sk_buff *skb) +{ + 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))) { + ifindex = dev_out->ifindex; + } else { + /* Unknown interface name : packet dropped */ + if (net_ratelimit()) + DEBUGP("ip6t_ROUTE: oif interface %s not found\n", route_info->oif); + + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + else + return NF_DROP; + } + + /* Trying the standard way of routing packets */ + if (route6(skb, ifindex, route_info)) { + dev_put(dev_out); + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + + ip_direct_send(skb); + return NF_STOLEN; + } else + return NF_DROP; +} + + +static unsigned int +route6_gw(const struct ip6t_route_target_info *route_info, + struct sk_buff *skb) +{ + if (route6(skb, 0, route_info)) { + if (route_info->flags & IP6T_ROUTE_CONTINUE) + return IP6T_CONTINUE; + + ip_direct_send(skb); + return NF_STOLEN; + } else + return NF_DROP; +} + + +static unsigned int +ip6t_route_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_route_target_info *route_info = targinfo; + struct sk_buff *skb = *pskb; + struct in6_addr *gw = (struct in6_addr*)&route_info->gw; + + if (route_info->flags & IP6T_ROUTE_CONTINUE) + goto do_it; + + /* If we are at PREROUTING or INPUT hook + * the TTL isn't decreased by the IP stack + */ + if (hooknum == NF_IP6_PRE_ROUTING || + hooknum == NF_IP6_LOCAL_IN) { + + struct ipv6hdr *ipv6h = skb->nh.ipv6h; + + if (ipv6h->hop_limit <= 1) { + /* Force OUTPUT device used as source address */ + skb->dev = skb->dst->dev; + + icmpv6_send(skb, ICMPV6_TIME_EXCEED, + ICMPV6_EXC_HOPLIMIT, 0, skb->dev); + + return NF_DROP; + } + + ipv6h->hop_limit--; + } + + + do_it: + if (route_info->oif[0]) + return route6_oif(route_info, *pskb); + + if (!ipv6_addr_any(gw)) + return route6_gw(route_info, *pskb); + + if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n"); + + return IP6T_CONTINUE; +} + + +static int +ip6t_route_checkentry(const char *tablename, + const struct ip6t_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (strcmp(tablename, "mangle") != 0) { + printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n"); + return 0; + } + + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_route_target_info))) { + printk(KERN_WARNING "ip6t_ROUTE: targinfosize %u != %Zu\n", + targinfosize, + IP6T_ALIGN(sizeof(struct ip6t_route_target_info))); + return 0; + } + + return 1; +} + + +static struct ip6t_target ip6t_route_reg = { + .name = "ROUTE", + .target = ip6t_route_target, + .checkentry = ip6t_route_checkentry, + .me = THIS_MODULE +}; + + +static int __init init(void) +{ + printk(KERN_DEBUG "registering ipv6 ROUTE target\n"); + if (ip6t_register_target(&ip6t_route_reg)) + return -EINVAL; + + return 0; +} + + +static void __exit fini(void) +{ + ip6t_unregister_target(&ip6t_route_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/Kconfig.ladd ./ROUTE/linux-2.6/net/ipv6/netfilter/Kconfig.ladd --- ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/Kconfig.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv6/netfilter/Kconfig.ladd 2004-03-08 15:06:42.000000000 +0100 @@ -0,0 +1,11 @@ +config IP6_NF_TARGET_ROUTE + tristate ' ROUTE target support' + depends on IP6_NF_MANGLE + help + This option adds a `ROUTE' target, which enables you to setup unusual + routes. The ROUTE target is also able to change the incoming interface + of a packet. + + The target can be or not a final target. It has to be used inside the + mangle table. + diff -Nru ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/Makefile.ladd ./ROUTE/linux-2.6/net/ipv6/netfilter/Makefile.ladd --- ./ROUTE.orig/linux-2.6/net/ipv6/netfilter/Makefile.ladd 1970-01-01 01:00:00.000000000 +0100 +++ ./ROUTE/linux-2.6/net/ipv6/netfilter/Makefile.ladd 2003-12-20 17:43:09.000000000 +0100 @@ -0,0 +1,2 @@ +obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o +obj-$(CONFIG_IP6_NF_TARGET_ROUTE) += ip6t_ROUTE.o ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x 2004-04-28 15:25 ` Cedric de Launois @ 2004-04-29 16:45 ` Patrick McHardy 0 siblings, 0 replies; 6+ messages in thread From: Patrick McHardy @ 2004-04-29 16:45 UTC (permalink / raw) To: Cedric de Launois; +Cc: Netfilter Development Mailinglist Cedric de Launois wrote: >Oops, sorry. This patch should be better. > > Still can't apply, the patch contains changes to a non-existing file, linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c. Regards Patrick >Regards, > >Cedric > > > >diff -Nru ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c ./ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c >--- ./ROUTE.orig/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-02-22 18:29:10.000000000 +0100 >+++ ./ROUTE/linux-2.6/net/ipv4/netfilter/ipt_ROUTE.c 2004-04-21 10:17:44.000000000 +0200 >@@ -19,6 +19,7 @@ > #include <net/ip.h> > #include <net/route.h> > #include <net/icmp.h> >+#include <net/checksum.h> > > #if 0 > #define DEBUGP printk >@@ -28,6 +29,7 @@ > > > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-04-29 16:45 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-04-21 8:16 [PATCH] ROUTE target : update to pom-ng + new version for kernel 2.6.x Cedric de Launois 2004-04-24 23:03 ` Patrick McHardy 2004-04-25 0:01 ` Esteban Ribicic 2004-04-26 4:46 ` Henrik Nordstrom 2004-04-28 15:25 ` Cedric de Launois 2004-04-29 16:45 ` Patrick McHardy
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.