aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2013-03-26 18:48:38 -0400
committerJesse Gross <jesse@nicira.com>2013-03-27 12:07:40 -0400
commita9341512c372fcc628dabc619898d910a06c54bc (patch)
tree0651be3fffbb5b5eb06401a41bb362b95326a4e8 /net/openvswitch
parent330305cc4a6b0cb75c22fc01b8826f0ad755550f (diff)
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: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/datapath.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index a4b724708a1a..6980c3e6f066 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1593,10 +1593,8 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
1593 return ERR_PTR(-ENOMEM); 1593 return ERR_PTR(-ENOMEM);
1594 1594
1595 retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd); 1595 retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
1596 if (retval < 0) { 1596 BUG_ON(retval < 0);
1597 kfree_skb(skb); 1597
1598 return ERR_PTR(retval);
1599 }
1600 return skb; 1598 return skb;
1601} 1599}
1602 1600
@@ -1726,24 +1724,32 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
1726 nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) 1724 nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type)
1727 err = -EINVAL; 1725 err = -EINVAL;
1728 1726
1727 reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1728 if (!reply) {
1729 err = -ENOMEM;
1730 goto exit_unlock;
1731 }
1732
1729 if (!err && a[OVS_VPORT_ATTR_OPTIONS]) 1733 if (!err && a[OVS_VPORT_ATTR_OPTIONS])
1730 err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]); 1734 err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
1731 if (err) 1735 if (err)
1732 goto exit_unlock; 1736 goto exit_free;
1737
1733 if (a[OVS_VPORT_ATTR_UPCALL_PID]) 1738 if (a[OVS_VPORT_ATTR_UPCALL_PID])
1734 vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); 1739 vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
1735 1740
1736 reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq, 1741 err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
1737 OVS_VPORT_CMD_NEW); 1742 info->snd_seq, 0, OVS_VPORT_CMD_NEW);
1738 if (IS_ERR(reply)) { 1743 BUG_ON(err < 0);
1739 netlink_set_err(sock_net(skb->sk)->genl_sock, 0,
1740 ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
1741 goto exit_unlock;
1742 }
1743 1744
1744 genl_notify(reply, genl_info_net(info), info->snd_portid, 1745 genl_notify(reply, genl_info_net(info), info->snd_portid,
1745 ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL); 1746 ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
1746 1747
1748 rtnl_unlock();
1749 return 0;
1750
1751exit_free:
1752 kfree_skb(reply);
1747exit_unlock: 1753exit_unlock:
1748 rtnl_unlock(); 1754 rtnl_unlock();
1749 return err; 1755 return err;