From patchwork Fri Apr 22 05:31:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 613385 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3qrklG3qGpz9t3s for ; Fri, 22 Apr 2016 15:32:10 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b=u+nfvr4t; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 94A18108FE; Thu, 21 Apr 2016 22:32:09 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx3v3.cudamail.com (mx3.cudamail.com [64.34.241.5]) by archives.nicira.com (Postfix) with ESMTPS id 685E8108FA for ; Thu, 21 Apr 2016 22:32:08 -0700 (PDT) Received: from bar6.cudamail.com (localhost [127.0.0.1]) by mx3v3.cudamail.com (Postfix) with ESMTPS id EF272160F67 for ; Thu, 21 Apr 2016 23:32:07 -0600 (MDT) X-ASG-Debug-ID: 1461303126-0b323710bd284af0001-byXFYA Received: from mx3-pf1.cudamail.com ([192.168.14.2]) by bar6.cudamail.com with ESMTP id 6Cgc2Pe0XeYBnBFX (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 21 Apr 2016 23:32:06 -0600 (MDT) X-Barracuda-Envelope-From: simon.horman@netronome.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.14.2 Received: from unknown (HELO mail-pf0-f169.google.com) (209.85.192.169) by mx3-pf1.cudamail.com with ESMTPS (RC4-SHA encrypted); 22 Apr 2016 05:32:05 -0000 Received-SPF: neutral (mx3-pf1.cudamail.com: 209.85.192.169 is neither permitted nor denied by SPF record at spf.mandrillapp.com) X-Barracuda-RBL-Trusted-Forwarder: 209.85.192.169 Received: by mail-pf0-f169.google.com with SMTP id e128so37450708pfe.3 for ; Thu, 21 Apr 2016 22:32:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=gF+jGGyqnkyNZ+sBvvb65OxpbnPfc0U0WOsEtE8JV7I=; b=u+nfvr4t6IfByM7k7GGV4KzEVeMJf8fyq66vaDsKZtqyK2QpOyolvilVPEVialzLKU na/ytZqXfqNGBwwwdx1PvIiOYNkAlOtYwiy6TEaHuVQ516XTxrs4kDkF65e8eE5EiKmu RwIeupP75plECmZJWOwbJASzslknice4RKnvqJUAEFzsLY/xzVLOJo1qhHHIxVGvEs0j vNrapOowtEVf4DmDyucX6arx+fnwv7M3g+BaAac6+KuILiz283blZahD3RFO8bbaw1Ws lP+l+ETxKSy4kt3wqK+m6JflXJzj6fzFGkjTOUc28mPJthxkBsqSE9bi4iqjqiKnzWS0 w4Dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=gF+jGGyqnkyNZ+sBvvb65OxpbnPfc0U0WOsEtE8JV7I=; b=KcXL2ryhVUvAh3+e6pPmBRizsue12Q14/sIhSbALlg05xE3fIHSCt3w7LXEzhP0zDI Tp0fcsLpfO5AfOJL3PEF1io7BSgiHzfNlQslWejW/zs0NTCuJxxukXyqIdBtkBGFRbEK QE5aUzZgzsgCj/j0cTl6rBE/oMtZp3NRITe7PGhN8ik44BhKZC29SUlVJGLsFp7i+eyz itqINJNwV5qw3dO8gCUM8OHNVJYJaNhcRAIZ1F3tWDkB4RiRmxgeh2vmiykOfEo4FLPj vWLZbLvNX8JgowHCHah0ZtY79fkvK3XTEbStM9lIwm/8Mjj8m7A1rEg6sgcT71SKFiac mdjQ== X-Gm-Message-State: AOPr4FXf0+6QbR/M7KArLxO0rX/6traM2gdwyiequNXsGDRHFVSMFIW5y9Ewjih6blKdTdqm X-Received: by 10.98.19.131 with SMTP id 3mr10172356pft.17.1461303125111; Thu, 21 Apr 2016 22:32:05 -0700 (PDT) Received: from penelope.kubiwireless.com (124-171-1-229.dyn.iinet.net.au. [124.171.1.229]) by smtp.gmail.com with ESMTPSA id e87sm4921112pfb.76.2016.04.21.22.32.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Apr 2016 22:32:03 -0700 (PDT) X-CudaMail-Envelope-Sender: simon.horman@netronome.com X-Barracuda-Apparent-Source-IP: 124.171.1.229 From: Simon Horman To: dev@openvswitch.org X-CudaMail-MID: CM-V1-420065712 X-CudaMail-DTE: 042116 X-CudaMail-Originating-IP: 209.85.192.169 Date: Fri, 22 Apr 2016 15:31:50 +1000 X-ASG-Orig-Subj: [##CM-V1-420065712##][PATCH] packets: use flow protocol when recalculating ipv6 checksums Message-Id: <1461303110-29111-1-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 X-GBUdb-Analysis: 0, 209.85.192.169, Ugly c=0.360316 p=-0.333333 Source Normal X-MessageSniffer-Rules: 0-0-0-16536-c X-Barracuda-Connect: UNKNOWN[192.168.14.2] X-Barracuda-Start-Time: 1461303126 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_RULE7568M, BSF_SC5_MJ1963, DKIM_SIGNED, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.28955 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.50 BSF_RULE7568M Custom Rule 7568M 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Cc: Simon Horman , Jarno Rajahalme Subject: [ovs-dev] [PATCH] packets: use flow protocol when recalculating ipv6 checksums X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" When using masked actions the ipv6_proto field of an action to set IPv6 fields may be zero rather than the prevailing protocol which will result in skipping checksum recalculation. This patch resolves the problem by relying on the protocol in the flow key rather than that in the set field action. A similar fix for the kernel datapath has been accepted into David Miller's 'net' tree as b4f70527f052 ("openvswitch: use flow protocol when recalculating ipv6 checksums"). Cc: Jarno Rajahalme Fixes: 6d670e7f0d45 ("lib/odp: Masked set action execution and printing.") Signed-off-by: Simon Horman --- While preparing this I noticed that there does seem to be some scope to consolidate packet_rh_present() and part of miniflow_extract(). --- lib/odp-execute.c | 4 +--- lib/packets.c | 39 +++++++++++++++++++++------------------ lib/packets.h | 2 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/odp-execute.c b/lib/odp-execute.c index b5204b270677..7efd9ec1d349 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -99,7 +99,6 @@ odp_set_ipv6(struct dp_packet *packet, const struct ovs_key_ipv6 *key, packet_set_ipv6( packet, - key->ipv6_proto, mask_ipv6_addr(nh->ip6_src.be32, key->ipv6_src, mask->ipv6_src, sbuf), mask_ipv6_addr(nh->ip6_dst.be32, key->ipv6_dst, mask->ipv6_dst, dbuf), key->ipv6_tclass | (old_tc & ~mask->ipv6_tclass), @@ -257,8 +256,7 @@ odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a) case OVS_KEY_ATTR_IPV6: ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6)); - packet_set_ipv6(packet, ipv6_key->ipv6_proto, - ipv6_key->ipv6_src, ipv6_key->ipv6_dst, + packet_set_ipv6(packet, ipv6_key->ipv6_src, ipv6_key->ipv6_dst, ipv6_key->ipv6_tclass, ipv6_key->ipv6_label, ipv6_key->ipv6_hlimit); break; diff --git a/lib/packets.c b/lib/packets.c index d0c0e68b534d..962fbdb6913c 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -837,10 +837,9 @@ packet_set_ipv4_addr(struct dp_packet *packet, * * This function assumes that L3 and L4 offsets are set in the packet. */ static bool -packet_rh_present(struct dp_packet *packet) +packet_rh_present(struct dp_packet *packet, uint8_t *nexthdr) { const struct ovs_16aligned_ip6_hdr *nh; - int nexthdr; size_t len; size_t remaining; uint8_t *data = dp_packet_l3(packet); @@ -852,14 +851,14 @@ packet_rh_present(struct dp_packet *packet) nh = ALIGNED_CAST(struct ovs_16aligned_ip6_hdr *, data); data += sizeof *nh; remaining -= sizeof *nh; - nexthdr = nh->ip6_nxt; + *nexthdr = nh->ip6_nxt; while (1) { - if ((nexthdr != IPPROTO_HOPOPTS) - && (nexthdr != IPPROTO_ROUTING) - && (nexthdr != IPPROTO_DSTOPTS) - && (nexthdr != IPPROTO_AH) - && (nexthdr != IPPROTO_FRAGMENT)) { + if ((*nexthdr != IPPROTO_HOPOPTS) + && (*nexthdr != IPPROTO_ROUTING) + && (*nexthdr != IPPROTO_DSTOPTS) + && (*nexthdr != IPPROTO_AH) + && (*nexthdr != IPPROTO_FRAGMENT)) { /* It's either a terminal header (e.g., TCP, UDP) or one we * don't understand. In either case, we're done with the * packet, so use it to fill in 'nw_proto'. */ @@ -875,34 +874,34 @@ packet_rh_present(struct dp_packet *packet) return false; } - if (nexthdr == IPPROTO_AH) { + if (*nexthdr == IPPROTO_AH) { /* A standard AH definition isn't available, but the fields * we care about are in the same location as the generic * option header--only the header length is calculated * differently. */ const struct ip6_ext *ext_hdr = (struct ip6_ext *)data; - nexthdr = ext_hdr->ip6e_nxt; + *nexthdr = ext_hdr->ip6e_nxt; len = (ext_hdr->ip6e_len + 2) * 4; - } else if (nexthdr == IPPROTO_FRAGMENT) { + } else if (*nexthdr == IPPROTO_FRAGMENT) { const struct ovs_16aligned_ip6_frag *frag_hdr = ALIGNED_CAST(struct ovs_16aligned_ip6_frag *, data); - nexthdr = frag_hdr->ip6f_nxt; + *nexthdr = frag_hdr->ip6f_nxt; len = sizeof *frag_hdr; - } else if (nexthdr == IPPROTO_ROUTING) { + } else if (*nexthdr == IPPROTO_ROUTING) { const struct ip6_rthdr *rh = (struct ip6_rthdr *)data; if (rh->ip6r_segleft > 0) { return true; } - nexthdr = rh->ip6r_nxt; + *nexthdr = rh->ip6r_nxt; len = (rh->ip6r_len + 1) * 8; } else { const struct ip6_ext *ext_hdr = (struct ip6_ext *)data; - nexthdr = ext_hdr->ip6e_nxt; + *nexthdr = ext_hdr->ip6e_nxt; len = (ext_hdr->ip6e_len + 1) * 8; } @@ -1010,11 +1009,15 @@ packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, ovs_be32 dst, * appropriate. 'packet' must contain a valid IPv6 packet with correctly * populated l[34] offsets. */ void -packet_set_ipv6(struct dp_packet *packet, uint8_t proto, const ovs_be32 src[4], +packet_set_ipv6(struct dp_packet *packet, const ovs_be32 src[4], const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl) { struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet); + bool rh_present; + uint8_t proto; + + rh_present = packet_rh_present(packet, &proto); if (memcmp(&nh->ip6_src, src, sizeof(ovs_be32[4]))) { packet_set_ipv6_addr(packet, proto, nh->ip6_src.be32, src, true); @@ -1022,7 +1025,7 @@ packet_set_ipv6(struct dp_packet *packet, uint8_t proto, const ovs_be32 src[4], if (memcmp(&nh->ip6_dst, dst, sizeof(ovs_be32[4]))) { packet_set_ipv6_addr(packet, proto, nh->ip6_dst.be32, dst, - !packet_rh_present(packet)); + !rh_present); } packet_set_ipv6_tc(&nh->ip6_flow, key_tc); @@ -1312,7 +1315,7 @@ compose_ipv6(struct dp_packet *packet, uint8_t proto, const ovs_be32 src[4], nh->ip6_plen = htons(size); data = dp_packet_put_zeros(packet, size); dp_packet_set_l4(packet, data); - packet_set_ipv6(packet, proto, src, dst, key_tc, key_fl, key_hl); + packet_set_ipv6(packet, src, dst, key_tc, key_fl, key_hl); return data; } diff --git a/lib/packets.h b/lib/packets.h index 8139a6b87495..2896b7849624 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1035,7 +1035,7 @@ void *snap_compose(struct dp_packet *, const struct eth_addr eth_dst, unsigned int oui, uint16_t snap_type, size_t size); void packet_set_ipv4(struct dp_packet *, ovs_be32 src, ovs_be32 dst, uint8_t tos, uint8_t ttl); -void packet_set_ipv6(struct dp_packet *, uint8_t proto, const ovs_be32 src[4], +void packet_set_ipv6(struct dp_packet *, const ovs_be32 src[4], const ovs_be32 dst[4], uint8_t tc, ovs_be32 fl, uint8_t hlmit); void packet_set_tcp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);