diff options
author | Patrick McHardy <kaber@trash.net> | 2014-01-03 07:16:13 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-01-07 17:50:43 -0500 |
commit | 3b088c4bc0035da662faa81818ba217e34c4bba4 (patch) | |
tree | 1d43e3ff229e464491a5764efae37ed030d11bd7 | |
parent | 688d18636f77e360ae9078d7cd78a2556a1f35c1 (diff) |
netfilter: nf_tables: make chain types override the default AF functions
Currently the AF-specific hook functions override the chain-type specific
hook functions. That doesn't make too much sense since the chain types
are a special case of the AF-specific hooks.
Make the AF-specific hook functions the default and make the optional
chain type hooks override them.
As a side effect, the necessary code restructuring reduces the code size,
f.i. in case of nf_tables_ipv4.o:
nf_tables_ipv4_init_net | -24
nft_do_chain_ipv4 | -113
2 functions changed, 137 bytes removed, diff: -137
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/bridge/netfilter/nf_tables_bridge.c | 38 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_tables_arp.c | 38 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_tables_ipv4.c | 43 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_tables_ipv6.c | 48 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 10 |
5 files changed, 81 insertions, 96 deletions
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c index cf54b22818c8..c5fdd9a693be 100644 --- a/net/bridge/netfilter/nf_tables_bridge.c +++ b/net/bridge/netfilter/nf_tables_bridge.c | |||
@@ -14,10 +14,29 @@ | |||
14 | #include <linux/netfilter_bridge.h> | 14 | #include <linux/netfilter_bridge.h> |
15 | #include <net/netfilter/nf_tables.h> | 15 | #include <net/netfilter/nf_tables.h> |
16 | 16 | ||
17 | static unsigned int | ||
18 | nft_do_chain_bridge(const struct nf_hook_ops *ops, | ||
19 | struct sk_buff *skb, | ||
20 | const struct net_device *in, | ||
21 | const struct net_device *out, | ||
22 | int (*okfn)(struct sk_buff *)) | ||
23 | { | ||
24 | struct nft_pktinfo pkt; | ||
25 | |||
26 | nft_set_pktinfo(&pkt, ops, skb, in, out); | ||
27 | |||
28 | return nft_do_chain_pktinfo(&pkt, ops); | ||
29 | } | ||
30 | |||
17 | static struct nft_af_info nft_af_bridge __read_mostly = { | 31 | static struct nft_af_info nft_af_bridge __read_mostly = { |
18 | .family = NFPROTO_BRIDGE, | 32 | .family = NFPROTO_BRIDGE, |
19 | .nhooks = NF_BR_NUMHOOKS, | 33 | .nhooks = NF_BR_NUMHOOKS, |
20 | .owner = THIS_MODULE, | 34 | .owner = THIS_MODULE, |
35 | .hooks = { | ||
36 | [NF_BR_LOCAL_IN] = nft_do_chain_bridge, | ||
37 | [NF_BR_FORWARD] = nft_do_chain_bridge, | ||
38 | [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, | ||
39 | }, | ||
21 | }; | 40 | }; |
22 | 41 | ||
23 | static int nf_tables_bridge_init_net(struct net *net) | 42 | static int nf_tables_bridge_init_net(struct net *net) |
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_bridge_net_ops = { | |||
48 | .exit = nf_tables_bridge_exit_net, | 67 | .exit = nf_tables_bridge_exit_net, |
49 | }; | 68 | }; |
50 | 69 | ||
51 | static unsigned int | ||
52 | nft_do_chain_bridge(const struct nf_hook_ops *ops, | ||
53 | struct sk_buff *skb, | ||
54 | const struct net_device *in, | ||
55 | const struct net_device *out, | ||
56 | int (*okfn)(struct sk_buff *)) | ||
57 | { | ||
58 | struct nft_pktinfo pkt; | ||
59 | |||
60 | nft_set_pktinfo(&pkt, ops, skb, in, out); | ||
61 | |||
62 | return nft_do_chain_pktinfo(&pkt, ops); | ||
63 | } | ||
64 | |||
65 | static struct nf_chain_type filter_bridge = { | 70 | static struct nf_chain_type filter_bridge = { |
66 | .family = NFPROTO_BRIDGE, | 71 | .family = NFPROTO_BRIDGE, |
67 | .name = "filter", | 72 | .name = "filter", |
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_bridge = { | |||
69 | .hook_mask = (1 << NF_BR_LOCAL_IN) | | 74 | .hook_mask = (1 << NF_BR_LOCAL_IN) | |
70 | (1 << NF_BR_FORWARD) | | 75 | (1 << NF_BR_FORWARD) | |
71 | (1 << NF_BR_LOCAL_OUT), | 76 | (1 << NF_BR_LOCAL_OUT), |
72 | .fn = { | ||
73 | [NF_BR_LOCAL_IN] = nft_do_chain_bridge, | ||
74 | [NF_BR_FORWARD] = nft_do_chain_bridge, | ||
75 | [NF_BR_LOCAL_OUT] = nft_do_chain_bridge, | ||
76 | }, | ||
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int __init nf_tables_bridge_init(void) | 79 | static int __init nf_tables_bridge_init(void) |
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c index 3e67ef1c676f..31bb778cebb8 100644 --- a/net/ipv4/netfilter/nf_tables_arp.c +++ b/net/ipv4/netfilter/nf_tables_arp.c | |||
@@ -14,10 +14,29 @@ | |||
14 | #include <linux/netfilter_arp.h> | 14 | #include <linux/netfilter_arp.h> |
15 | #include <net/netfilter/nf_tables.h> | 15 | #include <net/netfilter/nf_tables.h> |
16 | 16 | ||
17 | static unsigned int | ||
18 | nft_do_chain_arp(const struct nf_hook_ops *ops, | ||
19 | struct sk_buff *skb, | ||
20 | const struct net_device *in, | ||
21 | const struct net_device *out, | ||
22 | int (*okfn)(struct sk_buff *)) | ||
23 | { | ||
24 | struct nft_pktinfo pkt; | ||
25 | |||
26 | nft_set_pktinfo(&pkt, ops, skb, in, out); | ||
27 | |||
28 | return nft_do_chain_pktinfo(&pkt, ops); | ||
29 | } | ||
30 | |||
17 | static struct nft_af_info nft_af_arp __read_mostly = { | 31 | static struct nft_af_info nft_af_arp __read_mostly = { |
18 | .family = NFPROTO_ARP, | 32 | .family = NFPROTO_ARP, |
19 | .nhooks = NF_ARP_NUMHOOKS, | 33 | .nhooks = NF_ARP_NUMHOOKS, |
20 | .owner = THIS_MODULE, | 34 | .owner = THIS_MODULE, |
35 | .hooks = { | ||
36 | [NF_ARP_IN] = nft_do_chain_arp, | ||
37 | [NF_ARP_OUT] = nft_do_chain_arp, | ||
38 | [NF_ARP_FORWARD] = nft_do_chain_arp, | ||
39 | }, | ||
21 | }; | 40 | }; |
22 | 41 | ||
23 | static int nf_tables_arp_init_net(struct net *net) | 42 | static int nf_tables_arp_init_net(struct net *net) |
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_arp_net_ops = { | |||
48 | .exit = nf_tables_arp_exit_net, | 67 | .exit = nf_tables_arp_exit_net, |
49 | }; | 68 | }; |
50 | 69 | ||
51 | static unsigned int | ||
52 | nft_do_chain_arp(const struct nf_hook_ops *ops, | ||
53 | struct sk_buff *skb, | ||
54 | const struct net_device *in, | ||
55 | const struct net_device *out, | ||
56 | int (*okfn)(struct sk_buff *)) | ||
57 | { | ||
58 | struct nft_pktinfo pkt; | ||
59 | |||
60 | nft_set_pktinfo(&pkt, ops, skb, in, out); | ||
61 | |||
62 | return nft_do_chain_pktinfo(&pkt, ops); | ||
63 | } | ||
64 | |||
65 | static struct nf_chain_type filter_arp = { | 70 | static struct nf_chain_type filter_arp = { |
66 | .family = NFPROTO_ARP, | 71 | .family = NFPROTO_ARP, |
67 | .name = "filter", | 72 | .name = "filter", |
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_arp = { | |||
69 | .hook_mask = (1 << NF_ARP_IN) | | 74 | .hook_mask = (1 << NF_ARP_IN) | |
70 | (1 << NF_ARP_OUT) | | 75 | (1 << NF_ARP_OUT) | |
71 | (1 << NF_ARP_FORWARD), | 76 | (1 << NF_ARP_FORWARD), |
72 | .fn = { | ||
73 | [NF_ARP_IN] = nft_do_chain_arp, | ||
74 | [NF_ARP_OUT] = nft_do_chain_arp, | ||
75 | [NF_ARP_FORWARD] = nft_do_chain_arp, | ||
76 | }, | ||
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int __init nf_tables_arp_init(void) | 79 | static int __init nf_tables_arp_init(void) |
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c index 0f4cbfeb19bd..ed7e15a93410 100644 --- a/net/ipv4/netfilter/nf_tables_ipv4.c +++ b/net/ipv4/netfilter/nf_tables_ipv4.c | |||
@@ -18,14 +18,25 @@ | |||
18 | #include <net/ip.h> | 18 | #include <net/ip.h> |
19 | #include <net/netfilter/nf_tables_ipv4.h> | 19 | #include <net/netfilter/nf_tables_ipv4.h> |
20 | 20 | ||
21 | static unsigned int nft_do_chain_ipv4(const struct nf_hook_ops *ops, | ||
22 | struct sk_buff *skb, | ||
23 | const struct net_device *in, | ||
24 | const struct net_device *out, | ||
25 | int (*okfn)(struct sk_buff *)) | ||
26 | { | ||
27 | struct nft_pktinfo pkt; | ||
28 | |||
29 | nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); | ||
30 | |||
31 | return nft_do_chain_pktinfo(&pkt, ops); | ||
32 | } | ||
33 | |||
21 | static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, | 34 | static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, |
22 | struct sk_buff *skb, | 35 | struct sk_buff *skb, |
23 | const struct net_device *in, | 36 | const struct net_device *in, |
24 | const struct net_device *out, | 37 | const struct net_device *out, |
25 | int (*okfn)(struct sk_buff *)) | 38 | int (*okfn)(struct sk_buff *)) |
26 | { | 39 | { |
27 | struct nft_pktinfo pkt; | ||
28 | |||
29 | if (unlikely(skb->len < sizeof(struct iphdr) || | 40 | if (unlikely(skb->len < sizeof(struct iphdr) || |
30 | ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { | 41 | ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) { |
31 | if (net_ratelimit()) | 42 | if (net_ratelimit()) |
@@ -33,9 +44,8 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops, | |||
33 | "packet\n"); | 44 | "packet\n"); |
34 | return NF_ACCEPT; | 45 | return NF_ACCEPT; |
35 | } | 46 | } |
36 | nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); | ||
37 | 47 | ||
38 | return nft_do_chain_pktinfo(&pkt, ops); | 48 | return nft_do_chain_ipv4(ops, skb, in, out, okfn); |
39 | } | 49 | } |
40 | 50 | ||
41 | static struct nft_af_info nft_af_ipv4 __read_mostly = { | 51 | static struct nft_af_info nft_af_ipv4 __read_mostly = { |
@@ -43,7 +53,11 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = { | |||
43 | .nhooks = NF_INET_NUMHOOKS, | 53 | .nhooks = NF_INET_NUMHOOKS, |
44 | .owner = THIS_MODULE, | 54 | .owner = THIS_MODULE, |
45 | .hooks = { | 55 | .hooks = { |
56 | [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, | ||
46 | [NF_INET_LOCAL_OUT] = nft_ipv4_output, | 57 | [NF_INET_LOCAL_OUT] = nft_ipv4_output, |
58 | [NF_INET_FORWARD] = nft_do_chain_ipv4, | ||
59 | [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, | ||
60 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, | ||
47 | }, | 61 | }, |
48 | }; | 62 | }; |
49 | 63 | ||
@@ -75,20 +89,6 @@ static struct pernet_operations nf_tables_ipv4_net_ops = { | |||
75 | .exit = nf_tables_ipv4_exit_net, | 89 | .exit = nf_tables_ipv4_exit_net, |
76 | }; | 90 | }; |
77 | 91 | ||
78 | static unsigned int | ||
79 | nft_do_chain_ipv4(const struct nf_hook_ops *ops, | ||
80 | struct sk_buff *skb, | ||
81 | const struct net_device *in, | ||
82 | const struct net_device *out, | ||
83 | int (*okfn)(struct sk_buff *)) | ||
84 | { | ||
85 | struct nft_pktinfo pkt; | ||
86 | |||
87 | nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out); | ||
88 | |||
89 | return nft_do_chain_pktinfo(&pkt, ops); | ||
90 | } | ||
91 | |||
92 | static struct nf_chain_type filter_ipv4 = { | 92 | static struct nf_chain_type filter_ipv4 = { |
93 | .family = NFPROTO_IPV4, | 93 | .family = NFPROTO_IPV4, |
94 | .name = "filter", | 94 | .name = "filter", |
@@ -98,13 +98,6 @@ static struct nf_chain_type filter_ipv4 = { | |||
98 | (1 << NF_INET_FORWARD) | | 98 | (1 << NF_INET_FORWARD) | |
99 | (1 << NF_INET_PRE_ROUTING) | | 99 | (1 << NF_INET_PRE_ROUTING) | |
100 | (1 << NF_INET_POST_ROUTING), | 100 | (1 << NF_INET_POST_ROUTING), |
101 | .fn = { | ||
102 | [NF_INET_LOCAL_IN] = nft_do_chain_ipv4, | ||
103 | [NF_INET_LOCAL_OUT] = nft_ipv4_output, | ||
104 | [NF_INET_FORWARD] = nft_do_chain_ipv4, | ||
105 | [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4, | ||
106 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv4, | ||
107 | }, | ||
108 | }; | 101 | }; |
109 | 102 | ||
110 | static int __init nf_tables_ipv4_init(void) | 103 | static int __init nf_tables_ipv4_init(void) |
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c index d77db8a13505..54a2bcdc8a17 100644 --- a/net/ipv6/netfilter/nf_tables_ipv6.c +++ b/net/ipv6/netfilter/nf_tables_ipv6.c | |||
@@ -16,24 +16,35 @@ | |||
16 | #include <net/netfilter/nf_tables.h> | 16 | #include <net/netfilter/nf_tables.h> |
17 | #include <net/netfilter/nf_tables_ipv6.h> | 17 | #include <net/netfilter/nf_tables_ipv6.h> |
18 | 18 | ||
19 | static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops, | ||
20 | struct sk_buff *skb, | ||
21 | const struct net_device *in, | ||
22 | const struct net_device *out, | ||
23 | int (*okfn)(struct sk_buff *)) | ||
24 | { | ||
25 | struct nft_pktinfo pkt; | ||
26 | |||
27 | /* malformed packet, drop it */ | ||
28 | if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0) | ||
29 | return NF_DROP; | ||
30 | |||
31 | return nft_do_chain_pktinfo(&pkt, ops); | ||
32 | } | ||
33 | |||
19 | static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, | 34 | static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops, |
20 | struct sk_buff *skb, | 35 | struct sk_buff *skb, |
21 | const struct net_device *in, | 36 | const struct net_device *in, |
22 | const struct net_device *out, | 37 | const struct net_device *out, |
23 | int (*okfn)(struct sk_buff *)) | 38 | int (*okfn)(struct sk_buff *)) |
24 | { | 39 | { |
25 | struct nft_pktinfo pkt; | ||
26 | |||
27 | if (unlikely(skb->len < sizeof(struct ipv6hdr))) { | 40 | if (unlikely(skb->len < sizeof(struct ipv6hdr))) { |
28 | if (net_ratelimit()) | 41 | if (net_ratelimit()) |
29 | pr_info("nf_tables_ipv6: ignoring short SOCK_RAW " | 42 | pr_info("nf_tables_ipv6: ignoring short SOCK_RAW " |
30 | "packet\n"); | 43 | "packet\n"); |
31 | return NF_ACCEPT; | 44 | return NF_ACCEPT; |
32 | } | 45 | } |
33 | if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0) | ||
34 | return NF_DROP; | ||
35 | 46 | ||
36 | return nft_do_chain_pktinfo(&pkt, ops); | 47 | return nft_do_chain_ipv6(ops, skb, in, out, okfn); |
37 | } | 48 | } |
38 | 49 | ||
39 | static struct nft_af_info nft_af_ipv6 __read_mostly = { | 50 | static struct nft_af_info nft_af_ipv6 __read_mostly = { |
@@ -41,7 +52,11 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = { | |||
41 | .nhooks = NF_INET_NUMHOOKS, | 52 | .nhooks = NF_INET_NUMHOOKS, |
42 | .owner = THIS_MODULE, | 53 | .owner = THIS_MODULE, |
43 | .hooks = { | 54 | .hooks = { |
55 | [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, | ||
44 | [NF_INET_LOCAL_OUT] = nft_ipv6_output, | 56 | [NF_INET_LOCAL_OUT] = nft_ipv6_output, |
57 | [NF_INET_FORWARD] = nft_do_chain_ipv6, | ||
58 | [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, | ||
59 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, | ||
45 | }, | 60 | }, |
46 | }; | 61 | }; |
47 | 62 | ||
@@ -73,22 +88,6 @@ static struct pernet_operations nf_tables_ipv6_net_ops = { | |||
73 | .exit = nf_tables_ipv6_exit_net, | 88 | .exit = nf_tables_ipv6_exit_net, |
74 | }; | 89 | }; |
75 | 90 | ||
76 | static unsigned int | ||
77 | nft_do_chain_ipv6(const struct nf_hook_ops *ops, | ||
78 | struct sk_buff *skb, | ||
79 | const struct net_device *in, | ||
80 | const struct net_device *out, | ||
81 | int (*okfn)(struct sk_buff *)) | ||
82 | { | ||
83 | struct nft_pktinfo pkt; | ||
84 | |||
85 | /* malformed packet, drop it */ | ||
86 | if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0) | ||
87 | return NF_DROP; | ||
88 | |||
89 | return nft_do_chain_pktinfo(&pkt, ops); | ||
90 | } | ||
91 | |||
92 | static struct nf_chain_type filter_ipv6 = { | 91 | static struct nf_chain_type filter_ipv6 = { |
93 | .family = NFPROTO_IPV6, | 92 | .family = NFPROTO_IPV6, |
94 | .name = "filter", | 93 | .name = "filter", |
@@ -98,13 +97,6 @@ static struct nf_chain_type filter_ipv6 = { | |||
98 | (1 << NF_INET_FORWARD) | | 97 | (1 << NF_INET_FORWARD) | |
99 | (1 << NF_INET_PRE_ROUTING) | | 98 | (1 << NF_INET_PRE_ROUTING) | |
100 | (1 << NF_INET_POST_ROUTING), | 99 | (1 << NF_INET_POST_ROUTING), |
101 | .fn = { | ||
102 | [NF_INET_LOCAL_IN] = nft_do_chain_ipv6, | ||
103 | [NF_INET_LOCAL_OUT] = nft_ipv6_output, | ||
104 | [NF_INET_FORWARD] = nft_do_chain_ipv6, | ||
105 | [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6, | ||
106 | [NF_INET_POST_ROUTING] = nft_do_chain_ipv6, | ||
107 | }, | ||
108 | }; | 100 | }; |
109 | 101 | ||
110 | static int __init nf_tables_ipv6_init(void) | 102 | static int __init nf_tables_ipv6_init(void) |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 1fcef1ec1dc1..d568626bc0f9 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -927,9 +927,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
927 | if (hooknum >= afi->nhooks) | 927 | if (hooknum >= afi->nhooks) |
928 | return -EINVAL; | 928 | return -EINVAL; |
929 | 929 | ||
930 | hookfn = chain_type[family][type]->fn[hooknum]; | 930 | if (!(chain_type[family][type]->hook_mask & (1 << hooknum))) |
931 | if (hookfn == NULL) | ||
932 | return -EOPNOTSUPP; | 931 | return -EOPNOTSUPP; |
932 | hookfn = chain_type[family][type]->fn[hooknum]; | ||
933 | 933 | ||
934 | basechain = kzalloc(sizeof(*basechain), GFP_KERNEL); | 934 | basechain = kzalloc(sizeof(*basechain), GFP_KERNEL); |
935 | if (basechain == NULL) | 935 | if (basechain == NULL) |
@@ -944,9 +944,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
944 | ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM])); | 944 | ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM])); |
945 | ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY])); | 945 | ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY])); |
946 | ops->priv = chain; | 946 | ops->priv = chain; |
947 | ops->hook = hookfn; | 947 | ops->hook = afi->hooks[ops->hooknum]; |
948 | if (afi->hooks[ops->hooknum]) | 948 | if (hookfn) |
949 | ops->hook = afi->hooks[ops->hooknum]; | 949 | ops->hook = hookfn; |
950 | 950 | ||
951 | chain->flags |= NFT_BASE_CHAIN; | 951 | chain->flags |= NFT_BASE_CHAIN; |
952 | 952 | ||