📄 160-netfilter_route.patch
字号:
+ const struct xt_target *target,+#endif+ void *targinfo,+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+ unsigned int targinfosize,+#endif+ 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 LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+ 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;+ }+#endif++ return 1;+}+++static struct ipt_target ipt_route_reg = { + .name = "ROUTE",+ .target = ipt_route_target,+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)+ .targetsize = sizeof(struct ipt_route_target_info),+#endif+ .checkentry = ipt_route_checkentry,+ .me = THIS_MODULE,+};++static int __init init(void)+{+ /* Set up fake conntrack (stolen from raw.patch):+ - to never be deleted, not in any hashes */+ atomic_set(&route_tee_track.ct_general.use, 1);+ /* - and look it like as a confirmed connection */+ set_bit(IPS_CONFIRMED_BIT, &route_tee_track.status);+ /* Initialize fake conntrack so that NAT will skip it */+ route_tee_track.status |= IPS_NAT_DONE_MASK;++ return xt_register_target(&ipt_route_reg);+}+++static void __exit fini(void)+{+ xt_unregister_target(&ipt_route_reg);+}++module_init(init);+module_exit(fini);Index: linux-2.6.21.7/net/ipv4/netfilter/Kconfig===================================================================--- linux-2.6.21.7.orig/net/ipv4/netfilter/Kconfig+++ linux-2.6.21.7/net/ipv4/netfilter/Kconfig@@ -807,5 +807,22 @@ config IP_NF_TARGET_SET To compile it as a module, choose M here. If unsure, say N. +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'.+ endmenu Index: linux-2.6.21.7/net/ipv4/netfilter/Makefile===================================================================--- linux-2.6.21.7.orig/net/ipv4/netfilter/Makefile+++ linux-2.6.21.7/net/ipv4/netfilter/Makefile@@ -102,6 +102,7 @@ obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_EC obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o+obj-$(CONFIG_IP_NF_TARGET_ROUTE) += ipt_ROUTE.o obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.oIndex: linux-2.6.21.7/net/ipv6/ipv6_syms.c===================================================================--- linux-2.6.21.7.orig/net/ipv6/ipv6_syms.c+++ linux-2.6.21.7/net/ipv6/ipv6_syms.c@@ -10,6 +10,7 @@ EXPORT_SYMBOL(icmpv6_send); EXPORT_SYMBOL(icmpv6_statistics); EXPORT_SYMBOL(icmpv6_err_convert); EXPORT_SYMBOL(ndisc_mc_map);+EXPORT_SYMBOL(nd_tbl); EXPORT_SYMBOL(register_inet6addr_notifier); EXPORT_SYMBOL(unregister_inet6addr_notifier); EXPORT_SYMBOL(ip6_route_output);Index: linux-2.6.21.7/net/ipv6/netfilter/ip6t_ROUTE.c===================================================================--- /dev/null+++ linux-2.6.21.7/net/ipv6/netfilter/ip6t_ROUTE.c@@ -0,0 +1,330 @@+/*+ * 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.1 2004/11/23+ *+ * 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 <linux/version.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,+ const struct net_device *in,+ const struct net_device *out,+ unsigned int hooknum,+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)+ const struct xt_target *target,+#endif+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+ const void *targinfo,+ void *userinfo)+#else+ const void *targinfo)+#endif+{+ const struct ip6t_route_target_info *route_info = targinfo;+ struct sk_buff *skb = *pskb;+ struct in6_addr *gw = (struct in6_addr*)&route_info->gw;+ unsigned int res;++ 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--;+ }++ if ((route_info->flags & IP6T_ROUTE_TEE)) {+ /*+ * Copy the *pskb, and route the copy. Will later return+ * IP6T_CONTINUE for the original skb, which should continue+ * on its way as if nothing happened. The copy should be+ * independantly delivered to the ROUTE --gw.+ */+ skb = skb_copy(*pskb, GFP_ATOMIC);+ if (!skb) {+ if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: copy failed!\n");+ return IP6T_CONTINUE;+ }+ }++do_it:+ if (route_info->oif[0]) {+ res = route6_oif(route_info, skb);+ } else if (!ipv6_addr_any(gw)) {+ res = route6_gw(route_info, skb);+ } else {+ if (net_ratelimit()) + DEBUGP(KERN_DEBUG "ip6t_ROUTE: no parameter !\n");+ res = IP6T_CONTINUE;+ }++ if ((route_info->flags & IP6T_ROUTE_TEE))+ res = IP6T_CONTINUE;++ return res;+}+++static int +ip6t_route_checkentry(const char *tablename,+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)+ const void *entry,+#else+ const struct ip6t_entry *entry+#endif+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)+ const struct xt_target *target,+#endif+ void *targinfo,+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+ unsigned int targinfosize,+#endif+ unsigned int hook_mask)+{+ if (strcmp(tablename, "mangle") != 0) {+ printk("ip6t_ROUTE: can only be called from \"mangle\" table.\n");+ return 0;+ }++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)+ 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;+ }+#endif++ return 1;+}+++static struct ip6t_target ip6t_route_reg = {+ .name = "ROUTE",+ .target = ip6t_route_target,+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)+ .targetsize = sizeof(struct ip6t_route_target_info),+#endif+ .checkentry = ip6t_route_checkentry,+ .me = THIS_MODULE+};+++static int __init init(void)+{+ printk(KERN_DEBUG "registering ipv6 ROUTE target\n");+ if (xt_register_target(&ip6t_route_reg))+ return -EINVAL;++ return 0;+}+++static void __exit fini(void)+{+ xt_unregister_target(&ip6t_route_reg);+}++module_init(init);+module_exit(fini);+MODULE_LICENSE("GPL");Index: linux-2.6.21.7/net/ipv6/netfilter/Kconfig===================================================================--- linux-2.6.21.7.orig/net/ipv6/netfilter/Kconfig+++ linux-2.6.21.7/net/ipv6/netfilter/Kconfig@@ -209,5 +209,18 @@ config IP6_NF_RAW If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. If unsure, say `N'. +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.+ + Not working as a module.+ endmenu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -