ofproto: Make ->construct() and ->destruct() more symmetrical.
[sliver-openvswitch.git] / datapath / tunnel.c
index 5c05c49..1ef81ab 100644 (file)
@@ -249,11 +249,13 @@ static int add_port(struct vport *vport)
                struct tbl *new_table;
 
                new_table = tbl_expand(cur_table);
-               if (IS_ERR(new_table))
-                       return PTR_ERR(new_table);
-
-               rcu_assign_pointer(port_table, new_table);
-               tbl_deferred_destroy(cur_table, NULL);
+               if (IS_ERR(new_table)) {
+                       if (PTR_ERR(new_table) != -ENOSPC)
+                               return PTR_ERR(new_table);
+               } else {
+                       rcu_assign_pointer(port_table, new_table);
+                       tbl_deferred_destroy(cur_table, NULL);
+               }
        }
 
        err = tbl_insert(rtnl_dereference(port_table), &tnl_vport->tbl_node,
@@ -968,7 +970,7 @@ static struct tnl_cache *build_cache(struct vport *vport,
                err = flow_extract(skb, dst_vport->port_no, &flow_key,
                                   &flow_key_len, &is_frag);
 
-               kfree_skb(skb);
+               consume_skb(skb);
                if (err || is_frag)
                        goto done;
 
@@ -1081,12 +1083,13 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb,
                struct sk_buff *nskb;
 
                nskb = skb_gso_segment(skb, 0);
-               kfree_skb(skb);
                if (IS_ERR(nskb)) {
+                       kfree_skb(skb);
                        err = PTR_ERR(nskb);
                        goto error;
                }
 
+               consume_skb(skb);
                skb = nskb;
        } else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
                /* Pages aren't locked and could change at any time.