Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: don't allocate space for arp/bridge hooks unless needed

no need to define hook points if the family isn't supported.
Because we need these hooks for either nftables, arp/ebtables
or the 'call-iptables' hack we have in the bridge layer add two
new dependencies, NETFILTER_FAMILY_{ARP,BRIDGE}, and have the
users select them.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
2a95183a bb4badf3

+29
+4
include/linux/netfilter.h
··· 214 214 hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]); 215 215 break; 216 216 case NFPROTO_ARP: 217 + #ifdef CONFIG_NETFILTER_FAMILY_ARP 217 218 hook_head = rcu_dereference(net->nf.hooks_arp[hook]); 219 + #endif 218 220 break; 219 221 case NFPROTO_BRIDGE: 222 + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 220 223 hook_head = rcu_dereference(net->nf.hooks_bridge[hook]); 224 + #endif 221 225 break; 222 226 #if IS_ENABLED(CONFIG_DECNET) 223 227 case NFPROTO_DECNET:
+4
include/net/netns/netfilter.h
··· 19 19 #endif 20 20 struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; 21 21 struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; 22 + #ifdef CONFIG_NETFILTER_FAMILY_ARP 22 23 struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS]; 24 + #endif 25 + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 23 26 struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS]; 27 + #endif 24 28 #if IS_ENABLED(CONFIG_DECNET) 25 29 struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; 26 30 #endif
+1
net/Kconfig
··· 182 182 depends on BRIDGE 183 183 depends on NETFILTER && INET 184 184 depends on NETFILTER_ADVANCED 185 + select NETFILTER_FAMILY_BRIDGE 185 186 default m 186 187 ---help--- 187 188 Enabling this option will let arptables resp. iptables see bridged
+2
net/bridge/netfilter/Kconfig
··· 4 4 # 5 5 menuconfig NF_TABLES_BRIDGE 6 6 depends on BRIDGE && NETFILTER && NF_TABLES 7 + select NETFILTER_FAMILY_BRIDGE 7 8 tristate "Ethernet Bridge nf_tables support" 8 9 9 10 if NF_TABLES_BRIDGE ··· 30 29 menuconfig BRIDGE_NF_EBTABLES 31 30 tristate "Ethernet Bridge tables (ebtables) support" 32 31 depends on BRIDGE && NETFILTER && NETFILTER_XTABLES 32 + select NETFILTER_FAMILY_BRIDGE 33 33 help 34 34 ebtables is a general, extensible frame/packet identification 35 35 framework. Say 'Y' or 'M' here if you want to do Ethernet
+2
net/ipv4/netfilter/Kconfig
··· 72 72 73 73 config NF_TABLES_ARP 74 74 tristate "ARP nf_tables support" 75 + select NETFILTER_FAMILY_ARP 75 76 help 76 77 This option enables the ARP support for nf_tables. 77 78 ··· 393 392 config IP_NF_ARPTABLES 394 393 tristate "ARP tables support" 395 394 select NETFILTER_XTABLES 395 + select NETFILTER_FAMILY_ARP 396 396 depends on NETFILTER_ADVANCED 397 397 help 398 398 arptables is a general, extensible packet identification framework.
+6
net/netfilter/Kconfig
··· 12 12 config NETFILTER_NETLINK 13 13 tristate 14 14 15 + config NETFILTER_FAMILY_BRIDGE 16 + bool 17 + 18 + config NETFILTER_FAMILY_ARP 19 + bool 20 + 15 21 config NETFILTER_NETLINK_ACCT 16 22 tristate "Netfilter NFACCT over NFNETLINK interface" 17 23 depends on NETFILTER_ADVANCED
+8
net/netfilter/core.c
··· 267 267 switch (reg->pf) { 268 268 case NFPROTO_NETDEV: 269 269 break; 270 + #ifdef CONFIG_NETFILTER_FAMILY_ARP 270 271 case NFPROTO_ARP: 271 272 if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum)) 272 273 return NULL; 273 274 return net->nf.hooks_arp + reg->hooknum; 275 + #endif 276 + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 274 277 case NFPROTO_BRIDGE: 275 278 if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum)) 276 279 return NULL; 277 280 return net->nf.hooks_bridge + reg->hooknum; 281 + #endif 278 282 case NFPROTO_IPV4: 279 283 if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum)) 280 284 return NULL; ··· 577 573 { 578 574 __netfilter_net_init(net->nf.hooks_ipv4, ARRAY_SIZE(net->nf.hooks_ipv4)); 579 575 __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6)); 576 + #ifdef CONFIG_NETFILTER_FAMILY_ARP 580 577 __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp)); 578 + #endif 579 + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 581 580 __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge)); 581 + #endif 582 582 #if IS_ENABLED(CONFIG_DECNET) 583 583 __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet)); 584 584 #endif
+2
net/netfilter/nf_queue.c
··· 204 204 static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum) 205 205 { 206 206 switch (pf) { 207 + #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE 207 208 case NFPROTO_BRIDGE: 208 209 return rcu_dereference(net->nf.hooks_bridge[hooknum]); 210 + #endif 209 211 case NFPROTO_IPV4: 210 212 return rcu_dereference(net->nf.hooks_ipv4[hooknum]); 211 213 case NFPROTO_IPV6: