aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/xt_addrtype.c42
2 files changed, 28 insertions, 15 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c3f988aa1152..32bff6d86cb2 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -652,7 +652,6 @@ comment "Xtables matches"
652config NETFILTER_XT_MATCH_ADDRTYPE 652config NETFILTER_XT_MATCH_ADDRTYPE
653 tristate '"addrtype" address type match support' 653 tristate '"addrtype" address type match support'
654 depends on NETFILTER_ADVANCED 654 depends on NETFILTER_ADVANCED
655 depends on (IPV6 || IPV6=n)
656 ---help--- 655 ---help---
657 This option allows you to match what routing thinks of an address, 656 This option allows you to match what routing thinks of an address,
658 eg. UNICAST, LOCAL, BROADCAST, ... 657 eg. UNICAST, LOCAL, BROADCAST, ...
diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c
index 2220b85e9519..b77d383cec78 100644
--- a/net/netfilter/xt_addrtype.c
+++ b/net/netfilter/xt_addrtype.c
@@ -32,11 +32,32 @@ MODULE_ALIAS("ipt_addrtype");
32MODULE_ALIAS("ip6t_addrtype"); 32MODULE_ALIAS("ip6t_addrtype");
33 33
34#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 34#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
35static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt) 35static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
36 const struct in6_addr *addr)
36{ 37{
38 const struct nf_afinfo *afinfo;
39 struct flowi6 flow;
40 struct rt6_info *rt;
37 u32 ret; 41 u32 ret;
42 int route_err;
38 43
39 if (!rt) 44 memset(&flow, 0, sizeof(flow));
45 ipv6_addr_copy(&flow.daddr, addr);
46 if (dev)
47 flow.flowi6_oif = dev->ifindex;
48
49 rcu_read_lock();
50
51 afinfo = nf_get_afinfo(NFPROTO_IPV6);
52 if (afinfo != NULL)
53 route_err = afinfo->route(net, (struct dst_entry **)&rt,
54 flowi6_to_flowi(&flow), !!dev);
55 else
56 route_err = 1;
57
58 rcu_read_unlock();
59
60 if (route_err)
40 return XT_ADDRTYPE_UNREACHABLE; 61 return XT_ADDRTYPE_UNREACHABLE;
41 62
42 if (rt->rt6i_flags & RTF_REJECT) 63 if (rt->rt6i_flags & RTF_REJECT)
@@ -48,6 +69,9 @@ static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt)
48 ret |= XT_ADDRTYPE_LOCAL; 69 ret |= XT_ADDRTYPE_LOCAL;
49 if (rt->rt6i_flags & RTF_ANYCAST) 70 if (rt->rt6i_flags & RTF_ANYCAST)
50 ret |= XT_ADDRTYPE_ANYCAST; 71 ret |= XT_ADDRTYPE_ANYCAST;
72
73
74 dst_release(&rt->dst);
51 return ret; 75 return ret;
52} 76}
53 77
@@ -65,18 +89,8 @@ static bool match_type6(struct net *net, const struct net_device *dev,
65 return false; 89 return false;
66 90
67 if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | 91 if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
68 XT_ADDRTYPE_UNREACHABLE) & mask) { 92 XT_ADDRTYPE_UNREACHABLE) & mask)
69 struct rt6_info *rt; 93 return !!(mask & match_lookup_rt6(net, dev, addr));
70 u32 type;
71 int ifindex = dev ? dev->ifindex : 0;
72
73 rt = rt6_lookup(net, addr, NULL, ifindex, !!dev);
74
75 type = xt_addrtype_rt6_to_type(rt);
76
77 dst_release(&rt->dst);
78 return !!(mask & type);
79 }
80 return true; 94 return true;
81} 95}
82 96