@@ -39,6 +39,7 @@ enum {
*/
TCA_TUNNEL_KEY_ENC_TOS, /* u8 */
TCA_TUNNEL_KEY_ENC_TTL, /* u8 */
+ TCA_TUNNEL_KEY_FLAGS,
__TCA_TUNNEL_KEY_MAX,
};
@@ -193,6 +193,8 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_NESTED },
[TCA_TUNNEL_KEY_ENC_TOS] = { .type = NLA_U8 },
[TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
+ [TCA_TUNNEL_KEY_FLAGS] = { .type = NLA_BITFIELD32,
+ .validation_data = &tca_flags_allowed },
};
static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
@@ -218,6 +220,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
struct tcf_chain *goto_ch = NULL;
struct tc_tunnel_key *parm;
struct tcf_tunnel_key *t;
+ u32 index, act_flags = 0;
bool exists = false;
__be16 dst_port = 0;
__be64 key_id = 0;
@@ -225,7 +228,6 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
__be16 flags = 0;
u8 tos, ttl;
int ret = 0;
- u32 index;
int err;
if (!nla) {
@@ -346,9 +348,12 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
goto err_out;
}
+ if (tb[TCA_TUNNEL_KEY_FLAGS])
+ act_flags = nla_get_bitfield32(tb[TCA_TUNNEL_KEY_FLAGS]).value;
+
if (!exists) {
ret = tcf_idr_create(tn, index, est, a,
- &act_tunnel_key_ops, bind, 0);
+ &act_tunnel_key_ops, bind, act_flags);
if (ret) {
NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
goto release_tun_meta;
@@ -552,6 +557,15 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
goto nla_put_failure;
}
+ if (t->tcf_flags) {
+ struct nla_bitfield32 flags = { t->tcf_flags,
+ t->tcf_flags };
+
+ if (nla_put(skb, TCA_TUNNEL_KEY_FLAGS,
+ sizeof(struct nla_bitfield32), &flags))
+ goto nla_put_failure;
+ }
+
tcf_tm_dump(&tm, &t->tcf_tm);
if (nla_put_64bit(skb, TCA_TUNNEL_KEY_TM, sizeof(tm),
&tm, TCA_TUNNEL_KEY_PAD))