| From 75f01a4c9cc291ff5cb28ca1216adb163b7a20ee Mon Sep 17 00:00:00 2001 |
| From: Lance Richardson <lrichard@redhat.com> |
| Date: Thu, 12 Jan 2017 19:33:18 -0500 |
| Subject: [PATCH] openvswitch: maintain correct checksum state in conntrack |
| actions |
| |
| commit 75f01a4c9cc291ff5cb28ca1216adb163b7a20ee upstream. |
| |
| 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+ #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 <lrichard@redhat.com> |
| Acked-by: Pravin B Shelar <pshelar@ovn.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| |
| diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c |
| index 6b78bab27755..54253ea5976e 100644 |
| --- a/net/openvswitch/conntrack.c |
| +++ b/net/openvswitch/conntrack.c |
| @@ -514,7 +514,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) |
| @@ -579,6 +579,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; |
| } |
| @@ -886,7 +887,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); |
| @@ -900,6 +901,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; |
| -- |
| 2.12.0 |
| |