Skip to content

Commit

Permalink
datapath: maintain correct checksum state in conntrack actions.
Browse files Browse the repository at this point in the history
Upstream commit:
    commit 75f01a4c9cc291ff5cb28ca1216adb163b7a20ee
    Author: Lance Richardson <[email protected]>
    Date: Thu Jan 12 19:33:18 2017 -0500

    openvswitch: maintain correct checksum state in conntrack actions

    When executing conntrack actions on skbuffs with checksum mode
    CHECKSUM_COMPLETE, the checksum must be updated to account for
    header pushes and pulls. Otherwise we get "hw csum failure"
    logs similar to this (ICMP packet received on geneve tunnel
    via ixgbe NIC):

    [  405.740065] genev_sys_6081: hw csum failure
    [  405.740106] CPU: 3 PID: 0 Comm: swapper/3 Tainted: G          I     4.10.0-rc3+ openvswitch#1
    [  405.740108] Call Trace:
    [  405.740110]  <IRQ>
    [  405.740113]  dump_stack+0x63/0x87
    [  405.740116]  netdev_rx_csum_fault+0x3a/0x40
    [  405.740118]  __skb_checksum_complete+0xcf/0xe0
    [  405.740120]  nf_ip_checksum+0xc8/0xf0
    [  405.740124]  icmp_error+0x1de/0x351 [nf_conntrack_ipv4]
    [  405.740132]  nf_conntrack_in+0xe1/0x550 [nf_conntrack]
    [  405.740137]  ? find_bucket.isra.2+0x62/0x70 [openvswitch]
    [  405.740143]  __ovs_ct_lookup+0x95/0x980 [openvswitch]
    [  405.740145]  ? netif_rx_internal+0x44/0x110
    [  405.740149]  ovs_ct_execute+0x147/0x4b0 [openvswitch]
    [  405.740153]  do_execute_actions+0x22e/0xa70 [openvswitch]
    [  405.740157]  ovs_execute_actions+0x40/0x120 [openvswitch]
    [  405.740161]  ovs_dp_process_packet+0x84/0x120 [openvswitch]
    [  405.740166]  ovs_vport_receive+0x73/0xd0 [openvswitch]
    [  405.740168]  ? udp_rcv+0x1a/0x20
    [  405.740170]  ? ip_local_deliver_finish+0x93/0x1e0
    [  405.740172]  ? ip_local_deliver+0x6f/0xe0
    [  405.740174]  ? ip_rcv_finish+0x3a0/0x3a0
    [  405.740176]  ? ip_rcv_finish+0xdb/0x3a0
    [  405.740177]  ? ip_rcv+0x2a7/0x400
    [  405.740180]  ? __netif_receive_skb_core+0x970/0xa00
    [  405.740185]  netdev_frame_hook+0xd3/0x160 [openvswitch]
    [  405.740187]  __netif_receive_skb_core+0x1dc/0xa00
    [  405.740194]  ? ixgbe_clean_rx_irq+0x46d/0xa20 [ixgbe]
    [  405.740197]  __netif_receive_skb+0x18/0x60
    [  405.740199]  netif_receive_skb_internal+0x40/0xb0
    [  405.740201]  napi_gro_receive+0xcd/0x120
    [  405.740204]  gro_cell_poll+0x57/0x80 [geneve]
    [  405.740206]  net_rx_action+0x260/0x3c0
    [  405.740209]  __do_softirq+0xc9/0x28c
    [  405.740211]  irq_exit+0xd9/0xf0
    [  405.740213]  do_IRQ+0x51/0xd0
    [  405.740215]  common_interrupt+0x93/0x93

    Fixes: 7f8a436eaa2c ("openvswitch: Add conntrack action")
    Signed-off-by: Lance Richardson <[email protected]>
    Acked-by: Pravin B Shelar <[email protected]>
    Signed-off-by: David S. Miller <[email protected]>

Upstream: 75f01a4c9cc2 ("openvswitch: maintain correct checksum state in conntrack actions")
Signed-off-by: Joe Stringer <[email protected]>
Acked-by: Jarno Rajahalme <[email protected]>
  • Loading branch information
hlrichardson authored and joestringer committed Mar 3, 2017
1 parent 3c82e35 commit 073c7b8
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions datapath/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
int hooknum, nh_off, err = NF_ACCEPT;

nh_off = skb_network_offset(skb);
skb_pull(skb, nh_off);
skb_pull_rcsum(skb, nh_off);

/* See HOOK2MANIP(). */
if (maniptype == NF_NAT_MANIP_SRC)
Expand Down Expand Up @@ -620,6 +620,7 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
err = nf_nat_packet(ct, ctinfo, hooknum, skb);
push:
skb_push(skb, nh_off);
skb_postpush_rcsum(skb, skb->data, nh_off);

return err;
}
Expand Down Expand Up @@ -927,7 +928,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,

/* The conntrack module expects to be working at L3. */
nh_ofs = skb_network_offset(skb);
skb_pull(skb, nh_ofs);
skb_pull_rcsum(skb, nh_ofs);

if (key->ip.frag != OVS_FRAG_TYPE_NONE) {
err = handle_fragments(net, key, info->zone.id, skb);
Expand All @@ -941,6 +942,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
err = ovs_ct_lookup(net, key, info, skb);

skb_push(skb, nh_ofs);
skb_postpush_rcsum(skb, skb->data, nh_ofs);
if (err)
kfree_skb(skb);
return err;
Expand Down

0 comments on commit 073c7b8

Please sign in to comment.