From patchwork Tue Feb 9 08:22:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thadeu Lima de Souza Cascardo X-Patchwork-Id: 580665 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (unknown [IPv6:2600:3c00::f03c:91ff:fe6e:bdf7]) by ozlabs.org (Postfix) with ESMTP id A792E14090A for ; Tue, 9 Feb 2016 19:22:18 +1100 (AEDT) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 0A3C7108D4; Tue, 9 Feb 2016 00:22:17 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 6EA4D106E4 for ; Tue, 9 Feb 2016 00:22:15 -0800 (PST) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id E87B84205E1 for ; Tue, 9 Feb 2016 01:22:14 -0700 (MST) X-ASG-Debug-ID: 1455006134-09eadd2e8f65b50001-byXFYA Received: from mx1-pf1.cudamail.com ([192.168.24.1]) by bar5.cudamail.com with ESMTP id YoY5H1DQJXhe3T7T (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 09 Feb 2016 01:22:14 -0700 (MST) X-Barracuda-Envelope-From: cascardo@redhat.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.1 Received: from unknown (HELO mx1.redhat.com) (209.132.183.28) by mx1-pf1.cudamail.com with ESMTPS (DHE-RSA-AES256-SHA encrypted); 9 Feb 2016 08:22:14 -0000 Received-SPF: pass (mx1-pf1.cudamail.com: SPF record at _spf1.redhat.com designates 209.132.183.28 as permitted sender) X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-Barracuda-RBL-IP: 209.132.183.28 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 2F297B9AC9 for ; Tue, 9 Feb 2016 08:22:13 +0000 (UTC) Received: from indiana.gru.redhat.com (ovpn-113-30.phx2.redhat.com [10.3.113.30]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u198MAwL013664 for ; Tue, 9 Feb 2016 03:22:12 -0500 X-CudaMail-Envelope-Sender: cascardo@redhat.com From: Thadeu Lima de Souza Cascardo To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E1-208001686 X-CudaMail-DTE: 020916 X-CudaMail-Originating-IP: 209.132.183.28 Date: Tue, 9 Feb 2016 06:22:05 -0200 X-ASG-Orig-Subj: [##CM-E1-208001686##][PATCH 2/2] packets: fix compose_nd to not crash vswitchd Message-Id: <1455006125-13898-2-git-send-email-cascardo@redhat.com> In-Reply-To: <1455006125-13898-1-git-send-email-cascardo@redhat.com> References: <1455006125-13898-1-git-send-email-cascardo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: UNKNOWN[192.168.24.1] X-Barracuda-Start-Time: 1455006134 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Subject: [ovs-dev] [PATCH 2/2] packets: fix compose_nd to not crash vswitchd 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" packet_set_ipv6 and packet_set_nd assumed that valid packets were already in place, so they were not a good fit for composing new packets. In fact, packet_set_ipv6 didn't even set the IP version or set L4 offset, causing crashes when compose_nd tried to access L4. This patch introduces ipv6_compose and uses it for compose_nd, then set the ND packets without other helpers. Signed-off-by: Thadeu Lima de Souza Cascardo --- lib/packets.c | 46 ++++++++++++++++++++++++++++++++++++++-------- lib/packets.h | 3 +++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/lib/packets.c b/lib/packets.c index 93d75bc..b794398 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -1226,6 +1226,24 @@ compose_arp(struct dp_packet *b, uint16_t arp_op, } void +ipv6_compose(struct dp_packet *packet, uint8_t proto, + const struct in6_addr *src, const struct in6_addr *dst, + uint8_t key_tc, ovs_be32 key_fl, uint8_t key_hl) +{ + struct ovs_16aligned_ip6_hdr *ip6 = dp_packet_l3(packet); + ovs_be32 old_flow; + ip6->ip6_vfc = 0x60; + ip6->ip6_nxt = proto; + ip6->ip6_hlim = key_hl; + ip6->ip6_plen = 0; + old_flow = get_16aligned_be32(&ip6->ip6_flow) & htonl(0xF00FFFFF | ~IPV6_LABEL_MASK); + put_16aligned_be32(&ip6->ip6_flow, old_flow | key_fl | htonl(key_tc << 20)); + memcpy(&ip6->ip6_src, src, sizeof(ovs_be32[4])); + memcpy(&ip6->ip6_dst, dst, sizeof(ovs_be32[4])); + dp_packet_set_l4(packet, ip6 + 1); +} + +void compose_nd(struct dp_packet *b, const struct eth_addr eth_src, struct in6_addr * ipv6_src, struct in6_addr * ipv6_dst) { @@ -1233,26 +1251,38 @@ compose_nd(struct dp_packet *b, const struct eth_addr eth_src, struct eth_addr eth_dst; struct ovs_nd_msg *ns; struct ovs_nd_opt *nd_opt; + struct ovs_16aligned_ip6_hdr *ip6; + size_t plen = ND_MSG_LEN + ND_OPT_LEN; + uint32_t csum; in6_addr_solicited_node(&sn_addr, ipv6_dst); ipv6_multicast_to_ethernet(ð_dst, &sn_addr); - eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, - IPV6_HEADER_LEN + ICMP6_HEADER_LEN + ND_OPT_LEN); - packet_set_ipv6(b, IPPROTO_ICMPV6, - ALIGNED_CAST(ovs_be32 *, ipv6_src->s6_addr), - ALIGNED_CAST(ovs_be32 *, sn_addr.s6_addr), - 0, 0, 255); + eth_compose(b, eth_dst, eth_src, ETH_TYPE_IPV6, IPV6_HEADER_LEN + plen); + ipv6_compose(b, IPPROTO_ICMPV6, ipv6_src, &sn_addr, 0, 0, 255); + ip6 = dp_packet_l3(b); + ip6->ip6_plen = htons(plen); ns = dp_packet_l4(b); + memset(ns, 0, plen); nd_opt = &ns->options[0]; ns->icmph.icmp6_type = ND_NEIGHBOR_SOLICIT; ns->icmph.icmp6_code = 0; + memcpy(ns->target.be32, ipv6_dst, sizeof(ovs_be32[4])); nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR; - packet_set_nd(b, ALIGNED_CAST(ovs_be32 *, ipv6_dst->s6_addr), - eth_src, eth_addr_zero); + nd_opt->nd_opt_len = 1; + nd_opt->nd_opt_mac = eth_src; + + ns->icmph.icmp6_cksum = 0; + csum = packet_csum_pseudoheader6(ip6, htonl(plen)); + csum = csum_continue(csum, &ns->icmph, plen); + csum = csum_finish(csum); + ns->icmph.icmp6_cksum = csum; + if (!ns->icmph.icmp6_cksum) { + ns->icmph.icmp6_cksum = htons(0xffff); + } } uint32_t diff --git a/lib/packets.h b/lib/packets.h index b8fa8db..96a3251 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1062,6 +1062,9 @@ void packet_set_nd(struct dp_packet *, const ovs_be32 target[4], void packet_format_tcp_flags(struct ds *, uint16_t); const char *packet_tcp_flag_to_string(uint32_t flag); +void ipv6_compose(struct dp_packet *, uint8_t proto, const struct in6_addr *src, + const struct in6_addr *dst, uint8_t tc, + ovs_be32 fl, uint8_t hlmit); void compose_arp(struct dp_packet *, uint16_t arp_op, const struct eth_addr arp_sha, const struct eth_addr arp_tha, bool broadcast,