On Wed, 2018-02-14 at 17:13 -0500, Alexander Aring wrote: > This patch adds extack support for generic act handling. The extack > will be set deeper to each called function which is not part of netdev > core api. > > Based on work by David Ahern <dsah...@gmail.com>
hello Alexander, after looking at the code more closely, I think there is margin for some more improvement here (i.e make the message contents easier to grep from a log). Please let me know if the comments below make sense for you. thank you in advance! -- davide > Cc: David Ahern <dsah...@gmail.com> > Signed-off-by: Alexander Aring <ar...@mojatatu.com> > --- > net/sched/act_api.c | 93 > +++++++++++++++++++++++++++++++++++------------------ > 1 file changed, 61 insertions(+), 32 deletions(-) > > diff --git a/net/sched/act_api.c b/net/sched/act_api.c > index 8d89b026414f..a5138ae026a1 100644 > --- a/net/sched/act_api.c > +++ b/net/sched/act_api.c > @@ -617,31 +617,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) > + 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); > @@ -664,6 +673,7 @@ 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; > } > @@ -698,6 +708,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 action chain"); most of the times, the word 'action' is prepended by the word 'TC'. Proposal: "Failed to init TC action chain" > return ERR_PTR(err); > } > } > @@ -734,7 +745,7 @@ int tcf_action_init(struct net *net, struct tcf_proto > *tp, struct nlattr *nla, > 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; > > @@ -842,7 +853,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; > > @@ -851,6 +863,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 tc action > attributes"); see also @@ -975,6 +1000,7 @@ and @@ -975,6 +1000,7 @@: this is the same message you get in case tcf_add_notify() fails, and it's very similar to what you get when tcf_del_notify() fails: the only difference is uppercase/lowercase 'tc' word. Proposal: "Failed to fill netlink attributes while getting TC action" > kfree_skb(skb); > return -EINVAL; > } > @@ -859,7 +872,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; > @@ -867,20 +881,24 @@ 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) > goto err_mod; > @@ -895,7 +913,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; > @@ -909,35 +928,39 @@ 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 */ the above comment was already there before your patch. I think that it can be removed, now that we have an error message for this situation; it's also funny (and harmless) to leave it - but then maybe it becomes more clear if the word 'idiot' is spelled correctly :) > + NL_SET_ERR_MSG(extack, "Aborted Flush. Cannot flush unknown TC > action"); Also the tests below result in an aborted flush when they fail. So, 'Aborted Flush' can probably be omitted. Proposal: "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, "Aborted Flush. Failed to create flush > netlink notification"); Proposal: "Failed to create netlink notification while flushing TC action". But I'm not sure that these kind of errors deserve an extended ACK (see below). > 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) > + if (!nest) { > + NL_SET_ERR_MSG(extack, "Failed to add new netlink message"); "Failed to set nested attribute while flushing TC action". But I'm not sure that this kind of errors deserve an extended ACK. Probaly a good compromise is to do a single message in the error path of the function (i.e. below the "out_module_put" label). > goto out_module_put; > + } > > err = ops->walk(net, skb, &dcb, RTM_DELACTION, ops); > if (err <= 0) here the action flush is aborted because walk() failed. Is it worth adding a message here? (I'm also ok if there is a single error below "out_module_put" label). (and, for the record, I think we miss a nla_nest_cancel() here. I will post a patch targeting 'net' today.) > @@ -952,6 +975,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 flush notification"); Proposal: "Failed to send TC action flush notification" > > return err; > > @@ -964,7 +989,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 +1000,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"); see also @@ -1039,7 +1067,7 @@: this error message is almost the same as the one we get in case of failing tca_get_fill(..., RTM_NEWACTION, ...) in tcf_add_notify(). The only difference is the word 'tc' lowercase here, and uppercase word 'TC' in tcf_add_notify(). So, if these message must be different, it's better to specify better what went wrong _ something like: "Failed to fill netlink attributes while deleting TC action" > kfree_skb(skb); > return -EINVAL; > } > @@ -982,6 +1008,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 +1022,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]) > - return tca_action_flush(net, tb[1], n, portid); > + return tca_action_flush(net, tb[1], n, portid, extack); > > + NL_SET_ERR_MSG(extack, "Invalid netlink attributes to flush > actions"); "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 +1052,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 +1067,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 +1078,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 tc action > attributes"); see comment at @@ -975,6 +1000,7 @@ "Failed to fill netlink attributes while adding TC action" > kfree_skb(skb); > return -EINVAL; > } > @@ -1073,7 +1102,7 @@ static int tcf_action_add(struct net *net, struct > nlattr *nla, > 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; > @@ -1101,7 +1130,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"); "action" is lowercase in almost all messages, and tipically prepended by 'TC' keyword: "Missing netlink attributes for TC action" > return -EINVAL; > } > > @@ -1124,11 +1153,11 @@ static int tc_ctl_action(struct sk_buff *skb, struct > nlmsghdr *n, > 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();