@@ -26,6 +26,7 @@ enum {
TCA_GACT_PARMS,
TCA_GACT_PROB,
TCA_GACT_PAD,
+ TCA_GACT_FLAGS,
__TCA_GACT_MAX
};
#define TCA_GACT_MAX (__TCA_GACT_MAX - 1)
@@ -48,6 +48,8 @@ static g_rand gact_rand[MAX_RAND] = { NULL, gact_net_rand, gact_determ };
static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
[TCA_GACT_PARMS] = { .len = sizeof(struct tc_gact) },
[TCA_GACT_PROB] = { .len = sizeof(struct tc_gact_p) },
+ [TCA_GACT_FLAGS] = { .type = NLA_BITFIELD32,
+ .validation_data = &tca_flags_allowed },
};
static int tcf_gact_init(struct net *net, struct nlattr *nla,
@@ -60,8 +62,8 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
struct tcf_chain *goto_ch = NULL;
struct tc_gact *parm;
struct tcf_gact *gact;
+ u32 index, flags = 0;
int ret = 0;
- u32 index;
int err;
#ifdef CONFIG_GACT_PROB
struct tc_gact_p *p_parm = NULL;
@@ -96,10 +98,13 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
}
#endif
+ if (tb[TCA_GACT_FLAGS])
+ flags = nla_get_bitfield32(tb[TCA_GACT_FLAGS]).value;
+
err = tcf_idr_check_alloc(tn, &index, a, bind);
if (!err) {
ret = tcf_idr_create(tn, index, est, a,
- &act_gact_ops, bind, 0);
+ &act_gact_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
@@ -209,6 +214,15 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a,
goto nla_put_failure;
}
#endif
+ if (gact->tcf_flags) {
+ struct nla_bitfield32 flags = { gact->tcf_flags,
+ gact->tcf_flags };
+
+ if (nla_put(skb, TCA_GACT_FLAGS, sizeof(struct nla_bitfield32),
+ &flags))
+ goto nla_put_failure;
+ }
+
tcf_tm_dump(&t, &gact->tcf_tm);
if (nla_put_64bit(skb, TCA_GACT_TM, sizeof(t), &t, TCA_GACT_PAD))
goto nla_put_failure;