-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
netfilter: nf_tables: Add meta expression key for bridge interface name
NFT_META_BRI_IIFNAME to get packet input bridge interface name NFT_META_BRI_OIFNAME to get packet output bridge interface name Such meta key are accessible only through NFPROTO_BRIDGE family, on a dedicated nft meta module: nft_meta_bridge. Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
- Loading branch information
Tomasz Bursztyka
authored and
Pablo Neira Ayuso
committed
Apr 24, 2014
1 parent
aa45660
commit f5efc69
Showing
5 changed files
with
158 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright (c) 2014 Intel Corporation | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/netlink.h> | ||
#include <linux/netfilter.h> | ||
#include <linux/netfilter/nf_tables.h> | ||
#include <net/netfilter/nf_tables.h> | ||
#include <net/netfilter/nft_meta.h> | ||
|
||
#include "../br_private.h" | ||
|
||
static void nft_meta_bridge_get_eval(const struct nft_expr *expr, | ||
struct nft_data data[NFT_REG_MAX + 1], | ||
const struct nft_pktinfo *pkt) | ||
{ | ||
const struct nft_meta *priv = nft_expr_priv(expr); | ||
const struct net_device *in = pkt->in, *out = pkt->out; | ||
struct nft_data *dest = &data[priv->dreg]; | ||
const struct net_bridge_port *p; | ||
|
||
switch (priv->key) { | ||
case NFT_META_BRI_IIFNAME: | ||
if (in == NULL || (p = br_port_get_rcu(in)) == NULL) | ||
goto err; | ||
break; | ||
case NFT_META_BRI_OIFNAME: | ||
if (out == NULL || (p = br_port_get_rcu(out)) == NULL) | ||
goto err; | ||
break; | ||
default: | ||
goto out; | ||
} | ||
|
||
strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data)); | ||
return; | ||
out: | ||
return nft_meta_get_eval(expr, data, pkt); | ||
err: | ||
data[NFT_REG_VERDICT].verdict = NFT_BREAK; | ||
} | ||
|
||
static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, | ||
const struct nft_expr *expr, | ||
const struct nlattr * const tb[]) | ||
{ | ||
struct nft_meta *priv = nft_expr_priv(expr); | ||
int err; | ||
|
||
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); | ||
switch (priv->key) { | ||
case NFT_META_BRI_IIFNAME: | ||
case NFT_META_BRI_OIFNAME: | ||
break; | ||
default: | ||
return nft_meta_get_init(ctx, expr, tb); | ||
} | ||
|
||
priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); | ||
err = nft_validate_output_register(priv->dreg); | ||
if (err < 0) | ||
return err; | ||
|
||
err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE); | ||
if (err < 0) | ||
return err; | ||
|
||
return 0; | ||
} | ||
|
||
static struct nft_expr_type nft_meta_bridge_type; | ||
static const struct nft_expr_ops nft_meta_bridge_get_ops = { | ||
.type = &nft_meta_bridge_type, | ||
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), | ||
.eval = nft_meta_bridge_get_eval, | ||
.init = nft_meta_bridge_get_init, | ||
.dump = nft_meta_get_dump, | ||
}; | ||
|
||
static const struct nft_expr_ops nft_meta_bridge_set_ops = { | ||
.type = &nft_meta_bridge_type, | ||
.size = NFT_EXPR_SIZE(sizeof(struct nft_meta)), | ||
.eval = nft_meta_set_eval, | ||
.init = nft_meta_set_init, | ||
.dump = nft_meta_set_dump, | ||
}; | ||
|
||
static const struct nft_expr_ops * | ||
nft_meta_bridge_select_ops(const struct nft_ctx *ctx, | ||
const struct nlattr * const tb[]) | ||
{ | ||
if (tb[NFTA_META_KEY] == NULL) | ||
return ERR_PTR(-EINVAL); | ||
|
||
if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG]) | ||
return ERR_PTR(-EINVAL); | ||
|
||
if (tb[NFTA_META_DREG]) | ||
return &nft_meta_bridge_get_ops; | ||
|
||
if (tb[NFTA_META_SREG]) | ||
return &nft_meta_bridge_set_ops; | ||
|
||
return ERR_PTR(-EINVAL); | ||
} | ||
|
||
static struct nft_expr_type nft_meta_bridge_type __read_mostly = { | ||
.family = NFPROTO_BRIDGE, | ||
.name = "meta", | ||
.select_ops = &nft_meta_bridge_select_ops, | ||
.policy = nft_meta_policy, | ||
.maxattr = NFTA_META_MAX, | ||
.owner = THIS_MODULE, | ||
}; | ||
|
||
static int __init nft_meta_bridge_module_init(void) | ||
{ | ||
return nft_register_expr(&nft_meta_bridge_type); | ||
} | ||
|
||
static void __exit nft_meta_bridge_module_exit(void) | ||
{ | ||
nft_unregister_expr(&nft_meta_bridge_type); | ||
} | ||
|
||
module_init(nft_meta_bridge_module_init); | ||
module_exit(nft_meta_bridge_module_exit); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>"); | ||
MODULE_ALIAS_NFT_AF_EXPR(AF_BRIDGE, "meta"); |