From patchwork Mon Sep 2 18:09:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zahari Doychev X-Patchwork-Id: 1156703 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=googlemail.com header.i=@googlemail.com header.b="s3Xvh2TY"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46MdR55dy5z9s7T for ; Tue, 3 Sep 2019 04:10:09 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726773AbfIBSKI (ORCPT ); Mon, 2 Sep 2019 14:10:08 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:53750 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726506AbfIBSKH (ORCPT ); Mon, 2 Sep 2019 14:10:07 -0400 Received: by mail-wm1-f65.google.com with SMTP id q19so6665373wmc.3 for ; Mon, 02 Sep 2019 11:10:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=LKt2qX2lKxAy9En6DM3x9jZuRetXtcW/fLf4cxZ+m0I=; b=s3Xvh2TYWWPm2cjAKDbtrMm81XMIqgwVaj3C5LDL9Yj7aiV/O5BmhP1qXQS0+c7fn2 EHCRoLqYs8heYv7ShErBmEP2YqWGzl+ak2PFlqQ6yzKBvzCrAaXrgGFlng/EzVeOdpUQ nqvyW1nrqshLe6j+QLhiTjivCF8zfidb1x6v6sKj/T51VZr11DFX9SG+Cex+7PVx4QH0 9AnGHqYw28JbE2vpTkytOzSIOteooJOjkvTkcUFPWy/vuGfrwowglEqQj3KDnPZnstrl 9qQjVXA2OfnZMyxNfZbrw4xcgFABfMfU7+/7eMcS7OB3eVPWpvk24rDl09Hdel5WciXv Bfsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :mime-version:content-transfer-encoding; bh=LKt2qX2lKxAy9En6DM3x9jZuRetXtcW/fLf4cxZ+m0I=; b=kbxWHqlKlwL7/TFmdAxlGQ36uxjfmGDU1zSj07pPFkOUqHCIOWEKU+RBSDlJ7HXvHs xVas3LZH6km/UofjusgexkZDUVDn5ACX+6zYP4nbLCjr0BkObJYDFmCvrwOiLTzvASUz UeY2tPFVXFlckepdMdI1k/khmfoQj7JIDxIqMjR868dLJNmISQKL37D7/K4CLsHTRcrl +0yeSjFzeXeaaVBnUVQpbTEbxqzny6r53Snt+m4ISYCG1Ufu6CchpfNDjntPygXviQbc bGvwtehzKjHz9f2VPYHjSM0ZUdHSn27M7vRYIV+XxJe+ZZZ/AmZN5vR+bJZ78lDbdLnF KnMQ== X-Gm-Message-State: APjAAAW4YMZIgLcc3iDSS7NyiRraEZTeg8RjydxLkAg2qYdu1RUxGuqp XAud4YVYtmcWzyn1jbzmVv2XKPhsri0= X-Google-Smtp-Source: APXvYqwrV23Bi4Ch878f+eBoMbe3UBq01ZiJL3ljHtG/W8X86YtwkSbiB6JYjCxleFimcOO/1QE4NA== X-Received: by 2002:a1c:a713:: with SMTP id q19mr1275068wme.127.1567447804785; Mon, 02 Sep 2019 11:10:04 -0700 (PDT) Received: from tycho.fritz.box (ipbcc09208.dynamic.kabel-deutschland.de. [188.192.146.8]) by smtp.gmail.com with ESMTPSA id o9sm6628050wrh.46.2019.09.02.11.10.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2019 11:10:04 -0700 (PDT) From: Zahari Doychev To: netdev@vger.kernel.org Cc: bridge@lists.linux-foundation.org, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, jhs@mojatatu.com, dsahern@gmail.com, simon.horman@netronome.com, makita.toshiaki@lab.ntt.co.jp, xiyou.wangcong@gmail.com, jiri@resnulli.us, alexei.starovoitov@gmail.com, johannes@sipsolutions.net, Zahari Doychev Subject: [PATCH v3 1/2] net: bridge: use mac_len in bridge forwarding Date: Mon, 2 Sep 2019 20:09:59 +0200 Message-Id: <20190902181000.25638-1-zahari.doychev@linux.com> X-Mailer: git-send-email 2.22.0 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The bridge code cannot forward packets from various paths that set up the SKBs in different ways. Some of these packets get corrupted during the forwarding as not always is just ETH_HLEN pulled at the front. This happens e.g. when VLAN tags are pushed by using tc act_vlan on ingress. Example configuration is provided below. The test setup consists of two netdevs connected to external hosts. There is act_vlan on one of them adding two vlan tags on ingress and removing the tags on egress. The configuration is done using the following commands: ip link add name br0 type bridge vlan_filtering 1 ip link set dev br0 up ip link set dev net0 up ip link set dev net0 master br0 ip link set dev net1 up ip link set dev net1 master br0 bridge vlan add dev net0 vid 100 master bridge vlan add dev br0 vid 100 self bridge vlan add dev net1 vid 100 master tc qdisc add dev net0 handle ffff: clsact tc qdisc add dev net1 handle ffff: clsact tc filter add dev net0 ingress pref 1 protocol all flower \ action vlan push id 10 pipe action vlan push id 100 tc filter add dev net0 egress pref 1 protocol 802.1q flower \ vlan_id 100 vlan_ethtype 802.1q cvlan_id 10 \ action vlan pop pipe action vlan pop When using the setup above the packets coming on net0 get double tagged but the MAC headers gets corrupted when the packets go out of net1. The skb->data is pushed only by the ETH_HLEN length instead of mac_len in br_dev_queue_push_xmit. This later causes the function validate_xmit_vlan to insert the outer vlan tag behind the inner vlan tag as the skb->data does not point to the start of packet. The problem is fixed by using skb->mac_len instead of ETH_HLEN, which makes sure that the skb headers are correctly restored. This usually does not change anything, execpt the local bridge transmits which now need to set the skb->mac_len correctly in br_dev_xmit, as well as the broken case noted above. Signed-off-by: Zahari Doychev --- v2->v3: - move cover letter description to commit message --- net/bridge/br_device.c | 3 ++- net/bridge/br_forward.c | 4 ++-- net/bridge/br_vlan.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 681b72862c16..aeb77ff60311 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -55,8 +55,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) BR_INPUT_SKB_CB(skb)->frag_max_size = 0; skb_reset_mac_header(skb); + skb_reset_mac_len(skb); eth = eth_hdr(skb); - skb_pull(skb, ETH_HLEN); + skb_pull(skb, skb->mac_len); if (!br_allowed_ingress(br, br_vlan_group_rcu(br), skb, &vid)) goto out; diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 86637000f275..edb4f3533f05 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -32,7 +32,7 @@ static inline int should_deliver(const struct net_bridge_port *p, int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) { - skb_push(skb, ETH_HLEN); + skb_push(skb, skb->mac_len); if (!is_skb_forwardable(skb->dev, skb)) goto drop; @@ -94,7 +94,7 @@ static void __br_forward(const struct net_bridge_port *to, net = dev_net(indev); } else { if (unlikely(netpoll_tx_running(to->br->dev))) { - skb_push(skb, ETH_HLEN); + skb_push(skb, skb->mac_len); if (!is_skb_forwardable(skb->dev, skb)) kfree_skb(skb); else diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index bb98984cd27d..419067b314d7 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -466,13 +466,14 @@ static bool __allowed_ingress(const struct net_bridge *br, /* Tagged frame */ if (skb->vlan_proto != br->vlan_proto) { /* Protocol-mismatch, empty out vlan_tci for new tag */ - skb_push(skb, ETH_HLEN); + skb_push(skb, skb->mac_len); skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, skb_vlan_tag_get(skb)); if (unlikely(!skb)) return false; skb_pull(skb, ETH_HLEN); + skb_reset_network_header(skb); skb_reset_mac_len(skb); *vid = 0; tagged = false; From patchwork Mon Sep 2 18:10:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zahari Doychev X-Patchwork-Id: 1156704 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=googlemail.com header.i=@googlemail.com header.b="hZBO3jd2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46MdR74pqSz9s7T for ; Tue, 3 Sep 2019 04:10:11 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726843AbfIBSKK (ORCPT ); Mon, 2 Sep 2019 14:10:10 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:56243 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726506AbfIBSKK (ORCPT ); Mon, 2 Sep 2019 14:10:10 -0400 Received: by mail-wm1-f67.google.com with SMTP id g207so11492731wmg.5 for ; Mon, 02 Sep 2019 11:10:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AidZspGMGx6iPf3sywvvgbABtuj5XaTANuRL7olyHPs=; b=hZBO3jd2BUF1dS1m14xYyVxwBXb6xxjK2+t5eWX5PQCD7dUoPdtBMwV3IOWQ0UvIWg UTMTUd3fhy7m/kal3UiJNZIVUPKC2FcAqZ/QpB1hYNz+68FucXsiTq6SX+YDp2G5Ar61 1wGKOh/JmliWPDq60yyWQTvRt9OAKZdS15z2p5E4gsmT3RegAqvvz1sHY5vc1WmowJj/ JGLu35vJj5lfKdQ9ujj6W/5z0zODS+BV9Hhnh6zaFNc53yn+1Hzo4tPQLEkkXWFho3Dw MjwDW4HnVjpAk8RJAaDUeppVGekvqL62buOhPQzgaF5s5Bs2KQj/IJQub5loOt5TdnCt CrUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=AidZspGMGx6iPf3sywvvgbABtuj5XaTANuRL7olyHPs=; b=e0ovuY9wY0mlmsBvc1tITFKW2aNK3KLzjC9LYn94SnjurmpyLsizGfjiTf5/IXBHxF nl5NoPb7RT8kslgBgs9xmg/CV4LIQfZyxPyLJaF+Rfxvx2745U9w3wk49E80ATnUsiq/ DPV+yh7FSInSIafKBgWasePW8qLGGXwKxU+hW3ayMR0A7PcM41828qaoAFNtqlWPnhAz KmpRU+hnNYsXzqRfRfRtu5JFS1aBh+3eFv13bYqQKoEXAfFNWhsDfSx8nZa6zcm/NORN 8Xp5pOzbUYFKWEKkEkQceIrrme9KYhCK55DHP01pUpPYNMnlsarD2Bip3FA5ritTtMPF laHw== X-Gm-Message-State: APjAAAVx26dKE7W1sGaxipEMdFryscdUjtyuqyseUifxHu9/BXL0vEm4 9gRlZY/P5Aw8bW8oJjv0o/NtC0jVqTE= X-Google-Smtp-Source: APXvYqzKPWRwIjZAuXEWGQlBy5kLnbbIwKHhhdN4Q2u9rbwQ2apGPhPSejrpWKeVLxBC5OWjJp4IcQ== X-Received: by 2002:a1c:f007:: with SMTP id a7mr35093226wmb.172.1567447807601; Mon, 02 Sep 2019 11:10:07 -0700 (PDT) Received: from tycho.fritz.box (ipbcc09208.dynamic.kabel-deutschland.de. [188.192.146.8]) by smtp.gmail.com with ESMTPSA id o9sm6628050wrh.46.2019.09.02.11.10.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2019 11:10:07 -0700 (PDT) From: Zahari Doychev To: netdev@vger.kernel.org Cc: bridge@lists.linux-foundation.org, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, jhs@mojatatu.com, dsahern@gmail.com, simon.horman@netronome.com, makita.toshiaki@lab.ntt.co.jp, xiyou.wangcong@gmail.com, jiri@resnulli.us, alexei.starovoitov@gmail.com, johannes@sipsolutions.net, Zahari Doychev Subject: [PATCH v3 2/2] selftests: forwrading: tc vlan bridge test Date: Mon, 2 Sep 2019 20:10:00 +0200 Message-Id: <20190902181000.25638-2-zahari.doychev@linux.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190902181000.25638-1-zahari.doychev@linux.com> References: <20190902181000.25638-1-zahari.doychev@linux.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add bridge vlan aware forwarding test for vlans added by tc-act_vlan. The forwarding is tested in two cases when the bridge protocol and outer vlan tag protocol match and mismatch. The tests checks the correct usage of skb->mac_len in the bridge code. Signed-off-by: Zahari Doychev --- v2->v3: - selftest added --- .../forwarding/bridge_vlan_aware_tc_vlan.sh | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100755 tools/testing/selftests/net/forwarding/bridge_vlan_aware_tc_vlan.sh diff --git a/tools/testing/selftests/net/forwarding/bridge_vlan_aware_tc_vlan.sh b/tools/testing/selftests/net/forwarding/bridge_vlan_aware_tc_vlan.sh new file mode 100755 index 000000000000..215d6293fa54 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/bridge_vlan_aware_tc_vlan.sh @@ -0,0 +1,187 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# This test uses the standard topology for testing bridge forwarding. See +# README for more details. +# +# tc vlan actions are applied on one of the bridge ports and on other one +# the corresponding vlan network devices are created. +# + +ALL_TESTS=" + test_tc_vlan_bridge_ipv4_forwarding + test_tc_vlan_bridge_ipv4_forwarding_proto + test_tc_vlan_bridge_ipv6_forwarding + test_tc_vlan_bridge_ipv6_forwarding_proto +" + +NUM_NETIFS=4 +CHECK_TC="yes" +source lib.sh + +h_create() +{ + local dev=$1; shift + local ip=$1; shift + local ip6=$1 + + simple_if_init $dev $ip $ip6 +} + +h_destroy() +{ + local dev=$1; shift + local ip=$1; shift + local ip6=$1 + + simple_if_fini $dev $ip $ip6 +} + +switch_create() +{ + ip link add dev br0 type bridge vlan_filtering 1 vlan_protocol 802.1q \ + mcast_snooping 0 + + ip link set dev $swp1 master br0 + ip link set dev $swp2 master br0 + + ip link set dev br0 up + ip link set dev $swp1 up + ip link set dev $swp2 up + + bridge vlan add dev $swp1 vid $svid master + bridge vlan add dev br0 vid $svid self + bridge vlan add dev $swp2 vid $svid master +} + +switch_destroy() +{ + ip link set dev $swp2 down + ip link set dev $swp1 down + + ip link del dev br0 +} + +tc_vlan_create() +{ + tc qdisc add dev $swp1 clsact + + tc filter add dev $swp1 ingress pref 1 protocol all flower skip_hw \ + action vlan push id $cvid protocol 802.1q pipe \ + action vlan push id $svid protocol 802.1q + + tc filter add dev $swp1 egress pref 1 protocol 802.1q \ + flower skip_hw vlan_id $svid \ + vlan_ethtype 802.1q cvlan_id $cvid \ + action vlan pop pipe action vlan pop +} + +tc_vlan_destroy() +{ + tc filter del dev $swp1 ingress pref 1 + tc filter del dev $swp1 egress pref 1 + tc qdisc del dev $swp1 clsact +} + +vlan_create() +{ + local dev=$1; shift + local vid=$1; shift + local tpid=$1; + + ip link add link $dev name $dev.$vid type vlan id $vid proto $tpid + ip link set dev $dev up + ip link set dev $dev.$vid +} + +vlan_destroy() +{ + local dev=$1 + + ip link del dev $dev +} + +setup_prepare() +{ + h1=${NETIFS[p1]} + swp1=${NETIFS[p2]} + + swp2=${NETIFS[p3]} + h2=${NETIFS[p4]} + + cvid=10 + svid=100 + + vrf_prepare + + switch_create + + tc_vlan_create + + h_create $h1 192.0.2.1/24 2001:db8:1::1/64 + + vlan_create $h2 $svid 802.1q + vlan_create $h2.$svid $cvid 802.1q + + h_create $h2.$svid.$cvid 192.0.2.2/24 2001:db8:1::2/64 +} + +cleanup() +{ + pre_cleanup + + tc_vlan_destroy + + switch_destroy + + h_destroy $h1 192.0.2.1/24 2001:db8:1::1/64 + h_destroy $h2.$svid.$cvid 192.0.2.2/24 2001:db8:1::2/64 + + vlan_destroy $h2.$svid.$cvid + vlan_destroy $h2.$svid + + ip link del dev $h1 + ip link del dev $h2 + + vrf_cleanup +} + +test_tc_vlan_bridge_ipv4_forwarding() +{ + ip link set dev br0 type bridge vlan_protocol 802.1q + ping_do $h1 192.0.2.2 + check_err $? "Packets were not forwarded" + log_test "IPv4 tc-vlan bridge forwarding" +} + +test_tc_vlan_bridge_ipv4_forwarding_proto() +{ + ip link set dev br0 type bridge vlan_protocol 802.1ad + ping_do $h1 192.0.2.2 + check_err $? "Packets were not forwarded" + log_test "IPv4 tc-vlan bridge forwarding protocol mismatch" +} + +test_tc_vlan_bridge_ipv6_forwarding() +{ + ip link set dev br0 type bridge vlan_protocol 802.1q + ping6_do $h1 2001:db8:1::2 + check_err $? "Packets were not forwarded" + log_test "IPv6 tc-vlan bridge forwarding" +} + +test_tc_vlan_bridge_ipv6_forwarding_proto() +{ + ip link set dev br0 type bridge vlan_protocol 802.1ad + ping6_do $h1 2001:db8:1::2 + check_err $? "Packet were not forwarded" + log_test "IPv6 tc-vlan bridge forwarding protocol mismatch" +} +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS