From patchwork Sun Jul 8 09:15:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 10513047 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C3532603D7 for ; Sun, 8 Jul 2018 09:16:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B000D2893C for ; Sun, 8 Jul 2018 09:16:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A492928961; Sun, 8 Jul 2018 09:16:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, MAILING_LIST_MULTI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8BD5028948 for ; Sun, 8 Jul 2018 09:16:18 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41NjWN5NG3zDrHZ for ; Sun, 8 Jul 2018 19:16:16 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=mellanox.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="CWLMksU6"; dkim-atps=neutral X-Original-To: linux-mlxsw@lists.ozlabs.org Delivered-To: linux-mlxsw@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mellanox.com (client-ip=40.107.0.43; helo=eur02-am5-obe.outbound.protection.outlook.com; envelope-from=idosch@mellanox.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=mellanox.com Authentication-Results: lists.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="CWLMksU6"; dkim-atps=neutral Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00043.outbound.protection.outlook.com [40.107.0.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41NjWF5PsRzDqBW for ; Sun, 8 Jul 2018 19:16:09 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=nztXgUqmzAPlYpuzCq6zZSLD3lCeSACMPpCMjHBWUCs=; b=CWLMksU6LyScgkAyewDDGnE7TrIG2lcPNBJj3EX1GKfH3rPGpupW4W0cKhLZgDPDyXc+oJJJJ6fQ/TStwpKE0cRuOCXt5Tpfn2yvm1WW8Pi/4R5B3mrXRJx8Tlfz3fP7PTCVxleQOa9fJXUJxIHVbovJmbcbjMO1aoeZHZVFXcU= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=idosch@mellanox.com; Received: from splinter.mtl.com (193.47.165.251) by VI1PR0501MB2333.eurprd05.prod.outlook.com (2603:10a6:800:2c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.930.19; Sun, 8 Jul 2018 09:15:59 +0000 From: Ido Schimmel To: linux-internal@mellanox.com Subject: [PATCH net-next mlxsw v2 2/4] mlxsw: spectrum_router: Direct macvlans' MACs to router Date: Sun, 8 Jul 2018 12:15:36 +0300 Message-Id: <20180708091538.22068-3-idosch@mellanox.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180708091538.22068-1-idosch@mellanox.com> References: <20180708091538.22068-1-idosch@mellanox.com> MIME-Version: 1.0 X-Originating-IP: [193.47.165.251] X-ClientProxiedBy: DB6PR07CA0018.eurprd07.prod.outlook.com (2603:10a6:6:2d::28) To VI1PR0501MB2333.eurprd05.prod.outlook.com (2603:10a6:800:2c::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 31330f63-7e0e-4414-e8d2-08d5e4b36bac X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(5600053)(711020)(48565401081)(2017052603328)(7153060)(7193020); SRVR:VI1PR0501MB2333; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2333; 3:8Xi4fJmnhu5OlxqNWBTCC6I7Aq8CGHtS69cbWA6jnAlMvwMA/zueTFkZSpHI7gORdPpsN8PS7Gm6FQ/nDzknHpR9/z5fkvagiBpeoqA5ytoRmc0P6LuA99ichrC0w8Xei6lZsH2lbxZKTWomRHArxhRg+E2yjE66D/R6zdKrb1UnOtXmfxTVw+TWaBbYjogNroPZfRdcmkpMaDNnOEZ+992H6mO8C+pMqt1PuwOiLtR3Ce1xGUwN5dz2M1N5CzzI; 25:TsMVq2bM2rkkvZCr8L6ymb7zHe9K8zguyd6i4A2sjAyO0tA4E0JteoXVsEko112R6rVEfTBuh3694UMyaMvbF0NY6sAKvGtKlOu2cg8rrtvoFJzgltiYH3guZOmxhdT6aFun7qLNn5fBSZF2C1V3xo2ZgIDbTWiCc31B0ECJ+IXi1/ERrG2IuwT/trfqw9m2M3WnSDGkOz1wstnHdqrYR1XBFri6/01hIbX4KQcxdXu8QQ8D8PCuR6/C6I9+kjf7Liv1PljL7/DFparhVsW5Jb9BoktCorBtZBuUXuCixGRpC+pwLMUcyEsNn2rOwEUbBzeqqiR9suUIcMf7W3zWew==; 31:mWaMS8sA4GW7HfwEatL05XkzwzgC/sLpQA9prndLKR8MQOgQHFOKjwd5382io7/Zam339l4/1CIi5gutIID8UT5IJC2XFyc/2O2sE+kwRNDQTD7NmcmIsp0BirLOmSRkDdyeKO2XDVk46WkwyUriH1adHLW7GEX0XUXkiZuBrP/NPVgi8B+JZNa5EOewGnkDfQfs50f6NoxxxjPbTDZDpe+RrPpAY1zE0BBEXlwzd5A= X-MS-TrafficTypeDiagnostic: VI1PR0501MB2333: X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2333; 20:71/PEAia6cWC4l+3YdgToeS9W4tbn2xl1z2fhzwxi/dfFDFmlN06d/VefzkT5FqlQjsUyGh/ExjnC4oxEd3KWT69PwrRRVNBO/6J0OL8+3lyb1ZGH00K+OEjn95UpIGUCexCB17WKeg+nXFxDyNz1ZYBEEEpAru0tnXzjE1+y1ErQhBsEpGD+m75p5I096H7rDbZmAX/d9ECcwTsH3hVObrVbIyHgAcNGBIw5ura3eDmpJ2rxnF0pzZl9zSdv2eGVSt5HTR/zj9q+l9veHPWV5Oe60Fn2x+C8iLNJuMLyd0OciE/BT/536+rMSVgHp0WgzydaV/srWtYCd4v+edkgXEg0DsdVGaOTRptrWCtsIbS8pv138vAoWO7PpUwNQi0BVHOg1MHNerlZ/4EuErhRzpSUi1/FoQn4ViRfvvZB7JRI83oljvG43Fswb4ZnRmIgu/BA4CDxB9PsRyTErYBT6w0zCrEmT9iLqqfj8eD7+6irKQVOtp0tKcMgCxtdl26; 4:ZFSD9KnYs50GMs/5ZlECW2topSRFnqiesPaedUTh5jabcxCNXxQgTrR4DeCNiRx0hokrBLQ66PPLPCB7e9Cz3ToixY5eEcdkSqueCMh0ZcfIeB63t1DBZ8UdZrFRrC+7o/PL+lZZrmsU939rDVVDZUYar6fK+hEgjB2tiV3nrPxVvwPJ63FPBtfJqK/ZqRRor48qlwHJhBLxmwt3iR0OU4AVCOVCpeAdh6u+dohwjCqsGCEb9HqeAWriASfP3e1DyYQkfdiooWrt7U/P1xa6Fw== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(10201501046)(3231311)(944501410)(52105095)(6055026)(149027)(150027)(6041310)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123558120)(6072148)(201708071742011)(7699016); SRVR:VI1PR0501MB2333; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0501MB2333; X-Forefront-PRVS: 0727122FC6 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(366004)(346002)(136003)(396003)(376002)(39860400002)(189003)(199004)(3846002)(81166006)(5660300001)(47776003)(81156014)(8676002)(6116002)(107886003)(316002)(16586007)(1076002)(34206002)(37006003)(6666003)(66066001)(36756003)(48376002)(26005)(6512007)(4326008)(50466002)(6636002)(25786009)(16526019)(86362001)(52116002)(76176011)(51416003)(8936002)(6506007)(6486002)(53416004)(478600001)(2351001)(106356001)(305945005)(486006)(7736002)(446003)(476003)(105586002)(68736007)(2616005)(956004)(11346002)(2361001)(14444005)(386003)(2906002)(50226002)(53936002)(97736004); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0501MB2333; H:splinter.mtl.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR0501MB2333; 23:8mQPdsHkXqBgzbMPfv8jwo3eB6o5ZhJoXAFouqs?= =?us-ascii?Q?KXs3bWZ5KcnhVQitq0D5kzDwPdFK+46N0ejk9kZMyJz7qpYr/lsQqoAGvMwX?= =?us-ascii?Q?XzZysYeBwJo6l9SG47Z5rIOUhVvDtLfDXZYunVCCIZmDnhhx192M6d+wCrNL?= =?us-ascii?Q?SqaCxJYYU8d/9bqyaD+9Fkz4b/Z2ffKgCv3tSAOTHOEr6jBh7s0XqrRT+SED?= =?us-ascii?Q?AEerT4XMDqXQXy6MJHtjW/kojuu7MEj/NT6huSahk1++IWQTEEZSSaJZf8g3?= =?us-ascii?Q?a5JjghGnsvH8kNfWEe1yVhNa6ty7XmaCa+2j4Beaf/udjW0pBHh+nwtElsr3?= =?us-ascii?Q?7MOvDx4/+wqpQvzZ3q/arqJrHAoyGgP0FHIP7bAin+svRQYeH2Md7Zxyhw/r?= =?us-ascii?Q?1wyhlnz01bRsnZuhL1WJ5/vhVr3TMl0MZ7g0a5xOQR/8dfzmgRY+7vv43awW?= =?us-ascii?Q?gfHbAXrGva7dBEx3KmRAMyzxGAuv5BLLkkuTWezD4Loj4vgMysFixg3z5ZzZ?= =?us-ascii?Q?VuzGZISwKvI25xTX5Jz8Jql7Mdy3RAUvfgSJ+CvkU40+e1UBTF5meRxXrgBJ?= =?us-ascii?Q?mn5E93bOIDWrKSA99Ia8gof7SgXsGdkCdcu0LhVgDU2Us/M42EapLPjIrVRg?= =?us-ascii?Q?ep5g/lJzAoGjH0HPG+u0wLZkhYEyS0e6BgIW0CjAAvRRI5hMwT3g9Tig/3Yh?= =?us-ascii?Q?/5lgCzIVl7wISWPwogoKTDXdQNiAC6WnoDd/nMe83vXjkNimK2jXVAKzOKgq?= =?us-ascii?Q?aA6eRnyy2j7eQaMJc9ANVVOjM7qPt9H2yfDDDmqeXIaAhdRbNx/JcKJEf3DL?= =?us-ascii?Q?kAjs7QNpWckIVazMEqp3UeuhPlQZWiUxURSpaz5VV6INRb7g343ba/5MjJJ9?= =?us-ascii?Q?bTtBOGA+sx3eIXTAzo98VajSGn3r4oaHj+KnR45nZB1Fh/zadrbYQz91stCD?= =?us-ascii?Q?sLDeycPvoPU0DSLd0Ci9EAyhcr2bFS88pwt53HUIvIbJMVoTZCWXMTehJZUB?= =?us-ascii?Q?7P/exjpttqfQ+D1lC4wpxzwnUM4QVko4iosz4aMErsfPudMUAtgH090Sce5o?= =?us-ascii?Q?yq09ciy5zxUBwIIrFB7LReJ7T2FS4AUz1EWSe1jEPnz4H2LLc7L21JHyoecF?= =?us-ascii?Q?e8H62ewrGTkx70FIUT7B2D9+er5tu0LsfDY6buHZ6CmxityUjNLviNs6735I?= =?us-ascii?Q?Ls13rtOOI/1hDtcdEBI1F9XWA1LfPAPcKKJ8FipjEGBn7fgtL1crCzsvxPaM?= =?us-ascii?Q?PwqrjpEqc2enXWx8Tpj+AuWK7gZQwLLzLtWBqkFpn73gec19GGzC87900cqX?= =?us-ascii?Q?cMSkH88ZNBem1X+rz2omDV5c=3D?= X-Microsoft-Antispam-Message-Info: 9DRCsnTgzRJIGTmQig7aTjgQquvo+tiUC7cOP5jJ32C1MrtagRx+hs9BAsnBIZZv3VY+55smRGIZFXH6+MnRAOvcVWNRBXYSQ8ZagyaCDZiY1JLgX4IU1/3wudq8Q2XUc/FpTF/oDNUg1yxFcscANs/VU+uITiVgOoDCB2xB4gFLw6odF5DSKo9bwURoGkdhCfUKK9KbwE1ohgLmXEO/+PHLq4mOLtzIQY74AG7MPrkqOejMnnSVU/3VT7mCKpHJMJPzpaO/120vPYuZzireQjul/MckOw4WSCBOCzj84SdRv2Tb4AdTsOxnOqzT96h/yKNUHmjM+tlbG50AkZKxQo150w2l5s70ZxbPt4rtl3I= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2333; 6:mr4pj5/f1zo8/O/W6mKaPco902iScvRvzC87cLz/4DOdumsQIf8sZt0qdCR2HBbVl4GuMKI++40sJzbIWrA0v2M0lpYjJy3ICGy/Xczv4k/7vhY+hgYHLUarK61uM8RU/E+XYqNGP/x6B1uMX0AUf8NIEoJr+ILe8LbEhFg5TUvvKUCZzxuZ6cDI8TyTRaUHl83kRr1XAth5XBuTnucqgVooet2ibdPVUdQ3lcvGDDsz5FQWU7bd5dWoX4tCPwWpqIFYI7ehzQHFFxXQkKMlwYqHTT94lxPp8lvxdK4CCcABE9mkbA53VC/0Za0Em1BdMZEROVdMXF5Jb4I46QZd8hS2owu78Dpcdy4GexbHzSMhxAGOpG/bfCzlvQvX/viFr/OwX2yJ2Hr4xsMt5OpMuvEXs60hPZAoS0g36IbbPRwG2QVS6hQYr78D7UsxHn2WatqNBgI1aIXjIJW+YlJYrA==; 5:LDrfvhYt4ZqCkLOQVcDNRm282Ob/U73yeom46IL0oYASqYd+1ObTwnqnudad212Q8eW/+zCzGl6EjoR4a8LfXMz1N7929NCKS7F8bAAniZEFP/ZVXLy/XdLXBtVIvo+601ivQUE/Su7FsMH6ZrjpgmkVKuj4txVeIdlac7yZ7sA=; 24:LmUkNgNfkjk8xyhSryuRZkdHzG9T/vtWS1/0gIqBzt6/eXBRW2Cj5mj1aMlUi3wpFKZWHCxq80Z9mh3bt6daVp+fbbPpROw9KzIvVVINvdw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2333; 7:G+zsUK1WYqLCOiQdHghDtmxazU1+IubKSvXOz5pgJoKkciiDYkD6OzX6DPTTdP5TiErOSXcZ/O8MOR/7nE6XwR0eFYw0u4hipc1R27w2gKCZ44uwmEw4QVnXG+SAykDi4cj/QcFoMe5ppzk8NJyiBcrt7bkHFnWhMZ9TrpQ2d/tHygSC0mmt0htW0lGYCle0wHwzHVSWFHRhrs0Ur0RDWrTIcCMqCMP9tkpOKniuYW4Vn0OZBO38pjS+thcXf4P+ X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Jul 2018 09:15:59.3000 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 31330f63-7e0e-4414-e8d2-08d5e4b36bac X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0501MB2333 X-BeenThere: linux-mlxsw@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: mlxsw driver development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-mlxsw-bounces+patchwork-linux-mlxsw=patchwork.kernel.org@lists.ozlabs.org X-Virus-Scanned: ClamAV using ClamSMTP An IP packet received on a netdev with a macvlan upper whose MAC matches the packet's destination MAC will be re-injected to the Rx path as if it was received by the macvlan, and perform an L3 lookup. Reflect this functionality to the ASIC by programming FDB entries that will direct MACs of macvlan uppers to the router. In a similar fashion to router interfaces (RIFs) that are programmed upon the addition of the first IP address on an interface and destroyed upon the removal of the last IP address, the FDB entries for the macvlan are added and destroyed based on the addition of the first and removal of the last IP address on the macvlan. Signed-off-by: Ido Schimmel --- Notes: v2: * Change wording * Remove goto from mlxsw_sp_rif_macvlan_add() * Use is_vlan_dev() in mlxsw_sp_rif_vlan_fdb_del() instead of netif_is_bridge_master() v1: * Handle deletion of macvlans * Delete macvlan's MAC from bridge driver * Add warning when a RIF with a macvlan is deleted drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 11 ++ drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 + .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 133 +++++++++++++++++++++ 3 files changed, 146 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index bb1a3ee2120d..1263d1bab23b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -4471,6 +4471,9 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev, err = mlxsw_sp_port_ovs_join(mlxsw_sp_port); else mlxsw_sp_port_ovs_leave(mlxsw_sp_port); + } else if (netif_is_macvlan(upper_dev)) { + if (!info->linking) + mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev); } break; } @@ -4587,6 +4590,9 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev, mlxsw_sp_port_bridge_leave(mlxsw_sp_port, vlan_dev, upper_dev); + } else if (netif_is_macvlan(upper_dev)) { + if (!info->linking) + mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev); } else { err = -EINVAL; WARN_ON(1); @@ -4665,6 +4671,11 @@ static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev, } break; case NETDEV_CHANGEUPPER: + upper_dev = info->upper_dev; + if (info->linking) + break; + if (netif_is_macvlan(upper_dev)) + mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev); break; } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index f5294c9a4c92..59e104ddccd3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -408,6 +408,8 @@ static inline void mlxsw_sp_port_dcb_fini(struct mlxsw_sp_port *mlxsw_sp_port) int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp); void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp); int mlxsw_sp_netdevice_router_port_event(struct net_device *dev); +void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp, + const struct net_device *macvlan_dev); int mlxsw_sp_inetaddr_event(struct notifier_block *unused, unsigned long event, void *ptr); int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 948d8d00e676..1fbacfe10e02 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ #include #include #include +#include #include "spectrum.h" #include "core.h" @@ -165,6 +167,7 @@ struct mlxsw_sp_rif_ops { void (*deconfigure)(struct mlxsw_sp_rif *rif); struct mlxsw_sp_fid * (*fid_get)(struct mlxsw_sp_rif *rif, struct netlink_ext_ack *extack); + void (*fdb_del)(struct mlxsw_sp_rif *rif, const char *mac); }; static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree); @@ -6021,6 +6024,12 @@ mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *rif, struct net_device *dev, !list_empty(&inet6_dev->addr_list)) addr_list_empty = false; + /* macvlans do not have a RIF, but rather piggy back on the + * RIF of their lower device. + */ + if (netif_is_macvlan(dev) && addr_list_empty) + return true; + if (rif && addr_list_empty && !netif_is_l3_slave(rif->dev)) return true; @@ -6434,6 +6443,71 @@ static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev, return 0; } +static int mlxsw_sp_rif_macvlan_add(struct mlxsw_sp *mlxsw_sp, + const struct net_device *macvlan_dev, + struct netlink_ext_ack *extack) +{ + struct macvlan_dev *vlan = netdev_priv(macvlan_dev); + struct mlxsw_sp_rif *rif; + int err; + + rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan->lowerdev); + if (!rif) { + NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces"); + return -EOPNOTSUPP; + } + + err = mlxsw_sp_rif_fdb_op(mlxsw_sp, macvlan_dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), true); + if (err) + return err; + + /* Make sure the bridge driver does not have this MAC pointing at + * some other port. + */ + if (rif->ops->fdb_del) + rif->ops->fdb_del(rif, macvlan_dev->dev_addr); + + return 0; +} + +void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp, + const struct net_device *macvlan_dev) +{ + struct macvlan_dev *vlan = netdev_priv(macvlan_dev); + struct mlxsw_sp_rif *rif; + + rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan->lowerdev); + /* If we do not have a RIF, then we already took care of + * removing the macvlan's MAC during RIF deletion. + */ + if (!rif) + return; + mlxsw_sp_rif_fdb_op(mlxsw_sp, macvlan_dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); +} + +static int mlxsw_sp_inetaddr_macvlan_event(struct net_device *macvlan_dev, + unsigned long event, + struct netlink_ext_ack *extack) +{ + struct mlxsw_sp *mlxsw_sp; + + mlxsw_sp = mlxsw_sp_lower_get(macvlan_dev); + if (!mlxsw_sp) + return 0; + + switch (event) { + case NETDEV_UP: + return mlxsw_sp_rif_macvlan_add(mlxsw_sp, macvlan_dev, extack); + case NETDEV_DOWN: + mlxsw_sp_rif_macvlan_del(mlxsw_sp, macvlan_dev); + break; + } + + return 0; +} + static int __mlxsw_sp_inetaddr_event(struct net_device *dev, unsigned long event, struct netlink_ext_ack *extack) @@ -6446,6 +6520,8 @@ static int __mlxsw_sp_inetaddr_event(struct net_device *dev, return mlxsw_sp_inetaddr_bridge_event(dev, event, extack); else if (is_vlan_dev(dev)) return mlxsw_sp_inetaddr_vlan_event(dev, event, extack); + else if (netif_is_macvlan(dev)) + return mlxsw_sp_inetaddr_macvlan_event(dev, event, extack); else return 0; } @@ -6710,6 +6786,27 @@ int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event, return err; } +static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data) +{ + struct mlxsw_sp_rif *rif = data; + + if (!netif_is_macvlan(dev)) + return 0; + + return mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); +} + +static int mlxsw_sp_rif_macvlan_flush(struct mlxsw_sp_rif *rif) +{ + if (!netif_is_macvlan_port(rif->dev)) + return 0; + + netdev_warn(rif->dev, "Router interface is deleted. Upper macvlans will not work\n"); + return netdev_walk_all_upper_dev_rcu(rif->dev, + __mlxsw_sp_rif_macvlan_flush, rif); +} + static struct mlxsw_sp_rif_subport * mlxsw_sp_rif_subport_rif(const struct mlxsw_sp_rif *rif) { @@ -6776,6 +6873,7 @@ static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif) mlxsw_sp_fid_rif_set(fid, NULL); mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, mlxsw_sp_fid_index(fid), false); + mlxsw_sp_rif_macvlan_flush(rif); mlxsw_sp_rif_subport_op(rif, false); } @@ -6863,6 +6961,7 @@ static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif) mlxsw_sp_fid_rif_set(fid, NULL); mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, mlxsw_sp_fid_index(fid), false); + mlxsw_sp_rif_macvlan_flush(rif); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, mlxsw_sp_router_port(mlxsw_sp), false); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, @@ -6890,12 +6989,30 @@ mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif, return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid); } +static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac) +{ + u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); + struct switchdev_notifier_fdb_info info; + struct net_device *br_dev; + struct net_device *dev; + + br_dev = is_vlan_dev(rif->dev) ? vlan_dev_real_dev(rif->dev) : rif->dev; + dev = br_fdb_find_port(br_dev, mac, vid); + if (!dev) + return; + + info.addr = mac; + info.vid = vid; + call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info); +} + static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_ops = { .type = MLXSW_SP_RIF_TYPE_VLAN, .rif_size = sizeof(struct mlxsw_sp_rif), .configure = mlxsw_sp_rif_vlan_configure, .deconfigure = mlxsw_sp_rif_vlan_deconfigure, .fid_get = mlxsw_sp_rif_vlan_fid_get, + .fdb_del = mlxsw_sp_rif_vlan_fdb_del, }; static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif) @@ -6947,6 +7064,7 @@ static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif) mlxsw_sp_fid_rif_set(fid, NULL); mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, mlxsw_sp_fid_index(fid), false); + mlxsw_sp_rif_macvlan_flush(rif); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, mlxsw_sp_router_port(mlxsw_sp), false); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, @@ -6961,12 +7079,27 @@ mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif, return mlxsw_sp_fid_8021d_get(rif->mlxsw_sp, rif->dev->ifindex); } +static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac) +{ + struct switchdev_notifier_fdb_info info; + struct net_device *dev; + + dev = br_fdb_find_port(rif->dev, mac, 0); + if (!dev) + return; + + info.addr = mac; + info.vid = 0; + call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info); +} + static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = { .type = MLXSW_SP_RIF_TYPE_FID, .rif_size = sizeof(struct mlxsw_sp_rif), .configure = mlxsw_sp_rif_fid_configure, .deconfigure = mlxsw_sp_rif_fid_deconfigure, .fid_get = mlxsw_sp_rif_fid_fid_get, + .fdb_del = mlxsw_sp_rif_fid_fdb_del, }; static struct mlxsw_sp_rif_ipip_lb *