Commit a9341512 authored by Jesse Gross's avatar Jesse Gross

openvswitch: Preallocate reply skb in ovs_vport_cmd_set().

Allocation of the Netlink notification skb can potentially fail
after changing vport configuration.  In general, we try to avoid
this by undoing any change we made but that is difficult for existing
objects.  This avoids the problem by preallocating the buffer (which
is fixed size).
Signed-off-by: default avatarJesse Gross <jesse@nicira.com>
parent 330305cc
......@@ -1593,10 +1593,8 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
return ERR_PTR(-ENOMEM);
retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
if (retval < 0) {
kfree_skb(skb);
return ERR_PTR(retval);
}
BUG_ON(retval < 0);
return skb;
}
......@@ -1726,24 +1724,32 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type)
err = -EINVAL;
reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!reply) {
err = -ENOMEM;
goto exit_unlock;
}
if (!err && a[OVS_VPORT_ATTR_OPTIONS])
err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
if (err)
goto exit_unlock;
goto exit_free;
if (a[OVS_VPORT_ATTR_UPCALL_PID])
vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq,
OVS_VPORT_CMD_NEW);
if (IS_ERR(reply)) {
netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
goto exit_unlock;
}
err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
info->snd_seq, 0, OVS_VPORT_CMD_NEW);
BUG_ON(err < 0);
genl_notify(reply, genl_info_net(info), info->snd_portid,
ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
rtnl_unlock();
return 0;
exit_free:
kfree_skb(reply);
exit_unlock:
rtnl_unlock();
return err;
......
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