* [PATCH 0/5] Add suport for bridge if dev name meta exepression keys @ 2014-03-27 12:47 Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 1/5] netfilter: nf_tables: Stack expression type depending on their family Tomasz Bursztyka ` (5 more replies) 0 siblings, 6 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. I did not factorize nft_meta.c code to reuse nft_meta_select_ops() and nft_meta_bridge_init() At least solutions I had made the code too ugly. Declaring a type for select_ops functions, same for validate_get() one, and have an in-between functions called relevantly by meta_<bridge_>init etc... At least it looks like netfilter stack very rarely does typedef functions so I passed. Last 2 patches are about user-space support. Tomasz Bursztyka (4): kernel: netfilter: nf_tables: Stack expression type depending on their family netfilter: nf_tables: Make meta expression core functions public netfilter: nf_tables: Add meta expression key for bridge interface name libnftnl: meta: Add support for input and output bridge interface name nftables: meta: Add support for input and output bridge interface name -- 1.8.3.2 ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/5] netfilter: nf_tables: Stack expression type depending on their family 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka @ 2014-03-27 12:47 ` Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 2/5] netfilter: nf_tables: Make meta expression core functions public Tomasz Bursztyka ` (4 subsequent siblings) 5 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka To ensure family tight expression gets selected in priority to family agnostic ones. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> --- net/netfilter/nf_tables_api.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index adce01e..128bd9b 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -1094,7 +1094,10 @@ static void nft_ctx_init(struct nft_ctx *ctx, int nft_register_expr(struct nft_expr_type *type) { nfnl_lock(NFNL_SUBSYS_NFTABLES); - list_add_tail(&type->list, &nf_tables_expressions); + if (type->family == NFPROTO_UNSPEC) + list_add_tail(&type->list, &nf_tables_expressions); + else + list_add(&type->list, &nf_tables_expressions); nfnl_unlock(NFNL_SUBSYS_NFTABLES); return 0; } -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/5] netfilter: nf_tables: Make meta expression core functions public 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 1/5] netfilter: nf_tables: Stack expression type depending on their family Tomasz Bursztyka @ 2014-03-27 12:47 ` Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka ` (3 subsequent siblings) 5 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka This will be useful to create network family dedicated META expression as for NFPROTO_BRIDGE for instance. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> --- include/net/netfilter/nft_meta.h | 32 ++++++++++++++++++++++++++++++ net/netfilter/nft_meta.c | 42 ++++++++++++++++++++-------------------- 2 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 include/net/netfilter/nft_meta.h diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h new file mode 100644 index 0000000..2fcb32f --- /dev/null +++ b/include/net/netfilter/nft_meta.h @@ -0,0 +1,32 @@ +#ifndef _NFT_META_H_ +#define _NFT_META_H_ + +struct nft_meta { + enum nft_meta_keys key:8; + union { + enum nft_registers dreg:8; + enum nft_registers sreg:8; + }; +}; + +extern const struct nla_policy nft_meta_policy[]; + +int nft_meta_init_validate_get(uint32_t key); + +int nft_meta_init_validate_set(uint32_t key); + +int nft_meta_get_dump(struct sk_buff *skb, + const struct nft_expr *expr); + +int nft_meta_set_dump(struct sk_buff *skb, + const struct nft_expr *expr); + +void nft_meta_get_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt); + +void nft_meta_set_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt); + +#endif diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index e8254ad..1b1422c 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -18,18 +18,11 @@ #include <net/sock.h> #include <net/tcp_states.h> /* for TCP_TIME_WAIT */ #include <net/netfilter/nf_tables.h> +#include <net/netfilter/nft_meta.h> -struct nft_meta { - enum nft_meta_keys key:8; - union { - enum nft_registers dreg:8; - enum nft_registers sreg:8; - }; -}; - -static void nft_meta_get_eval(const struct nft_expr *expr, - struct nft_data data[NFT_REG_MAX + 1], - const struct nft_pktinfo *pkt) +void nft_meta_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 sk_buff *skb = pkt->skb; @@ -140,10 +133,11 @@ static void nft_meta_get_eval(const struct nft_expr *expr, err: data[NFT_REG_VERDICT].verdict = NFT_BREAK; } +EXPORT_SYMBOL_GPL(nft_meta_get_eval); -static void nft_meta_set_eval(const struct nft_expr *expr, - struct nft_data data[NFT_REG_MAX + 1], - const struct nft_pktinfo *pkt) +void nft_meta_set_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt) { const struct nft_meta *meta = nft_expr_priv(expr); struct sk_buff *skb = pkt->skb; @@ -163,14 +157,16 @@ static void nft_meta_set_eval(const struct nft_expr *expr, WARN_ON(1); } } +EXPORT_SYMBOL_GPL(nft_meta_set_eval); -static const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { +const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = { [NFTA_META_DREG] = { .type = NLA_U32 }, [NFTA_META_KEY] = { .type = NLA_U32 }, [NFTA_META_SREG] = { .type = NLA_U32 }, }; +EXPORT_SYMBOL_GPL(nft_meta_policy); -static int nft_meta_init_validate_set(uint32_t key) +int nft_meta_init_validate_set(uint32_t key) { switch (key) { case NFT_META_MARK: @@ -181,8 +177,9 @@ static int nft_meta_init_validate_set(uint32_t key) return -EOPNOTSUPP; } } +EXPORT_SYMBOL_GPL(nft_meta_init_validate_set); -static int nft_meta_init_validate_get(uint32_t key) +int nft_meta_init_validate_get(uint32_t key) { switch (key) { case NFT_META_LEN: @@ -211,6 +208,7 @@ static int nft_meta_init_validate_get(uint32_t key) } } +EXPORT_SYMBOL_GPL(nft_meta_init_validate_get); static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) @@ -246,8 +244,8 @@ static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr, return 0; } -static int nft_meta_get_dump(struct sk_buff *skb, - const struct nft_expr *expr) +int nft_meta_get_dump(struct sk_buff *skb, + const struct nft_expr *expr) { const struct nft_meta *priv = nft_expr_priv(expr); @@ -260,9 +258,10 @@ static int nft_meta_get_dump(struct sk_buff *skb, nla_put_failure: return -1; } +EXPORT_SYMBOL_GPL(nft_meta_get_dump); -static int nft_meta_set_dump(struct sk_buff *skb, - const struct nft_expr *expr) +int nft_meta_set_dump(struct sk_buff *skb, + const struct nft_expr *expr) { const struct nft_meta *priv = nft_expr_priv(expr); @@ -276,6 +275,7 @@ static int nft_meta_set_dump(struct sk_buff *skb, nla_put_failure: return -1; } +EXPORT_SYMBOL_GPL(nft_meta_set_dump); static struct nft_expr_type nft_meta_type; static const struct nft_expr_ops nft_meta_get_ops = { -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 1/5] netfilter: nf_tables: Stack expression type depending on their family Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 2/5] netfilter: nf_tables: Make meta expression core functions public Tomasz Bursztyka @ 2014-03-27 12:47 ` Tomasz Bursztyka 2014-03-27 12:59 ` Arturo Borrero Gonzalez 2014-03-27 12:47 ` [PATCH libnftnl 4/5] meta: Add support for input and output " Tomasz Bursztyka ` (2 subsequent siblings) 5 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka NFT_META_IBRIFNAME to get packet input bridge interface name NFT_META_OBRIFNAME 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> --- include/uapi/linux/netfilter/nf_tables.h | 4 + net/bridge/Makefile | 1 + net/bridge/netfilter/Kconfig | 12 ++- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/nft_meta_bridge.c | 162 +++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 net/bridge/netfilter/nft_meta_bridge.c diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 83c985a..6b84a2e 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -533,6 +533,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -552,6 +554,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/net/bridge/Makefile b/net/bridge/Makefile index e85498b2f..58acd82 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -16,4 +16,5 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o +obj-$(CONFIG_NF_TABLES_BRIDGE) += netfilter/ obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 5ca74a0..906783d 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -2,10 +2,20 @@ # Bridge netfilter configuration # # -config NF_TABLES_BRIDGE +menuconfig NF_TABLES_BRIDGE depends on NF_TABLES tristate "Ethernet Bridge nf_tables support" +if NF_TABLES_BRIDGE + +config NFT_BRIDGE_META + tristate "Netfilter nf_table bridge meta support" + depends on NFT_META + help + Add support for bridge dedicated meta key. + +endif # NF_TABLES_BRIDGE + menuconfig BRIDGE_NF_EBTABLES tristate "Ethernet Bridge tables (ebtables) support" depends on BRIDGE && NETFILTER diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index ea7629f..6f2f394 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c new file mode 100644 index 0000000..411a6b5 --- /dev/null +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2012 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; + + if (pkt->ops->pf != NFPROTO_BRIDGE) + goto out; + + 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_init_validate_get(uint32_t key) +{ + switch (key) { + case NFT_META_BRI_IIFNAME: + case NFT_META_BRI_OIFNAME: + return 0; + default: + break; + } + + return nft_meta_init_validate_get(key); +} + +static int nft_meta_bridge_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])); + + if (tb[NFTA_META_DREG]) { + err = nft_meta_bridge_init_validate_get(priv->key); + if (err < 0) + return err; + + priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); + err = nft_validate_output_register(priv->dreg); + if (err < 0) + return err; + + return nft_validate_data_load(ctx, priv->dreg, NULL, + NFT_DATA_VALUE); + } + + err = nft_meta_init_validate_set(priv->key); + if (err < 0) + return err; + + priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG])); + err = nft_validate_input_register(priv->sreg); + 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_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_bridge_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"); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-03-27 12:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka @ 2014-03-27 12:59 ` Arturo Borrero Gonzalez 2014-03-27 13:07 ` Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Arturo Borrero Gonzalez @ 2014-03-27 12:59 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: Netfilter Development Mailing list On 27 March 2014 13:47, Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> wrote: > > diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c > new file mode 100644 > index 0000000..411a6b5 > --- /dev/null > +++ b/net/bridge/netfilter/nft_meta_bridge.c > @@ -0,0 +1,162 @@ > +/* > + * Copyright (c) 2012 Intel Corporation > + * minor question: Why do you use 2012 here? regards -- Arturo Borrero González -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-03-27 12:59 ` Arturo Borrero Gonzalez @ 2014-03-27 13:07 ` Tomasz Bursztyka 0 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 13:07 UTC (permalink / raw) To: Arturo Borrero Gonzalez; +Cc: Netfilter Development Mailing list Hi Arturo, >> +/* >> >+ * Copyright (c) 2012 Intel Corporation >> >+ * > minor question: > Why do you use 2012 here? Living in the past... wrong c/p ;) Thanks, Tomasz ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH libnftnl 4/5] meta: Add support for input and output bridge interface name 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka ` (2 preceding siblings ...) 2014-03-27 12:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka @ 2014-03-27 12:47 ` Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH nftables 5/5] " Tomasz Bursztyka 2014-03-27 12:55 ` [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Patrick McHardy 5 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Add support for dedicated bridge meta key, related to device names: - NFT_META_BRI_IIFNAME - NFT_META_BRI_OIFNAME Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> --- include/linux/netfilter/nf_tables.h | 4 ++++ src/expr/meta.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index bb160d5..5b7bed5 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -536,6 +536,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -555,6 +557,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/src/expr/meta.c b/src/expr/meta.c index bee2f4c..fb945f0 100644 --- a/src/expr/meta.c +++ b/src/expr/meta.c @@ -23,7 +23,7 @@ #include "expr_ops.h" #ifndef NFT_META_MAX -#define NFT_META_MAX (NFT_META_L4PROTO + 1) +#define NFT_META_MAX (NFT_META_BRI_OIFNAME + 1) #endif struct nft_expr_meta { @@ -153,6 +153,8 @@ static const char *meta_key2str_array[NFT_META_MAX] = { [NFT_META_NFTRACE] = "nftrace", [NFT_META_RTCLASSID] = "rtclassid", [NFT_META_SECMARK] = "secmark", + [NFT_META_BRI_IIFNAME] = "bri_iifname", + [NFT_META_BRI_OIFNAME] = "bri_oifname", }; static const char *meta_key2str(uint8_t key) -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH nftables 5/5] meta: Add support for input and output bridge interface name 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka ` (3 preceding siblings ...) 2014-03-27 12:47 ` [PATCH libnftnl 4/5] meta: Add support for input and output " Tomasz Bursztyka @ 2014-03-27 12:47 ` Tomasz Bursztyka 2014-03-27 12:55 ` [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Patrick McHardy 5 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 12:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Add support to get an input or output bridge interface name through the relevant meta keys: bri_iifname and bri_oifname. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> --- include/linux/netfilter/nf_tables.h | 4 ++++ src/meta.c | 38 +++++++++++++++++++++---------------- src/parser.y | 4 ++++ src/scanner.l | 2 ++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index ff9b0a7..a5f8ec0 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -533,6 +533,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -552,6 +554,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/src/meta.c b/src/meta.c index ebc0c54..d95c124 100644 --- a/src/meta.c +++ b/src/meta.c @@ -298,40 +298,46 @@ static const struct datatype gid_type = { }; static const struct meta_template meta_templates[] = { - [NFT_META_LEN] = META_TEMPLATE("length", &integer_type, + [NFT_META_LEN] = META_TEMPLATE("length", &integer_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_PROTOCOL] = META_TEMPLATE("protocol", ðertype_type, + [NFT_META_PROTOCOL] = META_TEMPLATE("protocol", ðertype_type, 2 * 8, BYTEORDER_BIG_ENDIAN), - [NFT_META_NFPROTO] = META_TEMPLATE("nfproto", &nfproto_type, + [NFT_META_NFPROTO] = META_TEMPLATE("nfproto", &nfproto_type, 1 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_L4PROTO] = META_TEMPLATE("l4proto", &inet_protocol_type, + [NFT_META_L4PROTO] = META_TEMPLATE("l4proto", &inet_protocol_type, 1 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_PRIORITY] = META_TEMPLATE("priority", &tchandle_type, + [NFT_META_PRIORITY] = META_TEMPLATE("priority", &tchandle_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_MARK] = META_TEMPLATE("mark", &mark_type, + [NFT_META_MARK] = META_TEMPLATE("mark", &mark_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_IIF] = META_TEMPLATE("iif", &ifindex_type, + [NFT_META_IIF] = META_TEMPLATE("iif", &ifindex_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_IIFNAME] = META_TEMPLATE("iifname", &string_type, + [NFT_META_IIFNAME] = META_TEMPLATE("iifname", &string_type, IFNAMSIZ * BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN), - [NFT_META_IIFTYPE] = META_TEMPLATE("iiftype", &arphrd_type, + [NFT_META_IIFTYPE] = META_TEMPLATE("iiftype", &arphrd_type, 2 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_OIF] = META_TEMPLATE("oif", &ifindex_type, + [NFT_META_OIF] = META_TEMPLATE("oif", &ifindex_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_OIFNAME] = META_TEMPLATE("oifname", &string_type, + [NFT_META_OIFNAME] = META_TEMPLATE("oifname", &string_type, IFNAMSIZ * BITS_PER_BYTE, BYTEORDER_HOST_ENDIAN), - [NFT_META_OIFTYPE] = META_TEMPLATE("oiftype", &arphrd_type, + [NFT_META_OIFTYPE] = META_TEMPLATE("oiftype", &arphrd_type, 2 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_SKUID] = META_TEMPLATE("skuid", &uid_type, + [NFT_META_SKUID] = META_TEMPLATE("skuid", &uid_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_SKGID] = META_TEMPLATE("skgid", &gid_type, + [NFT_META_SKGID] = META_TEMPLATE("skgid", &gid_type, 4 * 8, BYTEORDER_HOST_ENDIAN), - [NFT_META_NFTRACE] = META_TEMPLATE("nftrace", &integer_type, + [NFT_META_NFTRACE] = META_TEMPLATE("nftrace", &integer_type, 1 , BYTEORDER_HOST_ENDIAN), - [NFT_META_RTCLASSID] = META_TEMPLATE("rtclassid", &realm_type, + [NFT_META_RTCLASSID] = META_TEMPLATE("rtclassid", &realm_type, 4 * 8, BYTEORDER_HOST_ENDIAN), + [NFT_META_BRI_IIFNAME] = META_TEMPLATE("bri_iifname", &string_type, + IFNAMSIZ * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN), + [NFT_META_BRI_OIFNAME] = META_TEMPLATE("bri_oifname", &string_type, + IFNAMSIZ * BITS_PER_BYTE, + BYTEORDER_HOST_ENDIAN), }; static void meta_expr_print(const struct expr *expr) diff --git a/src/parser.y b/src/parser.y index db6f493..e8aef1d 100644 --- a/src/parser.y +++ b/src/parser.y @@ -304,6 +304,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token SKGID "skgid" %token NFTRACE "nftrace" %token RTCLASSID "rtclassid" +%token BRI_IIFNAME "bri_iifname" +%token BRI_OIFNAME "bri_oifname" %token CT "ct" %token DIRECTION "direction" @@ -1563,6 +1565,8 @@ meta_key_unqualified : MARK { $$ = NFT_META_MARK; } | SKGID { $$ = NFT_META_SKGID; } | NFTRACE { $$ = NFT_META_NFTRACE; } | RTCLASSID { $$ = NFT_META_RTCLASSID; } + | BRI_IIFNAME { $$ = NFT_META_BRI_IIFNAME; } + | BRI_OIFNAME { $$ = NFT_META_BRI_OIFNAME; } ; meta_stmt : META meta_key SET expr diff --git a/src/scanner.l b/src/scanner.l index 47c5933..61c98b5 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -402,6 +402,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "skgid" { return SKGID; } "nftrace" { return NFTRACE; } "rtclassid" { return RTCLASSID; } +"bri_iifname" { return BRI_IIFNAME; } +"bri_oifname" { return BRI_OIFNAME; } "ct" { return CT; } "direction" { return DIRECTION; } -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 0/5] Add suport for bridge if dev name meta exepression keys 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka ` (4 preceding siblings ...) 2014-03-27 12:47 ` [PATCH nftables 5/5] " Tomasz Bursztyka @ 2014-03-27 12:55 ` Patrick McHardy 2014-03-27 13:11 ` Tomasz Bursztyka 5 siblings, 1 reply; 19+ messages in thread From: Patrick McHardy @ 2014-03-27 12:55 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: netfilter-devel On Thu, Mar 27, 2014 at 02:47:02PM +0200, Tomasz Bursztyka wrote: > Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. > > I did not factorize nft_meta.c code to reuse nft_meta_select_ops() and nft_meta_bridge_init() > At least solutions I had made the code too ugly. > Declaring a type for select_ops functions, same for validate_get() one, and have > an in-between functions called relevantly by meta_<bridge_>init etc... Thanks. The patches look fine, however I'd ask you to hold off until tommorrow. I have patches coming up that will introduce variable sized registers for concatenations, which remove some of the functions you export, so we can avoid some churn of first exporting, then removing them again by adding your patches on top. Should only be very minor changes to adapt. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/5] Add suport for bridge if dev name meta exepression keys 2014-03-27 12:55 ` [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Patrick McHardy @ 2014-03-27 13:11 ` Tomasz Bursztyka 0 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-03-27 13:11 UTC (permalink / raw) To: Patrick McHardy; +Cc: netfilter-devel Hi Patrick, > On Thu, Mar 27, 2014 at 02:47:02PM +0200, Tomasz Bursztyka wrote: >> Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. >> >> I did not factorize nft_meta.c code to reuse nft_meta_select_ops() and nft_meta_bridge_init() >> At least solutions I had made the code too ugly. >> Declaring a type for select_ops functions, same for validate_get() one, and have >> an in-between functions called relevantly by meta_<bridge_>init etc... > Thanks. The patches look fine, however I'd ask you to hold off until > tommorrow. I have patches coming up that will introduce variable sized > registers for concatenations, which remove some of the functions you > export, so we can avoid some churn of first exporting, then removing > them again by adding your patches on top. Should only be very minor > changes to adapt. Sure, I will rebase my patchset once your modifications are upstream. Tomasz ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 0/4] Add suport for bridge if dev name meta exepression keys @ 2014-04-04 9:47 Tomasz Bursztyka 2014-04-04 9:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-04 9:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. Changes against v1: - Rebased the kernel patch set against Patrick's nft_meta.c get/set init function split up. Last 2 patches are about user-space support. Tomasz Bursztyka (5): kernel: netfilter: nf_tables: Stack expression type depending on their family netfilter: nf_tables: Make meta expression core functions public netfilter: nf_tables: Add meta expression key for bridge interface name libnftnl: meta: Add support for input and output bridge interface name nftables: meta: Add support for input and output bridge interface name -- 1.8.3.2 ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-04 9:47 [PATCH v2 0/4] " Tomasz Bursztyka @ 2014-04-04 9:47 ` Tomasz Bursztyka 0 siblings, 0 replies; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-04 9:47 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka 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> --- include/uapi/linux/netfilter/nf_tables.h | 4 + net/bridge/Makefile | 1 + net/bridge/netfilter/Kconfig | 12 ++- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/nft_meta_bridge.c | 142 +++++++++++++++++++++++++++++++ 5 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 net/bridge/netfilter/nft_meta_bridge.c diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c88ccbf..45fb37c 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -536,6 +536,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -555,6 +557,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/net/bridge/Makefile b/net/bridge/Makefile index e85498b2f..58acd82 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -16,4 +16,5 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o +obj-$(CONFIG_NF_TABLES_BRIDGE) += netfilter/ obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 5ca74a0..906783d 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -2,10 +2,20 @@ # Bridge netfilter configuration # # -config NF_TABLES_BRIDGE +menuconfig NF_TABLES_BRIDGE depends on NF_TABLES tristate "Ethernet Bridge nf_tables support" +if NF_TABLES_BRIDGE + +config NFT_BRIDGE_META + tristate "Netfilter nf_table bridge meta support" + depends on NFT_META + help + Add support for bridge dedicated meta key. + +endif # NF_TABLES_BRIDGE + menuconfig BRIDGE_NF_EBTABLES tristate "Ethernet Bridge tables (ebtables) support" depends on BRIDGE && NETFILTER diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index ea7629f..6f2f394 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c new file mode 100644 index 0000000..d324441 --- /dev/null +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -0,0 +1,142 @@ +/* + * 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; + + if (pkt->ops->pf != NFPROTO_BRIDGE) + goto out; + + 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"); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v3 0/5] Add suport for bridge if dev name meta exepression keys @ 2014-04-08 11:25 Tomasz Bursztyka 2014-04-08 11:25 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-08 11:25 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. Changes against v2: - Applied Pablo's comment on patch 3 - Applied human readable names on patch 5 according to Pablo and Patrick comments. v1: - Rebased the kernel patch set against Patrick's nft_meta.c get/set init function split up. Last 2 patches are about user-space support. Tomasz Bursztyka (5): kernel: netfilter: nf_tables: Stack expression type depending on their family netfilter: nf_tables: Make meta expression core functions public netfilter: nf_tables: Add meta expression key for bridge interface name libnftnl: meta: Add support for input and output bridge interface name nftables: meta: Add support for input and output bridge interface name -- 1.8.3.2 ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-08 11:25 [PATCH v3 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka @ 2014-04-08 11:25 ` Tomasz Bursztyka 2014-04-14 11:36 ` Pablo Neira Ayuso 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-08 11:25 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka 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> --- include/uapi/linux/netfilter/nf_tables.h | 4 + net/bridge/Makefile | 1 + net/bridge/netfilter/Kconfig | 12 ++- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/nft_meta_bridge.c | 139 +++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 net/bridge/netfilter/nft_meta_bridge.c diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c88ccbf..45fb37c 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -536,6 +536,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -555,6 +557,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/net/bridge/Makefile b/net/bridge/Makefile index e85498b2f..58acd82 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -16,4 +16,5 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o +obj-$(CONFIG_NF_TABLES_BRIDGE) += netfilter/ obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 5ca74a0..906783d 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -2,10 +2,20 @@ # Bridge netfilter configuration # # -config NF_TABLES_BRIDGE +menuconfig NF_TABLES_BRIDGE depends on NF_TABLES tristate "Ethernet Bridge nf_tables support" +if NF_TABLES_BRIDGE + +config NFT_BRIDGE_META + tristate "Netfilter nf_table bridge meta support" + depends on NFT_META + help + Add support for bridge dedicated meta key. + +endif # NF_TABLES_BRIDGE + menuconfig BRIDGE_NF_EBTABLES tristate "Ethernet Bridge tables (ebtables) support" depends on BRIDGE && NETFILTER diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index ea7629f..6f2f394 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c new file mode 100644 index 0000000..4f02109 --- /dev/null +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -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"); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-08 11:25 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka @ 2014-04-14 11:36 ` Pablo Neira Ayuso 2014-04-14 11:48 ` Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Pablo Neira Ayuso @ 2014-04-14 11:36 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: netfilter-devel On Tue, Apr 08, 2014 at 02:25:22PM +0300, Tomasz Bursztyka wrote: > 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> > --- > include/uapi/linux/netfilter/nf_tables.h | 4 + > net/bridge/Makefile | 1 + > net/bridge/netfilter/Kconfig | 12 ++- > net/bridge/netfilter/Makefile | 1 + > net/bridge/netfilter/nft_meta_bridge.c | 139 +++++++++++++++++++++++++++++++ > 5 files changed, 156 insertions(+), 1 deletion(-) > create mode 100644 net/bridge/netfilter/nft_meta_bridge.c > > diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h > index c88ccbf..45fb37c 100644 > --- a/include/uapi/linux/netfilter/nf_tables.h > +++ b/include/uapi/linux/netfilter/nf_tables.h > @@ -536,6 +536,8 @@ enum nft_exthdr_attributes { > * @NFT_META_SECMARK: packet secmark (skb->secmark) > * @NFT_META_NFPROTO: netfilter protocol > * @NFT_META_L4PROTO: layer 4 protocol number > + * @NFT_META_BRI_IIFNAME: packet input bridge interface name > + * @NFT_META_BRI_OIFNAME: packet output bridge interface name > */ > enum nft_meta_keys { > NFT_META_LEN, > @@ -555,6 +557,8 @@ enum nft_meta_keys { > NFT_META_SECMARK, > NFT_META_NFPROTO, > NFT_META_L4PROTO, > + NFT_META_BRI_IIFNAME, > + NFT_META_BRI_OIFNAME, > }; > > /** > diff --git a/net/bridge/Makefile b/net/bridge/Makefile > index e85498b2f..58acd82 100644 > --- a/net/bridge/Makefile > +++ b/net/bridge/Makefile > @@ -16,4 +16,5 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o > > bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o > > +obj-$(CONFIG_NF_TABLES_BRIDGE) += netfilter/ > obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ I think you can add some backward compatibility alias: config CONFIG_BRIDGE_NF_EBTABLES select CONFIG_NETFILTER_BRIDGE so you can add CONFIG_NETFILTER_BRIDGE for that directory, which is more generic. obj-$(CONFIG_NETFILTER_BRIDGE) += netfilter/ > diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig > index 5ca74a0..906783d 100644 > --- a/net/bridge/netfilter/Kconfig > +++ b/net/bridge/netfilter/Kconfig > @@ -2,10 +2,20 @@ > # Bridge netfilter configuration > # > # > -config NF_TABLES_BRIDGE > +menuconfig NF_TABLES_BRIDGE > depends on NF_TABLES > tristate "Ethernet Bridge nf_tables support" > > +if NF_TABLES_BRIDGE > + > +config NFT_BRIDGE_META > + tristate "Netfilter nf_table bridge meta support" > + depends on NFT_META > + help > + Add support for bridge dedicated meta key. > + > +endif # NF_TABLES_BRIDGE > + > menuconfig BRIDGE_NF_EBTABLES > tristate "Ethernet Bridge tables (ebtables) support" > depends on BRIDGE && NETFILTER > diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile > index ea7629f..6f2f394 100644 > --- a/net/bridge/netfilter/Makefile > +++ b/net/bridge/netfilter/Makefile > @@ -3,6 +3,7 @@ > # > > obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o > +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o > > obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o > > diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c > new file mode 100644 > index 0000000..4f02109 > --- /dev/null > +++ b/net/bridge/netfilter/nft_meta_bridge.c I think you can remove the trailing _bridge, it's obvious that we're already in the bridge directory. Apart from those two, this looks good to me. Thanks Tomasz. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-14 11:36 ` Pablo Neira Ayuso @ 2014-04-14 11:48 ` Tomasz Bursztyka 2014-04-14 11:55 ` Pablo Neira Ayuso 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-14 11:48 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel Hi Pablo, > I think you can remove the trailing _bridge, it's obvious that we're > already in the bridge directory. All family-tight nftables modules seem to follow this rule, reason why I did so. (cf. reject, chain nat, etc...) Anyway, will resend a new version applying your Kconfig comment. Tomasz ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-14 11:48 ` Tomasz Bursztyka @ 2014-04-14 11:55 ` Pablo Neira Ayuso 0 siblings, 0 replies; 19+ messages in thread From: Pablo Neira Ayuso @ 2014-04-14 11:55 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: netfilter-devel On Mon, Apr 14, 2014 at 02:48:43PM +0300, Tomasz Bursztyka wrote: > Hi Pablo, > > >I think you can remove the trailing _bridge, it's obvious that we're > >already in the bridge directory. > > All family-tight nftables modules seem to follow this rule, reason > why I did so. > (cf. reject, chain nat, etc...) Right, otherwise module will clash before of similar name, so forget my comment on that. > Anyway, will resend a new version applying your Kconfig comment. Thanks. ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 0/5] Add suport for bridge if dev name meta expression keys @ 2014-04-14 12:41 Tomasz Bursztyka 2014-04-14 12:41 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-14 12:41 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka Here is the patch-set to add meta keys NFT_META_BRI_IIFNAME and NFT_META_BRI_OIFNAME. Changes against v3: - Applied Pablo's comment so CONFIG_NF_TABLES_BRIDGE and CONFIG_BRIDGE_NF_EBTABLES are interdependent with CONFIG_BRIDGE_NETFILTER in order to properly add netfilter sub-directory when building. v2: - Applied Pablo's comment on patch 3 - Applied human readable names on patch 5 according to Pablo and Patrick comments. v1: - Rebased the kernel patch set against Patrick's nft_meta.c get/set init function split up. Last 2 patches are about user-space support. Tomasz Bursztyka (5): kernel: netfilter: nf_tables: Stack expression type depending on their family netfilter: nf_tables: Make meta expression core functions public netfilter: nf_tables: Add meta expression key for bridge interface name libnftnl: meta: Add support for input and output bridge interface name nftables: meta: Add support for input and output bridge interface name -- 1.8.3.2 ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-14 12:41 [PATCH v4 0/5] Add suport for bridge if dev name meta expression keys Tomasz Bursztyka @ 2014-04-14 12:41 ` Tomasz Bursztyka 2014-04-23 12:03 ` Pablo Neira Ayuso 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-14 12:41 UTC (permalink / raw) To: netfilter-devel; +Cc: Tomasz Bursztyka 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> --- include/uapi/linux/netfilter/nf_tables.h | 4 + net/bridge/Makefile | 2 +- net/bridge/netfilter/Kconfig | 14 +++- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/nft_meta_bridge.c | 139 +++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 net/bridge/netfilter/nft_meta_bridge.c diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index c88ccbf..45fb37c 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -536,6 +536,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_BRI_IIFNAME: packet input bridge interface name + * @NFT_META_BRI_OIFNAME: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -555,6 +557,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_BRI_IIFNAME, + NFT_META_BRI_OIFNAME, }; /** diff --git a/net/bridge/Makefile b/net/bridge/Makefile index e85498b2f..906a18b 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -16,4 +16,4 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o -obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ +obj-$(CONFIG_BRIDGE_NETFILTER) += netfilter/ diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 5ca74a0..3baf29d 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -2,13 +2,25 @@ # Bridge netfilter configuration # # -config NF_TABLES_BRIDGE +menuconfig NF_TABLES_BRIDGE depends on NF_TABLES + select BRIDGE_NETFILTER tristate "Ethernet Bridge nf_tables support" +if NF_TABLES_BRIDGE + +config NFT_BRIDGE_META + tristate "Netfilter nf_table bridge meta support" + depends on NFT_META + help + Add support for bridge dedicated meta key. + +endif # NF_TABLES_BRIDGE + menuconfig BRIDGE_NF_EBTABLES tristate "Ethernet Bridge tables (ebtables) support" depends on BRIDGE && NETFILTER + select BRIDGE_NETFILTER select NETFILTER_XTABLES help ebtables is a general, extensible frame/packet identification diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index ea7629f..6f2f394 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c new file mode 100644 index 0000000..4f02109 --- /dev/null +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -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"); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-14 12:41 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka @ 2014-04-23 12:03 ` Pablo Neira Ayuso 2014-04-24 6:08 ` Tomasz Bursztyka 0 siblings, 1 reply; 19+ messages in thread From: Pablo Neira Ayuso @ 2014-04-23 12:03 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: netfilter-devel, kaber [-- Attachment #1: Type: text/plain, Size: 508 bytes --] Hi Tomasz, On Mon, Apr 14, 2014 at 03:41:28PM +0300, Tomasz Bursztyka wrote: > NFT_META_BRI_IIFNAME to get packet input bridge interface name > NFT_META_BRI_OIFNAME to get packet output bridge interface name I'm going to take this patchset and enqueue to the nftables tree (net-next), but before doing so, I'm going to rename NFT_META_BRI_IIFNAME to NFT_META_IBRIPORT, the original name is a bit long and I think the proposal to change the name also applies to this. I'm attaching the mangled patch here. [-- Attachment #2: 0001-netfilter-nf_tables-Add-meta-expression-key-for-brid.patch --] [-- Type: text/x-diff, Size: 7328 bytes --] >From d3090dfe18931781debfd6596b81b9af84a9b8aa Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> Date: Mon, 14 Apr 2014 15:41:28 +0300 Subject: [PATCH] netfilter: nf_tables: Add meta expression key for bridge interface name NFT_META_IBRIPORT to get packet input bridge interface name NFT_META_OBRIPORT 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> --- include/uapi/linux/netfilter/nf_tables.h | 4 + net/bridge/Makefile | 2 +- net/bridge/netfilter/Kconfig | 14 ++- net/bridge/netfilter/Makefile | 1 + net/bridge/netfilter/nft_meta_bridge.c | 139 ++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 net/bridge/netfilter/nft_meta_bridge.c diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 1601592..34928c1 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -563,6 +563,8 @@ enum nft_exthdr_attributes { * @NFT_META_SECMARK: packet secmark (skb->secmark) * @NFT_META_NFPROTO: netfilter protocol * @NFT_META_L4PROTO: layer 4 protocol number + * @NFT_META_IBRIPORT: packet input bridge interface name + * @NFT_META_OBRIPORT: packet output bridge interface name */ enum nft_meta_keys { NFT_META_LEN, @@ -582,6 +584,8 @@ enum nft_meta_keys { NFT_META_SECMARK, NFT_META_NFPROTO, NFT_META_L4PROTO, + NFT_META_IBRIPORT, + NFT_META_OBRIPORT, }; /** diff --git a/net/bridge/Makefile b/net/bridge/Makefile index e85498b2f..906a18b 100644 --- a/net/bridge/Makefile +++ b/net/bridge/Makefile @@ -16,4 +16,4 @@ bridge-$(CONFIG_BRIDGE_IGMP_SNOOPING) += br_multicast.o br_mdb.o bridge-$(CONFIG_BRIDGE_VLAN_FILTERING) += br_vlan.o -obj-$(CONFIG_BRIDGE_NF_EBTABLES) += netfilter/ +obj-$(CONFIG_BRIDGE_NETFILTER) += netfilter/ diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig index 5ca74a0..3baf29d 100644 --- a/net/bridge/netfilter/Kconfig +++ b/net/bridge/netfilter/Kconfig @@ -2,13 +2,25 @@ # Bridge netfilter configuration # # -config NF_TABLES_BRIDGE +menuconfig NF_TABLES_BRIDGE depends on NF_TABLES + select BRIDGE_NETFILTER tristate "Ethernet Bridge nf_tables support" +if NF_TABLES_BRIDGE + +config NFT_BRIDGE_META + tristate "Netfilter nf_table bridge meta support" + depends on NFT_META + help + Add support for bridge dedicated meta key. + +endif # NF_TABLES_BRIDGE + menuconfig BRIDGE_NF_EBTABLES tristate "Ethernet Bridge tables (ebtables) support" depends on BRIDGE && NETFILTER + select BRIDGE_NETFILTER select NETFILTER_XTABLES help ebtables is a general, extensible frame/packet identification diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index ea7629f..6f2f394 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o +obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c new file mode 100644 index 0000000..63c1b60 --- /dev/null +++ b/net/bridge/netfilter/nft_meta_bridge.c @@ -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_IBRIPORT: + if (in == NULL || (p = br_port_get_rcu(in)) == NULL) + goto err; + break; + case NFT_META_OBRIPORT: + 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_IBRIPORT: + case NFT_META_OBRIPORT: + 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"); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-23 12:03 ` Pablo Neira Ayuso @ 2014-04-24 6:08 ` Tomasz Bursztyka 2014-04-24 8:38 ` Pablo Neira Ayuso 0 siblings, 1 reply; 19+ messages in thread From: Tomasz Bursztyka @ 2014-04-24 6:08 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: netfilter-devel, kaber Hi Pablo, > I'm going to rename > NFT_META_BRI_IIFNAME to NFT_META_IBRIPORT, As you want. I took the name proposed by Patrick here, and since it's an API there is less concerns about having a really short human-writable name as for the nftables tool. Tomasz ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name 2014-04-24 6:08 ` Tomasz Bursztyka @ 2014-04-24 8:38 ` Pablo Neira Ayuso 0 siblings, 0 replies; 19+ messages in thread From: Pablo Neira Ayuso @ 2014-04-24 8:38 UTC (permalink / raw) To: Tomasz Bursztyka; +Cc: netfilter-devel, kaber On Thu, Apr 24, 2014 at 09:08:58AM +0300, Tomasz Bursztyka wrote: > Hi Pablo, > > >I'm going to rename > >NFT_META_BRI_IIFNAME to NFT_META_IBRIPORT, > > As you want. I took the name proposed by Patrick here, and since it's an API > there is less concerns about having a really short human-writable name as > for the nftables tool. Right, I just found that email. I just wanted to make sure everybody is happy with the current naming approach, so let's leave it as is. Series applies, thanks Tomasz. ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2014-04-24 8:39 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-03-27 12:47 [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 1/5] netfilter: nf_tables: Stack expression type depending on their family Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 2/5] netfilter: nf_tables: Make meta expression core functions public Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 2014-03-27 12:59 ` Arturo Borrero Gonzalez 2014-03-27 13:07 ` Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH libnftnl 4/5] meta: Add support for input and output " Tomasz Bursztyka 2014-03-27 12:47 ` [PATCH nftables 5/5] " Tomasz Bursztyka 2014-03-27 12:55 ` [PATCH 0/5] Add suport for bridge if dev name meta exepression keys Patrick McHardy 2014-03-27 13:11 ` Tomasz Bursztyka -- strict thread matches above, loose matches on Subject: below -- 2014-04-04 9:47 [PATCH v2 0/4] " Tomasz Bursztyka 2014-04-04 9:47 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 2014-04-08 11:25 [PATCH v3 0/5] Add suport for bridge if dev name meta exepression keys Tomasz Bursztyka 2014-04-08 11:25 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 2014-04-14 11:36 ` Pablo Neira Ayuso 2014-04-14 11:48 ` Tomasz Bursztyka 2014-04-14 11:55 ` Pablo Neira Ayuso 2014-04-14 12:41 [PATCH v4 0/5] Add suport for bridge if dev name meta expression keys Tomasz Bursztyka 2014-04-14 12:41 ` [PATCH 3/5] netfilter: nf_tables: Add meta expression key for bridge interface name Tomasz Bursztyka 2014-04-23 12:03 ` Pablo Neira Ayuso 2014-04-24 6:08 ` Tomasz Bursztyka 2014-04-24 8:38 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).