Skip to content

Commit

Permalink
openvswitch: Preallocate reply skb in ovs_vport_cmd_set().
Browse files Browse the repository at this point in the history
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: Jesse Gross <jesse@nicira.com>
  • Loading branch information
Jesse Gross committed Mar 27, 2013
1 parent 330305c commit a934151
Showing 1 changed file with 18 additions and 12 deletions.
30 changes: 18 additions & 12 deletions net/openvswitch/datapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a934151

Please sign in to comment.