[ovs-dev] [PATCH branch-2.7 1/1] datapath: maintain correct checksum state in conntrack actions.
Lance Richardson
lrichard at redhat.com
Thu Feb 9 12:57:31 UTC 2017
> From: "Joe Stringer" <joe at ovn.org>
> To: dev at openvswitch.org
> Cc: "Lance Richardson" <lrichard at redhat.com>
> Sent: Wednesday, February 8, 2017 8:14:08 PM
> Subject: [PATCH branch-2.7 1/1] datapath: maintain correct checksum state in conntrack actions.
>
> Upstream commit:
> 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+ #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 at redhat.com>
> Acked-by: Pravin B Shelar <pshelar at ovn.org>
> Signed-off-by: David S. Miller <davem at davemloft.net>
>
> Upstream: 75f01a4c9cc2 ("openvswitch: maintain correct checksum state in
> conntrack actions")
> Signed-off-by: Joe Stringer <joe at ovn.org>
> ---
> CC: Lance Richardson <lrichard at redhat.com>
> ---
> datapath/conntrack.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/datapath/conntrack.c b/datapath/conntrack.c
> index 3c51ce6bcfa8..a0c54438728e 100644
> --- a/datapath/conntrack.c
> +++ b/datapath/conntrack.c
> @@ -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)
> @@ -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;
> }
> @@ -931,7 +932,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);
> @@ -945,6 +946,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.11.0
>
>
Acked-by: Lance Richardson <lrichard at redhat.com>
More information about the dev
mailing list