netfilter: xt_addrtype: replace rt6_lookup with nf_afinfo->route

This avoids pulling in the ipv6 module when using (ipv4-only) iptables
-m addrtype.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Patrick McHardy <kaber@trash.net>

authored by Florian Westphal and committed by Patrick McHardy b7225041 0fae2e77

+28 -15
-1
net/netfilter/Kconfig
··· 652 652 config NETFILTER_XT_MATCH_ADDRTYPE 653 653 tristate '"addrtype" address type match support' 654 654 depends on NETFILTER_ADVANCED 655 - depends on (IPV6 || IPV6=n) 656 655 ---help--- 657 656 This option allows you to match what routing thinks of an address, 658 657 eg. UNICAST, LOCAL, BROADCAST, ...
+28 -14
net/netfilter/xt_addrtype.c
··· 32 32 MODULE_ALIAS("ip6t_addrtype"); 33 33 34 34 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 35 - static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt) 35 + static 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 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 61 return XT_ADDRTYPE_UNREACHABLE; 41 62 42 63 if (rt->rt6i_flags & RTF_REJECT) ··· 69 48 ret |= XT_ADDRTYPE_LOCAL; 70 49 if (rt->rt6i_flags & RTF_ANYCAST) 71 50 ret |= XT_ADDRTYPE_ANYCAST; 51 + 52 + 53 + dst_release(&rt->dst); 72 54 return ret; 73 55 } 74 56 ··· 89 65 return false; 90 66 91 67 if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | 92 - XT_ADDRTYPE_UNREACHABLE) & mask) { 93 - struct rt6_info *rt; 94 - u32 type; 95 - int ifindex = dev ? dev->ifindex : 0; 96 - 97 - rt = rt6_lookup(net, addr, NULL, ifindex, !!dev); 98 - 99 - type = xt_addrtype_rt6_to_type(rt); 100 - 101 - dst_release(&rt->dst); 102 - return !!(mask & type); 103 - } 68 + XT_ADDRTYPE_UNREACHABLE) & mask) 69 + return !!(mask & match_lookup_rt6(net, dev, addr)); 104 70 return true; 105 71 } 106 72