Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a46c52d9 authored by wenxu's avatar wenxu Committed by Pablo Neira Ayuso
Browse files

netfilter: nft_tunnel: Add NFTA_TUNNEL_MODE options



nft "tunnel" expr match both the tun_info of RX and TX. This patch
provide the NFTA_TUNNEL_MODE to individually match the tun_info of
RX or TX.

Signed-off-by: default avatarwenxu <wenxu@ucloud.cn>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 0604628b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1727,10 +1727,19 @@ enum nft_tunnel_keys {
};
#define NFT_TUNNEL_MAX	(__NFT_TUNNEL_MAX - 1)

enum nft_tunnel_mode {
	NFT_TUNNEL_MODE_NONE,
	NFT_TUNNEL_MODE_RX,
	NFT_TUNNEL_MODE_TX,
	__NFT_TUNNEL_MODE_MAX
};
#define NFT_TUNNEL_MODE_MAX	(__NFT_TUNNEL_MODE_MAX - 1)

enum nft_tunnel_attributes {
	NFTA_TUNNEL_UNSPEC,
	NFTA_TUNNEL_KEY,
	NFTA_TUNNEL_DREG,
	NFTA_TUNNEL_MODE,
	__NFTA_TUNNEL_MAX
};
#define NFTA_TUNNEL_MAX	(__NFTA_TUNNEL_MAX - 1)
+32 −2
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
struct nft_tunnel {
	enum nft_tunnel_keys	key:8;
	enum nft_registers	dreg:8;
	enum nft_tunnel_mode	mode:8;
};

static void nft_tunnel_get_eval(const struct nft_expr *expr,
@@ -29,14 +30,32 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,

	switch (priv->key) {
	case NFT_TUNNEL_PATH:
		nft_reg_store8(dest, !!tun_info);
		if (!tun_info) {
			nft_reg_store8(dest, false);
			return;
		}
		if (priv->mode == NFT_TUNNEL_MODE_NONE ||
		    (priv->mode == NFT_TUNNEL_MODE_RX &&
		     !(tun_info->mode & IP_TUNNEL_INFO_TX)) ||
		    (priv->mode == NFT_TUNNEL_MODE_TX &&
		     (tun_info->mode & IP_TUNNEL_INFO_TX)))
			nft_reg_store8(dest, true);
		else
			nft_reg_store8(dest, false);
		break;
	case NFT_TUNNEL_ID:
		if (!tun_info) {
			regs->verdict.code = NFT_BREAK;
			return;
		}
		if (priv->mode == NFT_TUNNEL_MODE_NONE ||
		    (priv->mode == NFT_TUNNEL_MODE_RX &&
		     !(tun_info->mode & IP_TUNNEL_INFO_TX)) ||
		    (priv->mode == NFT_TUNNEL_MODE_TX &&
		     (tun_info->mode & IP_TUNNEL_INFO_TX)))
			*dest = ntohl(tunnel_id_to_key32(tun_info->key.tun_id));
		else
			regs->verdict.code = NFT_BREAK;
		break;
	default:
		WARN_ON(1);
@@ -47,6 +66,7 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,
static const struct nla_policy nft_tunnel_policy[NFTA_TUNNEL_MAX + 1] = {
	[NFTA_TUNNEL_KEY]	= { .type = NLA_U32 },
	[NFTA_TUNNEL_DREG]	= { .type = NLA_U32 },
	[NFTA_TUNNEL_MODE]	= { .type = NLA_U32 },
};

static int nft_tunnel_get_init(const struct nft_ctx *ctx,
@@ -74,6 +94,14 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,

	priv->dreg = nft_parse_register(tb[NFTA_TUNNEL_DREG]);

	if (tb[NFTA_TUNNEL_MODE]) {
		priv->mode = ntohl(nla_get_be32(tb[NFTA_TUNNEL_MODE]));
		if (priv->mode > NFT_TUNNEL_MODE_MAX)
			return -EOPNOTSUPP;
	} else {
		priv->mode = NFT_TUNNEL_MODE_NONE;
	}

	return nft_validate_register_store(ctx, priv->dreg, NULL,
					   NFT_DATA_VALUE, len);
}
@@ -87,6 +115,8 @@ static int nft_tunnel_get_dump(struct sk_buff *skb,
		goto nla_put_failure;
	if (nft_dump_register(skb, NFTA_TUNNEL_DREG, priv->dreg))
		goto nla_put_failure;
	if (nla_put_be32(skb, NFTA_TUNNEL_MODE, htonl(priv->mode)))
		goto nla_put_failure;
	return 0;

nla_put_failure: