Change tc_fill_tclass() to return -EMSGSIZE when skb is too small. Change its caller to propagate this error (instead of -EINVAL) Signed-off-by: Eric Dumazet --- net/sched/sch_api.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index ed869a5ffc7377b7c19e66ae5fc9788e709488da..32ccd4672083aa19340520155aeba6d8b6ff546c 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1987,15 +1987,16 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, out_nlmsg_trim: nla_put_failure: nlmsg_trim(skb, b); - return -1; + return -EMSGSIZE; } static int tclass_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct Qdisc *q, unsigned long cl, int event, struct netlink_ext_ack *extack) { - struct sk_buff *skb; u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + struct sk_buff *skb; + int ret; if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC)) return 0; @@ -2004,9 +2005,10 @@ static int tclass_notify(struct net *net, struct sk_buff *oskb, if (!skb) return -ENOBUFS; - if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event, extack) < 0) { + ret = tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event, extack); + if (ret < 0) { kfree_skb(skb); - return -EINVAL; + return ret; } return rtnetlink_send(skb, net, portid, RTNLGRP_TC, @@ -2017,17 +2019,19 @@ static int tclass_get_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct Qdisc *q, unsigned long cl, struct netlink_ext_ack *extack) { - struct sk_buff *skb; u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + struct sk_buff *skb; + int ret; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (!skb) return -ENOBUFS; - if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, RTM_NEWTCLASS, - extack) < 0) { + ret = tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, + RTM_NEWTCLASS, extack); + if (ret < 0) { kfree_skb(skb); - return -EINVAL; + return ret; } return rtnetlink_send(skb, net, portid, RTNLGRP_TC, @@ -2041,7 +2045,7 @@ static int tclass_del_notify(struct net *net, struct netlink_ext_ack *extack) { u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; - struct sk_buff *skb; + struct sk_buff *skb = NULL; int err = 0; if (!cops->delete) @@ -2052,13 +2056,12 @@ static int tclass_del_notify(struct net *net, if (!skb) return -ENOBUFS; - if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, - RTM_DELTCLASS, extack) < 0) { + err = tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, + RTM_DELTCLASS, extack); + if (err < 0) { kfree_skb(skb); - return -EINVAL; + return err; } - } else { - skb = NULL; } err = cops->delete(q, cl, extack); -- 2.54.0.545.g6539524ca2-goog