Commit 87d38197 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

genetlink: fit NLMSG_DONE into same read() as families

Make sure ctrl_fill_info() returns sensible error codes and
propagate them out to netlink core. Let netlink core decide
when to return skb->len and when to treat the exit as an
error. Netlink core does better job at it, if we always
return skb->len the core doesn't know when we're done
dumping and NLMSG_DONE ends up in a separate read().
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0b11b1c5
...@@ -1232,7 +1232,7 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq, ...@@ -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); hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
if (hdr == NULL) if (hdr == NULL)
return -1; return -EMSGSIZE;
if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) || if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) || 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) ...@@ -1355,6 +1355,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
int fams_to_skip = cb->args[0]; int fams_to_skip = cb->args[0];
unsigned int id; unsigned int id;
int err = 0;
idr_for_each_entry(&genl_fam_idr, rt, id) { idr_for_each_entry(&genl_fam_idr, rt, id) {
if (!rt->netnsok && !net_eq(net, &init_net)) if (!rt->netnsok && !net_eq(net, &init_net))
...@@ -1363,16 +1364,17 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -1363,16 +1364,17 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
if (n++ < fams_to_skip) if (n++ < fams_to_skip)
continue; continue;
if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid, err = ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, cb->nlh->nlmsg_seq, NLM_F_MULTI,
skb, CTRL_CMD_NEWFAMILY) < 0) { skb, CTRL_CMD_NEWFAMILY);
if (err) {
n--; n--;
break; break;
} }
} }
cb->args[0] = n; cb->args[0] = n;
return skb->len; return err;
} }
static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family, static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment