From patchwork Wed Nov 23 04:09:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarno Rajahalme X-Patchwork-Id: 698033 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 3tNpl80j1Sz9t0Z for ; Wed, 23 Nov 2016 15:09:56 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756393AbcKWEJx (ORCPT ); Tue, 22 Nov 2016 23:09:53 -0500 Received: from relay4-d.mail.gandi.net ([217.70.183.196]:36351 "EHLO relay4-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755988AbcKWEJv (ORCPT ); Tue, 22 Nov 2016 23:09:51 -0500 Received: from mfilter28-d.gandi.net (mfilter28-d.gandi.net [217.70.178.159]) by relay4-d.mail.gandi.net (Postfix) with ESMTP id 42522172093; Wed, 23 Nov 2016 05:09:50 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter28-d.gandi.net Received: from relay4-d.mail.gandi.net ([IPv6:::ffff:217.70.183.196]) by mfilter28-d.gandi.net (mfilter28-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id i6aRtAzWTO4J; Wed, 23 Nov 2016 05:09:48 +0100 (CET) X-Originating-IP: 208.91.1.34 Received: from sc9-mailhost2.vmware.com (unknown [208.91.1.34]) (Authenticated sender: jarno@ovn.org) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id F27AD172095; Wed, 23 Nov 2016 05:09:47 +0100 (CET) From: Jarno Rajahalme To: netdev@vger.kernel.org Cc: jarno@ovn.org Subject: [PATCH net-next 2/2] openvswitch: Fix skb->protocol for vlan frames. Date: Tue, 22 Nov 2016 20:09:34 -0800 Message-Id: <1479874174-75329-2-git-send-email-jarno@ovn.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1479874174-75329-1-git-send-email-jarno@ovn.org> References: <1479874174-75329-1-git-send-email-jarno@ovn.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Do not set skb->protocol to be the ethertype of the L3 header, unless the packet only has the L3 header. For a non-hardware offloaded VLAN frame skb->protocol needs to be one of the VLAN ethertypes. Any VLAN offloading is undone on the OVS netlink interface. Due to this all VLAN packets sent to openvswitch module from userspace are non-offloaded. Incorrect skb->protocol value on a full-size non-offloaded VLAN skb causes packet drop due to failing MTU check, as the VLAN header should not be counted in when considering MTU in ovs_vport_send(). Fixes: 5108bbaddc ("openvswitch: add processing of L3 packets") Signed-off-by: Jarno Rajahalme --- net/openvswitch/datapath.c | 1 - net/openvswitch/flow.c | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 2d4c4d3..9c62b63 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -606,7 +606,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) rcu_assign_pointer(flow->sf_acts, acts); packet->priority = flow->key.phy.priority; packet->mark = flow->key.phy.skb_mark; - packet->protocol = flow->key.eth.type; rcu_read_lock(); dp = get_dp_rcu(net, ovs_header->dp_ifindex); diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 08aa926..9be9fda 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -477,12 +477,17 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key, } /** - * key_extract - extracts a flow key from an Ethernet frame. + * key_extract - extracts a flow key from a packet with or without an + * Ethernet header. * @skb: sk_buff that contains the frame, with skb->data pointing to the - * Ethernet header + * beginning of the packet. * @key: output flow key * - * The caller must ensure that skb->len >= ETH_HLEN. + * 'key->mac_proto' must be initialized to indicate the frame type. + * For an L3 frame 'key->mac_proto' must equal 'MAC_PROTO_NONE', and the + * caller must ensure that 'skb->protocol' is set to the ethertype of the L3 + * header. Otherwise the presence of an Ethernet header is assumed and + * the caller must ensure that skb->len >= ETH_HLEN. * * Returns 0 if successful, otherwise a negative errno value. * @@ -497,9 +502,6 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key, * on output, then just past the IP header, if one is present and * of a correct length, otherwise the same as skb->network_header. * For other key->eth.type values it is left untouched. - * - * - skb->protocol: the type of the data starting at skb->network_header. - * Equals to key->eth.type. */ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) { @@ -518,6 +520,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) return -EINVAL; skb_reset_network_header(skb); + key->eth.type = skb->protocol; } else { eth = eth_hdr(skb); ether_addr_copy(key->eth.src, eth->h_source); @@ -531,15 +534,14 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) if (unlikely(parse_vlan(skb, key))) return -ENOMEM; - skb->protocol = parse_ethertype(skb); - if (unlikely(skb->protocol == htons(0))) + key->eth.type = parse_ethertype(skb); + if (unlikely(key->eth.type == htons(0))) return -ENOMEM; skb_reset_network_header(skb); __skb_push(skb, skb->data - skb_mac_header(skb)); } skb_reset_mac_len(skb); - key->eth.type = skb->protocol; /* Network layer. */ if (key->eth.type == htons(ETH_P_IP)) {