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

Reply via email to