diff mbox series

[1/2,nf-next] netfilter: nft_meta: add NFT_META_BRI_PVID support

Message ID 1560928585-18352-1-git-send-email-wenxu@ucloud.cn
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [1/2,nf-next] netfilter: nft_meta: add NFT_META_BRI_PVID support | expand

Commit Message

wenxu June 19, 2019, 7:16 a.m. UTC
From: wenxu <wenxu@ucloud.cn>

nft add table bridge firewall
nft add chain bridge firewall zones { type filter hook prerouting priority - 300 \; }
nft add rule bridge firewall zones counter ct zone set vlan id map { 100 : 1, 200 : 2 }

As above set the bridge port with pvid, the received packet don't contain
the vlan tag which means the packet should belong to vlan 200 through pvid.
With this pacth user can get the pvid of bridge ports: "meta brpvid"

Signed-off-by: wenxu <wenxu@ucloud.cn>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_meta.c                 | 17 +++++++++++++++++
 2 files changed, 19 insertions(+)

Comments

Pablo Neira Ayuso June 19, 2019, 5:02 p.m. UTC | #1
On Wed, Jun 19, 2019 at 03:16:24PM +0800, wenxu@ucloud.cn wrote:
> From: wenxu <wenxu@ucloud.cn>
> 
> nft add table bridge firewall
> nft add chain bridge firewall zones { type filter hook prerouting priority - 300 \; }
> nft add rule bridge firewall zones counter ct zone set vlan id map { 100 : 1, 200 : 2 }

> As above set the bridge port with pvid, the received packet don't contain
> the vlan tag which means the packet should belong to vlan 200 through pvid.
> With this pacth user can get the pvid of bridge ports: "meta brpvid"

Would you also post the patches for nftables for review?

Would you post an example on how you use "meta brpvid" in your
ruleset? I don't see this is used in the example above,

More comments below.

> Signed-off-by: wenxu <wenxu@ucloud.cn>
> ---
>  include/uapi/linux/netfilter/nf_tables.h |  2 ++
>  net/netfilter/nft_meta.c                 | 17 +++++++++++++++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index 31a6b8f..4a16124 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -793,6 +793,7 @@ enum nft_exthdr_attributes {
>   * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp)
>   * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind)
>   * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
> + * @NFT_META_BRI_PVID: packet input bridge port pvid
>   */
>  enum nft_meta_keys {
>  	NFT_META_LEN,
> @@ -823,6 +824,7 @@ enum nft_meta_keys {
>  	NFT_META_SECPATH,
>  	NFT_META_IIFKIND,
>  	NFT_META_OIFKIND,
> +	NFT_META_BRI_PVID,
>  };
>  
>  /**
> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
> index 987d2d6..1fdb565 100644
> --- a/net/netfilter/nft_meta.c
> +++ b/net/netfilter/nft_meta.c
> @@ -243,6 +243,18 @@ void nft_meta_get_eval(const struct nft_expr *expr,
>  			goto err;
>  		strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
>  		return;
> +	case NFT_META_BRI_PVID:
> +		if (in == NULL || (p = br_port_get_rtnl_rcu(in)) == NULL)
> +			goto err;
> +		if (br_opt_get(p->br, BROPT_VLAN_ENABLED)) {
> +			u16 pvid = br_get_pvid(nbp_vlan_group_rcu(p));
> +
> +			if (pvid) {
> +				nft_reg_store16(dest, pvid);

I think you should store pvid into dest if pvid is zero too, right?
You cannot assume destination register is set to zero.

> +				return;
> +			}
> +		}
> +		goto err;
>  #endif
>  	case NFT_META_IIFKIND:
>  		if (in == NULL || in->rtnl_link_ops == NULL)
> @@ -370,6 +382,11 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
>  			return -EOPNOTSUPP;
>  		len = IFNAMSIZ;
>  		break;
> +	case NFT_META_BRI_PVID:
> +		if (ctx->family != NFPROTO_BRIDGE)
> +			return -EOPNOTSUPP;
> +		len = sizeof(u16);
> +		break;
>  #endif
>  	default:
>  		return -EOPNOTSUPP;
> -- 
> 1.8.3.1
>
wenxu June 20, 2019, 1:19 a.m. UTC | #2
I will post the nftable patches latter. Thanks!

在 2019/6/20 1:02, Pablo Neira Ayuso 写道:
> On Wed, Jun 19, 2019 at 03:16:24PM +0800, wenxu@ucloud.cn wrote:
>> From: wenxu <wenxu@ucloud.cn>
>>
>> nft add table bridge firewall
>> nft add chain bridge firewall zones { type filter hook prerouting priority - 300 \; }
>> nft add rule bridge firewall zones counter ct zone set vlan id map { 100 : 1, 200 : 2 }
>> As above set the bridge port with pvid, the received packet don't contain
>> the vlan tag which means the packet should belong to vlan 200 through pvid.
>> With this pacth user can get the pvid of bridge ports: "meta brpvid"
> Would you also post the patches for nftables for review?
>
> Would you post an example on how you use "meta brpvid" in your
> ruleset? I don't see this is used in the example above,
>
> More comments below.
>
>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>> ---
>>  include/uapi/linux/netfilter/nf_tables.h |  2 ++
>>  net/netfilter/nft_meta.c                 | 17 +++++++++++++++++
>>  2 files changed, 19 insertions(+)
>>
>> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
>> index 31a6b8f..4a16124 100644
>> --- a/include/uapi/linux/netfilter/nf_tables.h
>> +++ b/include/uapi/linux/netfilter/nf_tables.h
>> @@ -793,6 +793,7 @@ enum nft_exthdr_attributes {
>>   * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp)
>>   * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind)
>>   * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
>> + * @NFT_META_BRI_PVID: packet input bridge port pvid
>>   */
>>  enum nft_meta_keys {
>>  	NFT_META_LEN,
>> @@ -823,6 +824,7 @@ enum nft_meta_keys {
>>  	NFT_META_SECPATH,
>>  	NFT_META_IIFKIND,
>>  	NFT_META_OIFKIND,
>> +	NFT_META_BRI_PVID,
>>  };
>>  
>>  /**
>> diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
>> index 987d2d6..1fdb565 100644
>> --- a/net/netfilter/nft_meta.c
>> +++ b/net/netfilter/nft_meta.c
>> @@ -243,6 +243,18 @@ void nft_meta_get_eval(const struct nft_expr *expr,
>>  			goto err;
>>  		strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
>>  		return;
>> +	case NFT_META_BRI_PVID:
>> +		if (in == NULL || (p = br_port_get_rtnl_rcu(in)) == NULL)
>> +			goto err;
>> +		if (br_opt_get(p->br, BROPT_VLAN_ENABLED)) {
>> +			u16 pvid = br_get_pvid(nbp_vlan_group_rcu(p));
>> +
>> +			if (pvid) {
>> +				nft_reg_store16(dest, pvid);
> I think you should store pvid into dest if pvid is zero too, right?
> You cannot assume destination register is set to zero.
>
>> +				return;
>> +			}
>> +		}
>> +		goto err;
>>  #endif
>>  	case NFT_META_IIFKIND:
>>  		if (in == NULL || in->rtnl_link_ops == NULL)
>> @@ -370,6 +382,11 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,
>>  			return -EOPNOTSUPP;
>>  		len = IFNAMSIZ;
>>  		break;
>> +	case NFT_META_BRI_PVID:
>> +		if (ctx->family != NFPROTO_BRIDGE)
>> +			return -EOPNOTSUPP;
>> +		len = sizeof(u16);
>> +		break;
>>  #endif
>>  	default:
>>  		return -EOPNOTSUPP;
>> -- 
>> 1.8.3.1
>>
diff mbox series

Patch

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 31a6b8f..4a16124 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -793,6 +793,7 @@  enum nft_exthdr_attributes {
  * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp)
  * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind)
  * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind)
+ * @NFT_META_BRI_PVID: packet input bridge port pvid
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -823,6 +824,7 @@  enum nft_meta_keys {
 	NFT_META_SECPATH,
 	NFT_META_IIFKIND,
 	NFT_META_OIFKIND,
+	NFT_META_BRI_PVID,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 987d2d6..1fdb565 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -243,6 +243,18 @@  void nft_meta_get_eval(const struct nft_expr *expr,
 			goto err;
 		strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
 		return;
+	case NFT_META_BRI_PVID:
+		if (in == NULL || (p = br_port_get_rtnl_rcu(in)) == NULL)
+			goto err;
+		if (br_opt_get(p->br, BROPT_VLAN_ENABLED)) {
+			u16 pvid = br_get_pvid(nbp_vlan_group_rcu(p));
+
+			if (pvid) {
+				nft_reg_store16(dest, pvid);
+				return;
+			}
+		}
+		goto err;
 #endif
 	case NFT_META_IIFKIND:
 		if (in == NULL || in->rtnl_link_ops == NULL)
@@ -370,6 +382,11 @@  static int nft_meta_get_init(const struct nft_ctx *ctx,
 			return -EOPNOTSUPP;
 		len = IFNAMSIZ;
 		break;
+	case NFT_META_BRI_PVID:
+		if (ctx->family != NFPROTO_BRIDGE)
+			return -EOPNOTSUPP;
+		len = sizeof(u16);
+		break;
 #endif
 	default:
 		return -EOPNOTSUPP;