Skip to content

Commit

Permalink
datapath: make skb->csum consistent with rest of networking stack.
Browse files Browse the repository at this point in the history
As suggested by Jesse in the comment for patch "gre: Restructure
tunneling", following patch keeps skb->csum correct across ovs.

Signed-off-by: Pravin B Shelar <[email protected]>
Acked-by: Jesse Gross <[email protected]>
  • Loading branch information
Pravin B Shelar committed Jun 12, 2013
1 parent ca07718 commit 3cfede1
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 6 deletions.
8 changes: 8 additions & 0 deletions datapath/actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,17 @@ static int set_eth_addr(struct sk_buff *skb,
if (unlikely(err))
return err;

if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_sub(skb->csum, csum_partial(eth_hdr(skb),
ETH_ALEN * 2, 0));

memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);

if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_add(skb->csum, csum_partial(eth_hdr(skb),
ETH_ALEN * 2, 0));

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions datapath/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
memcpy(key->eth.dst, eth->h_dest, ETH_ALEN);

__skb_pull(skb, 2 * ETH_ALEN);
/* We are going to push all headers that we pull, so no need to
* update skb->csum here. */

if (vlan_tx_tag_present(skb))
key->eth.tci = htons(vlan_get_tci(skb));
Expand Down
5 changes: 5 additions & 0 deletions datapath/vlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ static inline int vlan_deaccel_tag(struct sk_buff *skb)
if (unlikely(!skb))
return -ENOMEM;

if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
skb->csum = csum_add(skb->csum,
csum_partial(skb->data + (2 * ETH_ALEN),
VLAN_HLEN, 0));

vlan_set_tci(skb, 0);
return 0;
}
Expand Down
3 changes: 1 addition & 2 deletions datapath/vport-gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ static int gre_rcv(struct sk_buff *skb)
tnl_flags = gre_flags_to_tunnel_flags(gre_flags, is_gre64);
tnl_tun_key_init(&tun_key, iph, key, tnl_flags);

__skb_pull(skb, hdr_len);
skb_postpull_rcsum(skb, skb_transport_header(skb), hdr_len + ETH_HLEN);
skb_pull_rcsum(skb, hdr_len);

ovs_tnl_rcv(vport, skb, &tun_key);
return 0;
Expand Down
1 change: 1 addition & 0 deletions datapath/vport-internal_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
skb->dev = netdev;
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, netdev);
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
forward_ip_summed(skb, false);

netif_rx(skb);
Expand Down
2 changes: 2 additions & 0 deletions datapath/vport-lisp.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ static int lisp_rcv(struct sock *sk, struct sk_buff *skb)
ethh->h_source[0] = 0x02;
ethh->h_proto = protocol;

ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);

ovs_tnl_rcv(vport_from_priv(lisp_port), skb, &tun_key);
goto out;

Expand Down
5 changes: 3 additions & 2 deletions datapath/vport-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,12 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
if (unlikely(!skb))
return;

skb_push(skb, ETH_HLEN);

if (unlikely(compute_ip_summed(skb, false)))
goto error;

skb_push(skb, ETH_HLEN);
ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN);

vlan_copy_skb_tci(skb);

ovs_vport_receive(vport, skb, NULL);
Expand Down
3 changes: 1 addition & 2 deletions datapath/vport-vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
vxh->vx_vni & htonl(0xff)))
goto error;

__skb_pull(skb, VXLAN_HLEN);
skb_postpull_rcsum(skb, skb_transport_header(skb), VXLAN_HLEN + ETH_HLEN);
skb_pull_rcsum(skb, VXLAN_HLEN);

key = cpu_to_be64(ntohl(vxh->vx_vni) >> 8);

Expand Down
6 changes: 6 additions & 0 deletions datapath/vport.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,10 @@ extern const struct vport_ops ovs_gre64_vport_ops;
extern const struct vport_ops ovs_vxlan_vport_ops;
extern const struct vport_ops ovs_lisp_vport_ops;

static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
const void *start, unsigned int len)
{
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
}
#endif /* vport.h */

0 comments on commit 3cfede1

Please sign in to comment.