diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 69d4676a402f..b0d1e00fe2c2 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -842,6 +842,7 @@ static const struct nla_policy tcf_action_policy[TCA_ACT_MAX + 1] = { struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, struct nlattr *nla, struct nlattr *est, char *name, int ovr, int bind, + struct nla_bitfield32 *root_flags, bool rtnl_held, struct netlink_ext_ack *extack) { @@ -914,10 +915,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, /* backward compatibility for policer */ if (name == NULL) err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind, - rtnl_held, tp, extack); + rtnl_held, root_flags, tp, extack); else err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held, - tp, extack); + root_flags, tp, extack); if (err < 0) goto err_mod; @@ -955,7 +956,8 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, struct nlattr *est, char *name, int ovr, int bind, struct tc_action *actions[], size_t *attr_size, - bool rtnl_held, struct netlink_ext_ack *extack) + bool rtnl_held, struct nla_bitfield32 *root_flags, + struct netlink_ext_ack *extack) { struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; struct tc_action *act; @@ -970,7 +972,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind, - rtnl_held, extack); + root_flags, rtnl_held, extack); if (IS_ERR(act)) { err = PTR_ERR(act); goto err; @@ -1350,6 +1352,7 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[], static int tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, u32 portid, int ovr, + struct nla_bitfield32 *root_flags, struct netlink_ext_ack *extack) { size_t attr_size = 0; @@ -1358,7 +1361,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla, for (loop = 0; loop < 10; loop++) { ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, - actions, &attr_size, true, extack); + actions, &attr_size, true, root_flags, + extack); if (ret != -EAGAIN) break; } @@ -1385,6 +1389,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_ROOT_MAX + 1]; u32 portid = skb ? NETLINK_CB(skb).portid : 0; + struct nla_bitfield32 root_flags = {0, 0}; int ret = 0, ovr = 0; if ((n->nlmsg_type != RTM_GETACTION) && @@ -1412,8 +1417,11 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, */ if (n->nlmsg_flags & NLM_F_REPLACE) ovr = 1; + if (tb[TCA_ROOT_FLAGS]) + root_flags = nla_get_bitfield32(tb[TCA_ROOT_FLAGS]); + ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr, - extack); + &root_flags, extack); break; case RTM_DELACTION: ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,