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

netfilter: nf_tables: add "inet" table for IPv4/IPv6

This patch adds a new table family and a new filter chain that you can
use to attach IPv4 and IPv6 rules. This should help to simplify
rule-set maintainance in dual-stack setups.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Patrick McHardy and committed by
Pablo Neira Ayuso
1d49144c 115a60b1

+116 -2
+2
include/net/netfilter/nf_tables_ipv4.h
··· 20 20 pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET; 21 21 } 22 22 23 + extern struct nft_af_info nft_af_ipv4; 24 + 23 25 #endif
+2
include/net/netfilter/nf_tables_ipv6.h
··· 27 27 return 0; 28 28 } 29 29 30 + extern struct nft_af_info nft_af_ipv6; 31 + 30 32 #endif
+1
include/net/netns/nftables.h
··· 10 10 struct list_head commit_list; 11 11 struct nft_af_info *ipv4; 12 12 struct nft_af_info *ipv6; 13 + struct nft_af_info *inet; 13 14 struct nft_af_info *arp; 14 15 struct nft_af_info *bridge; 15 16 u8 gencursor;
+1
include/uapi/linux/netfilter.h
··· 53 53 54 54 enum { 55 55 NFPROTO_UNSPEC = 0, 56 + NFPROTO_INET = 1, 56 57 NFPROTO_IPV4 = 2, 57 58 NFPROTO_ARP = 3, 58 59 NFPROTO_BRIDGE = 7,
+2 -1
net/ipv4/netfilter/nf_tables_ipv4.c
··· 48 48 return nft_do_chain_ipv4(ops, skb, in, out, okfn); 49 49 } 50 50 51 - static struct nft_af_info nft_af_ipv4 __read_mostly = { 51 + struct nft_af_info nft_af_ipv4 __read_mostly = { 52 52 .family = NFPROTO_IPV4, 53 53 .nhooks = NF_INET_NUMHOOKS, 54 54 .owner = THIS_MODULE, ··· 61 61 [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, 62 62 }, 63 63 }; 64 + EXPORT_SYMBOL_GPL(nft_af_ipv4); 64 65 65 66 static int nf_tables_ipv4_init_net(struct net *net) 66 67 {
+2 -1
net/ipv6/netfilter/nf_tables_ipv6.c
··· 47 47 return nft_do_chain_ipv6(ops, skb, in, out, okfn); 48 48 } 49 49 50 - static struct nft_af_info nft_af_ipv6 __read_mostly = { 50 + struct nft_af_info nft_af_ipv6 __read_mostly = { 51 51 .family = NFPROTO_IPV6, 52 52 .nhooks = NF_INET_NUMHOOKS, 53 53 .owner = THIS_MODULE, ··· 60 60 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, 61 61 }, 62 62 }; 63 + EXPORT_SYMBOL_GPL(nft_af_ipv6); 63 64 64 65 static int nf_tables_ipv6_init_net(struct net *net) 65 66 {
+8
net/netfilter/Kconfig
··· 428 428 429 429 To compile it as a module, choose M here. 430 430 431 + config NF_TABLES_INET 432 + depends on NF_TABLES 433 + select NF_TABLES_IPV4 434 + select NF_TABLES_IPV6 435 + tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support" 436 + help 437 + This option enables support for a mixed IPv4/IPv6 "inet" table. 438 + 431 439 config NFT_EXTHDR 432 440 depends on NF_TABLES 433 441 tristate "Netfilter nf_tables IPv6 exthdr module"
+1
net/netfilter/Makefile
··· 70 70 nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o 71 71 72 72 obj-$(CONFIG_NF_TABLES) += nf_tables.o 73 + obj-$(CONFIG_NF_TABLES_INET) += nf_tables_inet.o 73 74 obj-$(CONFIG_NFT_COMPAT) += nft_compat.o 74 75 obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o 75 76 obj-$(CONFIG_NFT_META) += nft_meta.o
+97
net/netfilter/nf_tables_inet.c
··· 1 + /* 2 + * Copyright (c) 2012-2014 Patrick McHardy <kaber@trash.net> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/init.h> 10 + #include <linux/module.h> 11 + #include <linux/ip.h> 12 + #include <linux/netfilter_ipv4.h> 13 + #include <linux/netfilter_ipv6.h> 14 + #include <net/netfilter/nf_tables.h> 15 + #include <net/netfilter/nf_tables_ipv4.h> 16 + #include <net/netfilter/nf_tables_ipv6.h> 17 + #include <net/ip.h> 18 + 19 + static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n) 20 + { 21 + struct nft_af_info *afi; 22 + 23 + if (n == 1) 24 + afi = &nft_af_ipv4; 25 + else 26 + afi = &nft_af_ipv6; 27 + 28 + ops->pf = afi->family; 29 + if (afi->hooks[ops->hooknum]) 30 + ops->hook = afi->hooks[ops->hooknum]; 31 + } 32 + 33 + static struct nft_af_info nft_af_inet __read_mostly = { 34 + .family = NFPROTO_INET, 35 + .nhooks = NF_INET_NUMHOOKS, 36 + .owner = THIS_MODULE, 37 + .nops = 2, 38 + .hook_ops_init = nft_inet_hook_ops_init, 39 + }; 40 + 41 + static int __net_init nf_tables_inet_init_net(struct net *net) 42 + { 43 + net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL); 44 + if (net->nft.inet == NULL) 45 + return -ENOMEM; 46 + memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet)); 47 + 48 + if (nft_register_afinfo(net, net->nft.inet) < 0) 49 + goto err; 50 + 51 + return 0; 52 + 53 + err: 54 + kfree(net->nft.inet); 55 + return -ENOMEM; 56 + } 57 + 58 + static void __net_exit nf_tables_inet_exit_net(struct net *net) 59 + { 60 + nft_unregister_afinfo(net->nft.inet); 61 + kfree(net->nft.inet); 62 + } 63 + 64 + static struct pernet_operations nf_tables_inet_net_ops = { 65 + .init = nf_tables_inet_init_net, 66 + .exit = nf_tables_inet_exit_net, 67 + }; 68 + 69 + static struct nf_chain_type filter_inet = { 70 + .family = NFPROTO_INET, 71 + .name = "filter", 72 + .type = NFT_CHAIN_T_DEFAULT, 73 + .hook_mask = (1 << NF_INET_LOCAL_IN) | 74 + (1 << NF_INET_LOCAL_OUT) | 75 + (1 << NF_INET_FORWARD) | 76 + (1 << NF_INET_PRE_ROUTING) | 77 + (1 << NF_INET_POST_ROUTING), 78 + }; 79 + 80 + static int __init nf_tables_inet_init(void) 81 + { 82 + nft_register_chain_type(&filter_inet); 83 + return register_pernet_subsys(&nf_tables_inet_net_ops); 84 + } 85 + 86 + static void __exit nf_tables_inet_exit(void) 87 + { 88 + unregister_pernet_subsys(&nf_tables_inet_net_ops); 89 + nft_unregister_chain_type(&filter_inet); 90 + } 91 + 92 + module_init(nf_tables_inet_init); 93 + module_exit(nf_tables_inet_exit); 94 + 95 + MODULE_LICENSE("GPL"); 96 + MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 97 + MODULE_ALIAS_NFT_FAMILY(1);