Skip to content

Commit

Permalink
If needed, DP originated packets should undergo csum/gso updates
Browse files Browse the repository at this point in the history
For packets that are tunneled, vRouter updates the checksum offset of
the packet to reflect tunnel addition. For mirrored packets, if the
mirror destination (analyzer) is local, no tunnel headers
(MPLSO(UDP/GRE)) are added and hence a checksum offset update is not
done. This behavior is wrong since we do add mirror headers (and hence a
tunnel) and the whole packet needs a checksum value.

Change-Id: Ia8c184d0980e7880bff90ff53f178e657a6be311
Closes-BUG: #1528460
  • Loading branch information
anandhk-juniper committed Dec 22, 2015
1 parent ede19c3 commit d6703ad
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 1 deletion.
24 changes: 24 additions & 0 deletions dp-core/vr_nexthop.c
Expand Up @@ -1266,6 +1266,13 @@ nh_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh,
*/
pkt_set_inner_network_header(pkt, pkt->vp_data);

if (pkt->vp_type == VP_TYPE_IP6)
pkt->vp_type = VP_TYPE_IP6OIP;
else if (pkt->vp_type == VP_TYPE_IP)
pkt->vp_type = VP_TYPE_IPOIP;
else
pkt->vp_type = VP_TYPE_IP;

/*
* Calculate the partial checksum for udp header
*/
Expand Down Expand Up @@ -1338,6 +1345,12 @@ nh_vxlan_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh,
goto send_fail;

pkt_set_network_header(pkt, pkt->vp_data);

if (pkt->vp_type == VP_TYPE_IPOIP)
pkt->vp_type = VP_TYPE_IP;
else if (pkt->vp_type == VP_TYPE_IP6OIP)
pkt->vp_type = VP_TYPE_IP6;

/*
* Change the packet type
*/
Expand Down Expand Up @@ -1476,6 +1489,11 @@ nh_mpls_udp_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh,
pkt->vp_flags |= VP_FLAG_GSO;


if (pkt->vp_type == VP_TYPE_IPOIP)
pkt->vp_type = VP_TYPE_IP;
else if (pkt->vp_type == VP_TYPE_IP6OIP)
pkt->vp_type = VP_TYPE_IP6;

/*
* Change the packet type
*/
Expand Down Expand Up @@ -1624,6 +1642,12 @@ nh_gre_tunnel(struct vr_packet *pkt, struct vr_nexthop *nh,
goto send_fail;
}
pkt_set_network_header(pkt, pkt->vp_data);

if (pkt->vp_type == VP_TYPE_IPOIP)
pkt->vp_type = VP_TYPE_IP;
else if (pkt->vp_type == VP_TYPE_IP6OIP)
pkt->vp_type = VP_TYPE_IP6;

if (pkt->vp_type == VP_TYPE_IP6)
pkt->vp_type = VP_TYPE_IP6OIP;
else if (pkt->vp_type == VP_TYPE_IP)
Expand Down
11 changes: 11 additions & 0 deletions include/vr_packet.h
Expand Up @@ -493,6 +493,17 @@ vr_pkt_type_is_overlay(unsigned short type)
return false;
}

static inline bool
vr_pkt_needs_csum_gso_update(struct vr_packet *pkt)
{
if (pkt->vp_flags & VP_FLAG_FROM_DP) {
if (pkt->vp_flags & (VP_FLAG_CSUM_PARTIAL | VP_FLAG_GSO))
return true;
}

return false;
}

static inline bool
vr_pkt_is_diag(struct vr_packet *pkt)
{
Expand Down
3 changes: 2 additions & 1 deletion linux/vr_host_interface.c
Expand Up @@ -782,7 +782,8 @@ linux_if_tx(struct vr_interface *vif, struct vr_packet *pkt)
skb_set_network_header(skb, (network_off - skb_headroom(skb)));
skb_reset_mac_len(skb);
}
} else if (vr_pkt_type_is_overlay(pkt->vp_type)) {
} else if (vr_pkt_type_is_overlay(pkt->vp_type) ||
vr_pkt_needs_csum_gso_update(pkt)) {
network_off = pkt_get_inner_network_header_off(pkt);

if (network_off) {
Expand Down
1 change: 1 addition & 0 deletions linux/vrouter_mod.c
Expand Up @@ -207,6 +207,7 @@ lh_palloc_head(struct vr_packet *pkt, unsigned int size)

npkt->vp_ttl = pkt->vp_ttl;
npkt->vp_flags = pkt->vp_flags;
npkt->vp_type = pkt->vp_type;

skb_frag_list_init(skb_head);
skb_frag_add_head(skb_head, skb);
Expand Down

0 comments on commit d6703ad

Please sign in to comment.