@@ -18,9 +18,19 @@ struct nft_tunnel {
enum nft_tunnel_mode mode:8;
};
+enum nft_inet_type {
+ NFT_INET_NONE_TYPE,
+ NFT_INET_IP_TYPE,
+ NFT_INET_IP6_TYPE,
+};
+
static bool nft_tunnel_mode_validate(enum nft_tunnel_mode priv_mode,
- u8 tun_mode)
+ u8 tun_mode, enum nft_inet_type type)
{
+ if ((type == NFT_INET_IP6_TYPE && !(tun_mode & IP_TUNNEL_INFO_IPV6)) ||
+ (type == NFT_INET_IP_TYPE && (tun_mode & IP_TUNNEL_INFO_IPV6)))
+ return false;
+
if (priv_mode == NFT_TUNNEL_MODE_NONE ||
(priv_mode == NFT_TUNNEL_MODE_RX &&
!(tun_mode & IP_TUNNEL_INFO_TX)) ||
@@ -47,7 +57,8 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,
nft_reg_store8(dest, false);
return;
}
- if (nft_tunnel_mode_validate(priv->mode, tun_info->mode))
+ if (nft_tunnel_mode_validate(priv->mode, tun_info->mode,
+ NFT_INET_NONE_TYPE))
nft_reg_store8(dest, true);
else
nft_reg_store8(dest, false);
@@ -57,7 +68,8 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,
regs->verdict.code = NFT_BREAK;
return;
}
- if (nft_tunnel_mode_validate(priv->mode, tun_info->mode))
+ if (nft_tunnel_mode_validate(priv->mode, tun_info->mode,
+ NFT_INET_NONE_TYPE))
*dest = ntohl(tunnel_id_to_key32(tun_info->key.tun_id));
else
regs->verdict.code = NFT_BREAK;
@@ -67,7 +79,8 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,
regs->verdict.code = NFT_BREAK;
return;
}
- if (nft_tunnel_mode_validate(priv->mode, tun_info->mode))
+ if (nft_tunnel_mode_validate(priv->mode, tun_info->mode,
+ NFT_INET_IP_TYPE))
*dest = tun_info->key.u.ipv4.src;
else
regs->verdict.code = NFT_BREAK;
@@ -77,7 +90,8 @@ static void nft_tunnel_get_eval(const struct nft_expr *expr,
regs->verdict.code = NFT_BREAK;
return;
}
- if (nft_tunnel_mode_validate(priv->mode, tun_info->mode))
+ if (nft_tunnel_mode_validate(priv->mode, tun_info->mode,
+ NFT_INET_IP_TYPE))
*dest = tun_info->key.u.ipv4.dst;
else
regs->verdict.code = NFT_BREAK;