From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from droplet.rkapl.cz ([46.101.253.207]:37308 "EHLO droplet.rkapl.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753624AbeBSUc7 (ORCPT ); Mon, 19 Feb 2018 15:32:59 -0500 From: Roman Kapl To: netdev@vger.kernel.org Cc: "David S . Miller" , Jiri Pirko , Cong Wang , Jiri Benc , Roman Kapl Subject: [PATCH v2] sched: report if filter is too large to dump Date: Mon, 19 Feb 2018 21:32:51 +0100 Message-Id: <20180219203251.30273-1-code@rkapl.cz> Sender: netdev-owner@vger.kernel.org List-ID: So far, if the filter was too large to fit in the allocated skb, the kernel did not return any error and stopped dumping. Modify the dumper so that it returns -EMSGSIZE when a filter fails to dump and it is the first filter in the skb. If we are not first, we will get a next chance with more room. I understand this is pretty near to being an API change, but the original design (silent truncation) can be considered a bug. Note: The error case can happen pretty easily if you create a filter with 32 actions and have 4kb pages. Also recent versions of iproute try to be clever with their buffer allocation size, which in turn leads to Signed-off-by: Roman Kapl --- v1 -> v2: add the "progress" comment, fixed error name in commit message. I've looked at other dumpers in rtnetnlink, there are various ways to handle that. For example rtnl_stats_dump has: WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); rtnl_dump_ifinfo has the same logic I am proposing: if (err < 0) if (skb->len) goto out; goto out_err; Other functions handle the error in the "wrong" way (= what we currently do). Although it might be OK if there is no array in what they return. I have not tested the behavior, since the only way I found was to have a device with many VFs. net/sched/cls_api.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index f21610c5da1a..92e9308bb920 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -1399,13 +1399,18 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) nla_get_u32(tca[TCA_CHAIN]) != chain->index) continue; if (!tcf_chain_dump(chain, q, parent, skb, cb, - index_start, &index)) + index_start, &index)) { + err = -EMSGSIZE; break; + } } cb->args[0] = index; out: + /* If we did no progress, the error (EMSGSIZE) is real */ + if (skb->len == 0 && err) + return err; return skb->len; } -- 2.16.1