@@ -10,6 +10,7 @@ enum {
TCA_CSUM_PARMS,
TCA_CSUM_TM,
TCA_CSUM_PAD,
+ TCA_CSUM_FLAGS,
__TCA_CSUM_MAX
};
#define TCA_CSUM_MAX (__TCA_CSUM_MAX - 1)
@@ -35,6 +35,8 @@
static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = {
[TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), },
+ [TCA_CSUM_FLAGS] = { .type = NLA_BITFIELD32,
+ .validation_data = &tca_flags_allowed },
};
static unsigned int csum_net_id;
@@ -50,9 +52,9 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
struct nlattr *tb[TCA_CSUM_MAX + 1];
struct tcf_chain *goto_ch = NULL;
struct tc_csum *parm;
+ u32 index, flags = 0;
struct tcf_csum *p;
int ret = 0, err;
- u32 index;
if (nla == NULL)
return -EINVAL;
@@ -66,10 +68,14 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
return -EINVAL;
parm = nla_data(tb[TCA_CSUM_PARMS]);
index = parm->index;
+
+ if (tb[TCA_CSUM_FLAGS])
+ flags = nla_get_bitfield32(tb[TCA_CSUM_FLAGS]).value;
+
err = tcf_idr_check_alloc(tn, &index, a, bind);
if (!err) {
ret = tcf_idr_create(tn, index, est, a,
- &act_csum_ops, bind, 0);
+ &act_csum_ops, bind, flags);
if (ret) {
tcf_idr_cleanup(tn, index);
return ret;
@@ -650,6 +656,14 @@ static int tcf_csum_dump(struct sk_buff *skb, struct tc_action *a, int bind,
if (nla_put(skb, TCA_CSUM_PARMS, sizeof(opt), &opt))
goto nla_put_failure;
+ if (p->tcf_flags) {
+ struct nla_bitfield32 flags = { p->tcf_flags,
+ p->tcf_flags };
+
+ if (nla_put(skb, TCA_CSUM_FLAGS, sizeof(struct nla_bitfield32),
+ &flags))
+ goto nla_put_failure;
+ }
tcf_tm_dump(&t, &p->tcf_tm);
if (nla_put_64bit(skb, TCA_CSUM_TM, sizeof(t), &t, TCA_CSUM_PAD))