From patchwork Fri Aug 14 01:30:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 507243 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 7CC021401EF for ; Fri, 14 Aug 2015 11:30:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752143AbbHNBab (ORCPT ); Thu, 13 Aug 2015 21:30:31 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:34517 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751622AbbHNBaa (ORCPT ); Thu, 13 Aug 2015 21:30:30 -0400 Received: by paccq16 with SMTP id cq16so5175104pac.1 for ; Thu, 13 Aug 2015 18:30:30 -0700 (PDT) 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=7g3kfKvOLBouT1cq5rZ68usaxNZKgDooB8mx5xd3XpQ=; b=hpnC9/jf9fa4qzhBDW2XeME9yVcGlpFyFYgLrFgliVTIdyPXt1cvdq2bqaVMwp1bfG 8sr54ajZVq1L/4WTypKDA8mOKj8WAsy9UGq2MsZd7qGGS3R6Qnm+QJvq1yIoIjw1Mxjm wIPR3uD6svsFXPCJV15cp3DOn0y0zEEdTGpfUIBqAOQvDMzaVqhGy7Jcmp31ehbPFazs oaXf6XI8SFfxM7YXm65BErIU1YYxb0EDpKhB6RT5e8y5fo3ildIhOKoaR7qw9KCIOYUw WTtF3lCFb6d8KWJimOhV6AtCWy25qLNGvDeFObJQVHg9MhR4bibfPxO4OPZSiIIkI5rr 4oeg== X-Gm-Message-State: ALoCoQnaTVGWuSfTRUzbHi2ijyoCaMyfqxNpL1fzdQDONoBFJLisN29k8n1K4lR2efaQbFTfwdkm X-Received: by 10.66.159.68 with SMTP id xa4mr84780376pab.105.1439515830217; Thu, 13 Aug 2015 18:30:30 -0700 (PDT) Received: from reginn.isobedori.kobe.vergenet.net (p7129-ipbfp904kobeminato.hyogo.ocn.ne.jp. [118.10.130.129]) by smtp.gmail.com with ESMTPSA id w17sm4020571pbt.17.2015.08.13.18.30.27 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 13 Aug 2015 18:30:29 -0700 (PDT) From: Simon Horman To: Pravin Shelar Cc: Jesse Gross , netdev@vger.kernel.org, dev@openvswitch.org, Simon Horman Subject: [PATCH/RFC] openvswitch: Retain parsed IPv6 header fields in flow on error skipping extension headers Date: Fri, 14 Aug 2015 10:30:13 +0900 Message-Id: <1439515813-29406-1-git-send-email-simon.horman@netronome.com> X-Mailer: git-send-email 2.1.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When an error occurs skipping IPv6 extension headers retain the already parsed IP protocol and IPv6 addresses in the flow. Also assume that the packet is not a fragment in the absence of information to the contrary; that is always use the frag_off value set by ipv6_skip_exthdr(). This allows matching on the IP protocol and IPv6 addresses of packets with malformed extension headers. Signed-off-by: Simon Horman --- * Some consideration should be given to unwanted side effects of this patch as it affects the handling of malformed packets. Signed-off-by: Simon Horman --- net/openvswitch/flow.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 8db22ef73626..3c5336c5d4ea 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -271,8 +271,6 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key) key->ipv6.addr.dst = nh->daddr; payload_ofs = ipv6_skip_exthdr(skb, payload_ofs, &nexthdr, &frag_off); - if (unlikely(payload_ofs < 0)) - return -EINVAL; if (frag_off) { if (frag_off & htons(~0x7)) @@ -283,6 +281,13 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key) key->ip.frag = OVS_FRAG_TYPE_NONE; } + /* Delayed handling of error in ipv6_skip_exthdr() as it + * always sets frag_off to a valid value which may be + * used to set key->ip.frag above. + */ + if (unlikely(payload_ofs < 0)) + return -EINVAL; + nh_len = payload_ofs - nh_ofs; skb_set_transport_header(skb, nh_ofs + nh_len); key->ip.proto = nexthdr; @@ -622,8 +627,6 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) nh_len = parse_ipv6hdr(skb, key); if (unlikely(nh_len < 0)) { - memset(&key->ip, 0, sizeof(key->ip)); - memset(&key->ipv6.addr, 0, sizeof(key->ipv6.addr)); if (nh_len == -EINVAL) { skb->transport_header = skb->network_header; error = 0;