Merge branch 'netlink-emsgsize'
Jakub Kicinski says: ==================== netlink: handle EMSGSIZE errors in the core Ido discovered some time back that we usually force NLMSG_DONE to be delivered in a separate recv() syscall, even if it would fit into the same skb as data messages. He made nexthop try to fit DONE with data in commit 8743aeff5bc4 ("nexthop: Fix infinite nexthop bucket dump when using maximum nexthop ID"), and nobody has complained so far. We have since also tried to follow the same pattern in new genetlink families, but explaining to people, or even remembering the correct handling ourselves is tedious. Let the netlink socket layer consume -EMSGSIZE errors. Practically speaking most families use this error code as "dump needs more space", anyway. v2: - init err to 0 in last patch v1: https://lore.kernel.org/all/20240301012845.2951053-1-kuba@kernel.org/ ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
784ee615af
@ -152,10 +152,7 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
if (err != -EMSGSIZE)
|
||||
return err;
|
||||
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -287,10 +284,7 @@ int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
if (err != -EMSGSIZE)
|
||||
return err;
|
||||
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -463,10 +457,7 @@ int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
if (err != -EMSGSIZE)
|
||||
return err;
|
||||
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int netdev_genl_netdevice_event(struct notifier_block *nb,
|
||||
|
@ -102,8 +102,6 @@ netdev_nl_page_pool_get_dump(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
mutex_unlock(&page_pools_lock);
|
||||
rtnl_unlock();
|
||||
|
||||
if (skb->len && err == -EMSGSIZE)
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -2267,6 +2267,15 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
|
||||
if (extra_mutex)
|
||||
mutex_unlock(extra_mutex);
|
||||
|
||||
/* EMSGSIZE plus something already in the skb means
|
||||
* that there's more to dump but current skb has filled up.
|
||||
* If the callback really wants to return EMSGSIZE to user space
|
||||
* it needs to do so again, on the next cb->dump() call,
|
||||
* without putting data in the skb.
|
||||
*/
|
||||
if (nlk->dump_done_errno == -EMSGSIZE && skb->len)
|
||||
nlk->dump_done_errno = skb->len;
|
||||
|
||||
cb->extack = NULL;
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1232,7 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
|
||||
|
||||
hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
|
||||
if (hdr == NULL)
|
||||
return -1;
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
|
||||
nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) ||
|
||||
@ -1355,6 +1355,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
struct net *net = sock_net(skb->sk);
|
||||
int fams_to_skip = cb->args[0];
|
||||
unsigned int id;
|
||||
int err = 0;
|
||||
|
||||
idr_for_each_entry(&genl_fam_idr, rt, id) {
|
||||
if (!rt->netnsok && !net_eq(net, &init_net))
|
||||
@ -1363,16 +1364,17 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
if (n++ < fams_to_skip)
|
||||
continue;
|
||||
|
||||
if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||
skb, CTRL_CMD_NEWFAMILY) < 0) {
|
||||
err = ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||
skb, CTRL_CMD_NEWFAMILY);
|
||||
if (err) {
|
||||
n--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cb->args[0] = n;
|
||||
return skb->len;
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family,
|
||||
|
Loading…
x
Reference in New Issue
Block a user