Route match v2
Subsystems (3)
RFC PATCH 1/1 Route match v2
Attached is a new "route" match, which matches against entries in the kernel routing table.
Changes since v1:
* IPv6 support in kernel
* Invert support for ALL options
* Various cleanup in userspace code (C99 initializers & unified v4/v6 parse)
I've tested the IPv6 support as best I can, but I'd appreciate someone who actually has production v6 nets giving it a run through.
Options:
[!] --route-src-exists Route for src exists [!] --route-src-eq value Route for src exists with prefix-length == value [!] --route-src-gt value Route for src exists with prefix-length > value [!] --route-src-lt value Route for src exists with prefix-length < value [!] --route-dst-exists Route for dst exists [!] --route-dst-eq value Route for dst exists with prefix-length == value [!] --route-dst-gt value Route for dst exists with prefix-length > value [!] --route-dst-lt value Route for dst exists with prefix-length < value
Examples:
Egress filtering (similar to rp_filter, but not silently dropped):
iptables -N spoofer -j LOG --log-prefix "Spoofed packet dropped: " iptables -N spoofer -j DROP
iptables -A FORWARD -i $INTERNAL_IF -m route ! --route-src-exists -j spoofer
rp_filter functionality on IPv6:
ip6tables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP
Allow a user to only browse internal websites:
iptables -A FORWARD -p tcp --dport 80 -m route --route-dst-exists -j ACCEPT
Allow an SNMP collector to reach all internal routers (/30 or /32)
iptables -A FORWARD -p udp --dport 161 -m route --route-dst-gt 29 -j ACCEPT
Comments?
Phil
include/linux/netfilter/xt_route.h new file +21 -0
@@ -0,0 +1,21 @@ +#ifndef _XT_ROUTE_H +#define _XT_ROUTE_H + +enum { +XT_ROUTE_SRC_EXISTS =0 , +XT_ROUTE_SRC_EQ , +XT_ROUTE_SRC_GT , +XT_ROUTE_SRC_LT , +XT_ROUTE_DST_EXISTS , +XT_ROUTE_DST_EQ , +XT_ROUTE_DST_GT , +XT_ROUTE_DST_LT , +}; + +struct xt_route_info { +u_int8_t invert; +u_int8_t mode; +u_int8_t prefixlen; +}; + +#endif /*_XT_ROUTE_H*/
net/ipv4/fib_semantics.c +2 -0
@@ -156,6 +156,8 @@ void free_fib_info(struct fib_info *fi)kfree (fi); } +EXPORT_SYMBOL_GPL (free_fib_info); +void fib_release_info (struct fib_info *fi) {spin_lock_bh (&fib_info_lock);
net/ipv6/ip6_fib.c +2 -0
@@ -897,6 +897,8 @@ struct fib6_node * fib6_lookup(struct fib6_node *root, struct in6_addr *daddr,return fn; } +EXPORT_SYMBOL_GPL (fib6_lookup); +/* * Get node with specified destination prefix (and source prefix, * if subtrees are used)
net/netfilter/Kconfig +10 -0
@@ -724,6 +724,16 @@ config NETFILTER_XT_MATCH_REALM If you want to compile it as a module, say M here and read <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. +config NETFILTER_XT_MATCH_ROUTE + tristate '"route" match support' + depends on NETFILTER_XTABLES + depends on NETFILTER_ADVANCED + help + This option adds a `route' match, which allows you to match on + the kernel routing table. + + To compile it as a module, choose M here. If unsure, say N. + config NETFILTER_XT_MATCH_SCTP tristate '"sctp" protocol match support (EXPERIMENTAL)' depends on NETFILTER_XTABLES && EXPERIMENTAL
net/netfilter/Makefile +1 -0
@@ -76,6 +76,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o +obj-$(CONFIG_NETFILTER_XT_MATCH_ROUTE) += xt_route.o obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
net/netfilter/xt_route.c new file +197 -0
197 lines not on this page · raw message
extensions/libxt_route.c new file +267 -0
267 lines not on this page · raw message
include/linux/netfilter/xt_route.h new file +21 -0
@@ -0,0 +1,21 @@ +#ifndef _XT_ROUTE_H +#define _XT_ROUTE_H + +enum { +XT_ROUTE_SRC_EXISTS =0 , +XT_ROUTE_SRC_EQ , +XT_ROUTE_SRC_GT , +XT_ROUTE_SRC_LT , +XT_ROUTE_DST_EXISTS , +XT_ROUTE_DST_EQ , +XT_ROUTE_DST_GT , +XT_ROUTE_DST_LT , +}; + +struct xt_route_info { +u_int8_t invert; +u_int8_t mode; +u_int8_t prefixlen; +}; + +#endif /*_XT_ROUTE_H*/
Quoted 17 lines · Phil Oester
Attached is a new "route" match, which matches against entries in the kernel routing table.
Changes since v1:
* IPv6 support in kernel
* Invert support for ALL options
* Various cleanup in userspace code (C99 initializers & unified v4/v6 parse)I've tested the IPv6 support as best I can, but I'd appreciate someone who actually has production v6 nets giving it a run through.
net/netfilter/xt_route.c new file +5
-0+static bool +route_mt6 (const struct sk_buff *skb,const struct net_device *in, +const struct net_device *out,const struct xt_match *match, +const void *matchinfo,int offset,unsigned int protoff, +bool *hotdrop)
net/netfilter/xt_route.c line 119
Quoted 10 lines
net/netfilter/xt_route.c new file +10
-0+{ +const struct xt_route_info *info = matchinfo; +const struct ipv6hdr *iph =ipv6_hdr (skb); +struct fib6_node *fn; +struct flowi fl = {0 }; + +switch (info->mode) { +case XT_ROUTE_SRC_EXISTS : + fl.nl_u.ip6_u.daddr = iph->saddr; + fn =fib6_lookup (&dev_net (in)->ipv6.fib6_main_tbl->tb6_root, &fl.fl6_dst,NULL );
This is always using the main table, which is inconsistent with the IPv4 support. It also shouldn't call IPv6 functions directly to avoid incorrect module dependencies.
Quoted 11 lines · Patrick McHardy
Quoted 11 lines
net/netfilter/xt_route.c new file +11
-0+static bool +route_mt6 (const struct sk_buff *skb,const struct net_device *in, +const struct net_device *out,const struct xt_match *match, +const void *matchinfo,int offset,unsigned int protoff, +bool *hotdrop) +{ +const struct xt_route_info *info = matchinfo; +const struct ipv6hdr *iph =ipv6_hdr (skb); +struct fib6_node *fn; +struct flowi fl = {0 }; +
Quoted 8 lines
net/netfilter/xt_route.c line 119
Quoted 4 lines
net/netfilter/xt_route.c new file +4
-0+switch (info->mode) { +case XT_ROUTE_SRC_EXISTS : + fl.nl_u.ip6_u.daddr = iph->saddr; + fn =fib6_lookup (&dev_net (in)->ipv6.fib6_main_tbl->tb6_root, &fl.fl6_dst,NULL );This is always using the main table, which is inconsistent with the IPv4 support. It also shouldn't call IPv6 functions directly to avoid incorrect module dependencies.
What are the alternatives? If we need to support IPv6 in the match, then we need to call the functions directly, no? Is there a helper function I'm missing?
Phil
Quoted 20 lines · Phil Oester
Quoted 10 lines · Patrick McHardy
Quoted 10 lines
net/netfilter/xt_route.c new file +10
-0+static bool +route_mt6 (const struct sk_buff *skb,const struct net_device *in, +const struct net_device *out,const struct xt_match *match, +const void *matchinfo,int offset,unsigned int protoff, +bool *hotdrop) +{ +const struct xt_route_info *info = matchinfo; +const struct ipv6hdr *iph =ipv6_hdr (skb); +struct fib6_node *fn; +struct flowi fl = {0 };Quoted 8 lines
net/netfilter/xt_route.c line 119
Quoted 5 lines
net/netfilter/xt_route.c new file +5
-0+ +switch (info->mode) { +case XT_ROUTE_SRC_EXISTS : + fl.nl_u.ip6_u.daddr = iph->saddr; + fn =fib6_lookup (&dev_net (in)->ipv6.fib6_main_tbl->tb6_root, &fl.fl6_dst,NULL );This is always using the main table, which is inconsistent with the IPv4 support. It also shouldn't call IPv6 functions directly to avoid incorrect module dependencies.
Quoted 3 lines
What are the alternatives? If we need to support IPv6 in the match, then we need to call the functions directly, no? Is there a helper function I'm missing?
There are the ->route functions is nf_afinfo, but I'm not sure if they will work for you. You may have too add some new ones.