{"id":833727,"url":"http://patchwork.ozlabs.org/api/1.2/patches/833727/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/20171103090344.19444-13-jiri@resnulli.us/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/1.2/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20171103090344.19444-13-jiri@resnulli.us>","list_archive_url":null,"date":"2017-11-03T09:03:40","name":"[net-next,12/16] mlxsw: spectrum_router: Onload conflicting tunnels","commit_ref":null,"pull_url":null,"state":"accepted","archived":true,"hash":"487bfbf090bbab2c44c61a221d5e9818a14abdce","submitter":{"id":15321,"url":"http://patchwork.ozlabs.org/api/1.2/people/15321/?format=json","name":"Jiri Pirko","email":"jiri@resnulli.us"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/1.2/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/20171103090344.19444-13-jiri@resnulli.us/mbox/","series":[{"id":11677,"url":"http://patchwork.ozlabs.org/api/1.2/series/11677/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=11677","date":"2017-11-03T09:03:28","name":"mlxsw: Handle changes in GRE configuration","version":1,"mbox":"http://patchwork.ozlabs.org/series/11677/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/833727/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/833727/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=resnulli-us.20150623.gappssmtp.com\n\theader.i=@resnulli-us.20150623.gappssmtp.com\n\theader.b=\"tLk+EpiF\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3ySwxr5v2nz9sNV\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri,  3 Nov 2017 20:04:32 +1100 (AEDT)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1755635AbdKCJEa (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 3 Nov 2017 05:04:30 -0400","from mail-wm0-f68.google.com ([74.125.82.68]:52786 \"EHLO\n\tmail-wm0-f68.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S932583AbdKCJD4 (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 3 Nov 2017 05:03:56 -0400","by mail-wm0-f68.google.com with SMTP id t139so31723wmt.1\n\tfor <netdev@vger.kernel.org>; Fri, 03 Nov 2017 02:03:55 -0700 (PDT)","from localhost (ip-94-113-127-32.net.upcbroadband.cz.\n\t[94.113.127.32]) by smtp.gmail.com with ESMTPSA id\n\tv15sm2049028wmf.25.2017.11.03.02.03.54\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tFri, 03 Nov 2017 02:03:54 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=resnulli-us.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=Aj/u1tkxJvBO6L0jwdGwNlQZYookG8rb36yBkPynVsY=;\n\tb=tLk+EpiFv6LIS2e3hioftNZuoiNNyAwWbur58/G+EpubzqI1ACHZZFt5AXkCKlO1BT\n\tUloQWr3SP/qeTVgqNrk+JBD5h7zFYADZ5m7i/Zl7b3mk49HwoiUaKYFJfOLc6BWOXkXQ\n\tOcCDx7EDkinhVbTErtHZuhyanxypdkABPd3AobDHwFR1Ys0qg7szlRqYDE8RhFMOtBs6\n\t6l1Rrx0zQBciESFJqAhiEqOktn3udvmhK8xb/hYOYtwQv0+OP2WoaA3I+MUMlescesYK\n\tQiv9WsdCgtsWv0jooJYZH1g1AcQhWn1eEzwJKG9suLxndeb8eZJlzsaScy7Bf2YCmU8z\n\taIJg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=Aj/u1tkxJvBO6L0jwdGwNlQZYookG8rb36yBkPynVsY=;\n\tb=k0Wn2q5PGyQL/M9tFDGzaJ47MOvD+yL4aGts2jmjhl7IRsPqF03KwIZgkAspzCahJC\n\t2pIvE4WbwpMJGYuLdAyAUGvCGFXQ+nXswYbBuGYgEum8FFAuQG2KP+TC7YKYZTUIaklH\n\ttlK9qAB01jjzH21VtFTki/gkuRS7lH+XbfoeZX3gm0ZfCLlWVmGgKUOxf+xWCxt7jehZ\n\tq0axxl8RCKAF/+Xj5dzcetJ0YIgL08o/n1s0GRx9hBa8VzvRmAVQM8bwueC/eyXWdRQS\n\th8D6nrQcITa9o3kU6j3ItQmnKLyRO/57LgHqtqIlBcHppyl8Y9o7f6zn8/EXg94AOD1s\n\tfVfQ==","X-Gm-Message-State":"AJaThX62ec1XUAyt6l1DsLfuUM5hYKUniB4uMsbPtw087owrnSUxd1wO\n\tw8v6O/YiaQa5wbcOYlx+VOkYlirS","X-Google-Smtp-Source":"ABhQp+Si5o65uPTsChwWk5eB1X8e0USkdxrvsavPJN++wVo8KjqiUqiOcd8fitvrLhHdghDmo2Midw==","X-Received":"by 10.28.190.20 with SMTP id o20mr4106553wmf.150.1509699835006; \n\tFri, 03 Nov 2017 02:03:55 -0700 (PDT)","From":"Jiri Pirko <jiri@resnulli.us>","To":"netdev@vger.kernel.org","Cc":"davem@davemloft.net, petrm@mellanox.com, idosch@mellanox.com,\n\tmlxsw@mellanox.com","Subject":"[patch net-next 12/16] mlxsw: spectrum_router: Onload conflicting\n\ttunnels","Date":"Fri,  3 Nov 2017 10:03:40 +0100","Message-Id":"<20171103090344.19444-13-jiri@resnulli.us>","X-Mailer":"git-send-email 2.9.5","In-Reply-To":"<20171103090344.19444-1-jiri@resnulli.us>","References":"<20171103090344.19444-1-jiri@resnulli.us>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"From: Petr Machata <petrm@mellanox.com>\n\nThe approach for offloading IP tunnels implemented currently by mlxsw\ndoesn't allow two tunnels that have the same local IP address in the\nsame (underlay) VRF. Previously, offloads were introduced on demand as\nencap routes were formed. When such a route was created that would cause\noffload of a conflicting tunnel, mlxsw_sp_ipip_entry_create() would\ndetect it and return -EEXIST, which would propagate up and cause FIB\nabort.\n\nNow however IPIP entries are created as soon as an offloadable netdevice\nis created, and the failure prevents creation of such device.\nFurthermore, if the driver is installed at the point where such\nconflicting tunnels exist, the failure actually prevents successful\nmodprobe.\n\nFurthermore, follow-up patches implement handling of NETDEV_CHANGE due\nto the local address change. However, NETDEV_CHANGE can't be vetoed. The\nfailure merely means that the offloads weren't updated, but the change\nin Linux configuration is not rolled back. It is thus desirable to have\na robust way of handling these conflicts, which can later be reused for\nhandling NETDEV_CHANGE as well.\n\nTo fix this, when a conflicting tunnel is created, instead of failing,\nsimply pull the old tunnel to slow path and reject offloading the\nnew one.\n\nIntroduce two functions: mlxsw_sp_ipip_entry_demote_tunnel() and\nmlxsw_sp_ipip_demote_tunnel_by_saddr() to handle this. Make them both\npublic, because they will be useful later on in this patchset.\n\nSigned-off-by: Petr Machata <petrm@mellanox.com>\nReviewed-by: Ido Schimmel <idosch@mellanox.com>\nSigned-off-by: Jiri Pirko <jiri@mellanox.com>\n---\n .../net/ethernet/mellanox/mlxsw/spectrum_router.c  | 73 +++++++++++++++-------\n .../net/ethernet/mellanox/mlxsw/spectrum_router.h  |  8 +++\n 2 files changed, 60 insertions(+), 21 deletions(-)","diff":"diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\nindex 897a384..832bfa1 100644\n--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\n+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\n@@ -1159,24 +1159,7 @@ mlxsw_sp_ipip_entry_create(struct mlxsw_sp *mlxsw_sp,\n \t\t\t   enum mlxsw_sp_ipip_type ipipt,\n \t\t\t   struct net_device *ol_dev)\n {\n-\tu32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev);\n-\tstruct mlxsw_sp_router *router = mlxsw_sp->router;\n \tstruct mlxsw_sp_ipip_entry *ipip_entry;\n-\tenum mlxsw_sp_l3proto ul_proto;\n-\tunion mlxsw_sp_l3addr saddr;\n-\n-\t/* The configuration where several tunnels have the same local address\n-\t * in the same underlay table needs special treatment in the HW. That is\n-\t * currently not implemented in the driver.\n-\t */\n-\tul_proto = router->ipip_ops_arr[ipipt]->ul_proto;\n-\tsaddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev);\n-\tlist_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,\n-\t\t\t    ipip_list_node) {\n-\t\tif (mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, saddr,\n-\t\t\t\t\t\t      ul_tb_id, ipip_entry))\n-\t\t\treturn ERR_PTR(-EEXIST);\n-\t}\n \n \tipip_entry = mlxsw_sp_ipip_entry_alloc(mlxsw_sp, ipipt, ol_dev);\n \tif (IS_ERR(ipip_entry))\n@@ -1292,14 +1275,24 @@ static int mlxsw_sp_netdevice_ipip_ol_reg_event(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t\t\tstruct net_device *ol_dev)\n {\n \tstruct mlxsw_sp_ipip_entry *ipip_entry;\n+\tenum mlxsw_sp_l3proto ul_proto;\n \tenum mlxsw_sp_ipip_type ipipt;\n+\tunion mlxsw_sp_l3addr saddr;\n+\tu32 ul_tb_id;\n \n \tmlxsw_sp_netdev_ipip_type(mlxsw_sp, ol_dev, &ipipt);\n \tif (mlxsw_sp_netdevice_ipip_can_offload(mlxsw_sp, ol_dev, ipipt)) {\n-\t\tipip_entry = mlxsw_sp_ipip_entry_create(mlxsw_sp, ipipt,\n-\t\t\t\t\t\t\tol_dev);\n-\t\tif (IS_ERR(ipip_entry))\n-\t\t\treturn PTR_ERR(ipip_entry);\n+\t\tul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev);\n+\t\tul_proto = mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto;\n+\t\tsaddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev);\n+\t\tif (!mlxsw_sp_ipip_demote_tunnel_by_saddr(mlxsw_sp, ul_proto,\n+\t\t\t\t\t\t\t  saddr, ul_tb_id,\n+\t\t\t\t\t\t\t  NULL)) {\n+\t\t\tipip_entry = mlxsw_sp_ipip_entry_create(mlxsw_sp, ipipt,\n+\t\t\t\t\t\t\t\tol_dev);\n+\t\t\tif (IS_ERR(ipip_entry))\n+\t\t\t\treturn PTR_ERR(ipip_entry);\n+\t\t}\n \t}\n \n \treturn 0;\n@@ -1441,6 +1434,44 @@ static int mlxsw_sp_netdevice_ipip_ol_vrf_event(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t\t\t   true, false, false, extack);\n }\n \n+void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t       struct mlxsw_sp_ipip_entry *ipip_entry)\n+{\n+\tstruct net_device *ol_dev = ipip_entry->ol_dev;\n+\n+\tif (ol_dev->flags & IFF_UP)\n+\t\tmlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);\n+\tmlxsw_sp_ipip_entry_destroy(mlxsw_sp, ipip_entry);\n+}\n+\n+/* The configuration where several tunnels have the same local address in the\n+ * same underlay table needs special treatment in the HW. That is currently not\n+ * implemented in the driver. This function finds and demotes the first tunnel\n+ * with a given source address, except the one passed in in the argument\n+ * `except'.\n+ */\n+bool\n+mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t     enum mlxsw_sp_l3proto ul_proto,\n+\t\t\t\t     union mlxsw_sp_l3addr saddr,\n+\t\t\t\t     u32 ul_tb_id,\n+\t\t\t\t     const struct mlxsw_sp_ipip_entry *except)\n+{\n+\tstruct mlxsw_sp_ipip_entry *ipip_entry, *tmp;\n+\n+\tlist_for_each_entry_safe(ipip_entry, tmp, &mlxsw_sp->router->ipip_list,\n+\t\t\t\t ipip_list_node) {\n+\t\tif (ipip_entry != except &&\n+\t\t    mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, saddr,\n+\t\t\t\t\t\t      ul_tb_id, ipip_entry)) {\n+\t\t\tmlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);\n+\t\t\treturn true;\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t     struct net_device *ol_dev,\n \t\t\t\t     unsigned long event,\ndiff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h\nindex 4b8a12a..5dd650b 100644\n--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h\n+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h\n@@ -110,6 +110,14 @@ int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t\tbool keep_encap,\n \t\t\t\t\tbool update_nexthops,\n \t\t\t\t\tstruct netlink_ext_ack *extack);\n+void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t       struct mlxsw_sp_ipip_entry *ipip_entry);\n+bool\n+mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t     enum mlxsw_sp_l3proto ul_proto,\n+\t\t\t\t     union mlxsw_sp_l3addr saddr,\n+\t\t\t\t     u32 ul_tb_id,\n+\t\t\t\t     const struct mlxsw_sp_ipip_entry *except);\n struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,\n \t\t\t\t\t       struct mlxsw_sp_nexthop *nh);\n bool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh);\n","prefixes":["net-next","12/16"]}