aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-10-13 18:06:06 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2013-10-14 12:00:04 -0400
commit0ca743a5599199152a31a7146b83213c786c2eb2 (patch)
treefd5cd87e1e1cf3f43d5868304c7c45f9bf11cef5 /include/net
parent9370761c56b66aa5c65e069a7b010111a025018d (diff)
netfilter: nf_tables: add compatibility layer for x_tables
This patch adds the x_tables compatibility layer. This allows you to use existing x_tables matches and targets from nf_tables. This compatibility later allows us to use existing matches/targets for features that are still missing in nf_tables. We can progressively replace them with native nf_tables extensions. It also provides the userspace compatibility software that allows you to express the rule-set using the iptables syntax but using the nf_tables kernel components. In order to get this compatibility layer working, I've done the following things: * add NFNL_SUBSYS_NFT_COMPAT: this new nfnetlink subsystem is used to query the x_tables match/target revision, so we don't need to use the native x_table getsockopt interface. * emulate xt structures: this required extending the struct nft_pktinfo to include the fragment offset, which is already obtained from ip[6]_tables and that is used by some matches/targets. * add support for default policy to base chains, required to emulate x_tables. * add NFTA_CHAIN_USE attribute to obtain the number of references to chains, required by x_tables emulation. * add chain packet/byte counters using per-cpu. * support 32-64 bits compat. For historical reasons, this patch includes the following patches that were posted in the netfilter-devel mailing list. From Pablo Neira Ayuso: * nf_tables: add default policy to base chains * netfilter: nf_tables: add NFTA_CHAIN_USE attribute * nf_tables: nft_compat: private data of target and matches in contiguous area * nf_tables: validate hooks for compat match/target * nf_tables: nft_compat: release cached matches/targets * nf_tables: x_tables support as a compile time option * nf_tables: fix alias for xtables over nftables module * nf_tables: add packet and byte counters per chain * nf_tables: fix per-chain counter stats if no counters are passed * nf_tables: don't bump chain stats * nf_tables: add protocol and flags for xtables over nf_tables * nf_tables: add ip[6]t_entry emulation * nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6] * nf_tables: support 32bits-64bits x_tables compat * nf_tables: fix compilation if CONFIG_COMPAT is disabled From Patrick McHardy: * nf_tables: move policy to struct nft_base_chain * nf_tables: send notifications for base chain policy changes From Alexander Primak: * nf_tables: remove the duplicate NF_INET_LOCAL_OUT From Nicolas Dichtel: * nf_tables: fix compilation when nf-netlink is a module Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/netfilter/nf_tables.h44
-rw-r--r--include/net/netfilter/nf_tables_ipv4.h23
-rw-r--r--include/net/netfilter/nf_tables_ipv6.h30
3 files changed, 90 insertions, 7 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 8403f7f52e81..a68f45f0fe2e 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/netfilter.h> 5#include <linux/netfilter.h>
6#include <linux/netfilter/x_tables.h>
6#include <linux/netfilter/nf_tables.h> 7#include <linux/netfilter/nf_tables.h>
7#include <net/netlink.h> 8#include <net/netlink.h>
8 9
@@ -15,8 +16,23 @@ struct nft_pktinfo {
15 u8 hooknum; 16 u8 hooknum;
16 u8 nhoff; 17 u8 nhoff;
17 u8 thoff; 18 u8 thoff;
19 /* for x_tables compatibility */
20 struct xt_action_param xt;
18}; 21};
19 22
23static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
24 const struct nf_hook_ops *ops,
25 struct sk_buff *skb,
26 const struct net_device *in,
27 const struct net_device *out)
28{
29 pkt->skb = skb;
30 pkt->in = pkt->xt.in = in;
31 pkt->out = pkt->xt.out = out;
32 pkt->hooknum = pkt->xt.hooknum = ops->hooknum;
33 pkt->xt.family = ops->pf;
34}
35
20struct nft_data { 36struct nft_data {
21 union { 37 union {
22 u32 data[4]; 38 u32 data[4];
@@ -57,6 +73,7 @@ static inline void nft_data_debug(const struct nft_data *data)
57 * @afi: address family info 73 * @afi: address family info
58 * @table: the table the chain is contained in 74 * @table: the table the chain is contained in
59 * @chain: the chain the rule is contained in 75 * @chain: the chain the rule is contained in
76 * @nla: netlink attributes
60 */ 77 */
61struct nft_ctx { 78struct nft_ctx {
62 const struct sk_buff *skb; 79 const struct sk_buff *skb;
@@ -64,6 +81,7 @@ struct nft_ctx {
64 const struct nft_af_info *afi; 81 const struct nft_af_info *afi;
65 const struct nft_table *table; 82 const struct nft_table *table;
66 const struct nft_chain *chain; 83 const struct nft_chain *chain;
84 const struct nlattr * const *nla;
67}; 85};
68 86
69struct nft_data_desc { 87struct nft_data_desc {
@@ -235,7 +253,8 @@ extern void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
235 * @maxattr: highest netlink attribute number 253 * @maxattr: highest netlink attribute number
236 */ 254 */
237struct nft_expr_type { 255struct nft_expr_type {
238 const struct nft_expr_ops *(*select_ops)(const struct nlattr * const tb[]); 256 const struct nft_expr_ops *(*select_ops)(const struct nft_ctx *,
257 const struct nlattr * const tb[]);
239 const struct nft_expr_ops *ops; 258 const struct nft_expr_ops *ops;
240 struct list_head list; 259 struct list_head list;
241 const char *name; 260 const char *name;
@@ -253,6 +272,8 @@ struct nft_expr_type {
253 * @destroy: destruction function 272 * @destroy: destruction function
254 * @dump: function to dump parameters 273 * @dump: function to dump parameters
255 * @type: expression type 274 * @type: expression type
275 * @validate: validate expression, called during loop detection
276 * @data: extra data to attach to this expression operation
256 */ 277 */
257struct nft_expr; 278struct nft_expr;
258struct nft_expr_ops { 279struct nft_expr_ops {
@@ -267,8 +288,11 @@ struct nft_expr_ops {
267 void (*destroy)(const struct nft_expr *expr); 288 void (*destroy)(const struct nft_expr *expr);
268 int (*dump)(struct sk_buff *skb, 289 int (*dump)(struct sk_buff *skb,
269 const struct nft_expr *expr); 290 const struct nft_expr *expr);
270 const struct nft_data * (*get_verdict)(const struct nft_expr *expr); 291 int (*validate)(const struct nft_ctx *ctx,
292 const struct nft_expr *expr,
293 const struct nft_data **data);
271 const struct nft_expr_type *type; 294 const struct nft_expr_type *type;
295 void *data;
272}; 296};
273 297
274#define NFT_EXPR_MAXATTR 16 298#define NFT_EXPR_MAXATTR 16
@@ -368,16 +392,25 @@ enum nft_chain_type {
368 NFT_CHAIN_T_MAX 392 NFT_CHAIN_T_MAX
369}; 393};
370 394
395struct nft_stats {
396 u64 bytes;
397 u64 pkts;
398};
399
371/** 400/**
372 * struct nft_base_chain - nf_tables base chain 401 * struct nft_base_chain - nf_tables base chain
373 * 402 *
374 * @ops: netfilter hook ops 403 * @ops: netfilter hook ops
375 * @type: chain type 404 * @type: chain type
405 * @policy: default policy
406 * @stats: per-cpu chain stats
376 * @chain: the chain 407 * @chain: the chain
377 */ 408 */
378struct nft_base_chain { 409struct nft_base_chain {
379 struct nf_hook_ops ops; 410 struct nf_hook_ops ops;
380 enum nft_chain_type type; 411 enum nft_chain_type type;
412 u8 policy;
413 struct nft_stats __percpu *stats;
381 struct nft_chain chain; 414 struct nft_chain chain;
382}; 415};
383 416
@@ -386,11 +419,8 @@ static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai
386 return container_of(chain, struct nft_base_chain, chain); 419 return container_of(chain, struct nft_base_chain, chain);
387} 420}
388 421
389extern unsigned int nft_do_chain(const struct nf_hook_ops *ops, 422extern unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
390 struct sk_buff *skb, 423 const struct nf_hook_ops *ops);
391 const struct net_device *in,
392 const struct net_device *out,
393 int (*okfn)(struct sk_buff *));
394 424
395/** 425/**
396 * struct nft_table - nf_tables table 426 * struct nft_table - nf_tables table
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
new file mode 100644
index 000000000000..1be1c2c197ee
--- /dev/null
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -0,0 +1,23 @@
1#ifndef _NF_TABLES_IPV4_H_
2#define _NF_TABLES_IPV4_H_
3
4#include <net/netfilter/nf_tables.h>
5#include <net/ip.h>
6
7static inline void
8nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
9 const struct nf_hook_ops *ops,
10 struct sk_buff *skb,
11 const struct net_device *in,
12 const struct net_device *out)
13{
14 struct iphdr *ip;
15
16 nft_set_pktinfo(pkt, ops, skb, in, out);
17
18 pkt->xt.thoff = ip_hdrlen(pkt->skb);
19 ip = ip_hdr(pkt->skb);
20 pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
21}
22
23#endif
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
new file mode 100644
index 000000000000..4a9b88a65963
--- /dev/null
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -0,0 +1,30 @@
1#ifndef _NF_TABLES_IPV6_H_
2#define _NF_TABLES_IPV6_H_
3
4#include <linux/netfilter_ipv6/ip6_tables.h>
5#include <net/ipv6.h>
6
7static inline int
8nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
9 const struct nf_hook_ops *ops,
10 struct sk_buff *skb,
11 const struct net_device *in,
12 const struct net_device *out)
13{
14 int protohdr, thoff = 0;
15 unsigned short frag_off;
16
17 nft_set_pktinfo(pkt, ops, skb, in, out);
18
19 protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
20 /* If malformed, drop it */
21 if (protohdr < 0)
22 return -1;
23
24 pkt->xt.thoff = thoff;
25 pkt->xt.fragoff = frag_off;
26
27 return 0;
28}
29
30#endif