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

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 <wenxu@ucloud.cn>
Reviewed-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

wenxu and committed by
Pablo Neira Ayuso
30e103fe 6aedd14b

+207 -53
+44
include/net/netfilter/nft_meta.h
··· 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
+6
net/bridge/netfilter/Kconfig
··· 9 9 bool "Ethernet Bridge nf_tables support" 10 10 11 11 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 + 12 18 config NFT_BRIDGE_REJECT 13 19 tristate "Netfilter nf_tables bridge reject support" 14 20 depends on NFT_REJECT && NFT_REJECT_IPV4 && NFT_REJECT_IPV6
+1
net/bridge/netfilter/Makefile
··· 3 3 # Makefile for the netfilter modules for Link Layer filtering on a bridge. 4 4 # 5 5 6 + obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o 6 7 obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o 7 8 8 9 # connection tracking
+127
net/bridge/netfilter/nft_meta_bridge.c
··· 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 <wenxu@ucloud.cn>"); 127 + MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "meta");
+1
net/netfilter/nf_tables_core.c
··· 19 19 #include <net/netfilter/nf_tables_core.h> 20 20 #include <net/netfilter/nf_tables.h> 21 21 #include <net/netfilter/nf_log.h> 22 + #include <net/netfilter/nft_meta.h> 22 23 23 24 static noinline void __nft_trace_packet(struct nft_traceinfo *info, 24 25 const struct nft_chain *chain,
+28 -53
net/netfilter/nft_meta.c
··· 21 21 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */ 22 22 #include <net/netfilter/nf_tables.h> 23 23 #include <net/netfilter/nf_tables_core.h> 24 + #include <net/netfilter/nft_meta.h> 24 25 25 26 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */ 26 27 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 - 35 28 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state); 36 - 37 - #ifdef CONFIG_NF_TABLES_BRIDGE 38 - #include "../bridge/br_private.h" 39 - #endif 40 29 41 30 void nft_meta_get_eval(const struct nft_expr *expr, 42 31 struct nft_regs *regs, ··· 36 47 const struct net_device *in = nft_in(pkt), *out = nft_out(pkt); 37 48 struct sock *sk; 38 49 u32 *dest = &regs->data[priv->dreg]; 39 - #ifdef CONFIG_NF_TABLES_BRIDGE 40 - const struct net_bridge_port *p; 41 - #endif 42 50 43 51 switch (priv->key) { 44 52 case NFT_META_LEN: ··· 215 229 nft_reg_store8(dest, secpath_exists(skb)); 216 230 break; 217 231 #endif 218 - #ifdef CONFIG_NF_TABLES_BRIDGE 219 - case NFT_META_BRI_IIFNAME: 220 - if (in == NULL || (p = br_port_get_rcu(in)) == NULL) 221 - goto err; 222 - strncpy((char *)dest, p->br->dev->name, IFNAMSIZ); 223 - return; 224 - case NFT_META_BRI_OIFNAME: 225 - if (out == NULL || (p = br_port_get_rcu(out)) == NULL) 226 - goto err; 227 - strncpy((char *)dest, p->br->dev->name, IFNAMSIZ); 228 - return; 229 - #endif 230 232 case NFT_META_IIFKIND: 231 233 if (in == NULL || in->rtnl_link_ops == NULL) 232 234 goto err; ··· 234 260 err: 235 261 regs->verdict.code = NFT_BREAK; 236 262 } 263 + EXPORT_SYMBOL_GPL(nft_meta_get_eval); 237 264 238 - static void nft_meta_set_eval(const struct nft_expr *expr, 239 - struct nft_regs *regs, 240 - const struct nft_pktinfo *pkt) 265 + void nft_meta_set_eval(const struct nft_expr *expr, 266 + struct nft_regs *regs, 267 + const struct nft_pktinfo *pkt) 241 268 { 242 269 const struct nft_meta *meta = nft_expr_priv(expr); 243 270 struct sk_buff *skb = pkt->skb; ··· 275 300 WARN_ON(1); 276 301 } 277 302 } 303 + EXPORT_SYMBOL_GPL(nft_meta_set_eval); 278 304 279 - static const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { 305 + const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { 280 306 [NFTA_META_DREG] = { .type = NLA_U32 }, 281 307 [NFTA_META_KEY] = { .type = NLA_U32 }, 282 308 [NFTA_META_SREG] = { .type = NLA_U32 }, 283 309 }; 310 + EXPORT_SYMBOL_GPL(nft_meta_policy); 284 311 285 - static int nft_meta_get_init(const struct nft_ctx *ctx, 286 - const struct nft_expr *expr, 287 - const struct nlattr * const tb[]) 312 + int nft_meta_get_init(const struct nft_ctx *ctx, 313 + const struct nft_expr *expr, 314 + const struct nlattr * const tb[]) 288 315 { 289 316 struct nft_meta *priv = nft_expr_priv(expr); 290 317 unsigned int len; ··· 337 360 len = sizeof(u8); 338 361 break; 339 362 #endif 340 - #ifdef CONFIG_NF_TABLES_BRIDGE 341 - case NFT_META_BRI_IIFNAME: 342 - case NFT_META_BRI_OIFNAME: 343 - if (ctx->family != NFPROTO_BRIDGE) 344 - return -EOPNOTSUPP; 345 - len = IFNAMSIZ; 346 - break; 347 - #endif 348 363 default: 349 364 return -EOPNOTSUPP; 350 365 } ··· 345 376 return nft_validate_register_store(ctx, priv->dreg, NULL, 346 377 NFT_DATA_VALUE, len); 347 378 } 379 + EXPORT_SYMBOL_GPL(nft_meta_get_init); 348 380 349 381 static int nft_meta_get_validate(const struct nft_ctx *ctx, 350 382 const struct nft_expr *expr, ··· 379 409 #endif 380 410 } 381 411 382 - static int nft_meta_set_validate(const struct nft_ctx *ctx, 383 - const struct nft_expr *expr, 384 - const struct nft_data **data) 412 + int nft_meta_set_validate(const struct nft_ctx *ctx, 413 + const struct nft_expr *expr, 414 + const struct nft_data **data) 385 415 { 386 416 struct nft_meta *priv = nft_expr_priv(expr); 387 417 unsigned int hooks; ··· 407 437 408 438 return nft_chain_validate_hooks(ctx->chain, hooks); 409 439 } 440 + EXPORT_SYMBOL_GPL(nft_meta_set_validate); 410 441 411 - static int nft_meta_set_init(const struct nft_ctx *ctx, 412 - const struct nft_expr *expr, 413 - const struct nlattr * const tb[]) 442 + int nft_meta_set_init(const struct nft_ctx *ctx, 443 + const struct nft_expr *expr, 444 + const struct nlattr * const tb[]) 414 445 { 415 446 struct nft_meta *priv = nft_expr_priv(expr); 416 447 unsigned int len; ··· 446 475 447 476 return 0; 448 477 } 478 + EXPORT_SYMBOL_GPL(nft_meta_set_init); 449 479 450 - static int nft_meta_get_dump(struct sk_buff *skb, 451 - const struct nft_expr *expr) 480 + int nft_meta_get_dump(struct sk_buff *skb, 481 + const struct nft_expr *expr) 452 482 { 453 483 const struct nft_meta *priv = nft_expr_priv(expr); 454 484 ··· 462 490 nla_put_failure: 463 491 return -1; 464 492 } 493 + EXPORT_SYMBOL_GPL(nft_meta_get_dump); 465 494 466 - static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr) 495 + int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr) 467 496 { 468 497 const struct nft_meta *priv = nft_expr_priv(expr); 469 498 ··· 478 505 nla_put_failure: 479 506 return -1; 480 507 } 508 + EXPORT_SYMBOL_GPL(nft_meta_set_dump); 481 509 482 - static void nft_meta_set_destroy(const struct nft_ctx *ctx, 483 - const struct nft_expr *expr) 510 + void nft_meta_set_destroy(const struct nft_ctx *ctx, 511 + const struct nft_expr *expr) 484 512 { 485 513 const struct nft_meta *priv = nft_expr_priv(expr); 486 514 487 515 if (priv->key == NFT_META_NFTRACE) 488 516 static_branch_dec(&nft_trace_enabled); 489 517 } 518 + EXPORT_SYMBOL_GPL(nft_meta_set_destroy); 490 519 491 520 static const struct nft_expr_ops nft_meta_get_ops = { 492 521 .type = &nft_meta_type,