X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Ftunnel.c;h=1ef81ab7893f08172d16df71861ad7bda1a7cb1f;hb=2bd5b8145b7cf1851d51e258ab614414f2496aae;hp=2bf61597d7a80eabe48d0cf452a004a60223d187;hpb=bf16ba4a9b1b4a38c867349e70e39d551b406b32;p=openvswitch diff --git a/datapath/tunnel.c b/datapath/tunnel.c index 2bf61597..1ef81ab7 100644 --- a/datapath/tunnel.c +++ b/datapath/tunnel.c @@ -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, @@ -450,9 +452,13 @@ void tnl_rcv(struct vport *vport, struct sk_buff *skb, u8 tos) secpath_reset(skb); ecn_decapsulate(skb, tos); - compute_ip_summed(skb, false); vlan_set_tci(skb, 0); + if (unlikely(compute_ip_summed(skb, false))) { + kfree_skb(skb); + return; + } + vport_receive(vport, skb); } @@ -718,7 +724,11 @@ bool tnl_frag_needed(struct vport *vport, const struct tnl_mutable_config *mutab (TNL_F_IN_KEY_MATCH | TNL_F_OUT_KEY_ACTION)) OVS_CB(nskb)->tun_id = flow_key; - compute_ip_summed(nskb, false); + if (unlikely(compute_ip_summed(nskb, false))) { + kfree_skb(nskb); + return false; + } + vport_receive(vport, nskb); return true; @@ -960,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; @@ -1053,12 +1063,6 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb, int min_headroom; int err; - forward_ip_summed(skb); - - err = vswitch_skb_checksum_setup(skb); - if (unlikely(err)) - goto error_free; - min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len + mutable->tunnel_hlen + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0); @@ -1073,18 +1077,21 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb, goto error_free; } + forward_ip_summed(skb, true); + if (skb_is_gso(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 (skb->ip_summed == CHECKSUM_PARTIAL) { + } else if (get_ip_summed(skb) == OVS_CSUM_PARTIAL) { /* Pages aren't locked and could change at any time. * If this happens after we compute the checksum, the * checksum will be wrong. We linearize now to avoid @@ -1099,8 +1106,9 @@ static struct sk_buff *handle_offloads(struct sk_buff *skb, err = skb_checksum_help(skb); if (unlikely(err)) goto error_free; - } else if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + } + + set_ip_summed(skb, OVS_CSUM_NONE); return skb; @@ -1295,8 +1303,12 @@ int tnl_send(struct vport *vport, struct sk_buff *skb) ip_send_check(iph); if (cache_vport) { + if (unlikely(compute_ip_summed(skb, true))) { + kfree_skb(skb); + goto next; + } + OVS_CB(skb)->flow = cache->flow; - compute_ip_summed(skb, true); vport_receive(cache_vport, skb); sent_len += orig_len; } else {