It's possible to start receiving packets on a datapath as soon as the internal device is created. It's therefore important that the datapath be fully initialized before this, which it currently isn't. In particularly, the fact that dp->stats_percpu is not yet set is potentially fatal. In addition, if allocation of the Netlink response failed it would leak the percpu memory. This fixes both problems.
Found by code inspection, in practice the datapath is probably always done initializing before someone can send a packet on it. Signed-off-by: Jesse Gross <[email protected]> --- datapath/datapath.c | 25 ++++++++++++++----------- 1 files changed, 14 insertions(+), 11 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index 232b265..63f4f61 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1346,6 +1346,17 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) if (!dp->table) goto err_free_dp; + dp->dp_ifindex = vport_get_ifindex(vport); + + dp->drop_frags = 0; + dp->stats_percpu = alloc_percpu(struct dp_stats_percpu); + if (!dp->stats_percpu) { + err = -ENOMEM; + goto err_destroy_table; + } + + change_datapath(dp, a); + /* Set up our datapath device. */ parms.name = nla_data(a[OVS_DP_ATTR_NAME]); parms.type = OVS_VPORT_TYPE_INTERNAL; @@ -1358,18 +1369,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) if (err == -EBUSY) err = -EEXIST; - goto err_destroy_table; + goto err_destroy_percpu; } - dp->dp_ifindex = vport_get_ifindex(vport); - - dp->drop_frags = 0; - dp->stats_percpu = alloc_percpu(struct dp_stats_percpu); - if (!dp->stats_percpu) { - err = -ENOMEM; - goto err_destroy_local_port; - } - - change_datapath(dp, a); reply = ovs_dp_cmd_build_info(dp, info->snd_pid, info->snd_seq, OVS_DP_CMD_NEW); err = PTR_ERR(reply); @@ -1387,6 +1388,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) err_destroy_local_port: dp_detach_port(get_vport_protected(dp, OVSP_LOCAL)); +err_destroy_percpu: + free_percpu(dp->stats_percpu); err_destroy_table: flow_tbl_destroy(get_table_protected(dp)); err_free_dp: -- 1.7.4.1 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
