Merge branch 'net-sched-act-add-extack-support'
Alexander Aring says: ==================== net: sched: act: add extack support this patch series adds extack support for the TC action subsystem. As example I for the extack support in a TC action I choosed mirred action. - Alex Cc: David Ahern <dsahern@gmail.com> changes since v3: - adapt recommended changes from Davide Caratti, please check if I catch everything. Thanks. changes since v2: - remove newline in extack of generic walker handling Thanks to Davide Caratti - add kernel@mojatatu.com in cc ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4a8864822d
|
@ -87,12 +87,15 @@ struct tc_action_ops {
|
|||
struct tcf_result *);
|
||||
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
|
||||
void (*cleanup)(struct tc_action *);
|
||||
int (*lookup)(struct net *, struct tc_action **, u32);
|
||||
int (*lookup)(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack);
|
||||
int (*init)(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **act, int ovr,
|
||||
int bind);
|
||||
int bind, struct netlink_ext_ack *extack);
|
||||
int (*walk)(struct net *, struct sk_buff *,
|
||||
struct netlink_callback *, int, const struct tc_action_ops *);
|
||||
struct netlink_callback *, int,
|
||||
const struct tc_action_ops *,
|
||||
struct netlink_ext_ack *);
|
||||
void (*stats_update)(struct tc_action *, u64, u32, u64);
|
||||
struct net_device *(*get_dev)(const struct tc_action *a);
|
||||
};
|
||||
|
@ -137,7 +140,8 @@ static inline void tc_action_net_exit(struct list_head *net_list,
|
|||
|
||||
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops);
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack);
|
||||
int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
|
||||
bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
|
||||
int bind);
|
||||
|
@ -162,10 +166,11 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
|
|||
int nr_actions, struct tcf_result *res);
|
||||
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
|
||||
struct nlattr *est, char *name, int ovr, int bind,
|
||||
struct list_head *actions);
|
||||
struct list_head *actions, struct netlink_ext_ack *extack);
|
||||
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);
|
||||
char *name, int ovr, int bind,
|
||||
struct netlink_ext_ack *extack);
|
||||
int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
|
||||
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
|
||||
int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
|
||||
|
|
|
@ -202,7 +202,8 @@ static int tcf_del_walker(struct tcf_idrinfo *idrinfo, struct sk_buff *skb,
|
|||
|
||||
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tcf_idrinfo *idrinfo = tn->idrinfo;
|
||||
|
||||
|
@ -211,7 +212,8 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
|
|||
} else if (type == RTM_GETACTION) {
|
||||
return tcf_dump_walker(idrinfo, skb, cb);
|
||||
} else {
|
||||
WARN(1, "tcf_generic_walker: unknown action %d\n", type);
|
||||
WARN(1, "tcf_generic_walker: unknown command %d\n", type);
|
||||
NL_SET_ERR_MSG(extack, "tcf_generic_walker: unknown command");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -605,7 +607,8 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
|
|||
|
||||
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)
|
||||
char *name, int ovr, int bind,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action *a;
|
||||
struct tc_action_ops *a_o;
|
||||
|
@ -616,31 +619,40 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
|
|||
int err;
|
||||
|
||||
if (name == NULL) {
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
err = -EINVAL;
|
||||
kind = tb[TCA_ACT_KIND];
|
||||
if (kind == NULL)
|
||||
if (!kind) {
|
||||
NL_SET_ERR_MSG(extack, "TC action kind must be specified");
|
||||
goto err_out;
|
||||
if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
|
||||
}
|
||||
if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
|
||||
NL_SET_ERR_MSG(extack, "TC action name too long");
|
||||
goto err_out;
|
||||
}
|
||||
if (tb[TCA_ACT_COOKIE]) {
|
||||
int cklen = nla_len(tb[TCA_ACT_COOKIE]);
|
||||
|
||||
if (cklen > TC_COOKIE_MAX_SIZE)
|
||||
if (cklen > TC_COOKIE_MAX_SIZE) {
|
||||
NL_SET_ERR_MSG(extack, "TC cookie size above the maximum");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
cookie = nla_memdup_cookie(tb);
|
||||
if (!cookie) {
|
||||
NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
|
||||
if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
|
||||
NL_SET_ERR_MSG(extack, "TC action name too long");
|
||||
err = -EINVAL;
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
a_o = tc_lookup_action_n(act_name);
|
||||
|
@ -663,15 +675,17 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
|
|||
goto err_mod;
|
||||
}
|
||||
#endif
|
||||
NL_SET_ERR_MSG(extack, "Failed to load TC action module");
|
||||
err = -ENOENT;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* backward compatibility for policer */
|
||||
if (name == NULL)
|
||||
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind);
|
||||
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
|
||||
extack);
|
||||
else
|
||||
err = a_o->init(net, nla, est, &a, ovr, bind);
|
||||
err = a_o->init(net, nla, est, &a, ovr, bind, extack);
|
||||
if (err < 0)
|
||||
goto err_mod;
|
||||
|
||||
|
@ -697,6 +711,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
|
|||
|
||||
list_add_tail(&a->list, &actions);
|
||||
tcf_action_destroy(&actions, bind);
|
||||
NL_SET_ERR_MSG(extack, "Failed to init TC action chain");
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
@ -726,19 +741,20 @@ static void cleanup_a(struct list_head *actions, int ovr)
|
|||
|
||||
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
|
||||
struct nlattr *est, char *name, int ovr, int bind,
|
||||
struct list_head *actions)
|
||||
struct list_head *actions, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
|
||||
struct tc_action *act;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
|
||||
act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind);
|
||||
act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
|
||||
extack);
|
||||
if (IS_ERR(act)) {
|
||||
err = PTR_ERR(act);
|
||||
goto err;
|
||||
|
@ -822,7 +838,7 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
|
|||
t->tca__pad2 = 0;
|
||||
|
||||
nest = nla_nest_start(skb, TCA_ACT_TAB);
|
||||
if (nest == NULL)
|
||||
if (!nest)
|
||||
goto out_nlmsg_trim;
|
||||
|
||||
if (tcf_action_dump(skb, actions, bind, ref) < 0)
|
||||
|
@ -840,7 +856,8 @@ static int tca_get_fill(struct sk_buff *skb, struct list_head *actions,
|
|||
|
||||
static int
|
||||
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
|
||||
struct list_head *actions, int event)
|
||||
struct list_head *actions, int event,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
|
@ -849,6 +866,7 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
|
|||
return -ENOBUFS;
|
||||
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
|
||||
0, 0) <= 0) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -857,7 +875,8 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
|
|||
}
|
||||
|
||||
static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
|
||||
struct nlmsghdr *n, u32 portid)
|
||||
struct nlmsghdr *n, u32 portid,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct nlattr *tb[TCA_ACT_MAX + 1];
|
||||
const struct tc_action_ops *ops;
|
||||
|
@ -865,22 +884,26 @@ static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
|
|||
int index;
|
||||
int err;
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
|
||||
err = -EINVAL;
|
||||
if (tb[TCA_ACT_INDEX] == NULL ||
|
||||
nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
|
||||
nla_len(tb[TCA_ACT_INDEX]) < sizeof(index)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid TC action index value");
|
||||
goto err_out;
|
||||
}
|
||||
index = nla_get_u32(tb[TCA_ACT_INDEX]);
|
||||
|
||||
err = -EINVAL;
|
||||
ops = tc_lookup_action(tb[TCA_ACT_KIND]);
|
||||
if (!ops) /* could happen in batch of actions */
|
||||
if (!ops) { /* could happen in batch of actions */
|
||||
NL_SET_ERR_MSG(extack, "Specified TC action not found");
|
||||
goto err_out;
|
||||
}
|
||||
err = -ENOENT;
|
||||
if (ops->lookup(net, &a, index) == 0)
|
||||
if (ops->lookup(net, &a, index, extack) == 0)
|
||||
goto err_mod;
|
||||
|
||||
module_put(ops->owner);
|
||||
|
@ -893,7 +916,8 @@ static struct tc_action *tcf_action_get_1(struct net *net, struct nlattr *nla,
|
|||
}
|
||||
|
||||
static int tca_action_flush(struct net *net, struct nlattr *nla,
|
||||
struct nlmsghdr *n, u32 portid)
|
||||
struct nlmsghdr *n, u32 portid,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned char *b;
|
||||
|
@ -907,37 +931,41 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
|
|||
int err = -ENOMEM;
|
||||
|
||||
skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
pr_debug("tca_action_flush: failed skb alloc\n");
|
||||
if (!skb)
|
||||
return err;
|
||||
}
|
||||
|
||||
b = skb_tail_pointer(skb);
|
||||
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, NULL);
|
||||
err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL, extack);
|
||||
if (err < 0)
|
||||
goto err_out;
|
||||
|
||||
err = -EINVAL;
|
||||
kind = tb[TCA_ACT_KIND];
|
||||
ops = tc_lookup_action(kind);
|
||||
if (!ops) /*some idjot trying to flush unknown action */
|
||||
if (!ops) { /*some idjot trying to flush unknown action */
|
||||
NL_SET_ERR_MSG(extack, "Cannot flush unknown TC action");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
|
||||
sizeof(*t), 0);
|
||||
if (!nlh)
|
||||
if (!nlh) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to create TC action flush notification");
|
||||
goto out_module_put;
|
||||
}
|
||||
t = nlmsg_data(nlh);
|
||||
t->tca_family = AF_UNSPEC;
|
||||
t->tca__pad1 = 0;
|
||||
t->tca__pad2 = 0;
|
||||
|
||||
nest = nla_nest_start(skb, TCA_ACT_TAB);
|
||||
if (nest == NULL)
|
||||
if (!nest) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to add new netlink message");
|
||||
goto out_module_put;
|
||||
}
|
||||
|
||||
err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops);
|
||||
err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops, extack);
|
||||
if (err <= 0) {
|
||||
nla_nest_cancel(skb, nest);
|
||||
goto out_module_put;
|
||||
|
@ -952,6 +980,8 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
|
|||
n->nlmsg_flags & NLM_F_ECHO);
|
||||
if (err > 0)
|
||||
return 0;
|
||||
if (err < 0)
|
||||
NL_SET_ERR_MSG(extack, "Failed to send TC action flush notification");
|
||||
|
||||
return err;
|
||||
|
||||
|
@ -964,7 +994,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
|
|||
|
||||
static int
|
||||
tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
||||
u32 portid)
|
||||
u32 portid, struct netlink_ext_ack *extack)
|
||||
{
|
||||
int ret;
|
||||
struct sk_buff *skb;
|
||||
|
@ -975,6 +1005,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
|||
|
||||
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
|
||||
0, 1) <= 0) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -982,6 +1013,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
|||
/* now do the delete */
|
||||
ret = tcf_action_destroy(actions, 0);
|
||||
if (ret < 0) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to delete TC action");
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
@ -995,26 +1027,27 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
|||
|
||||
static int
|
||||
tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
|
||||
u32 portid, int event)
|
||||
u32 portid, int event, struct netlink_ext_ack *extack)
|
||||
{
|
||||
int i, ret;
|
||||
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
|
||||
struct tc_action *act;
|
||||
LIST_HEAD(actions);
|
||||
|
||||
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, NULL);
|
||||
ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
|
||||
if (tb[1] != NULL)
|
||||
return tca_action_flush(net, tb[1], n, portid);
|
||||
else
|
||||
return -EINVAL;
|
||||
if (tb[1])
|
||||
return tca_action_flush(net, tb[1], n, portid, extack);
|
||||
|
||||
NL_SET_ERR_MSG(extack, "Invalid netlink attributes while flushing TC action");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
|
||||
act = tcf_action_get_1(net, tb[i], n, portid);
|
||||
act = tcf_action_get_1(net, tb[i], n, portid, extack);
|
||||
if (IS_ERR(act)) {
|
||||
ret = PTR_ERR(act);
|
||||
goto err;
|
||||
|
@ -1024,9 +1057,9 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
|
|||
}
|
||||
|
||||
if (event == RTM_GETACTION)
|
||||
ret = tcf_get_notify(net, portid, n, &actions, event);
|
||||
ret = tcf_get_notify(net, portid, n, &actions, event, extack);
|
||||
else { /* delete */
|
||||
ret = tcf_del_notify(net, n, &actions, portid);
|
||||
ret = tcf_del_notify(net, n, &actions, portid, extack);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
|
@ -1039,7 +1072,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
|
|||
|
||||
static int
|
||||
tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
||||
u32 portid)
|
||||
u32 portid, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err = 0;
|
||||
|
@ -1050,6 +1083,7 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
|||
|
||||
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
|
||||
RTM_NEWACTION, 0, 0) <= 0) {
|
||||
NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while deleting TC action");
|
||||
kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1062,16 +1096,18 @@ tcf_add_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
|
|||
}
|
||||
|
||||
static int tcf_action_add(struct net *net, struct nlattr *nla,
|
||||
struct nlmsghdr *n, u32 portid, int ovr)
|
||||
struct nlmsghdr *n, u32 portid, int ovr,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
int ret = 0;
|
||||
LIST_HEAD(actions);
|
||||
|
||||
ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions);
|
||||
ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions,
|
||||
extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return tcf_add_notify(net, n, &actions, portid);
|
||||
return tcf_add_notify(net, n, &actions, portid, extack);
|
||||
}
|
||||
|
||||
static u32 tcaa_root_flags_allowed = TCA_FLAG_LARGE_DUMP_ON;
|
||||
|
@ -1099,7 +1135,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
return ret;
|
||||
|
||||
if (tca[TCA_ACT_TAB] == NULL) {
|
||||
pr_notice("tc_ctl_action: received NO action attribs\n");
|
||||
NL_SET_ERR_MSG(extack, "Netlink action attributes missing");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1115,17 +1151,18 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
if (n->nlmsg_flags & NLM_F_REPLACE)
|
||||
ovr = 1;
|
||||
replay:
|
||||
ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr);
|
||||
ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr,
|
||||
extack);
|
||||
if (ret == -EAGAIN)
|
||||
goto replay;
|
||||
break;
|
||||
case RTM_DELACTION:
|
||||
ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
|
||||
portid, RTM_DELACTION);
|
||||
portid, RTM_DELACTION, extack);
|
||||
break;
|
||||
case RTM_GETACTION:
|
||||
ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
|
||||
portid, RTM_GETACTION);
|
||||
portid, RTM_GETACTION, extack);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
|
@ -1220,7 +1257,7 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
if (nest == NULL)
|
||||
goto out_module_put;
|
||||
|
||||
ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o);
|
||||
ret = a_o->walk(net, skb, cb, RTM_GETACTION, a_o, NULL);
|
||||
if (ret < 0)
|
||||
goto out_module_put;
|
||||
|
||||
|
|
|
@ -272,7 +272,7 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,
|
|||
|
||||
static int tcf_bpf_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **act,
|
||||
int replace, int bind)
|
||||
int replace, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, bpf_net_id);
|
||||
struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
|
||||
|
@ -367,14 +367,16 @@ static void tcf_bpf_cleanup(struct tc_action *act)
|
|||
|
||||
static int tcf_bpf_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, bpf_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, bpf_net_id);
|
||||
|
||||
|
|
|
@ -96,7 +96,8 @@ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {
|
|||
|
||||
static int tcf_connmark_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, connmark_net_id);
|
||||
struct nlattr *tb[TCA_CONNMARK_MAX + 1];
|
||||
|
@ -176,14 +177,16 @@ static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_connmark_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, connmark_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, connmark_net_id);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ static struct tc_action_ops act_csum_ops;
|
|||
|
||||
static int tcf_csum_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a, int ovr,
|
||||
int bind)
|
||||
int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, csum_net_id);
|
||||
struct tcf_csum_params *params_old, *params_new;
|
||||
|
@ -631,14 +631,16 @@ static void tcf_csum_cleanup(struct tc_action *a)
|
|||
|
||||
static int tcf_csum_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, csum_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_csum_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, csum_net_id);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
|
|||
|
||||
static int tcf_gact_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, gact_net_id);
|
||||
struct nlattr *tb[TCA_GACT_MAX + 1];
|
||||
|
@ -201,14 +201,16 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_gact_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, gact_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_gact_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, gact_net_id);
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,
|
|||
|
||||
static int tcf_ife_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, ife_net_id);
|
||||
struct nlattr *tb[TCA_IFE_MAX + 1];
|
||||
|
@ -824,14 +824,16 @@ static int tcf_ife_act(struct sk_buff *skb, const struct tc_action *a,
|
|||
|
||||
static int tcf_ife_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, ife_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, ife_net_id);
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
|
|||
|
||||
static int tcf_ipt_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a, int ovr,
|
||||
int bind)
|
||||
int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
|
||||
bind);
|
||||
|
@ -201,7 +201,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla,
|
|||
|
||||
static int tcf_xt_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a, int ovr,
|
||||
int bind)
|
||||
int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
|
||||
bind);
|
||||
|
@ -303,14 +303,16 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind,
|
|||
|
||||
static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, ipt_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, ipt_net_id);
|
||||
|
||||
|
@ -351,14 +353,16 @@ static struct pernet_operations ipt_net_ops = {
|
|||
|
||||
static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, xt_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, xt_net_id);
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ static struct tc_action_ops act_mirred_ops;
|
|||
|
||||
static int tcf_mirred_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a, int ovr,
|
||||
int bind)
|
||||
int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, mirred_net_id);
|
||||
struct nlattr *tb[TCA_MIRRED_MAX + 1];
|
||||
|
@ -80,13 +80,17 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
|
|||
bool exists = false;
|
||||
int ret;
|
||||
|
||||
if (nla == NULL)
|
||||
if (!nla) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be passed");
|
||||
return -EINVAL;
|
||||
ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, NULL);
|
||||
}
|
||||
ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy, extack);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (tb[TCA_MIRRED_PARMS] == NULL)
|
||||
if (!tb[TCA_MIRRED_PARMS]) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Missing required mirred parameters");
|
||||
return -EINVAL;
|
||||
}
|
||||
parm = nla_data(tb[TCA_MIRRED_PARMS]);
|
||||
|
||||
exists = tcf_idr_check(tn, parm->index, a, bind);
|
||||
|
@ -102,6 +106,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
|
|||
default:
|
||||
if (exists)
|
||||
tcf_idr_release(*a, bind);
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (parm->ifindex) {
|
||||
|
@ -117,8 +122,10 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
|
|||
}
|
||||
|
||||
if (!exists) {
|
||||
if (dev == NULL)
|
||||
if (!dev) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Specified device does not exist");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = tcf_idr_create(tn, parm->index, est, a,
|
||||
&act_mirred_ops, bind, true);
|
||||
if (ret)
|
||||
|
@ -265,14 +272,16 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
|
|||
|
||||
static int tcf_mirred_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, mirred_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_mirred_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, mirred_net_id);
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
|
|||
};
|
||||
|
||||
static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
|
||||
struct tc_action **a, int ovr, int bind)
|
||||
struct tc_action **a, int ovr, int bind,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, nat_net_id);
|
||||
struct nlattr *tb[TCA_NAT_MAX + 1];
|
||||
|
@ -277,14 +278,16 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_nat_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, nat_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, nat_net_id);
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,
|
|||
|
||||
static int tcf_pedit_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, pedit_net_id);
|
||||
struct nlattr *tb[TCA_PEDIT_MAX + 1];
|
||||
|
@ -419,14 +419,16 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_pedit_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, pedit_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, pedit_net_id);
|
||||
|
||||
|
|
|
@ -58,11 +58,12 @@ static struct tc_action_ops act_police_ops;
|
|||
|
||||
static int tcf_act_police_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, police_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
|
||||
|
@ -74,7 +75,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
|
|||
|
||||
static int tcf_act_police_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
int ret = 0, err;
|
||||
struct nlattr *tb[TCA_POLICE_MAX + 1];
|
||||
|
@ -304,7 +306,8 @@ static int tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_police_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, police_net_id);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ static const struct nla_policy sample_policy[TCA_SAMPLE_MAX + 1] = {
|
|||
|
||||
static int tcf_sample_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a, int ovr,
|
||||
int bind)
|
||||
int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, sample_net_id);
|
||||
struct nlattr *tb[TCA_SAMPLE_MAX + 1];
|
||||
|
@ -202,14 +202,16 @@ static int tcf_sample_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_sample_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, sample_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, sample_net_id);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
|
|||
|
||||
static int tcf_simp_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, simp_net_id);
|
||||
struct nlattr *tb[TCA_DEF_MAX + 1];
|
||||
|
@ -170,14 +170,16 @@ static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_simp_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, simp_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, simp_net_id);
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
|
|||
|
||||
static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbedit_net_id);
|
||||
struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
|
||||
|
@ -208,14 +208,16 @@ static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_skbedit_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbedit_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbedit_net_id);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ static const struct nla_policy skbmod_policy[TCA_SKBMOD_MAX + 1] = {
|
|||
|
||||
static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbmod_net_id);
|
||||
struct nlattr *tb[TCA_SKBMOD_MAX + 1];
|
||||
|
@ -232,14 +232,16 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_skbmod_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbmod_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, skbmod_net_id);
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
|
|||
|
||||
static int tunnel_key_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
|
||||
struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
|
||||
|
@ -291,14 +291,16 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tunnel_key_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {
|
|||
|
||||
static int tcf_vlan_init(struct net *net, struct nlattr *nla,
|
||||
struct nlattr *est, struct tc_action **a,
|
||||
int ovr, int bind)
|
||||
int ovr, int bind, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, vlan_net_id);
|
||||
struct nlattr *tb[TCA_VLAN_MAX + 1];
|
||||
|
@ -267,14 +267,16 @@ static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a,
|
|||
|
||||
static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, int type,
|
||||
const struct tc_action_ops *ops)
|
||||
const struct tc_action_ops *ops,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, vlan_net_id);
|
||||
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops);
|
||||
return tcf_generic_walker(tn, skb, cb, type, ops, extack);
|
||||
}
|
||||
|
||||
static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index)
|
||||
static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct tc_action_net *tn = net_generic(net, vlan_net_id);
|
||||
|
||||
|
|
|
@ -1434,7 +1434,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
|
|||
if (exts->police && tb[exts->police]) {
|
||||
act = tcf_action_init_1(net, tp, tb[exts->police],
|
||||
rate_tlv, "police", ovr,
|
||||
TCA_ACT_BIND);
|
||||
TCA_ACT_BIND, extack);
|
||||
if (IS_ERR(act))
|
||||
return PTR_ERR(act);
|
||||
|
||||
|
@ -1447,7 +1447,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
|
|||
|
||||
err = tcf_action_init(net, tp, tb[exts->action],
|
||||
rate_tlv, NULL, ovr, TCA_ACT_BIND,
|
||||
&actions);
|
||||
&actions, extack);
|
||||
if (err)
|
||||
return err;
|
||||
list_for_each_entry(act, &actions, list)
|
||||
|
|
Loading…
Reference in New Issue