aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-03-27 05:53:07 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-30 05:29:19 -0400
commit02c7b25e5f54321b9063e18d4f52cce07f8e081d (patch)
treec497bb71b3f152f3f07ea93dfbd605632e61457a
parentcc07eeb0e5ee18895241460bdccf91a4952731f9 (diff)
netfilter: nf_tables: build-in filter chain type
One module per supported filter chain family type takes too much memory for very little code - too much modularization - place all chain filter definitions in one single file. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netfilter/nf_tables.h3
-rw-r--r--net/bridge/netfilter/Kconfig2
-rw-r--r--net/bridge/netfilter/Makefile1
-rw-r--r--net/bridge/netfilter/nf_tables_bridge.c81
-rw-r--r--net/ipv4/netfilter/Kconfig4
-rw-r--r--net/ipv4/netfilter/Makefile2
-rw-r--r--net/ipv4/netfilter/nf_tables_arp.c60
-rw-r--r--net/ipv4/netfilter/nf_tables_ipv4.c69
-rw-r--r--net/ipv6/netfilter/Kconfig2
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/nf_tables_ipv6.c67
-rw-r--r--net/netfilter/Kconfig4
-rw-r--r--net/netfilter/Makefile9
-rw-r--r--net/netfilter/nf_tables_api.c3
-rw-r--r--net/netfilter/nf_tables_inet.c77
-rw-r--r--net/netfilter/nf_tables_netdev.c140
-rw-r--r--net/netfilter/nft_chain_filter.c398
17 files changed, 414 insertions, 509 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 1f7148fe0504..77c3c04c27ac 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1345,4 +1345,7 @@ struct nft_trans_flowtable {
1345#define nft_trans_flowtable(trans) \ 1345#define nft_trans_flowtable(trans) \
1346 (((struct nft_trans_flowtable *)trans->data)->flowtable) 1346 (((struct nft_trans_flowtable *)trans->data)->flowtable)
1347 1347
1348int __init nft_chain_filter_init(void);
1349void __exit nft_chain_filter_fini(void);
1350
1348#endif /* _NET_NF_TABLES_H */ 1351#endif /* _NET_NF_TABLES_H */
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 225d1668dfdd..f212447794bd 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -5,7 +5,7 @@
5menuconfig NF_TABLES_BRIDGE 5menuconfig NF_TABLES_BRIDGE
6 depends on BRIDGE && NETFILTER && NF_TABLES 6 depends on BRIDGE && NETFILTER && NF_TABLES
7 select NETFILTER_FAMILY_BRIDGE 7 select NETFILTER_FAMILY_BRIDGE
8 tristate "Ethernet Bridge nf_tables support" 8 bool "Ethernet Bridge nf_tables support"
9 9
10if NF_TABLES_BRIDGE 10if NF_TABLES_BRIDGE
11 11
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 2f28e16de6c7..4bc758dd4a8c 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -3,7 +3,6 @@
3# Makefile for the netfilter modules for Link Layer filtering on a bridge. 3# Makefile for the netfilter modules for Link Layer filtering on a bridge.
4# 4#
5 5
6obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o
7obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o 6obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o
8obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o 7obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o
9 8
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
deleted file mode 100644
index ffb8580dfdac..000000000000
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2013 Pablo Neira Ayuso <pablo@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/netfilter_bridge.h>
15#include <net/netfilter/nf_tables.h>
16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <net/netfilter/nf_tables_ipv4.h>
19#include <net/netfilter/nf_tables_ipv6.h>
20
21static unsigned int
22nft_do_chain_bridge(void *priv,
23 struct sk_buff *skb,
24 const struct nf_hook_state *state)
25{
26 struct nft_pktinfo pkt;
27
28 nft_set_pktinfo(&pkt, skb, state);
29
30 switch (eth_hdr(skb)->h_proto) {
31 case htons(ETH_P_IP):
32 nft_set_pktinfo_ipv4_validate(&pkt, skb);
33 break;
34 case htons(ETH_P_IPV6):
35 nft_set_pktinfo_ipv6_validate(&pkt, skb);
36 break;
37 default:
38 nft_set_pktinfo_unspec(&pkt, skb);
39 break;
40 }
41
42 return nft_do_chain(&pkt, priv);
43}
44
45static const struct nft_chain_type filter_bridge = {
46 .name = "filter",
47 .type = NFT_CHAIN_T_DEFAULT,
48 .family = NFPROTO_BRIDGE,
49 .owner = THIS_MODULE,
50 .hook_mask = (1 << NF_BR_PRE_ROUTING) |
51 (1 << NF_BR_LOCAL_IN) |
52 (1 << NF_BR_FORWARD) |
53 (1 << NF_BR_LOCAL_OUT) |
54 (1 << NF_BR_POST_ROUTING),
55 .hooks = {
56 [NF_BR_PRE_ROUTING] = nft_do_chain_bridge,
57 [NF_BR_LOCAL_IN] = nft_do_chain_bridge,
58 [NF_BR_FORWARD] = nft_do_chain_bridge,
59 [NF_BR_LOCAL_OUT] = nft_do_chain_bridge,
60 [NF_BR_POST_ROUTING] = nft_do_chain_bridge,
61 },
62};
63
64static int __init nf_tables_bridge_init(void)
65{
66 nft_register_chain_type(&filter_bridge);
67
68 return 0;
69}
70
71static void __exit nf_tables_bridge_exit(void)
72{
73 nft_unregister_chain_type(&filter_bridge);
74}
75
76module_init(nf_tables_bridge_init);
77module_exit(nf_tables_bridge_exit);
78
79MODULE_LICENSE("GPL");
80MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
81MODULE_ALIAS_NFT_CHAIN(AF_BRIDGE, "filter");
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index dfe6fa4ea554..280048e1e395 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -34,7 +34,7 @@ config NF_SOCKET_IPV4
34if NF_TABLES 34if NF_TABLES
35 35
36config NF_TABLES_IPV4 36config NF_TABLES_IPV4
37 tristate "IPv4 nf_tables support" 37 bool "IPv4 nf_tables support"
38 help 38 help
39 This option enables the IPv4 support for nf_tables. 39 This option enables the IPv4 support for nf_tables.
40 40
@@ -71,7 +71,7 @@ config NFT_FIB_IPV4
71endif # NF_TABLES_IPV4 71endif # NF_TABLES_IPV4
72 72
73config NF_TABLES_ARP 73config NF_TABLES_ARP
74 tristate "ARP nf_tables support" 74 bool "ARP nf_tables support"
75 select NETFILTER_FAMILY_ARP 75 select NETFILTER_FAMILY_ARP
76 help 76 help
77 This option enables the ARP support for nf_tables. 77 This option enables the ARP support for nf_tables.
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 2dad20eefd26..62ede5e3a3de 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -39,7 +39,6 @@ obj-$(CONFIG_NF_NAT_MASQUERADE_IPV4) += nf_nat_masquerade_ipv4.o
39# NAT protocols (nf_nat) 39# NAT protocols (nf_nat)
40obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o 40obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
41 41
42obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o
43obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o 42obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o
44obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o 43obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
45obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o 44obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
@@ -47,7 +46,6 @@ obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
47obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o 46obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o
48obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o 47obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o
49obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o 48obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
50obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
51 49
52# flow table support 50# flow table support
53obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o 51obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
deleted file mode 100644
index c2ee64208743..000000000000
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Copyright (c) 2008-2010 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2013 Pablo Neira Ayuso <pablo@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/netfilter_arp.h>
15#include <net/netfilter/nf_tables.h>
16
17static unsigned int
18nft_do_chain_arp(void *priv,
19 struct sk_buff *skb,
20 const struct nf_hook_state *state)
21{
22 struct nft_pktinfo pkt;
23
24 nft_set_pktinfo(&pkt, skb, state);
25 nft_set_pktinfo_unspec(&pkt, skb);
26
27 return nft_do_chain(&pkt, priv);
28}
29
30static const struct nft_chain_type filter_arp = {
31 .name = "filter",
32 .type = NFT_CHAIN_T_DEFAULT,
33 .family = NFPROTO_ARP,
34 .owner = THIS_MODULE,
35 .hook_mask = (1 << NF_ARP_IN) |
36 (1 << NF_ARP_OUT),
37 .hooks = {
38 [NF_ARP_IN] = nft_do_chain_arp,
39 [NF_ARP_OUT] = nft_do_chain_arp,
40 },
41};
42
43static int __init nf_tables_arp_init(void)
44{
45 nft_register_chain_type(&filter_arp);
46
47 return 0;
48}
49
50static void __exit nf_tables_arp_exit(void)
51{
52 nft_unregister_chain_type(&filter_arp);
53}
54
55module_init(nf_tables_arp_init);
56module_exit(nf_tables_arp_exit);
57
58MODULE_LICENSE("GPL");
59MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
60MODULE_ALIAS_NFT_CHAIN(3, "filter"); /* NFPROTO_ARP */
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
deleted file mode 100644
index c09667de0d68..000000000000
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/ip.h>
15#include <linux/netfilter_ipv4.h>
16#include <net/netfilter/nf_tables.h>
17#include <net/net_namespace.h>
18#include <net/ip.h>
19#include <net/netfilter/nf_tables_ipv4.h>
20
21static unsigned int nft_do_chain_ipv4(void *priv,
22 struct sk_buff *skb,
23 const struct nf_hook_state *state)
24{
25 struct nft_pktinfo pkt;
26
27 nft_set_pktinfo(&pkt, skb, state);
28 nft_set_pktinfo_ipv4(&pkt, skb);
29
30 return nft_do_chain(&pkt, priv);
31}
32
33static const struct nft_chain_type filter_ipv4 = {
34 .name = "filter",
35 .type = NFT_CHAIN_T_DEFAULT,
36 .family = NFPROTO_IPV4,
37 .owner = THIS_MODULE,
38 .hook_mask = (1 << NF_INET_LOCAL_IN) |
39 (1 << NF_INET_LOCAL_OUT) |
40 (1 << NF_INET_FORWARD) |
41 (1 << NF_INET_PRE_ROUTING) |
42 (1 << NF_INET_POST_ROUTING),
43 .hooks = {
44 [NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
45 [NF_INET_LOCAL_OUT] = nft_do_chain_ipv4,
46 [NF_INET_FORWARD] = nft_do_chain_ipv4,
47 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4,
48 [NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
49 },
50};
51
52static int __init nf_tables_ipv4_init(void)
53{
54 nft_register_chain_type(&filter_ipv4);
55
56 return 0;
57}
58
59static void __exit nf_tables_ipv4_exit(void)
60{
61 nft_unregister_chain_type(&filter_ipv4);
62}
63
64module_init(nf_tables_ipv4_init);
65module_exit(nf_tables_ipv4_exit);
66
67MODULE_LICENSE("GPL");
68MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
69MODULE_ALIAS_NFT_CHAIN(AF_INET, "filter");
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index d395d1590699..ccbfa83e4bb0 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -34,7 +34,7 @@ config NF_SOCKET_IPV6
34if NF_TABLES 34if NF_TABLES
35 35
36config NF_TABLES_IPV6 36config NF_TABLES_IPV6
37 tristate "IPv6 nf_tables support" 37 bool "IPv6 nf_tables support"
38 help 38 help
39 This option enables the IPv6 support for nf_tables. 39 This option enables the IPv6 support for nf_tables.
40 40
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index d984057b8395..44273d6f03a5 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -36,7 +36,6 @@ obj-$(CONFIG_NF_REJECT_IPV6) += nf_reject_ipv6.o
36obj-$(CONFIG_NF_DUP_IPV6) += nf_dup_ipv6.o 36obj-$(CONFIG_NF_DUP_IPV6) += nf_dup_ipv6.o
37 37
38# nf_tables 38# nf_tables
39obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o
40obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o 39obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
41obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o 40obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o
42obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o 41obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
deleted file mode 100644
index 496f69453457..000000000000
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/ipv6.h>
15#include <linux/netfilter_ipv6.h>
16#include <net/netfilter/nf_tables.h>
17#include <net/netfilter/nf_tables_ipv6.h>
18
19static unsigned int nft_do_chain_ipv6(void *priv,
20 struct sk_buff *skb,
21 const struct nf_hook_state *state)
22{
23 struct nft_pktinfo pkt;
24
25 nft_set_pktinfo(&pkt, skb, state);
26 nft_set_pktinfo_ipv6(&pkt, skb);
27
28 return nft_do_chain(&pkt, priv);
29}
30
31static const struct nft_chain_type filter_ipv6 = {
32 .name = "filter",
33 .type = NFT_CHAIN_T_DEFAULT,
34 .family = NFPROTO_IPV6,
35 .owner = THIS_MODULE,
36 .hook_mask = (1 << NF_INET_LOCAL_IN) |
37 (1 << NF_INET_LOCAL_OUT) |
38 (1 << NF_INET_FORWARD) |
39 (1 << NF_INET_PRE_ROUTING) |
40 (1 << NF_INET_POST_ROUTING),
41 .hooks = {
42 [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
43 [NF_INET_LOCAL_OUT] = nft_do_chain_ipv6,
44 [NF_INET_FORWARD] = nft_do_chain_ipv6,
45 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
46 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
47 },
48};
49
50static int __init nf_tables_ipv6_init(void)
51{
52 nft_register_chain_type(&filter_ipv6);
53
54 return 0;
55}
56
57static void __exit nf_tables_ipv6_exit(void)
58{
59 nft_unregister_chain_type(&filter_ipv6);
60}
61
62module_init(nf_tables_ipv6_init);
63module_exit(nf_tables_ipv6_exit);
64
65MODULE_LICENSE("GPL");
66MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
67MODULE_ALIAS_NFT_CHAIN(AF_INET6, "filter");
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index d3220b43c832..704b3832dbad 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -465,12 +465,12 @@ config NF_TABLES_INET
465 depends on IPV6 465 depends on IPV6
466 select NF_TABLES_IPV4 466 select NF_TABLES_IPV4
467 select NF_TABLES_IPV6 467 select NF_TABLES_IPV6
468 tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support" 468 bool "Netfilter nf_tables mixed IPv4/IPv6 tables support"
469 help 469 help
470 This option enables support for a mixed IPv4/IPv6 "inet" table. 470 This option enables support for a mixed IPv4/IPv6 "inet" table.
471 471
472config NF_TABLES_NETDEV 472config NF_TABLES_NETDEV
473 tristate "Netfilter nf_tables netdev tables support" 473 bool "Netfilter nf_tables netdev tables support"
474 help 474 help
475 This option enables support for the "netdev" table. 475 This option enables support for the "netdev" table.
476 476
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 5d9b8b959e58..fd32bd2c9521 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -73,13 +73,12 @@ obj-$(CONFIG_NETFILTER_CONNCOUNT) += nf_conncount.o
73obj-$(CONFIG_NF_DUP_NETDEV) += nf_dup_netdev.o 73obj-$(CONFIG_NF_DUP_NETDEV) += nf_dup_netdev.o
74 74
75# nf_tables 75# nf_tables
76nf_tables-objs := nf_tables_core.o nf_tables_api.o nf_tables_trace.o \ 76nf_tables-objs := nf_tables_core.o nf_tables_api.o nft_chain_filter.o \
77 nft_immediate.o nft_cmp.o nft_range.o nft_bitwise.o \ 77 nf_tables_trace.o nft_immediate.o nft_cmp.o nft_range.o \
78 nft_byteorder.o nft_payload.o nft_lookup.o nft_dynset.o 78 nft_bitwise.o nft_byteorder.o nft_payload.o nft_lookup.o \
79 nft_dynset.o
79 80
80obj-$(CONFIG_NF_TABLES) += nf_tables.o 81obj-$(CONFIG_NF_TABLES) += nf_tables.o
81obj-$(CONFIG_NF_TABLES_INET) += nf_tables_inet.o
82obj-$(CONFIG_NF_TABLES_NETDEV) += nf_tables_netdev.o
83obj-$(CONFIG_NFT_COMPAT) += nft_compat.o 82obj-$(CONFIG_NFT_COMPAT) += nft_compat.o
84obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o 83obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o
85obj-$(CONFIG_NFT_META) += nft_meta.o 84obj-$(CONFIG_NFT_META) += nft_meta.o
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9e4b1614ee39..97ec1c388bfe 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6584,6 +6584,8 @@ static int __init nf_tables_module_init(void)
6584{ 6584{
6585 int err; 6585 int err;
6586 6586
6587 nft_chain_filter_init();
6588
6587 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS, 6589 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
6588 GFP_KERNEL); 6590 GFP_KERNEL);
6589 if (info == NULL) { 6591 if (info == NULL) {
@@ -6618,6 +6620,7 @@ static void __exit nf_tables_module_exit(void)
6618 rcu_barrier(); 6620 rcu_barrier();
6619 nf_tables_core_module_exit(); 6621 nf_tables_core_module_exit();
6620 kfree(info); 6622 kfree(info);
6623 nft_chain_filter_fini();
6621} 6624}
6622 6625
6623module_init(nf_tables_module_init); 6626module_init(nf_tables_module_init);
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
deleted file mode 100644
index 202c4219969b..000000000000
--- a/net/netfilter/nf_tables_inet.c
+++ /dev/null
@@ -1,77 +0,0 @@
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/ipv6.h>
13#include <linux/netfilter_ipv4.h>
14#include <linux/netfilter_ipv6.h>
15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nf_tables_ipv4.h>
17#include <net/netfilter/nf_tables_ipv6.h>
18#include <net/ip.h>
19
20static unsigned int nft_do_chain_inet(void *priv, struct sk_buff *skb,
21 const struct nf_hook_state *state)
22{
23 struct nft_pktinfo pkt;
24
25 nft_set_pktinfo(&pkt, skb, state);
26
27 switch (state->pf) {
28 case NFPROTO_IPV4:
29 nft_set_pktinfo_ipv4(&pkt, skb);
30 break;
31 case NFPROTO_IPV6:
32 nft_set_pktinfo_ipv6(&pkt, skb);
33 break;
34 default:
35 break;
36 }
37
38 return nft_do_chain(&pkt, priv);
39}
40
41static const struct nft_chain_type filter_inet = {
42 .name = "filter",
43 .type = NFT_CHAIN_T_DEFAULT,
44 .family = NFPROTO_INET,
45 .owner = THIS_MODULE,
46 .hook_mask = (1 << NF_INET_LOCAL_IN) |
47 (1 << NF_INET_LOCAL_OUT) |
48 (1 << NF_INET_FORWARD) |
49 (1 << NF_INET_PRE_ROUTING) |
50 (1 << NF_INET_POST_ROUTING),
51 .hooks = {
52 [NF_INET_LOCAL_IN] = nft_do_chain_inet,
53 [NF_INET_LOCAL_OUT] = nft_do_chain_inet,
54 [NF_INET_FORWARD] = nft_do_chain_inet,
55 [NF_INET_PRE_ROUTING] = nft_do_chain_inet,
56 [NF_INET_POST_ROUTING] = nft_do_chain_inet,
57 },
58};
59
60static int __init nf_tables_inet_init(void)
61{
62 nft_register_chain_type(&filter_inet);
63
64 return 0;
65}
66
67static void __exit nf_tables_inet_exit(void)
68{
69 nft_unregister_chain_type(&filter_inet);
70}
71
72module_init(nf_tables_inet_init);
73module_exit(nf_tables_inet_exit);
74
75MODULE_LICENSE("GPL");
76MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
77MODULE_ALIAS_NFT_CHAIN(1, "filter");
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c
deleted file mode 100644
index 4c3835bca63e..000000000000
--- a/net/netfilter/nf_tables_netdev.c
+++ /dev/null
@@ -1,140 +0,0 @@
1/*
2 * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
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/netdevice.h>
12#include <net/netfilter/nf_tables.h>
13#include <linux/ip.h>
14#include <linux/ipv6.h>
15#include <net/netfilter/nf_tables_ipv4.h>
16#include <net/netfilter/nf_tables_ipv6.h>
17
18static unsigned int
19nft_do_chain_netdev(void *priv, struct sk_buff *skb,
20 const struct nf_hook_state *state)
21{
22 struct nft_pktinfo pkt;
23
24 nft_set_pktinfo(&pkt, skb, state);
25
26 switch (skb->protocol) {
27 case htons(ETH_P_IP):
28 nft_set_pktinfo_ipv4_validate(&pkt, skb);
29 break;
30 case htons(ETH_P_IPV6):
31 nft_set_pktinfo_ipv6_validate(&pkt, skb);
32 break;
33 default:
34 nft_set_pktinfo_unspec(&pkt, skb);
35 break;
36 }
37
38 return nft_do_chain(&pkt, priv);
39}
40
41static const struct nft_chain_type nft_filter_chain_netdev = {
42 .name = "filter",
43 .type = NFT_CHAIN_T_DEFAULT,
44 .family = NFPROTO_NETDEV,
45 .owner = THIS_MODULE,
46 .hook_mask = (1 << NF_NETDEV_INGRESS),
47 .hooks = {
48 [NF_NETDEV_INGRESS] = nft_do_chain_netdev,
49 },
50};
51
52static void nft_netdev_event(unsigned long event, struct net_device *dev,
53 struct nft_ctx *ctx)
54{
55 struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
56
57 switch (event) {
58 case NETDEV_UNREGISTER:
59 if (strcmp(basechain->dev_name, dev->name) != 0)
60 return;
61
62 __nft_release_basechain(ctx);
63 break;
64 case NETDEV_CHANGENAME:
65 if (dev->ifindex != basechain->ops.dev->ifindex)
66 return;
67
68 strncpy(basechain->dev_name, dev->name, IFNAMSIZ);
69 break;
70 }
71}
72
73static int nf_tables_netdev_event(struct notifier_block *this,
74 unsigned long event, void *ptr)
75{
76 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
77 struct nft_table *table;
78 struct nft_chain *chain, *nr;
79 struct nft_ctx ctx = {
80 .net = dev_net(dev),
81 };
82
83 if (event != NETDEV_UNREGISTER &&
84 event != NETDEV_CHANGENAME)
85 return NOTIFY_DONE;
86
87 nfnl_lock(NFNL_SUBSYS_NFTABLES);
88 list_for_each_entry(table, &ctx.net->nft.tables, list) {
89 if (table->family != NFPROTO_NETDEV)
90 continue;
91
92 ctx.family = table->family;
93 ctx.table = table;
94 list_for_each_entry_safe(chain, nr, &table->chains, list) {
95 if (!nft_is_base_chain(chain))
96 continue;
97
98 ctx.chain = chain;
99 nft_netdev_event(event, dev, &ctx);
100 }
101 }
102 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
103
104 return NOTIFY_DONE;
105}
106
107static struct notifier_block nf_tables_netdev_notifier = {
108 .notifier_call = nf_tables_netdev_event,
109};
110
111static int __init nf_tables_netdev_init(void)
112{
113 int ret;
114
115 nft_register_chain_type(&nft_filter_chain_netdev);
116
117 ret = register_netdevice_notifier(&nf_tables_netdev_notifier);
118 if (ret)
119 goto err_register_netdevice_notifier;
120
121 return 0;
122
123err_register_netdevice_notifier:
124 nft_unregister_chain_type(&nft_filter_chain_netdev);
125
126 return ret;
127}
128
129static void __exit nf_tables_netdev_exit(void)
130{
131 unregister_netdevice_notifier(&nf_tables_netdev_notifier);
132 nft_unregister_chain_type(&nft_filter_chain_netdev);
133}
134
135module_init(nf_tables_netdev_init);
136module_exit(nf_tables_netdev_exit);
137
138MODULE_LICENSE("GPL");
139MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
140MODULE_ALIAS_NFT_CHAIN(5, "filter"); /* NFPROTO_NETDEV */
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
new file mode 100644
index 000000000000..84c902477a91
--- /dev/null
+++ b/net/netfilter/nft_chain_filter.c
@@ -0,0 +1,398 @@
1#include <linux/init.h>
2#include <linux/kernel.h>
3#include <linux/netdevice.h>
4#include <net/net_namespace.h>
5#include <net/netfilter/nf_tables.h>
6#include <linux/netfilter_ipv4.h>
7#include <linux/netfilter_ipv6.h>
8#include <linux/netfilter_bridge.h>
9#include <linux/netfilter_arp.h>
10#include <net/netfilter/nf_tables_ipv4.h>
11#include <net/netfilter/nf_tables_ipv6.h>
12
13#ifdef CONFIG_NF_TABLES_IPV4
14static unsigned int nft_do_chain_ipv4(void *priv,
15 struct sk_buff *skb,
16 const struct nf_hook_state *state)
17{
18 struct nft_pktinfo pkt;
19
20 nft_set_pktinfo(&pkt, skb, state);
21 nft_set_pktinfo_ipv4(&pkt, skb);
22
23 return nft_do_chain(&pkt, priv);
24}
25
26static const struct nft_chain_type nft_chain_filter_ipv4 = {
27 .name = "filter",
28 .type = NFT_CHAIN_T_DEFAULT,
29 .family = NFPROTO_IPV4,
30 .hook_mask = (1 << NF_INET_LOCAL_IN) |
31 (1 << NF_INET_LOCAL_OUT) |
32 (1 << NF_INET_FORWARD) |
33 (1 << NF_INET_PRE_ROUTING) |
34 (1 << NF_INET_POST_ROUTING),
35 .hooks = {
36 [NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
37 [NF_INET_LOCAL_OUT] = nft_do_chain_ipv4,
38 [NF_INET_FORWARD] = nft_do_chain_ipv4,
39 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4,
40 [NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
41 },
42};
43
44static void nft_chain_filter_ipv4_init(void)
45{
46 nft_register_chain_type(&nft_chain_filter_ipv4);
47}
48static void nft_chain_filter_ipv4_fini(void)
49{
50 nft_unregister_chain_type(&nft_chain_filter_ipv4);
51}
52
53#else
54static inline void nft_chain_filter_ipv4_init(void) {}
55static inline void nft_chain_filter_ipv4_fini(void) {}
56#endif /* CONFIG_NF_TABLES_IPV4 */
57
58#ifdef CONFIG_NF_TABLES_ARP
59static unsigned int nft_do_chain_arp(void *priv, struct sk_buff *skb,
60 const struct nf_hook_state *state)
61{
62 struct nft_pktinfo pkt;
63
64 nft_set_pktinfo(&pkt, skb, state);
65 nft_set_pktinfo_unspec(&pkt, skb);
66
67 return nft_do_chain(&pkt, priv);
68}
69
70static const struct nft_chain_type nft_chain_filter_arp = {
71 .name = "filter",
72 .type = NFT_CHAIN_T_DEFAULT,
73 .family = NFPROTO_ARP,
74 .owner = THIS_MODULE,
75 .hook_mask = (1 << NF_ARP_IN) |
76 (1 << NF_ARP_OUT),
77 .hooks = {
78 [NF_ARP_IN] = nft_do_chain_arp,
79 [NF_ARP_OUT] = nft_do_chain_arp,
80 },
81};
82
83static void nft_chain_filter_arp_init(void)
84{
85 nft_register_chain_type(&nft_chain_filter_arp);
86}
87
88static void nft_chain_filter_arp_fini(void)
89{
90 nft_unregister_chain_type(&nft_chain_filter_arp);
91}
92#else
93static inline void nft_chain_filter_arp_init(void) {}
94static inline void nft_chain_filter_arp_fini(void) {}
95#endif /* CONFIG_NF_TABLES_ARP */
96
97#ifdef CONFIG_NF_TABLES_IPV6
98static unsigned int nft_do_chain_ipv6(void *priv,
99 struct sk_buff *skb,
100 const struct nf_hook_state *state)
101{
102 struct nft_pktinfo pkt;
103
104 nft_set_pktinfo(&pkt, skb, state);
105 nft_set_pktinfo_ipv6(&pkt, skb);
106
107 return nft_do_chain(&pkt, priv);
108}
109
110static const struct nft_chain_type nft_chain_filter_ipv6 = {
111 .name = "filter",
112 .type = NFT_CHAIN_T_DEFAULT,
113 .family = NFPROTO_IPV6,
114 .hook_mask = (1 << NF_INET_LOCAL_IN) |
115 (1 << NF_INET_LOCAL_OUT) |
116 (1 << NF_INET_FORWARD) |
117 (1 << NF_INET_PRE_ROUTING) |
118 (1 << NF_INET_POST_ROUTING),
119 .hooks = {
120 [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
121 [NF_INET_LOCAL_OUT] = nft_do_chain_ipv6,
122 [NF_INET_FORWARD] = nft_do_chain_ipv6,
123 [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
124 [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
125 },
126};
127
128static void nft_chain_filter_ipv6_init(void)
129{
130 nft_register_chain_type(&nft_chain_filter_ipv6);
131}
132
133static void nft_chain_filter_ipv6_fini(void)
134{
135 nft_unregister_chain_type(&nft_chain_filter_ipv6);
136}
137#else
138static inline void nft_chain_filter_ipv6_init(void) {}
139static inline void nft_chain_filter_ipv6_fini(void) {}
140#endif /* CONFIG_NF_TABLES_IPV6 */
141
142#ifdef CONFIG_NF_TABLES_INET
143static unsigned int nft_do_chain_inet(void *priv, struct sk_buff *skb,
144 const struct nf_hook_state *state)
145{
146 struct nft_pktinfo pkt;
147
148 nft_set_pktinfo(&pkt, skb, state);
149
150 switch (state->pf) {
151 case NFPROTO_IPV4:
152 nft_set_pktinfo_ipv4(&pkt, skb);
153 break;
154 case NFPROTO_IPV6:
155 nft_set_pktinfo_ipv6(&pkt, skb);
156 break;
157 default:
158 break;
159 }
160
161 return nft_do_chain(&pkt, priv);
162}
163
164static const struct nft_chain_type nft_chain_filter_inet = {
165 .name = "filter",
166 .type = NFT_CHAIN_T_DEFAULT,
167 .family = NFPROTO_INET,
168 .hook_mask = (1 << NF_INET_LOCAL_IN) |
169 (1 << NF_INET_LOCAL_OUT) |
170 (1 << NF_INET_FORWARD) |
171 (1 << NF_INET_PRE_ROUTING) |
172 (1 << NF_INET_POST_ROUTING),
173 .hooks = {
174 [NF_INET_LOCAL_IN] = nft_do_chain_inet,
175 [NF_INET_LOCAL_OUT] = nft_do_chain_inet,
176 [NF_INET_FORWARD] = nft_do_chain_inet,
177 [NF_INET_PRE_ROUTING] = nft_do_chain_inet,
178 [NF_INET_POST_ROUTING] = nft_do_chain_inet,
179 },
180};
181
182static void nft_chain_filter_inet_init(void)
183{
184 nft_register_chain_type(&nft_chain_filter_inet);
185}
186
187static void nft_chain_filter_inet_fini(void)
188{
189 nft_unregister_chain_type(&nft_chain_filter_inet);
190}
191#else
192static inline void nft_chain_filter_inet_init(void) {}
193static inline void nft_chain_filter_inet_fini(void) {}
194#endif /* CONFIG_NF_TABLES_IPV6 */
195
196#ifdef CONFIG_NF_TABLES_BRIDGE
197static unsigned int
198nft_do_chain_bridge(void *priv,
199 struct sk_buff *skb,
200 const struct nf_hook_state *state)
201{
202 struct nft_pktinfo pkt;
203
204 nft_set_pktinfo(&pkt, skb, state);
205
206 switch (eth_hdr(skb)->h_proto) {
207 case htons(ETH_P_IP):
208 nft_set_pktinfo_ipv4_validate(&pkt, skb);
209 break;
210 case htons(ETH_P_IPV6):
211 nft_set_pktinfo_ipv6_validate(&pkt, skb);
212 break;
213 default:
214 nft_set_pktinfo_unspec(&pkt, skb);
215 break;
216 }
217
218 return nft_do_chain(&pkt, priv);
219}
220
221static const struct nft_chain_type nft_chain_filter_bridge = {
222 .name = "filter",
223 .type = NFT_CHAIN_T_DEFAULT,
224 .family = NFPROTO_BRIDGE,
225 .hook_mask = (1 << NF_BR_PRE_ROUTING) |
226 (1 << NF_BR_LOCAL_IN) |
227 (1 << NF_BR_FORWARD) |
228 (1 << NF_BR_LOCAL_OUT) |
229 (1 << NF_BR_POST_ROUTING),
230 .hooks = {
231 [NF_BR_PRE_ROUTING] = nft_do_chain_bridge,
232 [NF_BR_LOCAL_IN] = nft_do_chain_bridge,
233 [NF_BR_FORWARD] = nft_do_chain_bridge,
234 [NF_BR_LOCAL_OUT] = nft_do_chain_bridge,
235 [NF_BR_POST_ROUTING] = nft_do_chain_bridge,
236 },
237};
238
239static void nft_chain_filter_bridge_init(void)
240{
241 nft_register_chain_type(&nft_chain_filter_bridge);
242}
243
244static void nft_chain_filter_bridge_fini(void)
245{
246 nft_unregister_chain_type(&nft_chain_filter_bridge);
247}
248#else
249static inline void nft_chain_filter_bridge_init(void) {}
250static inline void nft_chain_filter_bridge_fini(void) {}
251#endif /* CONFIG_NF_TABLES_BRIDGE */
252
253#ifdef CONFIG_NF_TABLES_NETDEV
254static unsigned int nft_do_chain_netdev(void *priv, struct sk_buff *skb,
255 const struct nf_hook_state *state)
256{
257 struct nft_pktinfo pkt;
258
259 nft_set_pktinfo(&pkt, skb, state);
260
261 switch (skb->protocol) {
262 case htons(ETH_P_IP):
263 nft_set_pktinfo_ipv4_validate(&pkt, skb);
264 break;
265 case htons(ETH_P_IPV6):
266 nft_set_pktinfo_ipv6_validate(&pkt, skb);
267 break;
268 default:
269 nft_set_pktinfo_unspec(&pkt, skb);
270 break;
271 }
272
273 return nft_do_chain(&pkt, priv);
274}
275
276static const struct nft_chain_type nft_chain_filter_netdev = {
277 .name = "filter",
278 .type = NFT_CHAIN_T_DEFAULT,
279 .family = NFPROTO_NETDEV,
280 .hook_mask = (1 << NF_NETDEV_INGRESS),
281 .hooks = {
282 [NF_NETDEV_INGRESS] = nft_do_chain_netdev,
283 },
284};
285
286static void nft_netdev_event(unsigned long event, struct net_device *dev,
287 struct nft_ctx *ctx)
288{
289 struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
290
291 switch (event) {
292 case NETDEV_UNREGISTER:
293 if (strcmp(basechain->dev_name, dev->name) != 0)
294 return;
295
296 __nft_release_basechain(ctx);
297 break;
298 case NETDEV_CHANGENAME:
299 if (dev->ifindex != basechain->ops.dev->ifindex)
300 return;
301
302 strncpy(basechain->dev_name, dev->name, IFNAMSIZ);
303 break;
304 }
305}
306
307static int nf_tables_netdev_event(struct notifier_block *this,
308 unsigned long event, void *ptr)
309{
310 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
311 struct nft_table *table;
312 struct nft_chain *chain, *nr;
313 struct nft_ctx ctx = {
314 .net = dev_net(dev),
315 };
316
317 if (event != NETDEV_UNREGISTER &&
318 event != NETDEV_CHANGENAME)
319 return NOTIFY_DONE;
320
321 nfnl_lock(NFNL_SUBSYS_NFTABLES);
322 list_for_each_entry(table, &ctx.net->nft.tables, list) {
323 if (table->family != NFPROTO_NETDEV)
324 continue;
325
326 ctx.family = table->family;
327 ctx.table = table;
328 list_for_each_entry_safe(chain, nr, &table->chains, list) {
329 if (!nft_is_base_chain(chain))
330 continue;
331
332 ctx.chain = chain;
333 nft_netdev_event(event, dev, &ctx);
334 }
335 }
336 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
337
338 return NOTIFY_DONE;
339}
340
341static struct notifier_block nf_tables_netdev_notifier = {
342 .notifier_call = nf_tables_netdev_event,
343};
344
345static int nft_chain_filter_netdev_init(void)
346{
347 int err;
348
349 nft_register_chain_type(&nft_chain_filter_netdev);
350
351 err = register_netdevice_notifier(&nf_tables_netdev_notifier);
352 if (err)
353 goto err_register_netdevice_notifier;
354
355 return 0;
356
357err_register_netdevice_notifier:
358 nft_unregister_chain_type(&nft_chain_filter_netdev);
359
360 return err;
361}
362
363static void nft_chain_filter_netdev_fini(void)
364{
365 nft_unregister_chain_type(&nft_chain_filter_netdev);
366 unregister_netdevice_notifier(&nf_tables_netdev_notifier);
367}
368#else
369static inline int nft_chain_filter_netdev_init(void) { return 0; }
370static inline void nft_chain_filter_netdev_fini(void) {}
371#endif /* CONFIG_NF_TABLES_NETDEV */
372
373int __init nft_chain_filter_init(void)
374{
375 int err;
376
377 err = nft_chain_filter_netdev_init();
378 if (err < 0)
379 return err;
380
381 nft_chain_filter_ipv4_init();
382 nft_chain_filter_ipv6_init();
383 nft_chain_filter_arp_init();
384 nft_chain_filter_inet_init();
385 nft_chain_filter_bridge_init();
386
387 return 0;
388}
389
390void __exit nft_chain_filter_fini(void)
391{
392 nft_chain_filter_bridge_fini();
393 nft_chain_filter_inet_fini();
394 nft_chain_filter_arp_fini();
395 nft_chain_filter_ipv6_fini();
396 nft_chain_filter_ipv4_fini();
397 nft_chain_filter_netdev_fini();
398}