From patchwork Thu Jul 5 13:58:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 10509391 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 59A37603D7 for ; Thu, 5 Jul 2018 14:03:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 46B9328985 for ; Thu, 5 Jul 2018 14:03:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3A972290AC; Thu, 5 Jul 2018 14:03:43 +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 2981B28985 for ; Thu, 5 Jul 2018 14:03:42 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41M02N2jbqzF20w for ; Fri, 6 Jul 2018 00:03:40 +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="lC3gVRRk"; 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.4.69; helo=eur03-db5-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="lC3gVRRk"; dkim-atps=neutral Received: from EUR03-DB5-obe.outbound.protection.outlook.com (mail-eopbgr40069.outbound.protection.outlook.com [40.107.4.69]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41LzxG2q7HzF1r1 for ; Thu, 5 Jul 2018 23:59:14 +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=WYoH3la93QLv7oV8x7Epok64lzfUq1Ry2GCN6aNVIWo=; b=lC3gVRRkNXNuvGTat5bfZXLkiWbeYk58Qlr4QcxhWTZbn1Vh9mfLlR81CRUy0Zx+egaRAS7W+HP6O5WIPOxF+LmotWhCOk1rs9p6v9Gs7QWgXwK1VXfdFlbZ/4Um9OgOQGD6L7PZjMxElUCjy7ZKQGjUTmoLkLbsKe31YCv2ed4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=idosch@mellanox.com; Received: from splinter.mtl.com (193.47.165.251) by VI1PR0501MB2334.eurprd05.prod.outlook.com (2603:10a6:800:2c::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.906.25; Thu, 5 Jul 2018 13:59:02 +0000 From: Ido Schimmel To: idosch@idosch.org Subject: [PATCH net-next mlxsw 2/4] mlxsw: spectrum_router: Direct macvlans' MACs to router Date: Thu, 5 Jul 2018 16:58:25 +0300 Message-Id: <20180705135827.14770-3-idosch@mellanox.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180705135827.14770-1-idosch@mellanox.com> References: <20180705135827.14770-1-idosch@mellanox.com> MIME-Version: 1.0 X-Originating-IP: [193.47.165.251] X-ClientProxiedBy: DB6P193CA0012.EURP193.PROD.OUTLOOK.COM (2603:10a6:6:29::22) To VI1PR0501MB2334.eurprd05.prod.outlook.com (2603:10a6:800:2c::23) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8c99e632-fd19-4251-5075-08d5e27f76f5 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(5600053)(711020)(48565401081)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(2017052603328)(7153060)(7193020); SRVR:VI1PR0501MB2334; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2334; 3:7wuB0feKLqSIb01lWPm03/zuEvRrT68oLfFPpvAE/C6i0Tm+PIU67XGwqFYBWo8gZ+1Z3Q/GQBc2vTUJJz4QNmu67x44N+2Jctd/vilmT+gxVhNmagZbiIBYk2zJZeowm14CEIHKtkK0x3+gQt1KB9GZahw9fo0urL3EfoSyD1U9W9Oaf8hEMHUdXucbt/HLqUFyjmjL0C7JXpm05J3WR5P/3qosRgsOSL4LiBIzT0LYb1MYWFWR1q266Zz341Rw; 25:0X1p1Kb+HMi11WfWkiC9clxavx9g+uapHj86Hl29skq2Zq8X8JgoTspXTUeX5WWSQkeSCmg/+W9Xvh61aETa9cmQ4MTxsy3Xt4dOYmrtJTF4UY6AEjeChcY3O629ZGGojIdW3QAY1ASL6qgU3p/xYEexX5JUvGfJpyeXjzMDOO6eTwRt+XpUVKdddsQRW1UNGKAc1igJl6CiP9SFUe66NOwKjSaFaM7H8XuSP4XjxOy1BI9LhOn0gowbbgO3xFido4PAsDuwryCms8TLaGEJ2mOso2Jv+wmoQTDmCp2BW7KANLmKRQjgPNA0QKtox1FeESDCSSDgeLEOzsmNRdAQ1g==; 31:Ndh966ZfhI8xKp0MFEhp5Y5s7rFiX++rT2bJsCUZLAISEzGakkEVDx0/2HgOQbooFj8qDQOtUoXDMrIsIPpNQIQJej2YuzpSCiO2Bz7ctgKR2Jk398xsPhksOqUq2L5OKGKhTWijvrlJu6NvrWGxqDRVx2+kQ61jPlhDmh63xbjwUexcDKQr1yWqVVy/2ANkbxgJyYzYNUgFXpzDXxzdKVtfat6jAblk3xuBwoMy3zA= X-MS-TrafficTypeDiagnostic: VI1PR0501MB2334: X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2334; 20:RF9wnogAfpGSL9UJHFDg7y5YuCay2LTU0zO9TUB1yjyNc55Ux4x9ktwNeAxKFmywGV0l1vwSkggKX/hj5G1cUbZlQe47UQJPjldgAQSgjRhRqB/9gio+3wIH1Rrvft3XnwUeFx2SMh/Ph75Q7EL9UtMl+WHUgokjVNBitY6U/gGuZMnetYFM3oqvJADAmHZ/nORAK3iA8A9kyTOftHqqGr4L5V4auqX0rWbnu14IpMDfeJszMTu8ZIqa32CCS9jK+gj+zY6iFZ3N5Y/PDEYJKyCAsNjqnHrw3tKF1312JmD4Yy6lhRVx4MfehRPNMeZF53rWQ05fFNNxA9VV+4qZUEfKMxM9uJLrhcqcc1A+05sOEgxr9N4J47EhNH+f4+tiEtgpOA/qyTpJfBmJw0xEVjeqXsEXJQMazdBoFCKVVTlY2hF/8bZ+34xdtwjZWqTTpQvaZ/uvwmXoRZFkQH3kznCxdaj5J7z6yKLV3k7jF3LE7Qk5mWVPU56+2WJLvAjI; 4:X1WVkhuCGcQZxbW+q1RdxDgeq2LpdIi/dtluQIuU6VN9iP3Rrqx0l04loMZ8o9eC9iI62NslIB+2HujOZOdUTGXJ65wlc/4+Z+ZoGraW3JhGezCrtgwtZYXSjbEsXD0MSgLYX7w0isw0WFQGnQ6nz1RjPzx3P2l1i87enTU0z0Ggb109Qp4S9bI7A17UFAAwoDkYf+itJCljsWJhoLnBKc1F7DrxUuGWt66j9i9gW337+9TdCM5nsNU2tXo9V9vM/ejEYyvJDa6DRteXo4sNQw== 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)(10201501046)(3002001)(3231254)(944501410)(52105095)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123562045)(20161123558120)(20161123564045)(6072148)(201708071742011)(7699016); SRVR:VI1PR0501MB2334; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0501MB2334; X-Forefront-PRVS: 0724FCD4CD X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(136003)(39860400002)(346002)(366004)(376002)(189003)(199004)(107886003)(478600001)(1076002)(14444005)(97736004)(6116002)(3846002)(2361001)(6916009)(53936002)(4326008)(8936002)(81156014)(81166006)(8676002)(2906002)(305945005)(7736002)(86362001)(25786009)(316002)(2351001)(6512007)(186003)(26005)(76176011)(386003)(6506007)(51416003)(5660300001)(16586007)(52116002)(16526019)(6486002)(50226002)(50466002)(36756003)(47776003)(68736007)(106356001)(105586002)(6666003)(66066001)(53416004)(2616005)(48376002)(486006)(476003)(956004)(11346002)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0501MB2334; 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; VI1PR0501MB2334; 23:SuOZbMSe4X0e73XXGJXKRhK91I/ie+vRuoUy8Qd?= =?us-ascii?Q?8LqsL5H05/PBF30Pf44fOQgzQ5h6X0geiLTmuW5cC8yza2jUvUkzFybiJLq0?= =?us-ascii?Q?JnxttxTadyGxdmAVOhL/WCha0KVhAgE1yms7JhLkvmmzsy6z05BPKhURCEn2?= =?us-ascii?Q?jYqRk3Qa4d5YTFph78wM4Ir6ElZtJHRBqW3O1iugjiv1lnBGWJq1nOD7BV68?= =?us-ascii?Q?Q2VKmSmnFV2iaRlG4q0E7kStg36Hyg5HtC4DcBw85uZvuH1cqNB4cYqrFlj5?= =?us-ascii?Q?1+xF4PzciPougMef7NerKtgf1myuAG2FdqJtg1aAQo9U4DH122Q3z0SoSO+L?= =?us-ascii?Q?RmktonMMLdYkchNEnTUfSXSYz7crzAmm92/aob1Ry//+SX3Wap867qFEvvS1?= =?us-ascii?Q?JoreRgxgNpGqvzpgQQyoQt8Xb9TTsztrTAqISIVcAt2E2Dyk+Y5+K1oblqyt?= =?us-ascii?Q?0TsjDBv3kd3k48t64a82hbWAEfeKHt4V35pqGVmqQpsirfcwFKaXIaeXz70I?= =?us-ascii?Q?NUPvUtJgmxv6rVcHC9S7OVL+h+TSGS+IxKSGJ/efqmxYbN2HHuH4kueEf1YN?= =?us-ascii?Q?0i9FvI2+cj3pdFryip3Yq7QB7cF7pd74mH6o68OMZVVr5ejIGQ5owg3MR5cE?= =?us-ascii?Q?AFGtVEYn000w96oV8n9PNLhEfVEnW/E3x90C1BvTR8cvBC8MyINkfWU3co/S?= =?us-ascii?Q?4xixSgQtjonO5y7y9MDeVT+OwrvdjjC03EaNkT9bnXxMReT6gE31eFb7U4TI?= =?us-ascii?Q?hXrn/+w6mAQFDCsuh9m77yviZBlLucUlrj71ELUNUobpy+tSBYWsBobLBfA8?= =?us-ascii?Q?HrdSqjeVgd42kmoRTM1aXhZ3A1LLb1XM0J+jvsb1NGNLfRgEjiYVGB6F6wFB?= =?us-ascii?Q?iVO0DNW8rsNhwcssejNrztooLeRREnKuf7UiGDbturmaHXGOIHz5kaqcuPi8?= =?us-ascii?Q?IKJgun4tCUvmAzWvx+Mrt+PgLckBX3dfhafYlka8zGeCY9D7aM4SIDGgVJMi?= =?us-ascii?Q?Z8wxH0WStqT2TbaerXD91EsS7GdR2mIMx+oypHw6hlai5EhKZJ2gUO+Jgwom?= =?us-ascii?Q?WaNefNNRlYRhMqYrsifq5fjX/nUuAQDsBnXM2hJrkSLjhSQ3uCoXurdEQprC?= =?us-ascii?Q?8cLw1qZP0K7mK5jKWmYJA/i/8HgVmaB481tcIb/STMpTNOBXpLAFPpVteqMw?= =?us-ascii?Q?M7oWB+Fwdojx17K8QYuDGE+0x77bmSDaK7fOMPf+pIcjqMggDPnNOu2LAoo2?= =?us-ascii?Q?MHOrvdjBNJmdCxkYhkK4ZWSdouCcyqSFea5S5VjQIV3FUGRCphR56TU+wWbp?= =?us-ascii?Q?Zrw=3D=3D?= X-Microsoft-Antispam-Message-Info: fxacwHf1UALUxb8STdnzB5IAxXvR/ZriWAV50j7Gx51Tqc5HtJ5iHbXMjHkbqAL6aB+Uo/6bCaO1mYJhtfy6bWlcXAb2fbkRdT1tdEYPbj957YQHGcnYnnvK3jmtEtcvqfOyYEuLinU0hsIfrMmiAxL0InjcWbkm8+TtC6CkoICqi1Oh1HRLQeV1phAtQdHswpSuwsKDw1SJlbm0aryoIOz6dE07n5Z2qCsq4U8ZMvuhZUXCUzNYTxM+KcIhGjzs2tEKn9TiPY5s/Lh01+z3XVHr215ZlWhAO92rMI8zSrLnnJQDiEfNadVbX4ZpM2ncaHHK8eA7qba53kTqhR/KfEVRTO0BY5hQQeCuz8R05jY= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2334; 6:sgcVVDlTV+ZmHm8AxLPie70NuyIMVZ9Bg20OlfkcIbjEejZxyXiSa+lzhLWiB5FV9PxmbLFx+o8ch5gH4ADwTkT/9EGgqIbh1OQKzPBkqBuZCcHTN5li0xAIoP8B0ZU0Zj1vAGeyFzlK1NnA6esuofj3fl4gGQHwUDBrm3VVcYSBMciXk7JIhR2wNaDJ+dCKUoaF2LPs5RDo2pT81hP8E57Nbx6o0gZTd4U2278M8cNLRqXoFPFYfGiyepTl0WCAdlgrXYDwXOJRscn16YU+5DAktWmKPWun93O45ltXHpKN9ITPelAEOTD3ehP1KSYUUOUOWt91medr+dNUcwngMjSJsiNH2V3hYGjrHRAv+jjvgooR9uEQPaiXz+NKFsLIg8j2SGvyMU7Z0xXacBHYmD49mvW2I8UZPJv+VVomrCM82fFlHN/3aNqFp5diXRLHxa6WG6XfoEJAuLSUPTm6Aw==; 5:0kLsV4qyUQWz/alaU4PGjDazSO3rw4aMruMwaHgDoztQZb6kFLGKsajcT6qAsZSBVgtbR3+Y4IauHJ4Y7zWE+z/sAyO9btAKIj6Y5XVy/AvoWZbu2h93/KT3D1wtoXIMTHxtL9sgXeOdM3G0JEYYalw4vf6e+7gEeu8x+ZrndCw=; 24:aDW5xsxizqfW7c9er175Cjl7D/N8dz5Sf4hSgo9Wno2G0fImQkqb7Lf+cxyW9f+HCXmaYZ4tf0XguiOAPSKWXclqnrPutQ4pzhJ8LB4rDIc= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; VI1PR0501MB2334; 7:kZ8MTcASdJUStVB9MJ4Fo9Y3TYTen4IlzE6OTU5/l9J3rj4IgSTIn4bMTdZeAzGyuRIwC7N3zwKDX3b73z7z+ewI4U6UHIws2m3+U3iQt25R4tLTaDAlnxASK4pSq+3ChO95RX5W6nbY2RAuK8c5dCJhI+0UIMPOGtl0QfDe0+BpExaXi9qszledUZ9w/8kH0hQEYRvzPzmrm1JijiSILjBt1bvXf0dR7VSyQn4FOIBfWDYMc83HaBDs3GiI/zlZ X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Jul 2018 13:59:02.2051 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8c99e632-fd19-4251-5075-08d5e27f76f5 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0501MB2334 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 undergo a 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: 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 | 136 +++++++++++++++++++++ 3 files changed, 149 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index cb02fdf1c8b2..a430b6af890a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -4469,6 +4469,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; } @@ -4585,6 +4588,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); @@ -4663,6 +4669,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 4a519d8edec8..531b81eee19b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -407,6 +407,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 2d29c6ec84d0..5f3cec969cca 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,73 @@ 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) + goto out; + rif->ops->fdb_del(rif, macvlan_dev->dev_addr); + +out: + 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 +6522,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 +6788,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 +6875,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 +6963,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, @@ -6892,12 +6993,31 @@ 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 = netif_is_bridge_master(rif->dev) ? rif->dev : + vlan_dev_real_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) @@ -6949,6 +7069,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, @@ -6963,12 +7084,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 *