Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/809083/?format=api
{ "id": 809083, "url": "http://patchwork.ozlabs.org/api/patches/809083/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170902152126.17286-15-jiri@resnulli.us/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "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": "<20170902152126.17286-15-jiri@resnulli.us>", "list_archive_url": null, "date": "2017-09-02T15:21:19", "name": "[net-next,14/21] mlxsw: spectrum_router: Support IPv4 overlay encap", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "9ee681465ea9926fe6248148c72c4ad441a564e6", "submitter": { "id": 15321, "url": "http://patchwork.ozlabs.org/api/people/15321/?format=api", "name": "Jiri Pirko", "email": "jiri@resnulli.us" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/20170902152126.17286-15-jiri@resnulli.us/mbox/", "series": [ { "id": 1159, "url": "http://patchwork.ozlabs.org/api/series/1159/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1159", "date": "2017-09-02T15:21:05", "name": "mlxsw: Offloading GRE tunnels", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/1159/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/809083/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/809083/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=\"Iv/JnehA\"; dkim-atps=neutral" ], "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xl0Fy1YPKz9sQl\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSun, 3 Sep 2017 01:21:58 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752778AbdIBPV4 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tSat, 2 Sep 2017 11:21:56 -0400", "from mail-wm0-f65.google.com ([74.125.82.65]:37551 \"EHLO\n\tmail-wm0-f65.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752753AbdIBPVw (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Sat, 2 Sep 2017 11:21:52 -0400", "by mail-wm0-f65.google.com with SMTP id x189so2639570wmg.4\n\tfor <netdev@vger.kernel.org>; Sat, 02 Sep 2017 08:21:51 -0700 (PDT)", "from localhost (jirka.pirko.cz. [84.16.102.26])\n\tby smtp.gmail.com with ESMTPSA id\n\tp87sm1305520wmf.22.2017.09.02.08.21.49\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tSat, 02 Sep 2017 08:21:49 -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=RAa9eYYvDkXvGzKJPVxP+mP9PzAvn2hA6LdQSSYAFDI=;\n\tb=Iv/JnehAZv8tahVtkjHJstThaLDO1nq+bPuh/GbhmzDKiH0Db5n9Hs33izgYGXKesO\n\toivty3z72b/S7cNxpL2aGJLCl8liZVHxtj1UkNXVy4dNWr/xTlj6/UX2NH1PS5DUmf1N\n\tfJFS1t0FlR4hWa+lRECJIxJZsdfH6OoBiH01SSINcbJAiY5VvI6dPKkGXbZGBqvBivP6\n\ttsNANGTdJpXCQ1zB5YP/Zo+pc8ZJYjwoCvcECgQreLK8ECcLxE1JE6A6DpjREyb7fjb6\n\tfLI2HHI1l4g0eoP67xoSe7rRRQWvPJeSfnfuL/O0NWTJyHlIQ77wQcBTcalb1Pxp9Zbm\n\tBngg==", "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=RAa9eYYvDkXvGzKJPVxP+mP9PzAvn2hA6LdQSSYAFDI=;\n\tb=bzeOuIiKJwD8FGxGPuZO7edbnvQOPN39F3lkRBfpgOFxTqlkOUKz4uz2DSP/nNLuoX\n\teoTi74xdio17JhGF2LfO7y9UwoH+kiwW76Q9pVTT+2Zum6FeazGICed4SitLN5K13QKj\n\tbviimwTtx0pKHMmNuojZviDUK4c1p0zKZ/r8dhrXULjHyZ82cOIpRConmHXjr8+XGWNW\n\tAuLrV/RgJIzI0HgHAS9D/yWGhffWOT0zn+6uDjc+Vg82RmSv71jaP4GsyF7cKrBOSm/5\n\tkHlULIz/MiR+rivzHB7EVlt5HqwKlthGUQiEPWpLVdZfzcEP2osSvIX+b60BDIZd1Ype\n\tjVWQ==", "X-Gm-Message-State": "AHPjjUjw6f+H+PJjfNBlCSh361U1WtCK1a7UawP/6yWIiT0GEM3/qA3Z\n\tgEvU1OZcZaa8evePD2I=", "X-Google-Smtp-Source": "ADKCNb6Tf5L1euqZAhCoVJkC9Dh19sPemhhZWoqqXAu0pLAjDsq2xrXup/EuyhAv4u+f8ILW9g8qww==", "X-Received": "by 10.28.213.198 with SMTP id m189mr1083737wmg.87.1504365710128; \n\tSat, 02 Sep 2017 08:21:50 -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 14/21] mlxsw: spectrum_router: Support IPv4 overlay\n\tencap", "Date": "Sat, 2 Sep 2017 17:21:19 +0200", "Message-Id": "<20170902152126.17286-15-jiri@resnulli.us>", "X-Mailer": "git-send-email 2.9.3", "In-Reply-To": "<20170902152126.17286-1-jiri@resnulli.us>", "References": "<20170902152126.17286-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\nThis introduces some common code for tracking of offloaded IP-in-IP\ntunnels, and support for offloading IPv4 overlay encapsulating routes in\nparticular. A follow-up patch will introduce IPv6 overlay as well.\n\nOffloaded tunnels are kept in a linked list of mlxsw_sp_ipip_entry\nobjects hooked up in mlxsw_sp_router. A network device that represents\nthe tunnel is used as a key to look up the corresponding IPIP entry.\nNote that in the future, more general keying mechanism will be needed,\nbecause parts of the tunnel information can be provided by the route.\n\nIPIP entries are reference counted, because several next hops may end up\nusing the same tunnel, and we only want to offload it once.\n\nEncapsulation path hooks into next hop handling. Routes that forward to\na tunnel are now considered gateway routes, thus giving them the same\ntreatment that other remote routes get. An IPIP next hop type is\nintroduced.\n\nDetails of individual tunnel types are kept in an array of\nmlxsw_sp_ipip_ops objects. If a tunnel type doesn't match any of the\nknown tunnel types, the next-hop is not considered an IPIP next hop.\n\nThe list of IPIP tunnel types is currently empty, follow-up patches will\nadd support for GRE. Traffic to IPIP tunnel types that are not\nexplicitly recognized by the driver traps and is handled in slow path.\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_ipip.h | 20 ++\n .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 238 ++++++++++++++++++++-\n 2 files changed, 257 insertions(+), 1 deletion(-)", "diff": "diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h\nindex 65eb493..7b40aa2 100644\n--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h\n+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h\n@@ -41,9 +41,29 @@ enum mlxsw_sp_ipip_type {\n \tMLXSW_SP_IPIP_TYPE_MAX,\n };\n \n+struct mlxsw_sp_ipip_entry {\n+\tenum mlxsw_sp_ipip_type ipipt;\n+\tstruct net_device *ol_dev; /* Overlay. */\n+\tstruct mlxsw_sp_rif_ipip_lb *ol_lb;\n+\tunsigned int ref_count; /* Number of next hops using the tunnel. */\n+\tstruct list_head ipip_list_node;\n+};\n+\n struct mlxsw_sp_ipip_ops {\n \tint dev_type;\n \tenum mlxsw_sp_l3proto ul_proto; /* Underlay. */\n+\n+\tint (*nexthop_update)(struct mlxsw_sp *mlxsw_sp, u32 adj_index,\n+\t\t\t struct mlxsw_sp_ipip_entry *ipip_entry);\n+\n+\tbool (*can_offload)(const struct mlxsw_sp *mlxsw_sp,\n+\t\t\t const struct net_device *ol_dev,\n+\t\t\t enum mlxsw_sp_l3proto ol_proto);\n+\n+\t/* Return a configuration for creating an overlay loopback RIF. */\n+\tstruct mlxsw_sp_rif_ipip_lb_config\n+\t(*ol_loopback_config)(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t const struct net_device *ol_dev);\n };\n \n extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];\ndiff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\nindex 53bdd0f..231b597 100644\n--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\n+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c\n@@ -89,6 +89,7 @@ struct mlxsw_sp_router {\n \tstruct delayed_work nexthop_probe_dw;\n #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */\n \tstruct list_head nexthop_neighs_list;\n+\tstruct list_head ipip_list;\n \tbool aborted;\n \tstruct notifier_block fib_nb;\n \tconst struct mlxsw_sp_rif_ops **rif_ops_arr;\n@@ -915,6 +916,170 @@ static u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)\n \t\treturn l3mdev_fib_table(ol_dev) ? : RT_TABLE_MAIN;\n }\n \n+static struct mlxsw_sp_rif *\n+mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,\n+\t\t const struct mlxsw_sp_rif_params *params);\n+\n+static struct mlxsw_sp_rif_ipip_lb *\n+mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\tenum mlxsw_sp_ipip_type ipipt,\n+\t\t\t\tstruct net_device *ol_dev)\n+{\n+\tstruct mlxsw_sp_rif_params_ipip_lb lb_params;\n+\tconst struct mlxsw_sp_ipip_ops *ipip_ops;\n+\tstruct mlxsw_sp_rif *rif;\n+\n+\tipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];\n+\tlb_params = (struct mlxsw_sp_rif_params_ipip_lb) {\n+\t\t.common.dev = ol_dev,\n+\t\t.common.lag = false,\n+\t\t.lb_config = ipip_ops->ol_loopback_config(mlxsw_sp, ol_dev),\n+\t};\n+\n+\trif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common);\n+\tif (IS_ERR(rif))\n+\t\treturn ERR_CAST(rif);\n+\treturn container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);\n+}\n+\n+static struct mlxsw_sp_ipip_entry *\n+mlxsw_sp_ipip_entry_alloc(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+\tstruct mlxsw_sp_ipip_entry *ipip_entry;\n+\tstruct mlxsw_sp_ipip_entry *ret = NULL;\n+\n+\tipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL);\n+\tif (!ipip_entry)\n+\t\treturn ERR_PTR(-ENOMEM);\n+\n+\tipip_entry->ol_lb = mlxsw_sp_ipip_ol_ipip_lb_create(mlxsw_sp, ipipt,\n+\t\t\t\t\t\t\t ol_dev);\n+\tif (IS_ERR(ipip_entry->ol_lb)) {\n+\t\tret = ERR_CAST(ipip_entry->ol_lb);\n+\t\tgoto err_ol_ipip_lb_create;\n+\t}\n+\n+\tipip_entry->ipipt = ipipt;\n+\tipip_entry->ol_dev = ol_dev;\n+\n+\treturn ipip_entry;\n+\n+err_ol_ipip_lb_create:\n+\tkfree(ipip_entry);\n+\treturn ret;\n+}\n+\n+static void\n+mlxsw_sp_ipip_entry_destroy(struct mlxsw_sp_ipip_entry *ipip_entry)\n+{\n+\tWARN_ON(ipip_entry->ref_count > 0);\n+\tmlxsw_sp_rif_destroy(&ipip_entry->ol_lb->common);\n+\tkfree(ipip_entry);\n+}\n+\n+static __be32\n+mlxsw_sp_ipip_netdev_saddr4(const struct net_device *ol_dev)\n+{\n+\tstruct ip_tunnel *tun = netdev_priv(ol_dev);\n+\n+\treturn tun->parms.iph.saddr;\n+}\n+\n+union mlxsw_sp_l3addr\n+mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto,\n+\t\t\t const struct net_device *ol_dev)\n+{\n+\tswitch (proto) {\n+\tcase MLXSW_SP_L3_PROTO_IPV4:\n+\t\treturn (union mlxsw_sp_l3addr) {\n+\t\t\t.addr4 = mlxsw_sp_ipip_netdev_saddr4(ol_dev),\n+\t\t};\n+\tcase MLXSW_SP_L3_PROTO_IPV6:\n+\t\tbreak;\n+\t};\n+\n+\tWARN_ON(1);\n+\treturn (union mlxsw_sp_l3addr) {\n+\t\t.addr4 = 0,\n+\t};\n+}\n+\n+static bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1,\n+\t\t\t const union mlxsw_sp_l3addr *addr2)\n+{\n+\treturn !memcmp(addr1, addr2, sizeof(*addr1));\n+}\n+\n+static bool\n+mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t const 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 struct mlxsw_sp_ipip_entry *ipip_entry)\n+{\n+\tu32 tun_ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);\n+\tenum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt;\n+\tunion mlxsw_sp_l3addr tun_saddr;\n+\n+\tif (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto)\n+\t\treturn false;\n+\n+\ttun_saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ipip_entry->ol_dev);\n+\treturn tun_ul_tb_id == ul_tb_id &&\n+\t mlxsw_sp_l3addr_eq(&tun_saddr, &saddr);\n+}\n+\n+static struct mlxsw_sp_ipip_entry *\n+mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,\n+\t\t\tenum mlxsw_sp_ipip_type ipipt,\n+\t\t\tstruct 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+\tlist_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,\n+\t\t\t ipip_list_node) {\n+\t\tif (ipip_entry->ol_dev == ol_dev)\n+\t\t\tgoto inc_ref_count;\n+\n+\t\t/* The configuration where several tunnels have the same local\n+\t\t * address in the same underlay table needs special treatment in\n+\t\t * the HW. That is currently not implemented in the driver.\n+\t\t */\n+\t\tul_proto = router->ipip_ops_arr[ipip_entry->ipipt]->ul_proto;\n+\t\tsaddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev);\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+\t\treturn ipip_entry;\n+\n+\tlist_add_tail(&ipip_entry->ipip_list_node,\n+\t\t &mlxsw_sp->router->ipip_list);\n+\n+inc_ref_count:\n+\t++ipip_entry->ref_count;\n+\treturn ipip_entry;\n+}\n+\n+static void\n+mlxsw_sp_ipip_entry_put(struct mlxsw_sp *mlxsw_sp,\n+\t\t\tstruct mlxsw_sp_ipip_entry *ipip_entry)\n+{\n+\tif (--ipip_entry->ref_count == 0) {\n+\t\tlist_del(&ipip_entry->ipip_list_node);\n+\t\tmlxsw_sp_ipip_entry_destroy(ipip_entry);\n+\t}\n+}\n+\n struct mlxsw_sp_neigh_key {\n \tstruct neighbour *n;\n };\n@@ -1654,6 +1819,7 @@ static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,\n \n enum mlxsw_sp_nexthop_type {\n \tMLXSW_SP_NEXTHOP_TYPE_ETH,\n+\tMLXSW_SP_NEXTHOP_TYPE_IPIP,\n };\n \n struct mlxsw_sp_nexthop_key {\n@@ -1683,6 +1849,7 @@ struct mlxsw_sp_nexthop {\n \tenum mlxsw_sp_nexthop_type type;\n \tunion {\n \t\tstruct mlxsw_sp_neigh_entry *neigh_entry;\n+\t\tstruct mlxsw_sp_ipip_entry *ipip_entry;\n \t};\n };\n \n@@ -1970,6 +2137,16 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,\n \treturn mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);\n }\n \n+static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t\tu32 adj_index,\n+\t\t\t\t\tstruct mlxsw_sp_nexthop *nh)\n+{\n+\tconst struct mlxsw_sp_ipip_ops *ipip_ops;\n+\n+\tipip_ops = mlxsw_sp->router->ipip_ops_arr[nh->ipip_entry->ipipt];\n+\treturn ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry);\n+}\n+\n static int\n mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,\n \t\t\t struct mlxsw_sp_nexthop_group *nh_grp,\n@@ -1994,6 +2171,10 @@ mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\terr = mlxsw_sp_nexthop_mac_update\n \t\t\t\t\t (mlxsw_sp, adj_index, nh);\n \t\t\t\tbreak;\n+\t\t\tcase MLXSW_SP_NEXTHOP_TYPE_IPIP:\n+\t\t\t\terr = mlxsw_sp_nexthop_ipip_update\n+\t\t\t\t\t (mlxsw_sp, adj_index, nh);\n+\t\t\t\tbreak;\n \t\t\t}\n \t\t\tif (err)\n \t\t\t\treturn err;\n@@ -2297,6 +2478,46 @@ static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,\n \treturn false;\n }\n \n+static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t enum mlxsw_sp_ipip_type ipipt,\n+\t\t\t\t struct mlxsw_sp_nexthop *nh,\n+\t\t\t\t struct net_device *ol_dev)\n+{\n+\tif (!nh->nh_grp->gateway || nh->ipip_entry)\n+\t\treturn 0;\n+\n+\tnh->ipip_entry = mlxsw_sp_ipip_entry_get(mlxsw_sp, ipipt, ol_dev);\n+\tif (IS_ERR(nh->ipip_entry))\n+\t\treturn PTR_ERR(nh->ipip_entry);\n+\n+\t__mlxsw_sp_nexthop_neigh_update(nh, false);\n+\treturn 0;\n+}\n+\n+static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t struct mlxsw_sp_nexthop *nh)\n+{\n+\tstruct mlxsw_sp_ipip_entry *ipip_entry = nh->ipip_entry;\n+\n+\tif (!ipip_entry)\n+\t\treturn;\n+\n+\t__mlxsw_sp_nexthop_neigh_update(nh, true);\n+\tmlxsw_sp_ipip_entry_put(mlxsw_sp, ipip_entry);\n+\tnh->ipip_entry = NULL;\n+}\n+\n+static bool mlxsw_sp_nexthop4_ipip_type(const struct mlxsw_sp *mlxsw_sp,\n+\t\t\t\t\tconst struct fib_nh *fib_nh,\n+\t\t\t\t\tenum mlxsw_sp_ipip_type *p_ipipt)\n+{\n+\tstruct net_device *dev = fib_nh->nh_dev;\n+\n+\treturn dev &&\n+\t fib_nh->nh_parent->fib_type == RTN_UNICAST &&\n+\t mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, p_ipipt);\n+}\n+\n static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t struct mlxsw_sp_nexthop *nh)\n {\n@@ -2305,6 +2526,9 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,\n \t\tmlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);\n \t\tmlxsw_sp_nexthop_rif_fini(nh);\n \t\tbreak;\n+\tcase MLXSW_SP_NEXTHOP_TYPE_IPIP:\n+\t\tmlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);\n+\t\tbreak;\n \t}\n }\n \n@@ -2312,10 +2536,19 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t struct mlxsw_sp_nexthop *nh,\n \t\t\t\t struct fib_nh *fib_nh)\n {\n+\tstruct mlxsw_sp_router *router = mlxsw_sp->router;\n \tstruct net_device *dev = fib_nh->nh_dev;\n+\tenum mlxsw_sp_ipip_type ipipt;\n \tstruct mlxsw_sp_rif *rif;\n \tint err;\n \n+\tif (mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fib_nh, &ipipt) &&\n+\t router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,\n+\t\t\t\t\t\t MLXSW_SP_L3_PROTO_IPV4)) {\n+\t\tnh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;\n+\t\treturn mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);\n+\t}\n+\n \tnh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;\n \trif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);\n \tif (!rif)\n@@ -2421,7 +2654,8 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,\n static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,\n \t\t\t\t const struct fib_info *fi)\n {\n-\treturn fi->fib_nh->nh_scope == RT_SCOPE_LINK;\n+\treturn fi->fib_nh->nh_scope == RT_SCOPE_LINK ||\n+\t mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fi->fib_nh, NULL);\n }\n \n static struct mlxsw_sp_nexthop_group *\n@@ -5411,11 +5645,13 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)\n static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)\n {\n \tmlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr;\n+\tINIT_LIST_HEAD(&mlxsw_sp->router->ipip_list);\n \treturn 0;\n }\n \n static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)\n {\n+\tWARN_ON(!list_empty(&mlxsw_sp->router->ipip_list));\n }\n \n static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)\n", "prefixes": [ "net-next", "14/21" ] }