Skip to content

Commit 30e103f

Browse files
wenxuummakynes
authored andcommitted
netfilter: nft_meta: move bridge meta keys into nft_meta_bridge
Separate bridge meta key from nft_meta to meta_bridge to avoid a dependency between the bridge module and nft_meta when using the bridge API available through include/linux/if_bridge.h Signed-off-by: wenxu <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 6aedd14 commit 30e103f

File tree

6 files changed

+207
-53
lines changed

6 files changed

+207
-53
lines changed

include/net/netfilter/nft_meta.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _NFT_META_H_
3+
#define _NFT_META_H_
4+
5+
struct nft_meta {
6+
enum nft_meta_keys key:8;
7+
union {
8+
enum nft_registers dreg:8;
9+
enum nft_registers sreg:8;
10+
};
11+
};
12+
13+
extern const struct nla_policy nft_meta_policy[];
14+
15+
int nft_meta_get_init(const struct nft_ctx *ctx,
16+
const struct nft_expr *expr,
17+
const struct nlattr * const tb[]);
18+
19+
int nft_meta_set_init(const struct nft_ctx *ctx,
20+
const struct nft_expr *expr,
21+
const struct nlattr * const tb[]);
22+
23+
int nft_meta_get_dump(struct sk_buff *skb,
24+
const struct nft_expr *expr);
25+
26+
int nft_meta_set_dump(struct sk_buff *skb,
27+
const struct nft_expr *expr);
28+
29+
void nft_meta_get_eval(const struct nft_expr *expr,
30+
struct nft_regs *regs,
31+
const struct nft_pktinfo *pkt);
32+
33+
void nft_meta_set_eval(const struct nft_expr *expr,
34+
struct nft_regs *regs,
35+
const struct nft_pktinfo *pkt);
36+
37+
void nft_meta_set_destroy(const struct nft_ctx *ctx,
38+
const struct nft_expr *expr);
39+
40+
int nft_meta_set_validate(const struct nft_ctx *ctx,
41+
const struct nft_expr *expr,
42+
const struct nft_data **data);
43+
44+
#endif

net/bridge/netfilter/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ menuconfig NF_TABLES_BRIDGE
99
bool "Ethernet Bridge nf_tables support"
1010

1111
if NF_TABLES_BRIDGE
12+
13+
config NFT_BRIDGE_META
14+
tristate "Netfilter nf_table bridge meta support"
15+
help
16+
Add support for bridge dedicated meta key.
17+
1218
config NFT_BRIDGE_REJECT
1319
tristate "Netfilter nf_tables bridge reject support"
1420
depends on NFT_REJECT && NFT_REJECT_IPV4 && NFT_REJECT_IPV6

net/bridge/netfilter/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Makefile for the netfilter modules for Link Layer filtering on a bridge.
44
#
55

6+
obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o
67
obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o
78

89
# connection tracking
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/kernel.h>
3+
#include <linux/init.h>
4+
#include <linux/module.h>
5+
#include <linux/netlink.h>
6+
#include <linux/netfilter.h>
7+
#include <linux/netfilter/nf_tables.h>
8+
#include <net/netfilter/nf_tables.h>
9+
#include <net/netfilter/nft_meta.h>
10+
11+
#include "../br_private.h"
12+
13+
static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
14+
struct nft_regs *regs,
15+
const struct nft_pktinfo *pkt)
16+
{
17+
const struct nft_meta *priv = nft_expr_priv(expr);
18+
const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
19+
u32 *dest = &regs->data[priv->dreg];
20+
const struct net_bridge_port *p;
21+
22+
switch (priv->key) {
23+
case NFT_META_BRI_IIFNAME:
24+
if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
25+
goto err;
26+
break;
27+
case NFT_META_BRI_OIFNAME:
28+
if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
29+
goto err;
30+
break;
31+
default:
32+
goto out;
33+
}
34+
35+
strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
36+
return;
37+
out:
38+
return nft_meta_get_eval(expr, regs, pkt);
39+
err:
40+
regs->verdict.code = NFT_BREAK;
41+
}
42+
43+
static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
44+
const struct nft_expr *expr,
45+
const struct nlattr * const tb[])
46+
{
47+
struct nft_meta *priv = nft_expr_priv(expr);
48+
unsigned int len;
49+
50+
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
51+
switch (priv->key) {
52+
case NFT_META_BRI_IIFNAME:
53+
case NFT_META_BRI_OIFNAME:
54+
len = IFNAMSIZ;
55+
break;
56+
default:
57+
return nft_meta_get_init(ctx, expr, tb);
58+
}
59+
60+
priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
61+
return nft_validate_register_store(ctx, priv->dreg, NULL,
62+
NFT_DATA_VALUE, len);
63+
}
64+
65+
static struct nft_expr_type nft_meta_bridge_type;
66+
static const struct nft_expr_ops nft_meta_bridge_get_ops = {
67+
.type = &nft_meta_bridge_type,
68+
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
69+
.eval = nft_meta_bridge_get_eval,
70+
.init = nft_meta_bridge_get_init,
71+
.dump = nft_meta_get_dump,
72+
};
73+
74+
static const struct nft_expr_ops nft_meta_bridge_set_ops = {
75+
.type = &nft_meta_bridge_type,
76+
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
77+
.eval = nft_meta_set_eval,
78+
.init = nft_meta_set_init,
79+
.destroy = nft_meta_set_destroy,
80+
.dump = nft_meta_set_dump,
81+
.validate = nft_meta_set_validate,
82+
};
83+
84+
static const struct nft_expr_ops *
85+
nft_meta_bridge_select_ops(const struct nft_ctx *ctx,
86+
const struct nlattr * const tb[])
87+
{
88+
if (tb[NFTA_META_KEY] == NULL)
89+
return ERR_PTR(-EINVAL);
90+
91+
if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG])
92+
return ERR_PTR(-EINVAL);
93+
94+
if (tb[NFTA_META_DREG])
95+
return &nft_meta_bridge_get_ops;
96+
97+
if (tb[NFTA_META_SREG])
98+
return &nft_meta_bridge_set_ops;
99+
100+
return ERR_PTR(-EINVAL);
101+
}
102+
103+
static struct nft_expr_type nft_meta_bridge_type __read_mostly = {
104+
.family = NFPROTO_BRIDGE,
105+
.name = "meta",
106+
.select_ops = nft_meta_bridge_select_ops,
107+
.policy = nft_meta_policy,
108+
.maxattr = NFTA_META_MAX,
109+
.owner = THIS_MODULE,
110+
};
111+
112+
static int __init nft_meta_bridge_module_init(void)
113+
{
114+
return nft_register_expr(&nft_meta_bridge_type);
115+
}
116+
117+
static void __exit nft_meta_bridge_module_exit(void)
118+
{
119+
nft_unregister_expr(&nft_meta_bridge_type);
120+
}
121+
122+
module_init(nft_meta_bridge_module_init);
123+
module_exit(nft_meta_bridge_module_exit);
124+
125+
MODULE_LICENSE("GPL");
126+
MODULE_AUTHOR("wenxu <[email protected]>");
127+
MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "meta");

net/netfilter/nf_tables_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <net/netfilter/nf_tables_core.h>
2020
#include <net/netfilter/nf_tables.h>
2121
#include <net/netfilter/nf_log.h>
22+
#include <net/netfilter/nft_meta.h>
2223

2324
static noinline void __nft_trace_packet(struct nft_traceinfo *info,
2425
const struct nft_chain *chain,

net/netfilter/nft_meta.c

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,12 @@
2121
#include <net/tcp_states.h> /* for TCP_TIME_WAIT */
2222
#include <net/netfilter/nf_tables.h>
2323
#include <net/netfilter/nf_tables_core.h>
24+
#include <net/netfilter/nft_meta.h>
2425

2526
#include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
2627

27-
struct nft_meta {
28-
enum nft_meta_keys key:8;
29-
union {
30-
enum nft_registers dreg:8;
31-
enum nft_registers sreg:8;
32-
};
33-
};
34-
3528
static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
3629

37-
#ifdef CONFIG_NF_TABLES_BRIDGE
38-
#include "../bridge/br_private.h"
39-
#endif
40-
4130
void nft_meta_get_eval(const struct nft_expr *expr,
4231
struct nft_regs *regs,
4332
const struct nft_pktinfo *pkt)
@@ -47,9 +36,6 @@ void nft_meta_get_eval(const struct nft_expr *expr,
4736
const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
4837
struct sock *sk;
4938
u32 *dest = &regs->data[priv->dreg];
50-
#ifdef CONFIG_NF_TABLES_BRIDGE
51-
const struct net_bridge_port *p;
52-
#endif
5339

5440
switch (priv->key) {
5541
case NFT_META_LEN:
@@ -228,18 +214,6 @@ void nft_meta_get_eval(const struct nft_expr *expr,
228214
case NFT_META_SECPATH:
229215
nft_reg_store8(dest, secpath_exists(skb));
230216
break;
231-
#endif
232-
#ifdef CONFIG_NF_TABLES_BRIDGE
233-
case NFT_META_BRI_IIFNAME:
234-
if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
235-
goto err;
236-
strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
237-
return;
238-
case NFT_META_BRI_OIFNAME:
239-
if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
240-
goto err;
241-
strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
242-
return;
243217
#endif
244218
case NFT_META_IIFKIND:
245219
if (in == NULL || in->rtnl_link_ops == NULL)
@@ -260,10 +234,11 @@ void nft_meta_get_eval(const struct nft_expr *expr,
260234
err:
261235
regs->verdict.code = NFT_BREAK;
262236
}
237+
EXPORT_SYMBOL_GPL(nft_meta_get_eval);
263238

264-
static void nft_meta_set_eval(const struct nft_expr *expr,
265-
struct nft_regs *regs,
266-
const struct nft_pktinfo *pkt)
239+
void nft_meta_set_eval(const struct nft_expr *expr,
240+
struct nft_regs *regs,
241+
const struct nft_pktinfo *pkt)
267242
{
268243
const struct nft_meta *meta = nft_expr_priv(expr);
269244
struct sk_buff *skb = pkt->skb;
@@ -300,16 +275,18 @@ static void nft_meta_set_eval(const struct nft_expr *expr,
300275
WARN_ON(1);
301276
}
302277
}
278+
EXPORT_SYMBOL_GPL(nft_meta_set_eval);
303279

304-
static const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
280+
const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
305281
[NFTA_META_DREG] = { .type = NLA_U32 },
306282
[NFTA_META_KEY] = { .type = NLA_U32 },
307283
[NFTA_META_SREG] = { .type = NLA_U32 },
308284
};
285+
EXPORT_SYMBOL_GPL(nft_meta_policy);
309286

310-
static int nft_meta_get_init(const struct nft_ctx *ctx,
311-
const struct nft_expr *expr,
312-
const struct nlattr * const tb[])
287+
int nft_meta_get_init(const struct nft_ctx *ctx,
288+
const struct nft_expr *expr,
289+
const struct nlattr * const tb[])
313290
{
314291
struct nft_meta *priv = nft_expr_priv(expr);
315292
unsigned int len;
@@ -359,14 +336,6 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
359336
case NFT_META_SECPATH:
360337
len = sizeof(u8);
361338
break;
362-
#endif
363-
#ifdef CONFIG_NF_TABLES_BRIDGE
364-
case NFT_META_BRI_IIFNAME:
365-
case NFT_META_BRI_OIFNAME:
366-
if (ctx->family != NFPROTO_BRIDGE)
367-
return -EOPNOTSUPP;
368-
len = IFNAMSIZ;
369-
break;
370339
#endif
371340
default:
372341
return -EOPNOTSUPP;
@@ -376,6 +345,7 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
376345
return nft_validate_register_store(ctx, priv->dreg, NULL,
377346
NFT_DATA_VALUE, len);
378347
}
348+
EXPORT_SYMBOL_GPL(nft_meta_get_init);
379349

380350
static int nft_meta_get_validate(const struct nft_ctx *ctx,
381351
const struct nft_expr *expr,
@@ -409,9 +379,9 @@ static int nft_meta_get_validate(const struct nft_ctx *ctx,
409379
#endif
410380
}
411381

412-
static int nft_meta_set_validate(const struct nft_ctx *ctx,
413-
const struct nft_expr *expr,
414-
const struct nft_data **data)
382+
int nft_meta_set_validate(const struct nft_ctx *ctx,
383+
const struct nft_expr *expr,
384+
const struct nft_data **data)
415385
{
416386
struct nft_meta *priv = nft_expr_priv(expr);
417387
unsigned int hooks;
@@ -437,10 +407,11 @@ static int nft_meta_set_validate(const struct nft_ctx *ctx,
437407

438408
return nft_chain_validate_hooks(ctx->chain, hooks);
439409
}
410+
EXPORT_SYMBOL_GPL(nft_meta_set_validate);
440411

441-
static int nft_meta_set_init(const struct nft_ctx *ctx,
442-
const struct nft_expr *expr,
443-
const struct nlattr * const tb[])
412+
int nft_meta_set_init(const struct nft_ctx *ctx,
413+
const struct nft_expr *expr,
414+
const struct nlattr * const tb[])
444415
{
445416
struct nft_meta *priv = nft_expr_priv(expr);
446417
unsigned int len;
@@ -475,9 +446,10 @@ static int nft_meta_set_init(const struct nft_ctx *ctx,
475446

476447
return 0;
477448
}
449+
EXPORT_SYMBOL_GPL(nft_meta_set_init);
478450

479-
static int nft_meta_get_dump(struct sk_buff *skb,
480-
const struct nft_expr *expr)
451+
int nft_meta_get_dump(struct sk_buff *skb,
452+
const struct nft_expr *expr)
481453
{
482454
const struct nft_meta *priv = nft_expr_priv(expr);
483455

@@ -490,8 +462,9 @@ static int nft_meta_get_dump(struct sk_buff *skb,
490462
nla_put_failure:
491463
return -1;
492464
}
465+
EXPORT_SYMBOL_GPL(nft_meta_get_dump);
493466

494-
static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
467+
int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
495468
{
496469
const struct nft_meta *priv = nft_expr_priv(expr);
497470

@@ -505,15 +478,17 @@ static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
505478
nla_put_failure:
506479
return -1;
507480
}
481+
EXPORT_SYMBOL_GPL(nft_meta_set_dump);
508482

509-
static void nft_meta_set_destroy(const struct nft_ctx *ctx,
510-
const struct nft_expr *expr)
483+
void nft_meta_set_destroy(const struct nft_ctx *ctx,
484+
const struct nft_expr *expr)
511485
{
512486
const struct nft_meta *priv = nft_expr_priv(expr);
513487

514488
if (priv->key == NFT_META_NFTRACE)
515489
static_branch_dec(&nft_trace_enabled);
516490
}
491+
EXPORT_SYMBOL_GPL(nft_meta_set_destroy);
517492

518493
static const struct nft_expr_ops nft_meta_get_ops = {
519494
.type = &nft_meta_type,

0 commit comments

Comments
 (0)