linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
   3
   4#include <linux/kernel.h>
   5#include <linux/types.h>
   6#include <linux/rhashtable.h>
   7#include <linux/bitops.h>
   8#include <linux/in6.h>
   9#include <linux/notifier.h>
  10#include <linux/inetdevice.h>
  11#include <linux/netdevice.h>
  12#include <linux/if_bridge.h>
  13#include <linux/socket.h>
  14#include <linux/route.h>
  15#include <linux/gcd.h>
  16#include <linux/if_macvlan.h>
  17#include <linux/refcount.h>
  18#include <linux/jhash.h>
  19#include <linux/net_namespace.h>
  20#include <linux/mutex.h>
  21#include <net/netevent.h>
  22#include <net/neighbour.h>
  23#include <net/arp.h>
  24#include <net/ip_fib.h>
  25#include <net/ip6_fib.h>
  26#include <net/nexthop.h>
  27#include <net/fib_rules.h>
  28#include <net/ip_tunnels.h>
  29#include <net/l3mdev.h>
  30#include <net/addrconf.h>
  31#include <net/ndisc.h>
  32#include <net/ipv6.h>
  33#include <net/fib_notifier.h>
  34#include <net/switchdev.h>
  35
  36#include "spectrum.h"
  37#include "core.h"
  38#include "reg.h"
  39#include "spectrum_cnt.h"
  40#include "spectrum_dpipe.h"
  41#include "spectrum_ipip.h"
  42#include "spectrum_mr.h"
  43#include "spectrum_mr_tcam.h"
  44#include "spectrum_router.h"
  45#include "spectrum_span.h"
  46
  47struct mlxsw_sp_fib;
  48struct mlxsw_sp_vr;
  49struct mlxsw_sp_lpm_tree;
  50struct mlxsw_sp_rif_ops;
  51
  52struct mlxsw_sp_rif {
  53        struct list_head nexthop_list;
  54        struct list_head neigh_list;
  55        struct net_device *dev; /* NULL for underlay RIF */
  56        struct mlxsw_sp_fid *fid;
  57        unsigned char addr[ETH_ALEN];
  58        int mtu;
  59        u16 rif_index;
  60        u16 vr_id;
  61        const struct mlxsw_sp_rif_ops *ops;
  62        struct mlxsw_sp *mlxsw_sp;
  63
  64        unsigned int counter_ingress;
  65        bool counter_ingress_valid;
  66        unsigned int counter_egress;
  67        bool counter_egress_valid;
  68};
  69
  70struct mlxsw_sp_rif_params {
  71        struct net_device *dev;
  72        union {
  73                u16 system_port;
  74                u16 lag_id;
  75        };
  76        u16 vid;
  77        bool lag;
  78};
  79
  80struct mlxsw_sp_rif_subport {
  81        struct mlxsw_sp_rif common;
  82        refcount_t ref_count;
  83        union {
  84                u16 system_port;
  85                u16 lag_id;
  86        };
  87        u16 vid;
  88        bool lag;
  89};
  90
  91struct mlxsw_sp_rif_ipip_lb {
  92        struct mlxsw_sp_rif common;
  93        struct mlxsw_sp_rif_ipip_lb_config lb_config;
  94        u16 ul_vr_id; /* Reserved for Spectrum-2. */
  95        u16 ul_rif_id; /* Reserved for Spectrum. */
  96};
  97
  98struct mlxsw_sp_rif_params_ipip_lb {
  99        struct mlxsw_sp_rif_params common;
 100        struct mlxsw_sp_rif_ipip_lb_config lb_config;
 101};
 102
 103struct mlxsw_sp_rif_ops {
 104        enum mlxsw_sp_rif_type type;
 105        size_t rif_size;
 106
 107        void (*setup)(struct mlxsw_sp_rif *rif,
 108                      const struct mlxsw_sp_rif_params *params);
 109        int (*configure)(struct mlxsw_sp_rif *rif);
 110        void (*deconfigure)(struct mlxsw_sp_rif *rif);
 111        struct mlxsw_sp_fid * (*fid_get)(struct mlxsw_sp_rif *rif,
 112                                         struct netlink_ext_ack *extack);
 113        void (*fdb_del)(struct mlxsw_sp_rif *rif, const char *mac);
 114};
 115
 116static struct mlxsw_sp_rif *
 117mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
 118                         const struct net_device *dev);
 119static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif);
 120static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree);
 121static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
 122                                  struct mlxsw_sp_lpm_tree *lpm_tree);
 123static int mlxsw_sp_vr_lpm_tree_bind(struct mlxsw_sp *mlxsw_sp,
 124                                     const struct mlxsw_sp_fib *fib,
 125                                     u8 tree_id);
 126static int mlxsw_sp_vr_lpm_tree_unbind(struct mlxsw_sp *mlxsw_sp,
 127                                       const struct mlxsw_sp_fib *fib);
 128
 129static unsigned int *
 130mlxsw_sp_rif_p_counter_get(struct mlxsw_sp_rif *rif,
 131                           enum mlxsw_sp_rif_counter_dir dir)
 132{
 133        switch (dir) {
 134        case MLXSW_SP_RIF_COUNTER_EGRESS:
 135                return &rif->counter_egress;
 136        case MLXSW_SP_RIF_COUNTER_INGRESS:
 137                return &rif->counter_ingress;
 138        }
 139        return NULL;
 140}
 141
 142static bool
 143mlxsw_sp_rif_counter_valid_get(struct mlxsw_sp_rif *rif,
 144                               enum mlxsw_sp_rif_counter_dir dir)
 145{
 146        switch (dir) {
 147        case MLXSW_SP_RIF_COUNTER_EGRESS:
 148                return rif->counter_egress_valid;
 149        case MLXSW_SP_RIF_COUNTER_INGRESS:
 150                return rif->counter_ingress_valid;
 151        }
 152        return false;
 153}
 154
 155static void
 156mlxsw_sp_rif_counter_valid_set(struct mlxsw_sp_rif *rif,
 157                               enum mlxsw_sp_rif_counter_dir dir,
 158                               bool valid)
 159{
 160        switch (dir) {
 161        case MLXSW_SP_RIF_COUNTER_EGRESS:
 162                rif->counter_egress_valid = valid;
 163                break;
 164        case MLXSW_SP_RIF_COUNTER_INGRESS:
 165                rif->counter_ingress_valid = valid;
 166                break;
 167        }
 168}
 169
 170static int mlxsw_sp_rif_counter_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
 171                                     unsigned int counter_index, bool enable,
 172                                     enum mlxsw_sp_rif_counter_dir dir)
 173{
 174        char ritr_pl[MLXSW_REG_RITR_LEN];
 175        bool is_egress = false;
 176        int err;
 177
 178        if (dir == MLXSW_SP_RIF_COUNTER_EGRESS)
 179                is_egress = true;
 180        mlxsw_reg_ritr_rif_pack(ritr_pl, rif_index);
 181        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
 182        if (err)
 183                return err;
 184
 185        mlxsw_reg_ritr_counter_pack(ritr_pl, counter_index, enable,
 186                                    is_egress);
 187        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
 188}
 189
 190int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
 191                                   struct mlxsw_sp_rif *rif,
 192                                   enum mlxsw_sp_rif_counter_dir dir, u64 *cnt)
 193{
 194        char ricnt_pl[MLXSW_REG_RICNT_LEN];
 195        unsigned int *p_counter_index;
 196        bool valid;
 197        int err;
 198
 199        valid = mlxsw_sp_rif_counter_valid_get(rif, dir);
 200        if (!valid)
 201                return -EINVAL;
 202
 203        p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir);
 204        if (!p_counter_index)
 205                return -EINVAL;
 206        mlxsw_reg_ricnt_pack(ricnt_pl, *p_counter_index,
 207                             MLXSW_REG_RICNT_OPCODE_NOP);
 208        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl);
 209        if (err)
 210                return err;
 211        *cnt = mlxsw_reg_ricnt_good_unicast_packets_get(ricnt_pl);
 212        return 0;
 213}
 214
 215static int mlxsw_sp_rif_counter_clear(struct mlxsw_sp *mlxsw_sp,
 216                                      unsigned int counter_index)
 217{
 218        char ricnt_pl[MLXSW_REG_RICNT_LEN];
 219
 220        mlxsw_reg_ricnt_pack(ricnt_pl, counter_index,
 221                             MLXSW_REG_RICNT_OPCODE_CLEAR);
 222        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl);
 223}
 224
 225int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
 226                               struct mlxsw_sp_rif *rif,
 227                               enum mlxsw_sp_rif_counter_dir dir)
 228{
 229        unsigned int *p_counter_index;
 230        int err;
 231
 232        p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir);
 233        if (!p_counter_index)
 234                return -EINVAL;
 235        err = mlxsw_sp_counter_alloc(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF,
 236                                     p_counter_index);
 237        if (err)
 238                return err;
 239
 240        err = mlxsw_sp_rif_counter_clear(mlxsw_sp, *p_counter_index);
 241        if (err)
 242                goto err_counter_clear;
 243
 244        err = mlxsw_sp_rif_counter_edit(mlxsw_sp, rif->rif_index,
 245                                        *p_counter_index, true, dir);
 246        if (err)
 247                goto err_counter_edit;
 248        mlxsw_sp_rif_counter_valid_set(rif, dir, true);
 249        return 0;
 250
 251err_counter_edit:
 252err_counter_clear:
 253        mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF,
 254                              *p_counter_index);
 255        return err;
 256}
 257
 258void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
 259                               struct mlxsw_sp_rif *rif,
 260                               enum mlxsw_sp_rif_counter_dir dir)
 261{
 262        unsigned int *p_counter_index;
 263
 264        if (!mlxsw_sp_rif_counter_valid_get(rif, dir))
 265                return;
 266
 267        p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir);
 268        if (WARN_ON(!p_counter_index))
 269                return;
 270        mlxsw_sp_rif_counter_edit(mlxsw_sp, rif->rif_index,
 271                                  *p_counter_index, false, dir);
 272        mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF,
 273                              *p_counter_index);
 274        mlxsw_sp_rif_counter_valid_set(rif, dir, false);
 275}
 276
 277static void mlxsw_sp_rif_counters_alloc(struct mlxsw_sp_rif *rif)
 278{
 279        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
 280        struct devlink *devlink;
 281
 282        devlink = priv_to_devlink(mlxsw_sp->core);
 283        if (!devlink_dpipe_table_counter_enabled(devlink,
 284                                                 MLXSW_SP_DPIPE_TABLE_NAME_ERIF))
 285                return;
 286        mlxsw_sp_rif_counter_alloc(mlxsw_sp, rif, MLXSW_SP_RIF_COUNTER_EGRESS);
 287}
 288
 289static void mlxsw_sp_rif_counters_free(struct mlxsw_sp_rif *rif)
 290{
 291        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
 292
 293        mlxsw_sp_rif_counter_free(mlxsw_sp, rif, MLXSW_SP_RIF_COUNTER_EGRESS);
 294}
 295
 296#define MLXSW_SP_PREFIX_COUNT (sizeof(struct in6_addr) * BITS_PER_BYTE + 1)
 297
 298struct mlxsw_sp_prefix_usage {
 299        DECLARE_BITMAP(b, MLXSW_SP_PREFIX_COUNT);
 300};
 301
 302#define mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) \
 303        for_each_set_bit(prefix, (prefix_usage)->b, MLXSW_SP_PREFIX_COUNT)
 304
 305static bool
 306mlxsw_sp_prefix_usage_eq(struct mlxsw_sp_prefix_usage *prefix_usage1,
 307                         struct mlxsw_sp_prefix_usage *prefix_usage2)
 308{
 309        return !memcmp(prefix_usage1, prefix_usage2, sizeof(*prefix_usage1));
 310}
 311
 312static void
 313mlxsw_sp_prefix_usage_cpy(struct mlxsw_sp_prefix_usage *prefix_usage1,
 314                          struct mlxsw_sp_prefix_usage *prefix_usage2)
 315{
 316        memcpy(prefix_usage1, prefix_usage2, sizeof(*prefix_usage1));
 317}
 318
 319static void
 320mlxsw_sp_prefix_usage_set(struct mlxsw_sp_prefix_usage *prefix_usage,
 321                          unsigned char prefix_len)
 322{
 323        set_bit(prefix_len, prefix_usage->b);
 324}
 325
 326static void
 327mlxsw_sp_prefix_usage_clear(struct mlxsw_sp_prefix_usage *prefix_usage,
 328                            unsigned char prefix_len)
 329{
 330        clear_bit(prefix_len, prefix_usage->b);
 331}
 332
 333struct mlxsw_sp_fib_key {
 334        unsigned char addr[sizeof(struct in6_addr)];
 335        unsigned char prefix_len;
 336};
 337
 338enum mlxsw_sp_fib_entry_type {
 339        MLXSW_SP_FIB_ENTRY_TYPE_REMOTE,
 340        MLXSW_SP_FIB_ENTRY_TYPE_LOCAL,
 341        MLXSW_SP_FIB_ENTRY_TYPE_TRAP,
 342        MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE,
 343        MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE,
 344
 345        /* This is a special case of local delivery, where a packet should be
 346         * decapsulated on reception. Note that there is no corresponding ENCAP,
 347         * because that's a type of next hop, not of FIB entry. (There can be
 348         * several next hops in a REMOTE entry, and some of them may be
 349         * encapsulating entries.)
 350         */
 351        MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP,
 352        MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP,
 353};
 354
 355struct mlxsw_sp_nexthop_group;
 356struct mlxsw_sp_fib_entry;
 357
 358struct mlxsw_sp_fib_node {
 359        struct mlxsw_sp_fib_entry *fib_entry;
 360        struct list_head list;
 361        struct rhash_head ht_node;
 362        struct mlxsw_sp_fib *fib;
 363        struct mlxsw_sp_fib_key key;
 364};
 365
 366struct mlxsw_sp_fib_entry_decap {
 367        struct mlxsw_sp_ipip_entry *ipip_entry;
 368        u32 tunnel_index;
 369};
 370
 371struct mlxsw_sp_fib_entry {
 372        struct mlxsw_sp_fib_node *fib_node;
 373        enum mlxsw_sp_fib_entry_type type;
 374        struct list_head nexthop_group_node;
 375        struct mlxsw_sp_nexthop_group *nh_group;
 376        struct mlxsw_sp_fib_entry_decap decap; /* Valid for decap entries. */
 377};
 378
 379struct mlxsw_sp_fib4_entry {
 380        struct mlxsw_sp_fib_entry common;
 381        u32 tb_id;
 382        u32 prio;
 383        u8 tos;
 384        u8 type;
 385};
 386
 387struct mlxsw_sp_fib6_entry {
 388        struct mlxsw_sp_fib_entry common;
 389        struct list_head rt6_list;
 390        unsigned int nrt6;
 391};
 392
 393struct mlxsw_sp_rt6 {
 394        struct list_head list;
 395        struct fib6_info *rt;
 396};
 397
 398struct mlxsw_sp_lpm_tree {
 399        u8 id; /* tree ID */
 400        unsigned int ref_count;
 401        enum mlxsw_sp_l3proto proto;
 402        unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT];
 403        struct mlxsw_sp_prefix_usage prefix_usage;
 404};
 405
 406struct mlxsw_sp_fib {
 407        struct rhashtable ht;
 408        struct list_head node_list;
 409        struct mlxsw_sp_vr *vr;
 410        struct mlxsw_sp_lpm_tree *lpm_tree;
 411        enum mlxsw_sp_l3proto proto;
 412};
 413
 414struct mlxsw_sp_vr {
 415        u16 id; /* virtual router ID */
 416        u32 tb_id; /* kernel fib table id */
 417        unsigned int rif_count;
 418        struct mlxsw_sp_fib *fib4;
 419        struct mlxsw_sp_fib *fib6;
 420        struct mlxsw_sp_mr_table *mr_table[MLXSW_SP_L3_PROTO_MAX];
 421        struct mlxsw_sp_rif *ul_rif;
 422        refcount_t ul_rif_refcnt;
 423};
 424
 425static const struct rhashtable_params mlxsw_sp_fib_ht_params;
 426
 427static struct mlxsw_sp_fib *mlxsw_sp_fib_create(struct mlxsw_sp *mlxsw_sp,
 428                                                struct mlxsw_sp_vr *vr,
 429                                                enum mlxsw_sp_l3proto proto)
 430{
 431        struct mlxsw_sp_lpm_tree *lpm_tree;
 432        struct mlxsw_sp_fib *fib;
 433        int err;
 434
 435        lpm_tree = mlxsw_sp->router->lpm.proto_trees[proto];
 436        fib = kzalloc(sizeof(*fib), GFP_KERNEL);
 437        if (!fib)
 438                return ERR_PTR(-ENOMEM);
 439        err = rhashtable_init(&fib->ht, &mlxsw_sp_fib_ht_params);
 440        if (err)
 441                goto err_rhashtable_init;
 442        INIT_LIST_HEAD(&fib->node_list);
 443        fib->proto = proto;
 444        fib->vr = vr;
 445        fib->lpm_tree = lpm_tree;
 446        mlxsw_sp_lpm_tree_hold(lpm_tree);
 447        err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, lpm_tree->id);
 448        if (err)
 449                goto err_lpm_tree_bind;
 450        return fib;
 451
 452err_lpm_tree_bind:
 453        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
 454err_rhashtable_init:
 455        kfree(fib);
 456        return ERR_PTR(err);
 457}
 458
 459static void mlxsw_sp_fib_destroy(struct mlxsw_sp *mlxsw_sp,
 460                                 struct mlxsw_sp_fib *fib)
 461{
 462        mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, fib);
 463        mlxsw_sp_lpm_tree_put(mlxsw_sp, fib->lpm_tree);
 464        WARN_ON(!list_empty(&fib->node_list));
 465        rhashtable_destroy(&fib->ht);
 466        kfree(fib);
 467}
 468
 469static struct mlxsw_sp_lpm_tree *
 470mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp)
 471{
 472        static struct mlxsw_sp_lpm_tree *lpm_tree;
 473        int i;
 474
 475        for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
 476                lpm_tree = &mlxsw_sp->router->lpm.trees[i];
 477                if (lpm_tree->ref_count == 0)
 478                        return lpm_tree;
 479        }
 480        return NULL;
 481}
 482
 483static int mlxsw_sp_lpm_tree_alloc(struct mlxsw_sp *mlxsw_sp,
 484                                   struct mlxsw_sp_lpm_tree *lpm_tree)
 485{
 486        char ralta_pl[MLXSW_REG_RALTA_LEN];
 487
 488        mlxsw_reg_ralta_pack(ralta_pl, true,
 489                             (enum mlxsw_reg_ralxx_protocol) lpm_tree->proto,
 490                             lpm_tree->id);
 491        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl);
 492}
 493
 494static void mlxsw_sp_lpm_tree_free(struct mlxsw_sp *mlxsw_sp,
 495                                   struct mlxsw_sp_lpm_tree *lpm_tree)
 496{
 497        char ralta_pl[MLXSW_REG_RALTA_LEN];
 498
 499        mlxsw_reg_ralta_pack(ralta_pl, false,
 500                             (enum mlxsw_reg_ralxx_protocol) lpm_tree->proto,
 501                             lpm_tree->id);
 502        mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl);
 503}
 504
 505static int
 506mlxsw_sp_lpm_tree_left_struct_set(struct mlxsw_sp *mlxsw_sp,
 507                                  struct mlxsw_sp_prefix_usage *prefix_usage,
 508                                  struct mlxsw_sp_lpm_tree *lpm_tree)
 509{
 510        char ralst_pl[MLXSW_REG_RALST_LEN];
 511        u8 root_bin = 0;
 512        u8 prefix;
 513        u8 last_prefix = MLXSW_REG_RALST_BIN_NO_CHILD;
 514
 515        mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage)
 516                root_bin = prefix;
 517
 518        mlxsw_reg_ralst_pack(ralst_pl, root_bin, lpm_tree->id);
 519        mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) {
 520                if (prefix == 0)
 521                        continue;
 522                mlxsw_reg_ralst_bin_pack(ralst_pl, prefix, last_prefix,
 523                                         MLXSW_REG_RALST_BIN_NO_CHILD);
 524                last_prefix = prefix;
 525        }
 526        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralst), ralst_pl);
 527}
 528
 529static struct mlxsw_sp_lpm_tree *
 530mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp,
 531                         struct mlxsw_sp_prefix_usage *prefix_usage,
 532                         enum mlxsw_sp_l3proto proto)
 533{
 534        struct mlxsw_sp_lpm_tree *lpm_tree;
 535        int err;
 536
 537        lpm_tree = mlxsw_sp_lpm_tree_find_unused(mlxsw_sp);
 538        if (!lpm_tree)
 539                return ERR_PTR(-EBUSY);
 540        lpm_tree->proto = proto;
 541        err = mlxsw_sp_lpm_tree_alloc(mlxsw_sp, lpm_tree);
 542        if (err)
 543                return ERR_PTR(err);
 544
 545        err = mlxsw_sp_lpm_tree_left_struct_set(mlxsw_sp, prefix_usage,
 546                                                lpm_tree);
 547        if (err)
 548                goto err_left_struct_set;
 549        memcpy(&lpm_tree->prefix_usage, prefix_usage,
 550               sizeof(lpm_tree->prefix_usage));
 551        memset(&lpm_tree->prefix_ref_count, 0,
 552               sizeof(lpm_tree->prefix_ref_count));
 553        lpm_tree->ref_count = 1;
 554        return lpm_tree;
 555
 556err_left_struct_set:
 557        mlxsw_sp_lpm_tree_free(mlxsw_sp, lpm_tree);
 558        return ERR_PTR(err);
 559}
 560
 561static void mlxsw_sp_lpm_tree_destroy(struct mlxsw_sp *mlxsw_sp,
 562                                      struct mlxsw_sp_lpm_tree *lpm_tree)
 563{
 564        mlxsw_sp_lpm_tree_free(mlxsw_sp, lpm_tree);
 565}
 566
 567static struct mlxsw_sp_lpm_tree *
 568mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp,
 569                      struct mlxsw_sp_prefix_usage *prefix_usage,
 570                      enum mlxsw_sp_l3proto proto)
 571{
 572        struct mlxsw_sp_lpm_tree *lpm_tree;
 573        int i;
 574
 575        for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
 576                lpm_tree = &mlxsw_sp->router->lpm.trees[i];
 577                if (lpm_tree->ref_count != 0 &&
 578                    lpm_tree->proto == proto &&
 579                    mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage,
 580                                             prefix_usage)) {
 581                        mlxsw_sp_lpm_tree_hold(lpm_tree);
 582                        return lpm_tree;
 583                }
 584        }
 585        return mlxsw_sp_lpm_tree_create(mlxsw_sp, prefix_usage, proto);
 586}
 587
 588static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree)
 589{
 590        lpm_tree->ref_count++;
 591}
 592
 593static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
 594                                  struct mlxsw_sp_lpm_tree *lpm_tree)
 595{
 596        if (--lpm_tree->ref_count == 0)
 597                mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
 598}
 599
 600#define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */
 601
 602static int mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp)
 603{
 604        struct mlxsw_sp_prefix_usage req_prefix_usage = {{ 0 } };
 605        struct mlxsw_sp_lpm_tree *lpm_tree;
 606        u64 max_trees;
 607        int err, i;
 608
 609        if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LPM_TREES))
 610                return -EIO;
 611
 612        max_trees = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LPM_TREES);
 613        mlxsw_sp->router->lpm.tree_count = max_trees - MLXSW_SP_LPM_TREE_MIN;
 614        mlxsw_sp->router->lpm.trees = kcalloc(mlxsw_sp->router->lpm.tree_count,
 615                                             sizeof(struct mlxsw_sp_lpm_tree),
 616                                             GFP_KERNEL);
 617        if (!mlxsw_sp->router->lpm.trees)
 618                return -ENOMEM;
 619
 620        for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
 621                lpm_tree = &mlxsw_sp->router->lpm.trees[i];
 622                lpm_tree->id = i + MLXSW_SP_LPM_TREE_MIN;
 623        }
 624
 625        lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage,
 626                                         MLXSW_SP_L3_PROTO_IPV4);
 627        if (IS_ERR(lpm_tree)) {
 628                err = PTR_ERR(lpm_tree);
 629                goto err_ipv4_tree_get;
 630        }
 631        mlxsw_sp->router->lpm.proto_trees[MLXSW_SP_L3_PROTO_IPV4] = lpm_tree;
 632
 633        lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage,
 634                                         MLXSW_SP_L3_PROTO_IPV6);
 635        if (IS_ERR(lpm_tree)) {
 636                err = PTR_ERR(lpm_tree);
 637                goto err_ipv6_tree_get;
 638        }
 639        mlxsw_sp->router->lpm.proto_trees[MLXSW_SP_L3_PROTO_IPV6] = lpm_tree;
 640
 641        return 0;
 642
 643err_ipv6_tree_get:
 644        lpm_tree = mlxsw_sp->router->lpm.proto_trees[MLXSW_SP_L3_PROTO_IPV4];
 645        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
 646err_ipv4_tree_get:
 647        kfree(mlxsw_sp->router->lpm.trees);
 648        return err;
 649}
 650
 651static void mlxsw_sp_lpm_fini(struct mlxsw_sp *mlxsw_sp)
 652{
 653        struct mlxsw_sp_lpm_tree *lpm_tree;
 654
 655        lpm_tree = mlxsw_sp->router->lpm.proto_trees[MLXSW_SP_L3_PROTO_IPV6];
 656        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
 657
 658        lpm_tree = mlxsw_sp->router->lpm.proto_trees[MLXSW_SP_L3_PROTO_IPV4];
 659        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
 660
 661        kfree(mlxsw_sp->router->lpm.trees);
 662}
 663
 664static bool mlxsw_sp_vr_is_used(const struct mlxsw_sp_vr *vr)
 665{
 666        return !!vr->fib4 || !!vr->fib6 ||
 667               !!vr->mr_table[MLXSW_SP_L3_PROTO_IPV4] ||
 668               !!vr->mr_table[MLXSW_SP_L3_PROTO_IPV6];
 669}
 670
 671static struct mlxsw_sp_vr *mlxsw_sp_vr_find_unused(struct mlxsw_sp *mlxsw_sp)
 672{
 673        struct mlxsw_sp_vr *vr;
 674        int i;
 675
 676        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
 677                vr = &mlxsw_sp->router->vrs[i];
 678                if (!mlxsw_sp_vr_is_used(vr))
 679                        return vr;
 680        }
 681        return NULL;
 682}
 683
 684static int mlxsw_sp_vr_lpm_tree_bind(struct mlxsw_sp *mlxsw_sp,
 685                                     const struct mlxsw_sp_fib *fib, u8 tree_id)
 686{
 687        char raltb_pl[MLXSW_REG_RALTB_LEN];
 688
 689        mlxsw_reg_raltb_pack(raltb_pl, fib->vr->id,
 690                             (enum mlxsw_reg_ralxx_protocol) fib->proto,
 691                             tree_id);
 692        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), raltb_pl);
 693}
 694
 695static int mlxsw_sp_vr_lpm_tree_unbind(struct mlxsw_sp *mlxsw_sp,
 696                                       const struct mlxsw_sp_fib *fib)
 697{
 698        char raltb_pl[MLXSW_REG_RALTB_LEN];
 699
 700        /* Bind to tree 0 which is default */
 701        mlxsw_reg_raltb_pack(raltb_pl, fib->vr->id,
 702                             (enum mlxsw_reg_ralxx_protocol) fib->proto, 0);
 703        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), raltb_pl);
 704}
 705
 706static u32 mlxsw_sp_fix_tb_id(u32 tb_id)
 707{
 708        /* For our purpose, squash main, default and local tables into one */
 709        if (tb_id == RT_TABLE_LOCAL || tb_id == RT_TABLE_DEFAULT)
 710                tb_id = RT_TABLE_MAIN;
 711        return tb_id;
 712}
 713
 714static struct mlxsw_sp_vr *mlxsw_sp_vr_find(struct mlxsw_sp *mlxsw_sp,
 715                                            u32 tb_id)
 716{
 717        struct mlxsw_sp_vr *vr;
 718        int i;
 719
 720        tb_id = mlxsw_sp_fix_tb_id(tb_id);
 721
 722        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
 723                vr = &mlxsw_sp->router->vrs[i];
 724                if (mlxsw_sp_vr_is_used(vr) && vr->tb_id == tb_id)
 725                        return vr;
 726        }
 727        return NULL;
 728}
 729
 730int mlxsw_sp_router_tb_id_vr_id(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
 731                                u16 *vr_id)
 732{
 733        struct mlxsw_sp_vr *vr;
 734        int err = 0;
 735
 736        mutex_lock(&mlxsw_sp->router->lock);
 737        vr = mlxsw_sp_vr_find(mlxsw_sp, tb_id);
 738        if (!vr) {
 739                err = -ESRCH;
 740                goto out;
 741        }
 742        *vr_id = vr->id;
 743out:
 744        mutex_unlock(&mlxsw_sp->router->lock);
 745        return err;
 746}
 747
 748static struct mlxsw_sp_fib *mlxsw_sp_vr_fib(const struct mlxsw_sp_vr *vr,
 749                                            enum mlxsw_sp_l3proto proto)
 750{
 751        switch (proto) {
 752        case MLXSW_SP_L3_PROTO_IPV4:
 753                return vr->fib4;
 754        case MLXSW_SP_L3_PROTO_IPV6:
 755                return vr->fib6;
 756        }
 757        return NULL;
 758}
 759
 760static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
 761                                              u32 tb_id,
 762                                              struct netlink_ext_ack *extack)
 763{
 764        struct mlxsw_sp_mr_table *mr4_table, *mr6_table;
 765        struct mlxsw_sp_fib *fib4;
 766        struct mlxsw_sp_fib *fib6;
 767        struct mlxsw_sp_vr *vr;
 768        int err;
 769
 770        vr = mlxsw_sp_vr_find_unused(mlxsw_sp);
 771        if (!vr) {
 772                NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported virtual routers");
 773                return ERR_PTR(-EBUSY);
 774        }
 775        fib4 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
 776        if (IS_ERR(fib4))
 777                return ERR_CAST(fib4);
 778        fib6 = mlxsw_sp_fib_create(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
 779        if (IS_ERR(fib6)) {
 780                err = PTR_ERR(fib6);
 781                goto err_fib6_create;
 782        }
 783        mr4_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
 784                                             MLXSW_SP_L3_PROTO_IPV4);
 785        if (IS_ERR(mr4_table)) {
 786                err = PTR_ERR(mr4_table);
 787                goto err_mr4_table_create;
 788        }
 789        mr6_table = mlxsw_sp_mr_table_create(mlxsw_sp, vr->id,
 790                                             MLXSW_SP_L3_PROTO_IPV6);
 791        if (IS_ERR(mr6_table)) {
 792                err = PTR_ERR(mr6_table);
 793                goto err_mr6_table_create;
 794        }
 795
 796        vr->fib4 = fib4;
 797        vr->fib6 = fib6;
 798        vr->mr_table[MLXSW_SP_L3_PROTO_IPV4] = mr4_table;
 799        vr->mr_table[MLXSW_SP_L3_PROTO_IPV6] = mr6_table;
 800        vr->tb_id = tb_id;
 801        return vr;
 802
 803err_mr6_table_create:
 804        mlxsw_sp_mr_table_destroy(mr4_table);
 805err_mr4_table_create:
 806        mlxsw_sp_fib_destroy(mlxsw_sp, fib6);
 807err_fib6_create:
 808        mlxsw_sp_fib_destroy(mlxsw_sp, fib4);
 809        return ERR_PTR(err);
 810}
 811
 812static void mlxsw_sp_vr_destroy(struct mlxsw_sp *mlxsw_sp,
 813                                struct mlxsw_sp_vr *vr)
 814{
 815        mlxsw_sp_mr_table_destroy(vr->mr_table[MLXSW_SP_L3_PROTO_IPV6]);
 816        vr->mr_table[MLXSW_SP_L3_PROTO_IPV6] = NULL;
 817        mlxsw_sp_mr_table_destroy(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4]);
 818        vr->mr_table[MLXSW_SP_L3_PROTO_IPV4] = NULL;
 819        mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib6);
 820        vr->fib6 = NULL;
 821        mlxsw_sp_fib_destroy(mlxsw_sp, vr->fib4);
 822        vr->fib4 = NULL;
 823}
 824
 825static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
 826                                           struct netlink_ext_ack *extack)
 827{
 828        struct mlxsw_sp_vr *vr;
 829
 830        tb_id = mlxsw_sp_fix_tb_id(tb_id);
 831        vr = mlxsw_sp_vr_find(mlxsw_sp, tb_id);
 832        if (!vr)
 833                vr = mlxsw_sp_vr_create(mlxsw_sp, tb_id, extack);
 834        return vr;
 835}
 836
 837static void mlxsw_sp_vr_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr)
 838{
 839        if (!vr->rif_count && list_empty(&vr->fib4->node_list) &&
 840            list_empty(&vr->fib6->node_list) &&
 841            mlxsw_sp_mr_table_empty(vr->mr_table[MLXSW_SP_L3_PROTO_IPV4]) &&
 842            mlxsw_sp_mr_table_empty(vr->mr_table[MLXSW_SP_L3_PROTO_IPV6]))
 843                mlxsw_sp_vr_destroy(mlxsw_sp, vr);
 844}
 845
 846static bool
 847mlxsw_sp_vr_lpm_tree_should_replace(struct mlxsw_sp_vr *vr,
 848                                    enum mlxsw_sp_l3proto proto, u8 tree_id)
 849{
 850        struct mlxsw_sp_fib *fib = mlxsw_sp_vr_fib(vr, proto);
 851
 852        if (!mlxsw_sp_vr_is_used(vr))
 853                return false;
 854        if (fib->lpm_tree->id == tree_id)
 855                return true;
 856        return false;
 857}
 858
 859static int mlxsw_sp_vr_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
 860                                        struct mlxsw_sp_fib *fib,
 861                                        struct mlxsw_sp_lpm_tree *new_tree)
 862{
 863        struct mlxsw_sp_lpm_tree *old_tree = fib->lpm_tree;
 864        int err;
 865
 866        fib->lpm_tree = new_tree;
 867        mlxsw_sp_lpm_tree_hold(new_tree);
 868        err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id);
 869        if (err)
 870                goto err_tree_bind;
 871        mlxsw_sp_lpm_tree_put(mlxsw_sp, old_tree);
 872        return 0;
 873
 874err_tree_bind:
 875        mlxsw_sp_lpm_tree_put(mlxsw_sp, new_tree);
 876        fib->lpm_tree = old_tree;
 877        return err;
 878}
 879
 880static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
 881                                         struct mlxsw_sp_fib *fib,
 882                                         struct mlxsw_sp_lpm_tree *new_tree)
 883{
 884        enum mlxsw_sp_l3proto proto = fib->proto;
 885        struct mlxsw_sp_lpm_tree *old_tree;
 886        u8 old_id, new_id = new_tree->id;
 887        struct mlxsw_sp_vr *vr;
 888        int i, err;
 889
 890        old_tree = mlxsw_sp->router->lpm.proto_trees[proto];
 891        old_id = old_tree->id;
 892
 893        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
 894                vr = &mlxsw_sp->router->vrs[i];
 895                if (!mlxsw_sp_vr_lpm_tree_should_replace(vr, proto, old_id))
 896                        continue;
 897                err = mlxsw_sp_vr_lpm_tree_replace(mlxsw_sp,
 898                                                   mlxsw_sp_vr_fib(vr, proto),
 899                                                   new_tree);
 900                if (err)
 901                        goto err_tree_replace;
 902        }
 903
 904        memcpy(new_tree->prefix_ref_count, old_tree->prefix_ref_count,
 905               sizeof(new_tree->prefix_ref_count));
 906        mlxsw_sp->router->lpm.proto_trees[proto] = new_tree;
 907        mlxsw_sp_lpm_tree_put(mlxsw_sp, old_tree);
 908
 909        return 0;
 910
 911err_tree_replace:
 912        for (i--; i >= 0; i--) {
 913                if (!mlxsw_sp_vr_lpm_tree_should_replace(vr, proto, new_id))
 914                        continue;
 915                mlxsw_sp_vr_lpm_tree_replace(mlxsw_sp,
 916                                             mlxsw_sp_vr_fib(vr, proto),
 917                                             old_tree);
 918        }
 919        return err;
 920}
 921
 922static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp)
 923{
 924        struct mlxsw_sp_vr *vr;
 925        u64 max_vrs;
 926        int i;
 927
 928        if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_VRS))
 929                return -EIO;
 930
 931        max_vrs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS);
 932        mlxsw_sp->router->vrs = kcalloc(max_vrs, sizeof(struct mlxsw_sp_vr),
 933                                        GFP_KERNEL);
 934        if (!mlxsw_sp->router->vrs)
 935                return -ENOMEM;
 936
 937        for (i = 0; i < max_vrs; i++) {
 938                vr = &mlxsw_sp->router->vrs[i];
 939                vr->id = i;
 940        }
 941
 942        return 0;
 943}
 944
 945static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp);
 946
 947static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp)
 948{
 949        /* At this stage we're guaranteed not to have new incoming
 950         * FIB notifications and the work queue is free from FIBs
 951         * sitting on top of mlxsw netdevs. However, we can still
 952         * have other FIBs queued. Flush the queue before flushing
 953         * the device's tables. No need for locks, as we're the only
 954         * writer.
 955         */
 956        mlxsw_core_flush_owq();
 957        mlxsw_sp_router_fib_flush(mlxsw_sp);
 958        kfree(mlxsw_sp->router->vrs);
 959}
 960
 961static struct net_device *
 962__mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev)
 963{
 964        struct ip_tunnel *tun = netdev_priv(ol_dev);
 965        struct net *net = dev_net(ol_dev);
 966
 967        return dev_get_by_index_rcu(net, tun->parms.link);
 968}
 969
 970u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)
 971{
 972        struct net_device *d;
 973        u32 tb_id;
 974
 975        rcu_read_lock();
 976        d = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
 977        if (d)
 978                tb_id = l3mdev_fib_table(d) ? : RT_TABLE_MAIN;
 979        else
 980                tb_id = RT_TABLE_MAIN;
 981        rcu_read_unlock();
 982
 983        return tb_id;
 984}
 985
 986static struct mlxsw_sp_rif *
 987mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
 988                    const struct mlxsw_sp_rif_params *params,
 989                    struct netlink_ext_ack *extack);
 990
 991static struct mlxsw_sp_rif_ipip_lb *
 992mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,
 993                                enum mlxsw_sp_ipip_type ipipt,
 994                                struct net_device *ol_dev,
 995                                struct netlink_ext_ack *extack)
 996{
 997        struct mlxsw_sp_rif_params_ipip_lb lb_params;
 998        const struct mlxsw_sp_ipip_ops *ipip_ops;
 999        struct mlxsw_sp_rif *rif;
1000
1001        ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];
1002        lb_params = (struct mlxsw_sp_rif_params_ipip_lb) {
1003                .common.dev = ol_dev,
1004                .common.lag = false,
1005                .lb_config = ipip_ops->ol_loopback_config(mlxsw_sp, ol_dev),
1006        };
1007
1008        rif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common, extack);
1009        if (IS_ERR(rif))
1010                return ERR_CAST(rif);
1011        return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);
1012}
1013
1014static struct mlxsw_sp_ipip_entry *
1015mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp,
1016                          enum mlxsw_sp_ipip_type ipipt,
1017                          struct net_device *ol_dev)
1018{
1019        const struct mlxsw_sp_ipip_ops *ipip_ops;
1020        struct mlxsw_sp_ipip_entry *ipip_entry;
1021        struct mlxsw_sp_ipip_entry *ret = NULL;
1022
1023        ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];
1024        ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL);
1025        if (!ipip_entry)
1026                return ERR_PTR(-ENOMEM);
1027
1028        ipip_entry->ol_lb = mlxsw_sp_ipip_ol_ipip_lb_create(mlxsw_sp, ipipt,
1029                                                            ol_dev, NULL);
1030        if (IS_ERR(ipip_entry->ol_lb)) {
1031                ret = ERR_CAST(ipip_entry->ol_lb);
1032                goto err_ol_ipip_lb_create;
1033        }
1034
1035        ipip_entry->ipipt = ipipt;
1036        ipip_entry->ol_dev = ol_dev;
1037
1038        switch (ipip_ops->ul_proto) {
1039        case MLXSW_SP_L3_PROTO_IPV4:
1040                ipip_entry->parms4 = mlxsw_sp_ipip_netdev_parms4(ol_dev);
1041                break;
1042        case MLXSW_SP_L3_PROTO_IPV6:
1043                WARN_ON(1);
1044                break;
1045        }
1046
1047        return ipip_entry;
1048
1049err_ol_ipip_lb_create:
1050        kfree(ipip_entry);
1051        return ret;
1052}
1053
1054static void
1055mlxsw_sp_ipip_entry_dealloc(struct mlxsw_sp_ipip_entry *ipip_entry)
1056{
1057        mlxsw_sp_rif_destroy(&ipip_entry->ol_lb->common);
1058        kfree(ipip_entry);
1059}
1060
1061static bool
1062mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,
1063                                  const enum mlxsw_sp_l3proto ul_proto,
1064                                  union mlxsw_sp_l3addr saddr,
1065                                  u32 ul_tb_id,
1066                                  struct mlxsw_sp_ipip_entry *ipip_entry)
1067{
1068        u32 tun_ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
1069        enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt;
1070        union mlxsw_sp_l3addr tun_saddr;
1071
1072        if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto)
1073                return false;
1074
1075        tun_saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ipip_entry->ol_dev);
1076        return tun_ul_tb_id == ul_tb_id &&
1077               mlxsw_sp_l3addr_eq(&tun_saddr, &saddr);
1078}
1079
1080static int
1081mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp,
1082                              struct mlxsw_sp_fib_entry *fib_entry,
1083                              struct mlxsw_sp_ipip_entry *ipip_entry)
1084{
1085        u32 tunnel_index;
1086        int err;
1087
1088        err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
1089                                  1, &tunnel_index);
1090        if (err)
1091                return err;
1092
1093        ipip_entry->decap_fib_entry = fib_entry;
1094        fib_entry->decap.ipip_entry = ipip_entry;
1095        fib_entry->decap.tunnel_index = tunnel_index;
1096        return 0;
1097}
1098
1099static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,
1100                                          struct mlxsw_sp_fib_entry *fib_entry)
1101{
1102        /* Unlink this node from the IPIP entry that it's the decap entry of. */
1103        fib_entry->decap.ipip_entry->decap_fib_entry = NULL;
1104        fib_entry->decap.ipip_entry = NULL;
1105        mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
1106                           1, fib_entry->decap.tunnel_index);
1107}
1108
1109static struct mlxsw_sp_fib_node *
1110mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
1111                         size_t addr_len, unsigned char prefix_len);
1112static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
1113                                     struct mlxsw_sp_fib_entry *fib_entry);
1114
1115static void
1116mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp,
1117                                 struct mlxsw_sp_ipip_entry *ipip_entry)
1118{
1119        struct mlxsw_sp_fib_entry *fib_entry = ipip_entry->decap_fib_entry;
1120
1121        mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, fib_entry);
1122        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
1123
1124        mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
1125}
1126
1127static void
1128mlxsw_sp_ipip_entry_promote_decap(struct mlxsw_sp *mlxsw_sp,
1129                                  struct mlxsw_sp_ipip_entry *ipip_entry,
1130                                  struct mlxsw_sp_fib_entry *decap_fib_entry)
1131{
1132        if (mlxsw_sp_fib_entry_decap_init(mlxsw_sp, decap_fib_entry,
1133                                          ipip_entry))
1134                return;
1135        decap_fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP;
1136
1137        if (mlxsw_sp_fib_entry_update(mlxsw_sp, decap_fib_entry))
1138                mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry);
1139}
1140
1141static struct mlxsw_sp_fib_entry *
1142mlxsw_sp_router_ip2me_fib_entry_find(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
1143                                     enum mlxsw_sp_l3proto proto,
1144                                     const union mlxsw_sp_l3addr *addr,
1145                                     enum mlxsw_sp_fib_entry_type type)
1146{
1147        struct mlxsw_sp_fib_node *fib_node;
1148        unsigned char addr_prefix_len;
1149        struct mlxsw_sp_fib *fib;
1150        struct mlxsw_sp_vr *vr;
1151        const void *addrp;
1152        size_t addr_len;
1153        u32 addr4;
1154
1155        vr = mlxsw_sp_vr_find(mlxsw_sp, tb_id);
1156        if (!vr)
1157                return NULL;
1158        fib = mlxsw_sp_vr_fib(vr, proto);
1159
1160        switch (proto) {
1161        case MLXSW_SP_L3_PROTO_IPV4:
1162                addr4 = be32_to_cpu(addr->addr4);
1163                addrp = &addr4;
1164                addr_len = 4;
1165                addr_prefix_len = 32;
1166                break;
1167        case MLXSW_SP_L3_PROTO_IPV6: /* fall through */
1168        default:
1169                WARN_ON(1);
1170                return NULL;
1171        }
1172
1173        fib_node = mlxsw_sp_fib_node_lookup(fib, addrp, addr_len,
1174                                            addr_prefix_len);
1175        if (!fib_node || fib_node->fib_entry->type != type)
1176                return NULL;
1177
1178        return fib_node->fib_entry;
1179}
1180
1181/* Given an IPIP entry, find the corresponding decap route. */
1182static struct mlxsw_sp_fib_entry *
1183mlxsw_sp_ipip_entry_find_decap(struct mlxsw_sp *mlxsw_sp,
1184                               struct mlxsw_sp_ipip_entry *ipip_entry)
1185{
1186        static struct mlxsw_sp_fib_node *fib_node;
1187        const struct mlxsw_sp_ipip_ops *ipip_ops;
1188        unsigned char saddr_prefix_len;
1189        union mlxsw_sp_l3addr saddr;
1190        struct mlxsw_sp_fib *ul_fib;
1191        struct mlxsw_sp_vr *ul_vr;
1192        const void *saddrp;
1193        size_t saddr_len;
1194        u32 ul_tb_id;
1195        u32 saddr4;
1196
1197        ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
1198
1199        ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev);
1200        ul_vr = mlxsw_sp_vr_find(mlxsw_sp, ul_tb_id);
1201        if (!ul_vr)
1202                return NULL;
1203
1204        ul_fib = mlxsw_sp_vr_fib(ul_vr, ipip_ops->ul_proto);
1205        saddr = mlxsw_sp_ipip_netdev_saddr(ipip_ops->ul_proto,
1206                                           ipip_entry->ol_dev);
1207
1208        switch (ipip_ops->ul_proto) {
1209        case MLXSW_SP_L3_PROTO_IPV4:
1210                saddr4 = be32_to_cpu(saddr.addr4);
1211                saddrp = &saddr4;
1212                saddr_len = 4;
1213                saddr_prefix_len = 32;
1214                break;
1215        default:
1216                WARN_ON(1);
1217                return NULL;
1218        }
1219
1220        fib_node = mlxsw_sp_fib_node_lookup(ul_fib, saddrp, saddr_len,
1221                                            saddr_prefix_len);
1222        if (!fib_node ||
1223            fib_node->fib_entry->type != MLXSW_SP_FIB_ENTRY_TYPE_TRAP)
1224                return NULL;
1225
1226        return fib_node->fib_entry;
1227}
1228
1229static struct mlxsw_sp_ipip_entry *
1230mlxsw_sp_ipip_entry_create(struct mlxsw_sp *mlxsw_sp,
1231                           enum mlxsw_sp_ipip_type ipipt,
1232                           struct net_device *ol_dev)
1233{
1234        struct mlxsw_sp_ipip_entry *ipip_entry;
1235
1236        ipip_entry = mlxsw_sp_ipip_entry_alloc(mlxsw_sp, ipipt, ol_dev);
1237        if (IS_ERR(ipip_entry))
1238                return ipip_entry;
1239
1240        list_add_tail(&ipip_entry->ipip_list_node,
1241                      &mlxsw_sp->router->ipip_list);
1242
1243        return ipip_entry;
1244}
1245
1246static void
1247mlxsw_sp_ipip_entry_destroy(struct mlxsw_sp *mlxsw_sp,
1248                            struct mlxsw_sp_ipip_entry *ipip_entry)
1249{
1250        list_del(&ipip_entry->ipip_list_node);
1251        mlxsw_sp_ipip_entry_dealloc(ipip_entry);
1252}
1253
1254static bool
1255mlxsw_sp_ipip_entry_matches_decap(struct mlxsw_sp *mlxsw_sp,
1256                                  const struct net_device *ul_dev,
1257                                  enum mlxsw_sp_l3proto ul_proto,
1258                                  union mlxsw_sp_l3addr ul_dip,
1259                                  struct mlxsw_sp_ipip_entry *ipip_entry)
1260{
1261        u32 ul_tb_id = l3mdev_fib_table(ul_dev) ? : RT_TABLE_MAIN;
1262        enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt;
1263
1264        if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto)
1265                return false;
1266
1267        return mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, ul_dip,
1268                                                 ul_tb_id, ipip_entry);
1269}
1270
1271/* Given decap parameters, find the corresponding IPIP entry. */
1272static struct mlxsw_sp_ipip_entry *
1273mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp,
1274                                  const struct net_device *ul_dev,
1275                                  enum mlxsw_sp_l3proto ul_proto,
1276                                  union mlxsw_sp_l3addr ul_dip)
1277{
1278        struct mlxsw_sp_ipip_entry *ipip_entry;
1279
1280        list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,
1281                            ipip_list_node)
1282                if (mlxsw_sp_ipip_entry_matches_decap(mlxsw_sp, ul_dev,
1283                                                      ul_proto, ul_dip,
1284                                                      ipip_entry))
1285                        return ipip_entry;
1286
1287        return NULL;
1288}
1289
1290static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,
1291                                      const struct net_device *dev,
1292                                      enum mlxsw_sp_ipip_type *p_type)
1293{
1294        struct mlxsw_sp_router *router = mlxsw_sp->router;
1295        const struct mlxsw_sp_ipip_ops *ipip_ops;
1296        enum mlxsw_sp_ipip_type ipipt;
1297
1298        for (ipipt = 0; ipipt < MLXSW_SP_IPIP_TYPE_MAX; ++ipipt) {
1299                ipip_ops = router->ipip_ops_arr[ipipt];
1300                if (dev->type == ipip_ops->dev_type) {
1301                        if (p_type)
1302                                *p_type = ipipt;
1303                        return true;
1304                }
1305        }
1306        return false;
1307}
1308
1309bool mlxsw_sp_netdev_is_ipip_ol(const struct mlxsw_sp *mlxsw_sp,
1310                                const struct net_device *dev)
1311{
1312        return mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL);
1313}
1314
1315static struct mlxsw_sp_ipip_entry *
1316mlxsw_sp_ipip_entry_find_by_ol_dev(struct mlxsw_sp *mlxsw_sp,
1317                                   const struct net_device *ol_dev)
1318{
1319        struct mlxsw_sp_ipip_entry *ipip_entry;
1320
1321        list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list,
1322                            ipip_list_node)
1323                if (ipip_entry->ol_dev == ol_dev)
1324                        return ipip_entry;
1325
1326        return NULL;
1327}
1328
1329static struct mlxsw_sp_ipip_entry *
1330mlxsw_sp_ipip_entry_find_by_ul_dev(const struct mlxsw_sp *mlxsw_sp,
1331                                   const struct net_device *ul_dev,
1332                                   struct mlxsw_sp_ipip_entry *start)
1333{
1334        struct mlxsw_sp_ipip_entry *ipip_entry;
1335
1336        ipip_entry = list_prepare_entry(start, &mlxsw_sp->router->ipip_list,
1337                                        ipip_list_node);
1338        list_for_each_entry_continue(ipip_entry, &mlxsw_sp->router->ipip_list,
1339                                     ipip_list_node) {
1340                struct net_device *ol_dev = ipip_entry->ol_dev;
1341                struct net_device *ipip_ul_dev;
1342
1343                rcu_read_lock();
1344                ipip_ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
1345                rcu_read_unlock();
1346
1347                if (ipip_ul_dev == ul_dev)
1348                        return ipip_entry;
1349        }
1350
1351        return NULL;
1352}
1353
1354bool mlxsw_sp_netdev_is_ipip_ul(struct mlxsw_sp *mlxsw_sp,
1355                                const struct net_device *dev)
1356{
1357        bool is_ipip_ul;
1358
1359        mutex_lock(&mlxsw_sp->router->lock);
1360        is_ipip_ul = mlxsw_sp_ipip_entry_find_by_ul_dev(mlxsw_sp, dev, NULL);
1361        mutex_unlock(&mlxsw_sp->router->lock);
1362
1363        return is_ipip_ul;
1364}
1365
1366static bool mlxsw_sp_netdevice_ipip_can_offload(struct mlxsw_sp *mlxsw_sp,
1367                                                const struct net_device *ol_dev,
1368                                                enum mlxsw_sp_ipip_type ipipt)
1369{
1370        const struct mlxsw_sp_ipip_ops *ops
1371                = mlxsw_sp->router->ipip_ops_arr[ipipt];
1372
1373        /* For deciding whether decap should be offloaded, we don't care about
1374         * overlay protocol, so ask whether either one is supported.
1375         */
1376        return ops->can_offload(mlxsw_sp, ol_dev, MLXSW_SP_L3_PROTO_IPV4) ||
1377               ops->can_offload(mlxsw_sp, ol_dev, MLXSW_SP_L3_PROTO_IPV6);
1378}
1379
1380static int mlxsw_sp_netdevice_ipip_ol_reg_event(struct mlxsw_sp *mlxsw_sp,
1381                                                struct net_device *ol_dev)
1382{
1383        enum mlxsw_sp_ipip_type ipipt = MLXSW_SP_IPIP_TYPE_MAX;
1384        struct mlxsw_sp_ipip_entry *ipip_entry;
1385        enum mlxsw_sp_l3proto ul_proto;
1386        union mlxsw_sp_l3addr saddr;
1387        u32 ul_tb_id;
1388
1389        mlxsw_sp_netdev_ipip_type(mlxsw_sp, ol_dev, &ipipt);
1390        if (mlxsw_sp_netdevice_ipip_can_offload(mlxsw_sp, ol_dev, ipipt)) {
1391                ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev);
1392                ul_proto = mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto;
1393                saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev);
1394                if (!mlxsw_sp_ipip_demote_tunnel_by_saddr(mlxsw_sp, ul_proto,
1395                                                          saddr, ul_tb_id,
1396                                                          NULL)) {
1397                        ipip_entry = mlxsw_sp_ipip_entry_create(mlxsw_sp, ipipt,
1398                                                                ol_dev);
1399                        if (IS_ERR(ipip_entry))
1400                                return PTR_ERR(ipip_entry);
1401                }
1402        }
1403
1404        return 0;
1405}
1406
1407static void mlxsw_sp_netdevice_ipip_ol_unreg_event(struct mlxsw_sp *mlxsw_sp,
1408                                                   struct net_device *ol_dev)
1409{
1410        struct mlxsw_sp_ipip_entry *ipip_entry;
1411
1412        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1413        if (ipip_entry)
1414                mlxsw_sp_ipip_entry_destroy(mlxsw_sp, ipip_entry);
1415}
1416
1417static void
1418mlxsw_sp_ipip_entry_ol_up_event(struct mlxsw_sp *mlxsw_sp,
1419                                struct mlxsw_sp_ipip_entry *ipip_entry)
1420{
1421        struct mlxsw_sp_fib_entry *decap_fib_entry;
1422
1423        decap_fib_entry = mlxsw_sp_ipip_entry_find_decap(mlxsw_sp, ipip_entry);
1424        if (decap_fib_entry)
1425                mlxsw_sp_ipip_entry_promote_decap(mlxsw_sp, ipip_entry,
1426                                                  decap_fib_entry);
1427}
1428
1429static int
1430mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif, u16 ul_vr_id,
1431                        u16 ul_rif_id, bool enable)
1432{
1433        struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config;
1434        struct mlxsw_sp_rif *rif = &lb_rif->common;
1435        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
1436        char ritr_pl[MLXSW_REG_RITR_LEN];
1437        u32 saddr4;
1438
1439        switch (lb_cf.ul_protocol) {
1440        case MLXSW_SP_L3_PROTO_IPV4:
1441                saddr4 = be32_to_cpu(lb_cf.saddr.addr4);
1442                mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
1443                                    rif->rif_index, rif->vr_id, rif->dev->mtu);
1444                mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt,
1445                            MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET,
1446                            ul_vr_id, ul_rif_id, saddr4, lb_cf.okey);
1447                break;
1448
1449        case MLXSW_SP_L3_PROTO_IPV6:
1450                return -EAFNOSUPPORT;
1451        }
1452
1453        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
1454}
1455
1456static int mlxsw_sp_netdevice_ipip_ol_update_mtu(struct mlxsw_sp *mlxsw_sp,
1457                                                 struct net_device *ol_dev)
1458{
1459        struct mlxsw_sp_ipip_entry *ipip_entry;
1460        struct mlxsw_sp_rif_ipip_lb *lb_rif;
1461        int err = 0;
1462
1463        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1464        if (ipip_entry) {
1465                lb_rif = ipip_entry->ol_lb;
1466                err = mlxsw_sp_rif_ipip_lb_op(lb_rif, lb_rif->ul_vr_id,
1467                                              lb_rif->ul_rif_id, true);
1468                if (err)
1469                        goto out;
1470                lb_rif->common.mtu = ol_dev->mtu;
1471        }
1472
1473out:
1474        return err;
1475}
1476
1477static void mlxsw_sp_netdevice_ipip_ol_up_event(struct mlxsw_sp *mlxsw_sp,
1478                                                struct net_device *ol_dev)
1479{
1480        struct mlxsw_sp_ipip_entry *ipip_entry;
1481
1482        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1483        if (ipip_entry)
1484                mlxsw_sp_ipip_entry_ol_up_event(mlxsw_sp, ipip_entry);
1485}
1486
1487static void
1488mlxsw_sp_ipip_entry_ol_down_event(struct mlxsw_sp *mlxsw_sp,
1489                                  struct mlxsw_sp_ipip_entry *ipip_entry)
1490{
1491        if (ipip_entry->decap_fib_entry)
1492                mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry);
1493}
1494
1495static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp,
1496                                                  struct net_device *ol_dev)
1497{
1498        struct mlxsw_sp_ipip_entry *ipip_entry;
1499
1500        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1501        if (ipip_entry)
1502                mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);
1503}
1504
1505static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,
1506                                         struct mlxsw_sp_rif *old_rif,
1507                                         struct mlxsw_sp_rif *new_rif);
1508static int
1509mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp,
1510                                 struct mlxsw_sp_ipip_entry *ipip_entry,
1511                                 bool keep_encap,
1512                                 struct netlink_ext_ack *extack)
1513{
1514        struct mlxsw_sp_rif_ipip_lb *old_lb_rif = ipip_entry->ol_lb;
1515        struct mlxsw_sp_rif_ipip_lb *new_lb_rif;
1516
1517        new_lb_rif = mlxsw_sp_ipip_ol_ipip_lb_create(mlxsw_sp,
1518                                                     ipip_entry->ipipt,
1519                                                     ipip_entry->ol_dev,
1520                                                     extack);
1521        if (IS_ERR(new_lb_rif))
1522                return PTR_ERR(new_lb_rif);
1523        ipip_entry->ol_lb = new_lb_rif;
1524
1525        if (keep_encap)
1526                mlxsw_sp_nexthop_rif_migrate(mlxsw_sp, &old_lb_rif->common,
1527                                             &new_lb_rif->common);
1528
1529        mlxsw_sp_rif_destroy(&old_lb_rif->common);
1530
1531        return 0;
1532}
1533
1534static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
1535                                        struct mlxsw_sp_rif *rif);
1536
1537/**
1538 * __mlxsw_sp_ipip_entry_update_tunnel - Update offload related to IPIP entry.
1539 * @mlxsw_sp: mlxsw_sp.
1540 * @ipip_entry: IPIP entry.
1541 * @recreate_loopback: Recreates the associated loopback RIF.
1542 * @keep_encap: Updates next hops that use the tunnel netdevice. This is only
1543 *              relevant when recreate_loopback is true.
1544 * @update_nexthops: Updates next hops, keeping the current loopback RIF. This
1545 *                   is only relevant when recreate_loopback is false.
1546 * @extack: extack.
1547 *
1548 * Return: Non-zero value on failure.
1549 */
1550int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
1551                                        struct mlxsw_sp_ipip_entry *ipip_entry,
1552                                        bool recreate_loopback,
1553                                        bool keep_encap,
1554                                        bool update_nexthops,
1555                                        struct netlink_ext_ack *extack)
1556{
1557        int err;
1558
1559        /* RIFs can't be edited, so to update loopback, we need to destroy and
1560         * recreate it. That creates a window of opportunity where RALUE and
1561         * RATR registers end up referencing a RIF that's already gone. RATRs
1562         * are handled in mlxsw_sp_ipip_entry_ol_lb_update(), and to take care
1563         * of RALUE, demote the decap route back.
1564         */
1565        if (ipip_entry->decap_fib_entry)
1566                mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry);
1567
1568        if (recreate_loopback) {
1569                err = mlxsw_sp_ipip_entry_ol_lb_update(mlxsw_sp, ipip_entry,
1570                                                       keep_encap, extack);
1571                if (err)
1572                        return err;
1573        } else if (update_nexthops) {
1574                mlxsw_sp_nexthop_rif_update(mlxsw_sp,
1575                                            &ipip_entry->ol_lb->common);
1576        }
1577
1578        if (ipip_entry->ol_dev->flags & IFF_UP)
1579                mlxsw_sp_ipip_entry_ol_up_event(mlxsw_sp, ipip_entry);
1580
1581        return 0;
1582}
1583
1584static int mlxsw_sp_netdevice_ipip_ol_vrf_event(struct mlxsw_sp *mlxsw_sp,
1585                                                struct net_device *ol_dev,
1586                                                struct netlink_ext_ack *extack)
1587{
1588        struct mlxsw_sp_ipip_entry *ipip_entry =
1589                mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1590
1591        if (!ipip_entry)
1592                return 0;
1593
1594        return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1595                                                   true, false, false, extack);
1596}
1597
1598static int
1599mlxsw_sp_netdevice_ipip_ul_vrf_event(struct mlxsw_sp *mlxsw_sp,
1600                                     struct mlxsw_sp_ipip_entry *ipip_entry,
1601                                     struct net_device *ul_dev,
1602                                     bool *demote_this,
1603                                     struct netlink_ext_ack *extack)
1604{
1605        u32 ul_tb_id = l3mdev_fib_table(ul_dev) ? : RT_TABLE_MAIN;
1606        enum mlxsw_sp_l3proto ul_proto;
1607        union mlxsw_sp_l3addr saddr;
1608
1609        /* Moving underlay to a different VRF might cause local address
1610         * conflict, and the conflicting tunnels need to be demoted.
1611         */
1612        ul_proto = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt]->ul_proto;
1613        saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ipip_entry->ol_dev);
1614        if (mlxsw_sp_ipip_demote_tunnel_by_saddr(mlxsw_sp, ul_proto,
1615                                                 saddr, ul_tb_id,
1616                                                 ipip_entry)) {
1617                *demote_this = true;
1618                return 0;
1619        }
1620
1621        return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1622                                                   true, true, false, extack);
1623}
1624
1625static int
1626mlxsw_sp_netdevice_ipip_ul_up_event(struct mlxsw_sp *mlxsw_sp,
1627                                    struct mlxsw_sp_ipip_entry *ipip_entry,
1628                                    struct net_device *ul_dev)
1629{
1630        return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1631                                                   false, false, true, NULL);
1632}
1633
1634static int
1635mlxsw_sp_netdevice_ipip_ul_down_event(struct mlxsw_sp *mlxsw_sp,
1636                                      struct mlxsw_sp_ipip_entry *ipip_entry,
1637                                      struct net_device *ul_dev)
1638{
1639        /* A down underlay device causes encapsulated packets to not be
1640         * forwarded, but decap still works. So refresh next hops without
1641         * touching anything else.
1642         */
1643        return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1644                                                   false, false, true, NULL);
1645}
1646
1647static int
1648mlxsw_sp_netdevice_ipip_ol_change_event(struct mlxsw_sp *mlxsw_sp,
1649                                        struct net_device *ol_dev,
1650                                        struct netlink_ext_ack *extack)
1651{
1652        const struct mlxsw_sp_ipip_ops *ipip_ops;
1653        struct mlxsw_sp_ipip_entry *ipip_entry;
1654        int err;
1655
1656        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, ol_dev);
1657        if (!ipip_entry)
1658                /* A change might make a tunnel eligible for offloading, but
1659                 * that is currently not implemented. What falls to slow path
1660                 * stays there.
1661                 */
1662                return 0;
1663
1664        /* A change might make a tunnel not eligible for offloading. */
1665        if (!mlxsw_sp_netdevice_ipip_can_offload(mlxsw_sp, ol_dev,
1666                                                 ipip_entry->ipipt)) {
1667                mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);
1668                return 0;
1669        }
1670
1671        ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
1672        err = ipip_ops->ol_netdev_change(mlxsw_sp, ipip_entry, extack);
1673        return err;
1674}
1675
1676void mlxsw_sp_ipip_entry_demote_tunnel(struct mlxsw_sp *mlxsw_sp,
1677                                       struct mlxsw_sp_ipip_entry *ipip_entry)
1678{
1679        struct net_device *ol_dev = ipip_entry->ol_dev;
1680
1681        if (ol_dev->flags & IFF_UP)
1682                mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);
1683        mlxsw_sp_ipip_entry_destroy(mlxsw_sp, ipip_entry);
1684}
1685
1686/* The configuration where several tunnels have the same local address in the
1687 * same underlay table needs special treatment in the HW. That is currently not
1688 * implemented in the driver. This function finds and demotes the first tunnel
1689 * with a given source address, except the one passed in in the argument
1690 * `except'.
1691 */
1692bool
1693mlxsw_sp_ipip_demote_tunnel_by_saddr(struct mlxsw_sp *mlxsw_sp,
1694                                     enum mlxsw_sp_l3proto ul_proto,
1695                                     union mlxsw_sp_l3addr saddr,
1696                                     u32 ul_tb_id,
1697                                     const struct mlxsw_sp_ipip_entry *except)
1698{
1699        struct mlxsw_sp_ipip_entry *ipip_entry, *tmp;
1700
1701        list_for_each_entry_safe(ipip_entry, tmp, &mlxsw_sp->router->ipip_list,
1702                                 ipip_list_node) {
1703                if (ipip_entry != except &&
1704                    mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, saddr,
1705                                                      ul_tb_id, ipip_entry)) {
1706                        mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);
1707                        return true;
1708                }
1709        }
1710
1711        return false;
1712}
1713
1714static void mlxsw_sp_ipip_demote_tunnel_by_ul_netdev(struct mlxsw_sp *mlxsw_sp,
1715                                                     struct net_device *ul_dev)
1716{
1717        struct mlxsw_sp_ipip_entry *ipip_entry, *tmp;
1718
1719        list_for_each_entry_safe(ipip_entry, tmp, &mlxsw_sp->router->ipip_list,
1720                                 ipip_list_node) {
1721                struct net_device *ol_dev = ipip_entry->ol_dev;
1722                struct net_device *ipip_ul_dev;
1723
1724                rcu_read_lock();
1725                ipip_ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
1726                rcu_read_unlock();
1727                if (ipip_ul_dev == ul_dev)
1728                        mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);
1729        }
1730}
1731
1732int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp,
1733                                     struct net_device *ol_dev,
1734                                     unsigned long event,
1735                                     struct netdev_notifier_info *info)
1736{
1737        struct netdev_notifier_changeupper_info *chup;
1738        struct netlink_ext_ack *extack;
1739        int err = 0;
1740
1741        mutex_lock(&mlxsw_sp->router->lock);
1742        switch (event) {
1743        case NETDEV_REGISTER:
1744                err = mlxsw_sp_netdevice_ipip_ol_reg_event(mlxsw_sp, ol_dev);
1745                break;
1746        case NETDEV_UNREGISTER:
1747                mlxsw_sp_netdevice_ipip_ol_unreg_event(mlxsw_sp, ol_dev);
1748                break;
1749        case NETDEV_UP:
1750                mlxsw_sp_netdevice_ipip_ol_up_event(mlxsw_sp, ol_dev);
1751                break;
1752        case NETDEV_DOWN:
1753                mlxsw_sp_netdevice_ipip_ol_down_event(mlxsw_sp, ol_dev);
1754                break;
1755        case NETDEV_CHANGEUPPER:
1756                chup = container_of(info, typeof(*chup), info);
1757                extack = info->extack;
1758                if (netif_is_l3_master(chup->upper_dev))
1759                        err = mlxsw_sp_netdevice_ipip_ol_vrf_event(mlxsw_sp,
1760                                                                   ol_dev,
1761                                                                   extack);
1762                break;
1763        case NETDEV_CHANGE:
1764                extack = info->extack;
1765                err = mlxsw_sp_netdevice_ipip_ol_change_event(mlxsw_sp,
1766                                                              ol_dev, extack);
1767                break;
1768        case NETDEV_CHANGEMTU:
1769                err = mlxsw_sp_netdevice_ipip_ol_update_mtu(mlxsw_sp, ol_dev);
1770                break;
1771        }
1772        mutex_unlock(&mlxsw_sp->router->lock);
1773        return err;
1774}
1775
1776static int
1777__mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
1778                                   struct mlxsw_sp_ipip_entry *ipip_entry,
1779                                   struct net_device *ul_dev,
1780                                   bool *demote_this,
1781                                   unsigned long event,
1782                                   struct netdev_notifier_info *info)
1783{
1784        struct netdev_notifier_changeupper_info *chup;
1785        struct netlink_ext_ack *extack;
1786
1787        switch (event) {
1788        case NETDEV_CHANGEUPPER:
1789                chup = container_of(info, typeof(*chup), info);
1790                extack = info->extack;
1791                if (netif_is_l3_master(chup->upper_dev))
1792                        return mlxsw_sp_netdevice_ipip_ul_vrf_event(mlxsw_sp,
1793                                                                    ipip_entry,
1794                                                                    ul_dev,
1795                                                                    demote_this,
1796                                                                    extack);
1797                break;
1798
1799        case NETDEV_UP:
1800                return mlxsw_sp_netdevice_ipip_ul_up_event(mlxsw_sp, ipip_entry,
1801                                                           ul_dev);
1802        case NETDEV_DOWN:
1803                return mlxsw_sp_netdevice_ipip_ul_down_event(mlxsw_sp,
1804                                                             ipip_entry,
1805                                                             ul_dev);
1806        }
1807        return 0;
1808}
1809
1810int
1811mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
1812                                 struct net_device *ul_dev,
1813                                 unsigned long event,
1814                                 struct netdev_notifier_info *info)
1815{
1816        struct mlxsw_sp_ipip_entry *ipip_entry = NULL;
1817        int err = 0;
1818
1819        mutex_lock(&mlxsw_sp->router->lock);
1820        while ((ipip_entry = mlxsw_sp_ipip_entry_find_by_ul_dev(mlxsw_sp,
1821                                                                ul_dev,
1822                                                                ipip_entry))) {
1823                struct mlxsw_sp_ipip_entry *prev;
1824                bool demote_this = false;
1825
1826                err = __mlxsw_sp_netdevice_ipip_ul_event(mlxsw_sp, ipip_entry,
1827                                                         ul_dev, &demote_this,
1828                                                         event, info);
1829                if (err) {
1830                        mlxsw_sp_ipip_demote_tunnel_by_ul_netdev(mlxsw_sp,
1831                                                                 ul_dev);
1832                        break;
1833                }
1834
1835                if (demote_this) {
1836                        if (list_is_first(&ipip_entry->ipip_list_node,
1837                                          &mlxsw_sp->router->ipip_list))
1838                                prev = NULL;
1839                        else
1840                                /* This can't be cached from previous iteration,
1841                                 * because that entry could be gone now.
1842                                 */
1843                                prev = list_prev_entry(ipip_entry,
1844                                                       ipip_list_node);
1845                        mlxsw_sp_ipip_entry_demote_tunnel(mlxsw_sp, ipip_entry);
1846                        ipip_entry = prev;
1847                }
1848        }
1849        mutex_unlock(&mlxsw_sp->router->lock);
1850
1851        return err;
1852}
1853
1854int mlxsw_sp_router_nve_promote_decap(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
1855                                      enum mlxsw_sp_l3proto ul_proto,
1856                                      const union mlxsw_sp_l3addr *ul_sip,
1857                                      u32 tunnel_index)
1858{
1859        enum mlxsw_sp_fib_entry_type type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
1860        struct mlxsw_sp_router *router = mlxsw_sp->router;
1861        struct mlxsw_sp_fib_entry *fib_entry;
1862        int err = 0;
1863
1864        mutex_lock(&mlxsw_sp->router->lock);
1865
1866        if (WARN_ON_ONCE(router->nve_decap_config.valid)) {
1867                err = -EINVAL;
1868                goto out;
1869        }
1870
1871        router->nve_decap_config.ul_tb_id = ul_tb_id;
1872        router->nve_decap_config.tunnel_index = tunnel_index;
1873        router->nve_decap_config.ul_proto = ul_proto;
1874        router->nve_decap_config.ul_sip = *ul_sip;
1875        router->nve_decap_config.valid = true;
1876
1877        /* It is valid to create a tunnel with a local IP and only later
1878         * assign this IP address to a local interface
1879         */
1880        fib_entry = mlxsw_sp_router_ip2me_fib_entry_find(mlxsw_sp, ul_tb_id,
1881                                                         ul_proto, ul_sip,
1882                                                         type);
1883        if (!fib_entry)
1884                goto out;
1885
1886        fib_entry->decap.tunnel_index = tunnel_index;
1887        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP;
1888
1889        err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
1890        if (err)
1891                goto err_fib_entry_update;
1892
1893        goto out;
1894
1895err_fib_entry_update:
1896        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
1897        mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
1898out:
1899        mutex_unlock(&mlxsw_sp->router->lock);
1900        return err;
1901}
1902
1903void mlxsw_sp_router_nve_demote_decap(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
1904                                      enum mlxsw_sp_l3proto ul_proto,
1905                                      const union mlxsw_sp_l3addr *ul_sip)
1906{
1907        enum mlxsw_sp_fib_entry_type type = MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP;
1908        struct mlxsw_sp_router *router = mlxsw_sp->router;
1909        struct mlxsw_sp_fib_entry *fib_entry;
1910
1911        mutex_lock(&mlxsw_sp->router->lock);
1912
1913        if (WARN_ON_ONCE(!router->nve_decap_config.valid))
1914                goto out;
1915
1916        router->nve_decap_config.valid = false;
1917
1918        fib_entry = mlxsw_sp_router_ip2me_fib_entry_find(mlxsw_sp, ul_tb_id,
1919                                                         ul_proto, ul_sip,
1920                                                         type);
1921        if (!fib_entry)
1922                goto out;
1923
1924        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
1925        mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
1926out:
1927        mutex_unlock(&mlxsw_sp->router->lock);
1928}
1929
1930static bool mlxsw_sp_router_nve_is_decap(struct mlxsw_sp *mlxsw_sp,
1931                                         u32 ul_tb_id,
1932                                         enum mlxsw_sp_l3proto ul_proto,
1933                                         const union mlxsw_sp_l3addr *ul_sip)
1934{
1935        struct mlxsw_sp_router *router = mlxsw_sp->router;
1936
1937        return router->nve_decap_config.valid &&
1938               router->nve_decap_config.ul_tb_id == ul_tb_id &&
1939               router->nve_decap_config.ul_proto == ul_proto &&
1940               !memcmp(&router->nve_decap_config.ul_sip, ul_sip,
1941                       sizeof(*ul_sip));
1942}
1943
1944struct mlxsw_sp_neigh_key {
1945        struct neighbour *n;
1946};
1947
1948struct mlxsw_sp_neigh_entry {
1949        struct list_head rif_list_node;
1950        struct rhash_head ht_node;
1951        struct mlxsw_sp_neigh_key key;
1952        u16 rif;
1953        bool connected;
1954        unsigned char ha[ETH_ALEN];
1955        struct list_head nexthop_list; /* list of nexthops using
1956                                        * this neigh entry
1957                                        */
1958        struct list_head nexthop_neighs_list_node;
1959        unsigned int counter_index;
1960        bool counter_valid;
1961};
1962
1963static const struct rhashtable_params mlxsw_sp_neigh_ht_params = {
1964        .key_offset = offsetof(struct mlxsw_sp_neigh_entry, key),
1965        .head_offset = offsetof(struct mlxsw_sp_neigh_entry, ht_node),
1966        .key_len = sizeof(struct mlxsw_sp_neigh_key),
1967};
1968
1969struct mlxsw_sp_neigh_entry *
1970mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif,
1971                        struct mlxsw_sp_neigh_entry *neigh_entry)
1972{
1973        if (!neigh_entry) {
1974                if (list_empty(&rif->neigh_list))
1975                        return NULL;
1976                else
1977                        return list_first_entry(&rif->neigh_list,
1978                                                typeof(*neigh_entry),
1979                                                rif_list_node);
1980        }
1981        if (list_is_last(&neigh_entry->rif_list_node, &rif->neigh_list))
1982                return NULL;
1983        return list_next_entry(neigh_entry, rif_list_node);
1984}
1985
1986int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry)
1987{
1988        return neigh_entry->key.n->tbl->family;
1989}
1990
1991unsigned char *
1992mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry)
1993{
1994        return neigh_entry->ha;
1995}
1996
1997u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
1998{
1999        struct neighbour *n;
2000
2001        n = neigh_entry->key.n;
2002        return ntohl(*((__be32 *) n->primary_key));
2003}
2004
2005struct in6_addr *
2006mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry)
2007{
2008        struct neighbour *n;
2009
2010        n = neigh_entry->key.n;
2011        return (struct in6_addr *) &n->primary_key;
2012}
2013
2014int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp,
2015                               struct mlxsw_sp_neigh_entry *neigh_entry,
2016                               u64 *p_counter)
2017{
2018        if (!neigh_entry->counter_valid)
2019                return -EINVAL;
2020
2021        return mlxsw_sp_flow_counter_get(mlxsw_sp, neigh_entry->counter_index,
2022                                         p_counter, NULL);
2023}
2024
2025static struct mlxsw_sp_neigh_entry *
2026mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n,
2027                           u16 rif)
2028{
2029        struct mlxsw_sp_neigh_entry *neigh_entry;
2030
2031        neigh_entry = kzalloc(sizeof(*neigh_entry), GFP_KERNEL);
2032        if (!neigh_entry)
2033                return NULL;
2034
2035        neigh_entry->key.n = n;
2036        neigh_entry->rif = rif;
2037        INIT_LIST_HEAD(&neigh_entry->nexthop_list);
2038
2039        return neigh_entry;
2040}
2041
2042static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry)
2043{
2044        kfree(neigh_entry);
2045}
2046
2047static int
2048mlxsw_sp_neigh_entry_insert(struct mlxsw_sp *mlxsw_sp,
2049                            struct mlxsw_sp_neigh_entry *neigh_entry)
2050{
2051        return rhashtable_insert_fast(&mlxsw_sp->router->neigh_ht,
2052                                      &neigh_entry->ht_node,
2053                                      mlxsw_sp_neigh_ht_params);
2054}
2055
2056static void
2057mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp,
2058                            struct mlxsw_sp_neigh_entry *neigh_entry)
2059{
2060        rhashtable_remove_fast(&mlxsw_sp->router->neigh_ht,
2061                               &neigh_entry->ht_node,
2062                               mlxsw_sp_neigh_ht_params);
2063}
2064
2065static bool
2066mlxsw_sp_neigh_counter_should_alloc(struct mlxsw_sp *mlxsw_sp,
2067                                    struct mlxsw_sp_neigh_entry *neigh_entry)
2068{
2069        struct devlink *devlink;
2070        const char *table_name;
2071
2072        switch (mlxsw_sp_neigh_entry_type(neigh_entry)) {
2073        case AF_INET:
2074                table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST4;
2075                break;
2076        case AF_INET6:
2077                table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST6;
2078                break;
2079        default:
2080                WARN_ON(1);
2081                return false;
2082        }
2083
2084        devlink = priv_to_devlink(mlxsw_sp->core);
2085        return devlink_dpipe_table_counter_enabled(devlink, table_name);
2086}
2087
2088static void
2089mlxsw_sp_neigh_counter_alloc(struct mlxsw_sp *mlxsw_sp,
2090                             struct mlxsw_sp_neigh_entry *neigh_entry)
2091{
2092        if (!mlxsw_sp_neigh_counter_should_alloc(mlxsw_sp, neigh_entry))
2093                return;
2094
2095        if (mlxsw_sp_flow_counter_alloc(mlxsw_sp, &neigh_entry->counter_index))
2096                return;
2097
2098        neigh_entry->counter_valid = true;
2099}
2100
2101static void
2102mlxsw_sp_neigh_counter_free(struct mlxsw_sp *mlxsw_sp,
2103                            struct mlxsw_sp_neigh_entry *neigh_entry)
2104{
2105        if (!neigh_entry->counter_valid)
2106                return;
2107        mlxsw_sp_flow_counter_free(mlxsw_sp,
2108                                   neigh_entry->counter_index);
2109        neigh_entry->counter_valid = false;
2110}
2111
2112static struct mlxsw_sp_neigh_entry *
2113mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
2114{
2115        struct mlxsw_sp_neigh_entry *neigh_entry;
2116        struct mlxsw_sp_rif *rif;
2117        int err;
2118
2119        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, n->dev);
2120        if (!rif)
2121                return ERR_PTR(-EINVAL);
2122
2123        neigh_entry = mlxsw_sp_neigh_entry_alloc(mlxsw_sp, n, rif->rif_index);
2124        if (!neigh_entry)
2125                return ERR_PTR(-ENOMEM);
2126
2127        err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
2128        if (err)
2129                goto err_neigh_entry_insert;
2130
2131        mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry);
2132        list_add(&neigh_entry->rif_list_node, &rif->neigh_list);
2133
2134        return neigh_entry;
2135
2136err_neigh_entry_insert:
2137        mlxsw_sp_neigh_entry_free(neigh_entry);
2138        return ERR_PTR(err);
2139}
2140
2141static void
2142mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp,
2143                             struct mlxsw_sp_neigh_entry *neigh_entry)
2144{
2145        list_del(&neigh_entry->rif_list_node);
2146        mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry);
2147        mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
2148        mlxsw_sp_neigh_entry_free(neigh_entry);
2149}
2150
2151static struct mlxsw_sp_neigh_entry *
2152mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
2153{
2154        struct mlxsw_sp_neigh_key key;
2155
2156        key.n = n;
2157        return rhashtable_lookup_fast(&mlxsw_sp->router->neigh_ht,
2158                                      &key, mlxsw_sp_neigh_ht_params);
2159}
2160
2161static void
2162mlxsw_sp_router_neighs_update_interval_init(struct mlxsw_sp *mlxsw_sp)
2163{
2164        unsigned long interval;
2165
2166#if IS_ENABLED(CONFIG_IPV6)
2167        interval = min_t(unsigned long,
2168                         NEIGH_VAR(&arp_tbl.parms, DELAY_PROBE_TIME),
2169                         NEIGH_VAR(&nd_tbl.parms, DELAY_PROBE_TIME));
2170#else
2171        interval = NEIGH_VAR(&arp_tbl.parms, DELAY_PROBE_TIME);
2172#endif
2173        mlxsw_sp->router->neighs_update.interval = jiffies_to_msecs(interval);
2174}
2175
2176static void mlxsw_sp_router_neigh_ent_ipv4_process(struct mlxsw_sp *mlxsw_sp,
2177                                                   char *rauhtd_pl,
2178                                                   int ent_index)
2179{
2180        struct net_device *dev;
2181        struct neighbour *n;
2182        __be32 dipn;
2183        u32 dip;
2184        u16 rif;
2185
2186        mlxsw_reg_rauhtd_ent_ipv4_unpack(rauhtd_pl, ent_index, &rif, &dip);
2187
2188        if (!mlxsw_sp->router->rifs[rif]) {
2189                dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect RIF in neighbour entry\n");
2190                return;
2191        }
2192
2193        dipn = htonl(dip);
2194        dev = mlxsw_sp->router->rifs[rif]->dev;
2195        n = neigh_lookup(&arp_tbl, &dipn, dev);
2196        if (!n)
2197                return;
2198
2199        netdev_dbg(dev, "Updating neighbour with IP=%pI4h\n", &dip);
2200        neigh_event_send(n, NULL);
2201        neigh_release(n);
2202}
2203
2204#if IS_ENABLED(CONFIG_IPV6)
2205static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp,
2206                                                   char *rauhtd_pl,
2207                                                   int rec_index)
2208{
2209        struct net_device *dev;
2210        struct neighbour *n;
2211        struct in6_addr dip;
2212        u16 rif;
2213
2214        mlxsw_reg_rauhtd_ent_ipv6_unpack(rauhtd_pl, rec_index, &rif,
2215                                         (char *) &dip);
2216
2217        if (!mlxsw_sp->router->rifs[rif]) {
2218                dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect RIF in neighbour entry\n");
2219                return;
2220        }
2221
2222        dev = mlxsw_sp->router->rifs[rif]->dev;
2223        n = neigh_lookup(&nd_tbl, &dip, dev);
2224        if (!n)
2225                return;
2226
2227        netdev_dbg(dev, "Updating neighbour with IP=%pI6c\n", &dip);
2228        neigh_event_send(n, NULL);
2229        neigh_release(n);
2230}
2231#else
2232static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp,
2233                                                   char *rauhtd_pl,
2234                                                   int rec_index)
2235{
2236}
2237#endif
2238
2239static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp,
2240                                                   char *rauhtd_pl,
2241                                                   int rec_index)
2242{
2243        u8 num_entries;
2244        int i;
2245
2246        num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl,
2247                                                                rec_index);
2248        /* Hardware starts counting at 0, so add 1. */
2249        num_entries++;
2250
2251        /* Each record consists of several neighbour entries. */
2252        for (i = 0; i < num_entries; i++) {
2253                int ent_index;
2254
2255                ent_index = rec_index * MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC + i;
2256                mlxsw_sp_router_neigh_ent_ipv4_process(mlxsw_sp, rauhtd_pl,
2257                                                       ent_index);
2258        }
2259
2260}
2261
2262static void mlxsw_sp_router_neigh_rec_ipv6_process(struct mlxsw_sp *mlxsw_sp,
2263                                                   char *rauhtd_pl,
2264                                                   int rec_index)
2265{
2266        /* One record contains one entry. */
2267        mlxsw_sp_router_neigh_ent_ipv6_process(mlxsw_sp, rauhtd_pl,
2268                                               rec_index);
2269}
2270
2271static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
2272                                              char *rauhtd_pl, int rec_index)
2273{
2274        switch (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, rec_index)) {
2275        case MLXSW_REG_RAUHTD_TYPE_IPV4:
2276                mlxsw_sp_router_neigh_rec_ipv4_process(mlxsw_sp, rauhtd_pl,
2277                                                       rec_index);
2278                break;
2279        case MLXSW_REG_RAUHTD_TYPE_IPV6:
2280                mlxsw_sp_router_neigh_rec_ipv6_process(mlxsw_sp, rauhtd_pl,
2281                                                       rec_index);
2282                break;
2283        }
2284}
2285
2286static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
2287{
2288        u8 num_rec, last_rec_index, num_entries;
2289
2290        num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl);
2291        last_rec_index = num_rec - 1;
2292
2293        if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM)
2294                return false;
2295        if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) ==
2296            MLXSW_REG_RAUHTD_TYPE_IPV6)
2297                return true;
2298
2299        num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl,
2300                                                                last_rec_index);
2301        if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC)
2302                return true;
2303        return false;
2304}
2305
2306static int
2307__mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp,
2308                                       char *rauhtd_pl,
2309                                       enum mlxsw_reg_rauhtd_type type)
2310{
2311        int i, num_rec;
2312        int err;
2313
2314        /* Ensure the RIF we read from the device does not change mid-dump. */
2315        mutex_lock(&mlxsw_sp->router->lock);
2316        do {
2317                mlxsw_reg_rauhtd_pack(rauhtd_pl, type);
2318                err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(rauhtd),
2319                                      rauhtd_pl);
2320                if (err) {
2321                        dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to dump neighbour table\n");
2322                        break;
2323                }
2324                num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl);
2325                for (i = 0; i < num_rec; i++)
2326                        mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl,
2327                                                          i);
2328        } while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
2329        mutex_unlock(&mlxsw_sp->router->lock);
2330
2331        return err;
2332}
2333
2334static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
2335{
2336        enum mlxsw_reg_rauhtd_type type;
2337        char *rauhtd_pl;
2338        int err;
2339
2340        rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL);
2341        if (!rauhtd_pl)
2342                return -ENOMEM;
2343
2344        type = MLXSW_REG_RAUHTD_TYPE_IPV4;
2345        err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type);
2346        if (err)
2347                goto out;
2348
2349        type = MLXSW_REG_RAUHTD_TYPE_IPV6;
2350        err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type);
2351out:
2352        kfree(rauhtd_pl);
2353        return err;
2354}
2355
2356static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp)
2357{
2358        struct mlxsw_sp_neigh_entry *neigh_entry;
2359
2360        mutex_lock(&mlxsw_sp->router->lock);
2361        list_for_each_entry(neigh_entry, &mlxsw_sp->router->nexthop_neighs_list,
2362                            nexthop_neighs_list_node)
2363                /* If this neigh have nexthops, make the kernel think this neigh
2364                 * is active regardless of the traffic.
2365                 */
2366                neigh_event_send(neigh_entry->key.n, NULL);
2367        mutex_unlock(&mlxsw_sp->router->lock);
2368}
2369
2370static void
2371mlxsw_sp_router_neighs_update_work_schedule(struct mlxsw_sp *mlxsw_sp)
2372{
2373        unsigned long interval = mlxsw_sp->router->neighs_update.interval;
2374
2375        mlxsw_core_schedule_dw(&mlxsw_sp->router->neighs_update.dw,
2376                               msecs_to_jiffies(interval));
2377}
2378
2379static void mlxsw_sp_router_neighs_update_work(struct work_struct *work)
2380{
2381        struct mlxsw_sp_router *router;
2382        int err;
2383
2384        router = container_of(work, struct mlxsw_sp_router,
2385                              neighs_update.dw.work);
2386        err = mlxsw_sp_router_neighs_update_rauhtd(router->mlxsw_sp);
2387        if (err)
2388                dev_err(router->mlxsw_sp->bus_info->dev, "Could not update kernel for neigh activity");
2389
2390        mlxsw_sp_router_neighs_update_nh(router->mlxsw_sp);
2391
2392        mlxsw_sp_router_neighs_update_work_schedule(router->mlxsw_sp);
2393}
2394
2395static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work)
2396{
2397        struct mlxsw_sp_neigh_entry *neigh_entry;
2398        struct mlxsw_sp_router *router;
2399
2400        router = container_of(work, struct mlxsw_sp_router,
2401                              nexthop_probe_dw.work);
2402        /* Iterate over nexthop neighbours, find those who are unresolved and
2403         * send arp on them. This solves the chicken-egg problem when
2404         * the nexthop wouldn't get offloaded until the neighbor is resolved
2405         * but it wouldn't get resolved ever in case traffic is flowing in HW
2406         * using different nexthop.
2407         */
2408        mutex_lock(&router->lock);
2409        list_for_each_entry(neigh_entry, &router->nexthop_neighs_list,
2410                            nexthop_neighs_list_node)
2411                if (!neigh_entry->connected)
2412                        neigh_event_send(neigh_entry->key.n, NULL);
2413        mutex_unlock(&router->lock);
2414
2415        mlxsw_core_schedule_dw(&router->nexthop_probe_dw,
2416                               MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL);
2417}
2418
2419static void
2420mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
2421                              struct mlxsw_sp_neigh_entry *neigh_entry,
2422                              bool removing, bool dead);
2423
2424static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding)
2425{
2426        return adding ? MLXSW_REG_RAUHT_OP_WRITE_ADD :
2427                        MLXSW_REG_RAUHT_OP_WRITE_DELETE;
2428}
2429
2430static int
2431mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp,
2432                                struct mlxsw_sp_neigh_entry *neigh_entry,
2433                                enum mlxsw_reg_rauht_op op)
2434{
2435        struct neighbour *n = neigh_entry->key.n;
2436        u32 dip = ntohl(*((__be32 *) n->primary_key));
2437        char rauht_pl[MLXSW_REG_RAUHT_LEN];
2438
2439        mlxsw_reg_rauht_pack4(rauht_pl, op, neigh_entry->rif, neigh_entry->ha,
2440                              dip);
2441        if (neigh_entry->counter_valid)
2442                mlxsw_reg_rauht_pack_counter(rauht_pl,
2443                                             neigh_entry->counter_index);
2444        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
2445}
2446
2447static int
2448mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp,
2449                                struct mlxsw_sp_neigh_entry *neigh_entry,
2450                                enum mlxsw_reg_rauht_op op)
2451{
2452        struct neighbour *n = neigh_entry->key.n;
2453        char rauht_pl[MLXSW_REG_RAUHT_LEN];
2454        const char *dip = n->primary_key;
2455
2456        mlxsw_reg_rauht_pack6(rauht_pl, op, neigh_entry->rif, neigh_entry->ha,
2457                              dip);
2458        if (neigh_entry->counter_valid)
2459                mlxsw_reg_rauht_pack_counter(rauht_pl,
2460                                             neigh_entry->counter_index);
2461        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl);
2462}
2463
2464bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry)
2465{
2466        struct neighbour *n = neigh_entry->key.n;
2467
2468        /* Packets with a link-local destination address are trapped
2469         * after LPM lookup and never reach the neighbour table, so
2470         * there is no need to program such neighbours to the device.
2471         */
2472        if (ipv6_addr_type((struct in6_addr *) &n->primary_key) &
2473            IPV6_ADDR_LINKLOCAL)
2474                return true;
2475        return false;
2476}
2477
2478static void
2479mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp,
2480                            struct mlxsw_sp_neigh_entry *neigh_entry,
2481                            bool adding)
2482{
2483        enum mlxsw_reg_rauht_op op = mlxsw_sp_rauht_op(adding);
2484        int err;
2485
2486        if (!adding && !neigh_entry->connected)
2487                return;
2488        neigh_entry->connected = adding;
2489        if (neigh_entry->key.n->tbl->family == AF_INET) {
2490                err = mlxsw_sp_router_neigh_entry_op4(mlxsw_sp, neigh_entry,
2491                                                      op);
2492                if (err)
2493                        return;
2494        } else if (neigh_entry->key.n->tbl->family == AF_INET6) {
2495                if (mlxsw_sp_neigh_ipv6_ignore(neigh_entry))
2496                        return;
2497                err = mlxsw_sp_router_neigh_entry_op6(mlxsw_sp, neigh_entry,
2498                                                      op);
2499                if (err)
2500                        return;
2501        } else {
2502                WARN_ON_ONCE(1);
2503                return;
2504        }
2505
2506        if (adding)
2507                neigh_entry->key.n->flags |= NTF_OFFLOADED;
2508        else
2509                neigh_entry->key.n->flags &= ~NTF_OFFLOADED;
2510}
2511
2512void
2513mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
2514                                    struct mlxsw_sp_neigh_entry *neigh_entry,
2515                                    bool adding)
2516{
2517        if (adding)
2518                mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry);
2519        else
2520                mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry);
2521        mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, true);
2522}
2523
2524struct mlxsw_sp_netevent_work {
2525        struct work_struct work;
2526        struct mlxsw_sp *mlxsw_sp;
2527        struct neighbour *n;
2528};
2529
2530static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
2531{
2532        struct mlxsw_sp_netevent_work *net_work =
2533                container_of(work, struct mlxsw_sp_netevent_work, work);
2534        struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
2535        struct mlxsw_sp_neigh_entry *neigh_entry;
2536        struct neighbour *n = net_work->n;
2537        unsigned char ha[ETH_ALEN];
2538        bool entry_connected;
2539        u8 nud_state, dead;
2540
2541        /* If these parameters are changed after we release the lock,
2542         * then we are guaranteed to receive another event letting us
2543         * know about it.
2544         */
2545        read_lock_bh(&n->lock);
2546        memcpy(ha, n->ha, ETH_ALEN);
2547        nud_state = n->nud_state;
2548        dead = n->dead;
2549        read_unlock_bh(&n->lock);
2550
2551        mutex_lock(&mlxsw_sp->router->lock);
2552        mlxsw_sp_span_respin(mlxsw_sp);
2553
2554        entry_connected = nud_state & NUD_VALID && !dead;
2555        neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
2556        if (!entry_connected && !neigh_entry)
2557                goto out;
2558        if (!neigh_entry) {
2559                neigh_entry = mlxsw_sp_neigh_entry_create(mlxsw_sp, n);
2560                if (IS_ERR(neigh_entry))
2561                        goto out;
2562        }
2563
2564        memcpy(neigh_entry->ha, ha, ETH_ALEN);
2565        mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected);
2566        mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected,
2567                                      dead);
2568
2569        if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
2570                mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
2571
2572out:
2573        mutex_unlock(&mlxsw_sp->router->lock);
2574        neigh_release(n);
2575        kfree(net_work);
2576}
2577
2578static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp);
2579
2580static void mlxsw_sp_router_mp_hash_event_work(struct work_struct *work)
2581{
2582        struct mlxsw_sp_netevent_work *net_work =
2583                container_of(work, struct mlxsw_sp_netevent_work, work);
2584        struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
2585
2586        mlxsw_sp_mp_hash_init(mlxsw_sp);
2587        kfree(net_work);
2588}
2589
2590static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp);
2591
2592static void mlxsw_sp_router_update_priority_work(struct work_struct *work)
2593{
2594        struct mlxsw_sp_netevent_work *net_work =
2595                container_of(work, struct mlxsw_sp_netevent_work, work);
2596        struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
2597
2598        __mlxsw_sp_router_init(mlxsw_sp);
2599        kfree(net_work);
2600}
2601
2602static int mlxsw_sp_router_schedule_work(struct net *net,
2603                                         struct notifier_block *nb,
2604                                         void (*cb)(struct work_struct *))
2605{
2606        struct mlxsw_sp_netevent_work *net_work;
2607        struct mlxsw_sp_router *router;
2608
2609        router = container_of(nb, struct mlxsw_sp_router, netevent_nb);
2610        if (!net_eq(net, mlxsw_sp_net(router->mlxsw_sp)))
2611                return NOTIFY_DONE;
2612
2613        net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
2614        if (!net_work)
2615                return NOTIFY_BAD;
2616
2617        INIT_WORK(&net_work->work, cb);
2618        net_work->mlxsw_sp = router->mlxsw_sp;
2619        mlxsw_core_schedule_work(&net_work->work);
2620        return NOTIFY_DONE;
2621}
2622
2623static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
2624                                          unsigned long event, void *ptr)
2625{
2626        struct mlxsw_sp_netevent_work *net_work;
2627        struct mlxsw_sp_port *mlxsw_sp_port;
2628        struct mlxsw_sp *mlxsw_sp;
2629        unsigned long interval;
2630        struct neigh_parms *p;
2631        struct neighbour *n;
2632
2633        switch (event) {
2634        case NETEVENT_DELAY_PROBE_TIME_UPDATE:
2635                p = ptr;
2636
2637                /* We don't care about changes in the default table. */
2638                if (!p->dev || (p->tbl->family != AF_INET &&
2639                                p->tbl->family != AF_INET6))
2640                        return NOTIFY_DONE;
2641
2642                /* We are in atomic context and can't take RTNL mutex,
2643                 * so use RCU variant to walk the device chain.
2644                 */
2645                mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(p->dev);
2646                if (!mlxsw_sp_port)
2647                        return NOTIFY_DONE;
2648
2649                mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2650                interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME));
2651                mlxsw_sp->router->neighs_update.interval = interval;
2652
2653                mlxsw_sp_port_dev_put(mlxsw_sp_port);
2654                break;
2655        case NETEVENT_NEIGH_UPDATE:
2656                n = ptr;
2657
2658                if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6)
2659                        return NOTIFY_DONE;
2660
2661                mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(n->dev);
2662                if (!mlxsw_sp_port)
2663                        return NOTIFY_DONE;
2664
2665                net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
2666                if (!net_work) {
2667                        mlxsw_sp_port_dev_put(mlxsw_sp_port);
2668                        return NOTIFY_BAD;
2669                }
2670
2671                INIT_WORK(&net_work->work, mlxsw_sp_router_neigh_event_work);
2672                net_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2673                net_work->n = n;
2674
2675                /* Take a reference to ensure the neighbour won't be
2676                 * destructed until we drop the reference in delayed
2677                 * work.
2678                 */
2679                neigh_clone(n);
2680                mlxsw_core_schedule_work(&net_work->work);
2681                mlxsw_sp_port_dev_put(mlxsw_sp_port);
2682                break;
2683        case NETEVENT_IPV4_MPATH_HASH_UPDATE:
2684        case NETEVENT_IPV6_MPATH_HASH_UPDATE:
2685                return mlxsw_sp_router_schedule_work(ptr, nb,
2686                                mlxsw_sp_router_mp_hash_event_work);
2687
2688        case NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE:
2689                return mlxsw_sp_router_schedule_work(ptr, nb,
2690                                mlxsw_sp_router_update_priority_work);
2691        }
2692
2693        return NOTIFY_DONE;
2694}
2695
2696static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp)
2697{
2698        int err;
2699
2700        err = rhashtable_init(&mlxsw_sp->router->neigh_ht,
2701                              &mlxsw_sp_neigh_ht_params);
2702        if (err)
2703                return err;
2704
2705        /* Initialize the polling interval according to the default
2706         * table.
2707         */
2708        mlxsw_sp_router_neighs_update_interval_init(mlxsw_sp);
2709
2710        /* Create the delayed works for the activity_update */
2711        INIT_DELAYED_WORK(&mlxsw_sp->router->neighs_update.dw,
2712                          mlxsw_sp_router_neighs_update_work);
2713        INIT_DELAYED_WORK(&mlxsw_sp->router->nexthop_probe_dw,
2714                          mlxsw_sp_router_probe_unresolved_nexthops);
2715        mlxsw_core_schedule_dw(&mlxsw_sp->router->neighs_update.dw, 0);
2716        mlxsw_core_schedule_dw(&mlxsw_sp->router->nexthop_probe_dw, 0);
2717        return 0;
2718}
2719
2720static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp)
2721{
2722        cancel_delayed_work_sync(&mlxsw_sp->router->neighs_update.dw);
2723        cancel_delayed_work_sync(&mlxsw_sp->router->nexthop_probe_dw);
2724        rhashtable_destroy(&mlxsw_sp->router->neigh_ht);
2725}
2726
2727static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
2728                                         struct mlxsw_sp_rif *rif)
2729{
2730        struct mlxsw_sp_neigh_entry *neigh_entry, *tmp;
2731
2732        list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list,
2733                                 rif_list_node) {
2734                mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, false);
2735                mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
2736        }
2737}
2738
2739enum mlxsw_sp_nexthop_type {
2740        MLXSW_SP_NEXTHOP_TYPE_ETH,
2741        MLXSW_SP_NEXTHOP_TYPE_IPIP,
2742};
2743
2744struct mlxsw_sp_nexthop_key {
2745        struct fib_nh *fib_nh;
2746};
2747
2748struct mlxsw_sp_nexthop {
2749        struct list_head neigh_list_node; /* member of neigh entry list */
2750        struct list_head rif_list_node;
2751        struct list_head router_list_node;
2752        struct mlxsw_sp_nexthop_group *nh_grp; /* pointer back to the group
2753                                                * this belongs to
2754                                                */
2755        struct rhash_head ht_node;
2756        struct mlxsw_sp_nexthop_key key;
2757        unsigned char gw_addr[sizeof(struct in6_addr)];
2758        int ifindex;
2759        int nh_weight;
2760        int norm_nh_weight;
2761        int num_adj_entries;
2762        struct mlxsw_sp_rif *rif;
2763        u8 should_offload:1, /* set indicates this neigh is connected and
2764                              * should be put to KVD linear area of this group.
2765                              */
2766           offloaded:1, /* set in case the neigh is actually put into
2767                         * KVD linear area of this group.
2768                         */
2769           update:1; /* set indicates that MAC of this neigh should be
2770                      * updated in HW
2771                      */
2772        enum mlxsw_sp_nexthop_type type;
2773        union {
2774                struct mlxsw_sp_neigh_entry *neigh_entry;
2775                struct mlxsw_sp_ipip_entry *ipip_entry;
2776        };
2777        unsigned int counter_index;
2778        bool counter_valid;
2779};
2780
2781struct mlxsw_sp_nexthop_group {
2782        void *priv;
2783        struct rhash_head ht_node;
2784        struct list_head fib_list; /* list of fib entries that use this group */
2785        struct neigh_table *neigh_tbl;
2786        u8 adj_index_valid:1,
2787           gateway:1; /* routes using the group use a gateway */
2788        u32 adj_index;
2789        u16 ecmp_size;
2790        u16 count;
2791        int sum_norm_weight;
2792        struct mlxsw_sp_nexthop nexthops[0];
2793#define nh_rif  nexthops[0].rif
2794};
2795
2796void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp,
2797                                    struct mlxsw_sp_nexthop *nh)
2798{
2799        struct devlink *devlink;
2800
2801        devlink = priv_to_devlink(mlxsw_sp->core);
2802        if (!devlink_dpipe_table_counter_enabled(devlink,
2803                                                 MLXSW_SP_DPIPE_TABLE_NAME_ADJ))
2804                return;
2805
2806        if (mlxsw_sp_flow_counter_alloc(mlxsw_sp, &nh->counter_index))
2807                return;
2808
2809        nh->counter_valid = true;
2810}
2811
2812void mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
2813                                   struct mlxsw_sp_nexthop *nh)
2814{
2815        if (!nh->counter_valid)
2816                return;
2817        mlxsw_sp_flow_counter_free(mlxsw_sp, nh->counter_index);
2818        nh->counter_valid = false;
2819}
2820
2821int mlxsw_sp_nexthop_counter_get(struct mlxsw_sp *mlxsw_sp,
2822                                 struct mlxsw_sp_nexthop *nh, u64 *p_counter)
2823{
2824        if (!nh->counter_valid)
2825                return -EINVAL;
2826
2827        return mlxsw_sp_flow_counter_get(mlxsw_sp, nh->counter_index,
2828                                         p_counter, NULL);
2829}
2830
2831struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
2832                                               struct mlxsw_sp_nexthop *nh)
2833{
2834        if (!nh) {
2835                if (list_empty(&router->nexthop_list))
2836                        return NULL;
2837                else
2838                        return list_first_entry(&router->nexthop_list,
2839                                                typeof(*nh), router_list_node);
2840        }
2841        if (list_is_last(&nh->router_list_node, &router->nexthop_list))
2842                return NULL;
2843        return list_next_entry(nh, router_list_node);
2844}
2845
2846bool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh)
2847{
2848        return nh->offloaded;
2849}
2850
2851unsigned char *mlxsw_sp_nexthop_ha(struct mlxsw_sp_nexthop *nh)
2852{
2853        if (!nh->offloaded)
2854                return NULL;
2855        return nh->neigh_entry->ha;
2856}
2857
2858int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index,
2859                             u32 *p_adj_size, u32 *p_adj_hash_index)
2860{
2861        struct mlxsw_sp_nexthop_group *nh_grp = nh->nh_grp;
2862        u32 adj_hash_index = 0;
2863        int i;
2864
2865        if (!nh->offloaded || !nh_grp->adj_index_valid)
2866                return -EINVAL;
2867
2868        *p_adj_index = nh_grp->adj_index;
2869        *p_adj_size = nh_grp->ecmp_size;
2870
2871        for (i = 0; i < nh_grp->count; i++) {
2872                struct mlxsw_sp_nexthop *nh_iter = &nh_grp->nexthops[i];
2873
2874                if (nh_iter == nh)
2875                        break;
2876                if (nh_iter->offloaded)
2877                        adj_hash_index += nh_iter->num_adj_entries;
2878        }
2879
2880        *p_adj_hash_index = adj_hash_index;
2881        return 0;
2882}
2883
2884struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh)
2885{
2886        return nh->rif;
2887}
2888
2889bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)
2890{
2891        struct mlxsw_sp_nexthop_group *nh_grp = nh->nh_grp;
2892        int i;
2893
2894        for (i = 0; i < nh_grp->count; i++) {
2895                struct mlxsw_sp_nexthop *nh_iter = &nh_grp->nexthops[i];
2896
2897                if (nh_iter->type == MLXSW_SP_NEXTHOP_TYPE_IPIP)
2898                        return true;
2899        }
2900        return false;
2901}
2902
2903static struct fib_info *
2904mlxsw_sp_nexthop4_group_fi(const struct mlxsw_sp_nexthop_group *nh_grp)
2905{
2906        return nh_grp->priv;
2907}
2908
2909struct mlxsw_sp_nexthop_group_cmp_arg {
2910        enum mlxsw_sp_l3proto proto;
2911        union {
2912                struct fib_info *fi;
2913                struct mlxsw_sp_fib6_entry *fib6_entry;
2914        };
2915};
2916
2917static bool
2918mlxsw_sp_nexthop6_group_has_nexthop(const struct mlxsw_sp_nexthop_group *nh_grp,
2919                                    const struct in6_addr *gw, int ifindex,
2920                                    int weight)
2921{
2922        int i;
2923
2924        for (i = 0; i < nh_grp->count; i++) {
2925                const struct mlxsw_sp_nexthop *nh;
2926
2927                nh = &nh_grp->nexthops[i];
2928                if (nh->ifindex == ifindex && nh->nh_weight == weight &&
2929                    ipv6_addr_equal(gw, (struct in6_addr *) nh->gw_addr))
2930                        return true;
2931        }
2932
2933        return false;
2934}
2935
2936static bool
2937mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp,
2938                            const struct mlxsw_sp_fib6_entry *fib6_entry)
2939{
2940        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
2941
2942        if (nh_grp->count != fib6_entry->nrt6)
2943                return false;
2944
2945        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
2946                struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh;
2947                struct in6_addr *gw;
2948                int ifindex, weight;
2949
2950                ifindex = fib6_nh->fib_nh_dev->ifindex;
2951                weight = fib6_nh->fib_nh_weight;
2952                gw = &fib6_nh->fib_nh_gw6;
2953                if (!mlxsw_sp_nexthop6_group_has_nexthop(nh_grp, gw, ifindex,
2954                                                         weight))
2955                        return false;
2956        }
2957
2958        return true;
2959}
2960
2961static int
2962mlxsw_sp_nexthop_group_cmp(struct rhashtable_compare_arg *arg, const void *ptr)
2963{
2964        const struct mlxsw_sp_nexthop_group_cmp_arg *cmp_arg = arg->key;
2965        const struct mlxsw_sp_nexthop_group *nh_grp = ptr;
2966
2967        switch (cmp_arg->proto) {
2968        case MLXSW_SP_L3_PROTO_IPV4:
2969                return cmp_arg->fi != mlxsw_sp_nexthop4_group_fi(nh_grp);
2970        case MLXSW_SP_L3_PROTO_IPV6:
2971                return !mlxsw_sp_nexthop6_group_cmp(nh_grp,
2972                                                    cmp_arg->fib6_entry);
2973        default:
2974                WARN_ON(1);
2975                return 1;
2976        }
2977}
2978
2979static int
2980mlxsw_sp_nexthop_group_type(const struct mlxsw_sp_nexthop_group *nh_grp)
2981{
2982        return nh_grp->neigh_tbl->family;
2983}
2984
2985static u32 mlxsw_sp_nexthop_group_hash_obj(const void *data, u32 len, u32 seed)
2986{
2987        const struct mlxsw_sp_nexthop_group *nh_grp = data;
2988        const struct mlxsw_sp_nexthop *nh;
2989        struct fib_info *fi;
2990        unsigned int val;
2991        int i;
2992
2993        switch (mlxsw_sp_nexthop_group_type(nh_grp)) {
2994        case AF_INET:
2995                fi = mlxsw_sp_nexthop4_group_fi(nh_grp);
2996                return jhash(&fi, sizeof(fi), seed);
2997        case AF_INET6:
2998                val = nh_grp->count;
2999                for (i = 0; i < nh_grp->count; i++) {
3000                        nh = &nh_grp->nexthops[i];
3001                        val ^= jhash(&nh->ifindex, sizeof(nh->ifindex), seed);
3002                }
3003                return jhash(&val, sizeof(val), seed);
3004        default:
3005                WARN_ON(1);
3006                return 0;
3007        }
3008}
3009
3010static u32
3011mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed)
3012{
3013        unsigned int val = fib6_entry->nrt6;
3014        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
3015        struct net_device *dev;
3016
3017        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
3018                dev = mlxsw_sp_rt6->rt->fib6_nh->fib_nh_dev;
3019                val ^= jhash(&dev->ifindex, sizeof(dev->ifindex), seed);
3020        }
3021
3022        return jhash(&val, sizeof(val), seed);
3023}
3024
3025static u32
3026mlxsw_sp_nexthop_group_hash(const void *data, u32 len, u32 seed)
3027{
3028        const struct mlxsw_sp_nexthop_group_cmp_arg *cmp_arg = data;
3029
3030        switch (cmp_arg->proto) {
3031        case MLXSW_SP_L3_PROTO_IPV4:
3032                return jhash(&cmp_arg->fi, sizeof(cmp_arg->fi), seed);
3033        case MLXSW_SP_L3_PROTO_IPV6:
3034                return mlxsw_sp_nexthop6_group_hash(cmp_arg->fib6_entry, seed);
3035        default:
3036                WARN_ON(1);
3037                return 0;
3038        }
3039}
3040
3041static const struct rhashtable_params mlxsw_sp_nexthop_group_ht_params = {
3042        .head_offset = offsetof(struct mlxsw_sp_nexthop_group, ht_node),
3043        .hashfn      = mlxsw_sp_nexthop_group_hash,
3044        .obj_hashfn  = mlxsw_sp_nexthop_group_hash_obj,
3045        .obj_cmpfn   = mlxsw_sp_nexthop_group_cmp,
3046};
3047
3048static int mlxsw_sp_nexthop_group_insert(struct mlxsw_sp *mlxsw_sp,
3049                                         struct mlxsw_sp_nexthop_group *nh_grp)
3050{
3051        if (mlxsw_sp_nexthop_group_type(nh_grp) == AF_INET6 &&
3052            !nh_grp->gateway)
3053                return 0;
3054
3055        return rhashtable_insert_fast(&mlxsw_sp->router->nexthop_group_ht,
3056                                      &nh_grp->ht_node,
3057                                      mlxsw_sp_nexthop_group_ht_params);
3058}
3059
3060static void mlxsw_sp_nexthop_group_remove(struct mlxsw_sp *mlxsw_sp,
3061                                          struct mlxsw_sp_nexthop_group *nh_grp)
3062{
3063        if (mlxsw_sp_nexthop_group_type(nh_grp) == AF_INET6 &&
3064            !nh_grp->gateway)
3065                return;
3066
3067        rhashtable_remove_fast(&mlxsw_sp->router->nexthop_group_ht,
3068                               &nh_grp->ht_node,
3069                               mlxsw_sp_nexthop_group_ht_params);
3070}
3071
3072static struct mlxsw_sp_nexthop_group *
3073mlxsw_sp_nexthop4_group_lookup(struct mlxsw_sp *mlxsw_sp,
3074                               struct fib_info *fi)
3075{
3076        struct mlxsw_sp_nexthop_group_cmp_arg cmp_arg;
3077
3078        cmp_arg.proto = MLXSW_SP_L3_PROTO_IPV4;
3079        cmp_arg.fi = fi;
3080        return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_group_ht,
3081                                      &cmp_arg,
3082                                      mlxsw_sp_nexthop_group_ht_params);
3083}
3084
3085static struct mlxsw_sp_nexthop_group *
3086mlxsw_sp_nexthop6_group_lookup(struct mlxsw_sp *mlxsw_sp,
3087                               struct mlxsw_sp_fib6_entry *fib6_entry)
3088{
3089        struct mlxsw_sp_nexthop_group_cmp_arg cmp_arg;
3090
3091        cmp_arg.proto = MLXSW_SP_L3_PROTO_IPV6;
3092        cmp_arg.fib6_entry = fib6_entry;
3093        return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_group_ht,
3094                                      &cmp_arg,
3095                                      mlxsw_sp_nexthop_group_ht_params);
3096}
3097
3098static const struct rhashtable_params mlxsw_sp_nexthop_ht_params = {
3099        .key_offset = offsetof(struct mlxsw_sp_nexthop, key),
3100        .head_offset = offsetof(struct mlxsw_sp_nexthop, ht_node),
3101        .key_len = sizeof(struct mlxsw_sp_nexthop_key),
3102};
3103
3104static int mlxsw_sp_nexthop_insert(struct mlxsw_sp *mlxsw_sp,
3105                                   struct mlxsw_sp_nexthop *nh)
3106{
3107        return rhashtable_insert_fast(&mlxsw_sp->router->nexthop_ht,
3108                                      &nh->ht_node, mlxsw_sp_nexthop_ht_params);
3109}
3110
3111static void mlxsw_sp_nexthop_remove(struct mlxsw_sp *mlxsw_sp,
3112                                    struct mlxsw_sp_nexthop *nh)
3113{
3114        rhashtable_remove_fast(&mlxsw_sp->router->nexthop_ht, &nh->ht_node,
3115                               mlxsw_sp_nexthop_ht_params);
3116}
3117
3118static struct mlxsw_sp_nexthop *
3119mlxsw_sp_nexthop_lookup(struct mlxsw_sp *mlxsw_sp,
3120                        struct mlxsw_sp_nexthop_key key)
3121{
3122        return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_ht, &key,
3123                                      mlxsw_sp_nexthop_ht_params);
3124}
3125
3126static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp,
3127                                             const struct mlxsw_sp_fib *fib,
3128                                             u32 adj_index, u16 ecmp_size,
3129                                             u32 new_adj_index,
3130                                             u16 new_ecmp_size)
3131{
3132        char raleu_pl[MLXSW_REG_RALEU_LEN];
3133
3134        mlxsw_reg_raleu_pack(raleu_pl,
3135                             (enum mlxsw_reg_ralxx_protocol) fib->proto,
3136                             fib->vr->id, adj_index, ecmp_size, new_adj_index,
3137                             new_ecmp_size);
3138        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raleu), raleu_pl);
3139}
3140
3141static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp,
3142                                          struct mlxsw_sp_nexthop_group *nh_grp,
3143                                          u32 old_adj_index, u16 old_ecmp_size)
3144{
3145        struct mlxsw_sp_fib_entry *fib_entry;
3146        struct mlxsw_sp_fib *fib = NULL;
3147        int err;
3148
3149        list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) {
3150                if (fib == fib_entry->fib_node->fib)
3151                        continue;
3152                fib = fib_entry->fib_node->fib;
3153                err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib,
3154                                                        old_adj_index,
3155                                                        old_ecmp_size,
3156                                                        nh_grp->adj_index,
3157                                                        nh_grp->ecmp_size);
3158                if (err)
3159                        return err;
3160        }
3161        return 0;
3162}
3163
3164static int __mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
3165                                     struct mlxsw_sp_nexthop *nh)
3166{
3167        struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
3168        char ratr_pl[MLXSW_REG_RATR_LEN];
3169
3170        mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY,
3171                            true, MLXSW_REG_RATR_TYPE_ETHERNET,
3172                            adj_index, neigh_entry->rif);
3173        mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha);
3174        if (nh->counter_valid)
3175                mlxsw_reg_ratr_counter_pack(ratr_pl, nh->counter_index, true);
3176        else
3177                mlxsw_reg_ratr_counter_pack(ratr_pl, 0, false);
3178
3179        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
3180}
3181
3182int mlxsw_sp_nexthop_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,
3183                            struct mlxsw_sp_nexthop *nh)
3184{
3185        int i;
3186
3187        for (i = 0; i < nh->num_adj_entries; i++) {
3188                int err;
3189
3190                err = __mlxsw_sp_nexthop_update(mlxsw_sp, adj_index + i, nh);
3191                if (err)
3192                        return err;
3193        }
3194
3195        return 0;
3196}
3197
3198static int __mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
3199                                          u32 adj_index,
3200                                          struct mlxsw_sp_nexthop *nh)
3201{
3202        const struct mlxsw_sp_ipip_ops *ipip_ops;
3203
3204        ipip_ops = mlxsw_sp->router->ipip_ops_arr[nh->ipip_entry->ipipt];
3205        return ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry);
3206}
3207
3208static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp,
3209                                        u32 adj_index,
3210                                        struct mlxsw_sp_nexthop *nh)
3211{
3212        int i;
3213
3214        for (i = 0; i < nh->num_adj_entries; i++) {
3215                int err;
3216
3217                err = __mlxsw_sp_nexthop_ipip_update(mlxsw_sp, adj_index + i,
3218                                                     nh);
3219                if (err)
3220                        return err;
3221        }
3222
3223        return 0;
3224}
3225
3226static int
3227mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp,
3228                              struct mlxsw_sp_nexthop_group *nh_grp,
3229                              bool reallocate)
3230{
3231        u32 adj_index = nh_grp->adj_index; /* base */
3232        struct mlxsw_sp_nexthop *nh;
3233        int i;
3234
3235        for (i = 0; i < nh_grp->count; i++) {
3236                nh = &nh_grp->nexthops[i];
3237
3238                if (!nh->should_offload) {
3239                        nh->offloaded = 0;
3240                        continue;
3241                }
3242
3243                if (nh->update || reallocate) {
3244                        int err = 0;
3245
3246                        switch (nh->type) {
3247                        case MLXSW_SP_NEXTHOP_TYPE_ETH:
3248                                err = mlxsw_sp_nexthop_update
3249                                            (mlxsw_sp, adj_index, nh);
3250                                break;
3251                        case MLXSW_SP_NEXTHOP_TYPE_IPIP:
3252                                err = mlxsw_sp_nexthop_ipip_update
3253                                            (mlxsw_sp, adj_index, nh);
3254                                break;
3255                        }
3256                        if (err)
3257                                return err;
3258                        nh->update = 0;
3259                        nh->offloaded = 1;
3260                }
3261                adj_index += nh->num_adj_entries;
3262        }
3263        return 0;
3264}
3265
3266static int
3267mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp,
3268                                    struct mlxsw_sp_nexthop_group *nh_grp)
3269{
3270        struct mlxsw_sp_fib_entry *fib_entry;
3271        int err;
3272
3273        list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) {
3274                err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
3275                if (err)
3276                        return err;
3277        }
3278        return 0;
3279}
3280
3281static void mlxsw_sp_adj_grp_size_round_up(u16 *p_adj_grp_size)
3282{
3283        /* Valid sizes for an adjacency group are:
3284         * 1-64, 512, 1024, 2048 and 4096.
3285         */
3286        if (*p_adj_grp_size <= 64)
3287                return;
3288        else if (*p_adj_grp_size <= 512)
3289                *p_adj_grp_size = 512;
3290        else if (*p_adj_grp_size <= 1024)
3291                *p_adj_grp_size = 1024;
3292        else if (*p_adj_grp_size <= 2048)
3293                *p_adj_grp_size = 2048;
3294        else
3295                *p_adj_grp_size = 4096;
3296}
3297
3298static void mlxsw_sp_adj_grp_size_round_down(u16 *p_adj_grp_size,
3299                                             unsigned int alloc_size)
3300{
3301        if (alloc_size >= 4096)
3302                *p_adj_grp_size = 4096;
3303        else if (alloc_size >= 2048)
3304                *p_adj_grp_size = 2048;
3305        else if (alloc_size >= 1024)
3306                *p_adj_grp_size = 1024;
3307        else if (alloc_size >= 512)
3308                *p_adj_grp_size = 512;
3309}
3310
3311static int mlxsw_sp_fix_adj_grp_size(struct mlxsw_sp *mlxsw_sp,
3312                                     u16 *p_adj_grp_size)
3313{
3314        unsigned int alloc_size;
3315        int err;
3316
3317        /* Round up the requested group size to the next size supported
3318         * by the device and make sure the request can be satisfied.
3319         */
3320        mlxsw_sp_adj_grp_size_round_up(p_adj_grp_size);
3321        err = mlxsw_sp_kvdl_alloc_count_query(mlxsw_sp,
3322                                              MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
3323                                              *p_adj_grp_size, &alloc_size);
3324        if (err)
3325                return err;
3326        /* It is possible the allocation results in more allocated
3327         * entries than requested. Try to use as much of them as
3328         * possible.
3329         */
3330        mlxsw_sp_adj_grp_size_round_down(p_adj_grp_size, alloc_size);
3331
3332        return 0;
3333}
3334
3335static void
3336mlxsw_sp_nexthop_group_normalize(struct mlxsw_sp_nexthop_group *nh_grp)
3337{
3338        int i, g = 0, sum_norm_weight = 0;
3339        struct mlxsw_sp_nexthop *nh;
3340
3341        for (i = 0; i < nh_grp->count; i++) {
3342                nh = &nh_grp->nexthops[i];
3343
3344                if (!nh->should_offload)
3345                        continue;
3346                if (g > 0)
3347                        g = gcd(nh->nh_weight, g);
3348                else
3349                        g = nh->nh_weight;
3350        }
3351
3352        for (i = 0; i < nh_grp->count; i++) {
3353                nh = &nh_grp->nexthops[i];
3354
3355                if (!nh->should_offload)
3356                        continue;
3357                nh->norm_nh_weight = nh->nh_weight / g;
3358                sum_norm_weight += nh->norm_nh_weight;
3359        }
3360
3361        nh_grp->sum_norm_weight = sum_norm_weight;
3362}
3363
3364static void
3365mlxsw_sp_nexthop_group_rebalance(struct mlxsw_sp_nexthop_group *nh_grp)
3366{
3367        int total = nh_grp->sum_norm_weight;
3368        u16 ecmp_size = nh_grp->ecmp_size;
3369        int i, weight = 0, lower_bound = 0;
3370
3371        for (i = 0; i < nh_grp->count; i++) {
3372                struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
3373                int upper_bound;
3374
3375                if (!nh->should_offload)
3376                        continue;
3377                weight += nh->norm_nh_weight;
3378                upper_bound = DIV_ROUND_CLOSEST(ecmp_size * weight, total);
3379                nh->num_adj_entries = upper_bound - lower_bound;
3380                lower_bound = upper_bound;
3381        }
3382}
3383
3384static struct mlxsw_sp_nexthop *
3385mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
3386                     const struct mlxsw_sp_rt6 *mlxsw_sp_rt6);
3387
3388static void
3389mlxsw_sp_nexthop4_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3390                                        struct mlxsw_sp_nexthop_group *nh_grp)
3391{
3392        int i;
3393
3394        for (i = 0; i < nh_grp->count; i++) {
3395                struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
3396
3397                if (nh->offloaded)
3398                        nh->key.fib_nh->fib_nh_flags |= RTNH_F_OFFLOAD;
3399                else
3400                        nh->key.fib_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
3401        }
3402}
3403
3404static void
3405__mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp_nexthop_group *nh_grp,
3406                                          struct mlxsw_sp_fib6_entry *fib6_entry)
3407{
3408        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
3409
3410        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
3411                struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh;
3412                struct mlxsw_sp_nexthop *nh;
3413
3414                nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6);
3415                if (nh && nh->offloaded)
3416                        fib6_nh->fib_nh_flags |= RTNH_F_OFFLOAD;
3417                else
3418                        fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
3419        }
3420}
3421
3422static void
3423mlxsw_sp_nexthop6_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3424                                        struct mlxsw_sp_nexthop_group *nh_grp)
3425{
3426        struct mlxsw_sp_fib6_entry *fib6_entry;
3427
3428        /* Unfortunately, in IPv6 the route and the nexthop are described by
3429         * the same struct, so we need to iterate over all the routes using the
3430         * nexthop group and set / clear the offload indication for them.
3431         */
3432        list_for_each_entry(fib6_entry, &nh_grp->fib_list,
3433                            common.nexthop_group_node)
3434                __mlxsw_sp_nexthop6_group_offload_refresh(nh_grp, fib6_entry);
3435}
3436
3437static void
3438mlxsw_sp_nexthop_group_offload_refresh(struct mlxsw_sp *mlxsw_sp,
3439                                       struct mlxsw_sp_nexthop_group *nh_grp)
3440{
3441        switch (mlxsw_sp_nexthop_group_type(nh_grp)) {
3442        case AF_INET:
3443                mlxsw_sp_nexthop4_group_offload_refresh(mlxsw_sp, nh_grp);
3444                break;
3445        case AF_INET6:
3446                mlxsw_sp_nexthop6_group_offload_refresh(mlxsw_sp, nh_grp);
3447                break;
3448        }
3449}
3450
3451static void
3452mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,
3453                               struct mlxsw_sp_nexthop_group *nh_grp)
3454{
3455        u16 ecmp_size, old_ecmp_size;
3456        struct mlxsw_sp_nexthop *nh;
3457        bool offload_change = false;
3458        u32 adj_index;
3459        bool old_adj_index_valid;
3460        u32 old_adj_index;
3461        int i;
3462        int err;
3463
3464        if (!nh_grp->gateway) {
3465                mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
3466                return;
3467        }
3468
3469        for (i = 0; i < nh_grp->count; i++) {
3470                nh = &nh_grp->nexthops[i];
3471
3472                if (nh->should_offload != nh->offloaded) {
3473                        offload_change = true;
3474                        if (nh->should_offload)
3475                                nh->update = 1;
3476                }
3477        }
3478        if (!offload_change) {
3479                /* Nothing was added or removed, so no need to reallocate. Just
3480                 * update MAC on existing adjacency indexes.
3481                 */
3482                err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, false);
3483                if (err) {
3484                        dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n");
3485                        goto set_trap;
3486                }
3487                return;
3488        }
3489        mlxsw_sp_nexthop_group_normalize(nh_grp);
3490        if (!nh_grp->sum_norm_weight)
3491                /* No neigh of this group is connected so we just set
3492                 * the trap and let everthing flow through kernel.
3493                 */
3494                goto set_trap;
3495
3496        ecmp_size = nh_grp->sum_norm_weight;
3497        err = mlxsw_sp_fix_adj_grp_size(mlxsw_sp, &ecmp_size);
3498        if (err)
3499                /* No valid allocation size available. */
3500                goto set_trap;
3501
3502        err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
3503                                  ecmp_size, &adj_index);
3504        if (err) {
3505                /* We ran out of KVD linear space, just set the
3506                 * trap and let everything flow through kernel.
3507                 */
3508                dev_warn(mlxsw_sp->bus_info->dev, "Failed to allocate KVD linear area for nexthop group.\n");
3509                goto set_trap;
3510        }
3511        old_adj_index_valid = nh_grp->adj_index_valid;
3512        old_adj_index = nh_grp->adj_index;
3513        old_ecmp_size = nh_grp->ecmp_size;
3514        nh_grp->adj_index_valid = 1;
3515        nh_grp->adj_index = adj_index;
3516        nh_grp->ecmp_size = ecmp_size;
3517        mlxsw_sp_nexthop_group_rebalance(nh_grp);
3518        err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, true);
3519        if (err) {
3520                dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n");
3521                goto set_trap;
3522        }
3523
3524        mlxsw_sp_nexthop_group_offload_refresh(mlxsw_sp, nh_grp);
3525
3526        if (!old_adj_index_valid) {
3527                /* The trap was set for fib entries, so we have to call
3528                 * fib entry update to unset it and use adjacency index.
3529                 */
3530                err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
3531                if (err) {
3532                        dev_warn(mlxsw_sp->bus_info->dev, "Failed to add adjacency index to fib entries.\n");
3533                        goto set_trap;
3534                }
3535                return;
3536        }
3537
3538        err = mlxsw_sp_adj_index_mass_update(mlxsw_sp, nh_grp,
3539                                             old_adj_index, old_ecmp_size);
3540        mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
3541                           old_ecmp_size, old_adj_index);
3542        if (err) {
3543                dev_warn(mlxsw_sp->bus_info->dev, "Failed to mass-update adjacency index for nexthop group.\n");
3544                goto set_trap;
3545        }
3546
3547        return;
3548
3549set_trap:
3550        old_adj_index_valid = nh_grp->adj_index_valid;
3551        nh_grp->adj_index_valid = 0;
3552        for (i = 0; i < nh_grp->count; i++) {
3553                nh = &nh_grp->nexthops[i];
3554                nh->offloaded = 0;
3555        }
3556        err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp);
3557        if (err)
3558                dev_warn(mlxsw_sp->bus_info->dev, "Failed to set traps for fib entries.\n");
3559        mlxsw_sp_nexthop_group_offload_refresh(mlxsw_sp, nh_grp);
3560        if (old_adj_index_valid)
3561                mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
3562                                   nh_grp->ecmp_size, nh_grp->adj_index);
3563}
3564
3565static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh,
3566                                            bool removing)
3567{
3568        if (!removing)
3569                nh->should_offload = 1;
3570        else
3571                nh->should_offload = 0;
3572        nh->update = 1;
3573}
3574
3575static int
3576mlxsw_sp_nexthop_dead_neigh_replace(struct mlxsw_sp *mlxsw_sp,
3577                                    struct mlxsw_sp_neigh_entry *neigh_entry)
3578{
3579        struct neighbour *n, *old_n = neigh_entry->key.n;
3580        struct mlxsw_sp_nexthop *nh;
3581        bool entry_connected;
3582        u8 nud_state, dead;
3583        int err;
3584
3585        nh = list_first_entry(&neigh_entry->nexthop_list,
3586                              struct mlxsw_sp_nexthop, neigh_list_node);
3587
3588        n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev);
3589        if (!n) {
3590                n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr,
3591                                 nh->rif->dev);
3592                if (IS_ERR(n))
3593                        return PTR_ERR(n);
3594                neigh_event_send(n, NULL);
3595        }
3596
3597        mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
3598        neigh_entry->key.n = n;
3599        err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
3600        if (err)
3601                goto err_neigh_entry_insert;
3602
3603        read_lock_bh(&n->lock);
3604        nud_state = n->nud_state;
3605        dead = n->dead;
3606        read_unlock_bh(&n->lock);
3607        entry_connected = nud_state & NUD_VALID && !dead;
3608
3609        list_for_each_entry(nh, &neigh_entry->nexthop_list,
3610                            neigh_list_node) {
3611                neigh_release(old_n);
3612                neigh_clone(n);
3613                __mlxsw_sp_nexthop_neigh_update(nh, !entry_connected);
3614                mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3615        }
3616
3617        neigh_release(n);
3618
3619        return 0;
3620
3621err_neigh_entry_insert:
3622        neigh_entry->key.n = old_n;
3623        mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry);
3624        neigh_release(n);
3625        return err;
3626}
3627
3628static void
3629mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp,
3630                              struct mlxsw_sp_neigh_entry *neigh_entry,
3631                              bool removing, bool dead)
3632{
3633        struct mlxsw_sp_nexthop *nh;
3634
3635        if (list_empty(&neigh_entry->nexthop_list))
3636                return;
3637
3638        if (dead) {
3639                int err;
3640
3641                err = mlxsw_sp_nexthop_dead_neigh_replace(mlxsw_sp,
3642                                                          neigh_entry);
3643                if (err)
3644                        dev_err(mlxsw_sp->bus_info->dev, "Failed to replace dead neigh\n");
3645                return;
3646        }
3647
3648        list_for_each_entry(nh, &neigh_entry->nexthop_list,
3649                            neigh_list_node) {
3650                __mlxsw_sp_nexthop_neigh_update(nh, removing);
3651                mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3652        }
3653}
3654
3655static void mlxsw_sp_nexthop_rif_init(struct mlxsw_sp_nexthop *nh,
3656                                      struct mlxsw_sp_rif *rif)
3657{
3658        if (nh->rif)
3659                return;
3660
3661        nh->rif = rif;
3662        list_add(&nh->rif_list_node, &rif->nexthop_list);
3663}
3664
3665static void mlxsw_sp_nexthop_rif_fini(struct mlxsw_sp_nexthop *nh)
3666{
3667        if (!nh->rif)
3668                return;
3669
3670        list_del(&nh->rif_list_node);
3671        nh->rif = NULL;
3672}
3673
3674static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
3675                                       struct mlxsw_sp_nexthop *nh)
3676{
3677        struct mlxsw_sp_neigh_entry *neigh_entry;
3678        struct neighbour *n;
3679        u8 nud_state, dead;
3680        int err;
3681
3682        if (!nh->nh_grp->gateway || nh->neigh_entry)
3683                return 0;
3684
3685        /* Take a reference of neigh here ensuring that neigh would
3686         * not be destructed before the nexthop entry is finished.
3687         * The reference is taken either in neigh_lookup() or
3688         * in neigh_create() in case n is not found.
3689         */
3690        n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev);
3691        if (!n) {
3692                n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr,
3693                                 nh->rif->dev);
3694                if (IS_ERR(n))
3695                        return PTR_ERR(n);
3696                neigh_event_send(n, NULL);
3697        }
3698        neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
3699        if (!neigh_entry) {
3700                neigh_entry = mlxsw_sp_neigh_entry_create(mlxsw_sp, n);
3701                if (IS_ERR(neigh_entry)) {
3702                        err = -EINVAL;
3703                        goto err_neigh_entry_create;
3704                }
3705        }
3706
3707        /* If that is the first nexthop connected to that neigh, add to
3708         * nexthop_neighs_list
3709         */
3710        if (list_empty(&neigh_entry->nexthop_list))
3711                list_add_tail(&neigh_entry->nexthop_neighs_list_node,
3712                              &mlxsw_sp->router->nexthop_neighs_list);
3713
3714        nh->neigh_entry = neigh_entry;
3715        list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list);
3716        read_lock_bh(&n->lock);
3717        nud_state = n->nud_state;
3718        dead = n->dead;
3719        read_unlock_bh(&n->lock);
3720        __mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID && !dead));
3721
3722        return 0;
3723
3724err_neigh_entry_create:
3725        neigh_release(n);
3726        return err;
3727}
3728
3729static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
3730                                        struct mlxsw_sp_nexthop *nh)
3731{
3732        struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
3733        struct neighbour *n;
3734
3735        if (!neigh_entry)
3736                return;
3737        n = neigh_entry->key.n;
3738
3739        __mlxsw_sp_nexthop_neigh_update(nh, true);
3740        list_del(&nh->neigh_list_node);
3741        nh->neigh_entry = NULL;
3742
3743        /* If that is the last nexthop connected to that neigh, remove from
3744         * nexthop_neighs_list
3745         */
3746        if (list_empty(&neigh_entry->nexthop_list))
3747                list_del(&neigh_entry->nexthop_neighs_list_node);
3748
3749        if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list))
3750                mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry);
3751
3752        neigh_release(n);
3753}
3754
3755static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
3756{
3757        struct net_device *ul_dev;
3758        bool is_up;
3759
3760        rcu_read_lock();
3761        ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
3762        is_up = ul_dev ? (ul_dev->flags & IFF_UP) : true;
3763        rcu_read_unlock();
3764
3765        return is_up;
3766}
3767
3768static void mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
3769                                       struct mlxsw_sp_nexthop *nh,
3770                                       struct mlxsw_sp_ipip_entry *ipip_entry)
3771{
3772        bool removing;
3773
3774        if (!nh->nh_grp->gateway || nh->ipip_entry)
3775                return;
3776
3777        nh->ipip_entry = ipip_entry;
3778        removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev);
3779        __mlxsw_sp_nexthop_neigh_update(nh, removing);
3780        mlxsw_sp_nexthop_rif_init(nh, &ipip_entry->ol_lb->common);
3781}
3782
3783static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,
3784                                       struct mlxsw_sp_nexthop *nh)
3785{
3786        struct mlxsw_sp_ipip_entry *ipip_entry = nh->ipip_entry;
3787
3788        if (!ipip_entry)
3789                return;
3790
3791        __mlxsw_sp_nexthop_neigh_update(nh, true);
3792        nh->ipip_entry = NULL;
3793}
3794
3795static bool mlxsw_sp_nexthop4_ipip_type(const struct mlxsw_sp *mlxsw_sp,
3796                                        const struct fib_nh *fib_nh,
3797                                        enum mlxsw_sp_ipip_type *p_ipipt)
3798{
3799        struct net_device *dev = fib_nh->fib_nh_dev;
3800
3801        return dev &&
3802               fib_nh->nh_parent->fib_type == RTN_UNICAST &&
3803               mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, p_ipipt);
3804}
3805
3806static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
3807                                       struct mlxsw_sp_nexthop *nh)
3808{
3809        switch (nh->type) {
3810        case MLXSW_SP_NEXTHOP_TYPE_ETH:
3811                mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
3812                mlxsw_sp_nexthop_rif_fini(nh);
3813                break;
3814        case MLXSW_SP_NEXTHOP_TYPE_IPIP:
3815                mlxsw_sp_nexthop_rif_fini(nh);
3816                mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);
3817                break;
3818        }
3819}
3820
3821static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp,
3822                                       struct mlxsw_sp_nexthop *nh,
3823                                       struct fib_nh *fib_nh)
3824{
3825        const struct mlxsw_sp_ipip_ops *ipip_ops;
3826        struct net_device *dev = fib_nh->fib_nh_dev;
3827        struct mlxsw_sp_ipip_entry *ipip_entry;
3828        struct mlxsw_sp_rif *rif;
3829        int err;
3830
3831        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, dev);
3832        if (ipip_entry) {
3833                ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
3834                if (ipip_ops->can_offload(mlxsw_sp, dev,
3835                                          MLXSW_SP_L3_PROTO_IPV4)) {
3836                        nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
3837                        mlxsw_sp_nexthop_ipip_init(mlxsw_sp, nh, ipip_entry);
3838                        return 0;
3839                }
3840        }
3841
3842        nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
3843        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
3844        if (!rif)
3845                return 0;
3846
3847        mlxsw_sp_nexthop_rif_init(nh, rif);
3848        err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
3849        if (err)
3850                goto err_neigh_init;
3851
3852        return 0;
3853
3854err_neigh_init:
3855        mlxsw_sp_nexthop_rif_fini(nh);
3856        return err;
3857}
3858
3859static void mlxsw_sp_nexthop4_type_fini(struct mlxsw_sp *mlxsw_sp,
3860                                        struct mlxsw_sp_nexthop *nh)
3861{
3862        mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
3863}
3864
3865static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
3866                                  struct mlxsw_sp_nexthop_group *nh_grp,
3867                                  struct mlxsw_sp_nexthop *nh,
3868                                  struct fib_nh *fib_nh)
3869{
3870        struct net_device *dev = fib_nh->fib_nh_dev;
3871        struct in_device *in_dev;
3872        int err;
3873
3874        nh->nh_grp = nh_grp;
3875        nh->key.fib_nh = fib_nh;
3876#ifdef CONFIG_IP_ROUTE_MULTIPATH
3877        nh->nh_weight = fib_nh->fib_nh_weight;
3878#else
3879        nh->nh_weight = 1;
3880#endif
3881        memcpy(&nh->gw_addr, &fib_nh->fib_nh_gw4, sizeof(fib_nh->fib_nh_gw4));
3882        err = mlxsw_sp_nexthop_insert(mlxsw_sp, nh);
3883        if (err)
3884                return err;
3885
3886        mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
3887        list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
3888
3889        if (!dev)
3890                return 0;
3891
3892        rcu_read_lock();
3893        in_dev = __in_dev_get_rcu(dev);
3894        if (in_dev && IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
3895            fib_nh->fib_nh_flags & RTNH_F_LINKDOWN) {
3896                rcu_read_unlock();
3897                return 0;
3898        }
3899        rcu_read_unlock();
3900
3901        err = mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh);
3902        if (err)
3903                goto err_nexthop_neigh_init;
3904
3905        return 0;
3906
3907err_nexthop_neigh_init:
3908        mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
3909        return err;
3910}
3911
3912static void mlxsw_sp_nexthop4_fini(struct mlxsw_sp *mlxsw_sp,
3913                                   struct mlxsw_sp_nexthop *nh)
3914{
3915        mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh);
3916        list_del(&nh->router_list_node);
3917        mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
3918        mlxsw_sp_nexthop_remove(mlxsw_sp, nh);
3919}
3920
3921static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,
3922                                    unsigned long event, struct fib_nh *fib_nh)
3923{
3924        struct mlxsw_sp_nexthop_key key;
3925        struct mlxsw_sp_nexthop *nh;
3926
3927        if (mlxsw_sp->router->aborted)
3928                return;
3929
3930        key.fib_nh = fib_nh;
3931        nh = mlxsw_sp_nexthop_lookup(mlxsw_sp, key);
3932        if (!nh)
3933                return;
3934
3935        switch (event) {
3936        case FIB_EVENT_NH_ADD:
3937                mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh);
3938                break;
3939        case FIB_EVENT_NH_DEL:
3940                mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh);
3941                break;
3942        }
3943
3944        mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3945}
3946
3947static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
3948                                        struct mlxsw_sp_rif *rif)
3949{
3950        struct mlxsw_sp_nexthop *nh;
3951        bool removing;
3952
3953        list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) {
3954                switch (nh->type) {
3955                case MLXSW_SP_NEXTHOP_TYPE_ETH:
3956                        removing = false;
3957                        break;
3958                case MLXSW_SP_NEXTHOP_TYPE_IPIP:
3959                        removing = !mlxsw_sp_ipip_netdev_ul_up(rif->dev);
3960                        break;
3961                default:
3962                        WARN_ON(1);
3963                        continue;
3964                }
3965
3966                __mlxsw_sp_nexthop_neigh_update(nh, removing);
3967                mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3968        }
3969}
3970
3971static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,
3972                                         struct mlxsw_sp_rif *old_rif,
3973                                         struct mlxsw_sp_rif *new_rif)
3974{
3975        struct mlxsw_sp_nexthop *nh;
3976
3977        list_splice_init(&old_rif->nexthop_list, &new_rif->nexthop_list);
3978        list_for_each_entry(nh, &new_rif->nexthop_list, rif_list_node)
3979                nh->rif = new_rif;
3980        mlxsw_sp_nexthop_rif_update(mlxsw_sp, new_rif);
3981}
3982
3983static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
3984                                           struct mlxsw_sp_rif *rif)
3985{
3986        struct mlxsw_sp_nexthop *nh, *tmp;
3987
3988        list_for_each_entry_safe(nh, tmp, &rif->nexthop_list, rif_list_node) {
3989                mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
3990                mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3991        }
3992}
3993
3994static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
3995                                   struct fib_info *fi)
3996{
3997        const struct fib_nh *nh = fib_info_nh(fi, 0);
3998
3999        return nh->fib_nh_scope == RT_SCOPE_LINK ||
4000               mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, nh, NULL);
4001}
4002
4003static struct mlxsw_sp_nexthop_group *
4004mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
4005{
4006        unsigned int nhs = fib_info_num_path(fi);
4007        struct mlxsw_sp_nexthop_group *nh_grp;
4008        struct mlxsw_sp_nexthop *nh;
4009        struct fib_nh *fib_nh;
4010        int i;
4011        int err;
4012
4013        nh_grp = kzalloc(struct_size(nh_grp, nexthops, nhs), GFP_KERNEL);
4014        if (!nh_grp)
4015                return ERR_PTR(-ENOMEM);
4016        nh_grp->priv = fi;
4017        INIT_LIST_HEAD(&nh_grp->fib_list);
4018        nh_grp->neigh_tbl = &arp_tbl;
4019
4020        nh_grp->gateway = mlxsw_sp_fi_is_gateway(mlxsw_sp, fi);
4021        nh_grp->count = nhs;
4022        fib_info_hold(fi);
4023        for (i = 0; i < nh_grp->count; i++) {
4024                nh = &nh_grp->nexthops[i];
4025                fib_nh = fib_info_nh(fi, i);
4026                err = mlxsw_sp_nexthop4_init(mlxsw_sp, nh_grp, nh, fib_nh);
4027                if (err)
4028                        goto err_nexthop4_init;
4029        }
4030        err = mlxsw_sp_nexthop_group_insert(mlxsw_sp, nh_grp);
4031        if (err)
4032                goto err_nexthop_group_insert;
4033        mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
4034        return nh_grp;
4035
4036err_nexthop_group_insert:
4037err_nexthop4_init:
4038        for (i--; i >= 0; i--) {
4039                nh = &nh_grp->nexthops[i];
4040                mlxsw_sp_nexthop4_fini(mlxsw_sp, nh);
4041        }
4042        fib_info_put(fi);
4043        kfree(nh_grp);
4044        return ERR_PTR(err);
4045}
4046
4047static void
4048mlxsw_sp_nexthop4_group_destroy(struct mlxsw_sp *mlxsw_sp,
4049                                struct mlxsw_sp_nexthop_group *nh_grp)
4050{
4051        struct mlxsw_sp_nexthop *nh;
4052        int i;
4053
4054        mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp);
4055        for (i = 0; i < nh_grp->count; i++) {
4056                nh = &nh_grp->nexthops[i];
4057                mlxsw_sp_nexthop4_fini(mlxsw_sp, nh);
4058        }
4059        mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
4060        WARN_ON_ONCE(nh_grp->adj_index_valid);
4061        fib_info_put(mlxsw_sp_nexthop4_group_fi(nh_grp));
4062        kfree(nh_grp);
4063}
4064
4065static int mlxsw_sp_nexthop4_group_get(struct mlxsw_sp *mlxsw_sp,
4066                                       struct mlxsw_sp_fib_entry *fib_entry,
4067                                       struct fib_info *fi)
4068{
4069        struct mlxsw_sp_nexthop_group *nh_grp;
4070
4071        nh_grp = mlxsw_sp_nexthop4_group_lookup(mlxsw_sp, fi);
4072        if (!nh_grp) {
4073                nh_grp = mlxsw_sp_nexthop4_group_create(mlxsw_sp, fi);
4074                if (IS_ERR(nh_grp))
4075                        return PTR_ERR(nh_grp);
4076        }
4077        list_add_tail(&fib_entry->nexthop_group_node, &nh_grp->fib_list);
4078        fib_entry->nh_group = nh_grp;
4079        return 0;
4080}
4081
4082static void mlxsw_sp_nexthop4_group_put(struct mlxsw_sp *mlxsw_sp,
4083                                        struct mlxsw_sp_fib_entry *fib_entry)
4084{
4085        struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group;
4086
4087        list_del(&fib_entry->nexthop_group_node);
4088        if (!list_empty(&nh_grp->fib_list))
4089                return;
4090        mlxsw_sp_nexthop4_group_destroy(mlxsw_sp, nh_grp);
4091}
4092
4093static bool
4094mlxsw_sp_fib4_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
4095{
4096        struct mlxsw_sp_fib4_entry *fib4_entry;
4097
4098        fib4_entry = container_of(fib_entry, struct mlxsw_sp_fib4_entry,
4099                                  common);
4100        return !fib4_entry->tos;
4101}
4102
4103static bool
4104mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry)
4105{
4106        struct mlxsw_sp_nexthop_group *nh_group = fib_entry->nh_group;
4107
4108        switch (fib_entry->fib_node->fib->proto) {
4109        case MLXSW_SP_L3_PROTO_IPV4:
4110                if (!mlxsw_sp_fib4_entry_should_offload(fib_entry))
4111                        return false;
4112                break;
4113        case MLXSW_SP_L3_PROTO_IPV6:
4114                break;
4115        }
4116
4117        switch (fib_entry->type) {
4118        case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE:
4119                return !!nh_group->adj_index_valid;
4120        case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL:
4121                return !!nh_group->nh_rif;
4122        case MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE:
4123        case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
4124        case MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP:
4125                return true;
4126        default:
4127                return false;
4128        }
4129}
4130
4131static struct mlxsw_sp_nexthop *
4132mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp,
4133                     const struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
4134{
4135        int i;
4136
4137        for (i = 0; i < nh_grp->count; i++) {
4138                struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i];
4139                struct fib6_info *rt = mlxsw_sp_rt6->rt;
4140
4141                if (nh->rif && nh->rif->dev == rt->fib6_nh->fib_nh_dev &&
4142                    ipv6_addr_equal((const struct in6_addr *) &nh->gw_addr,
4143                                    &rt->fib6_nh->fib_nh_gw6))
4144                        return nh;
4145                continue;
4146        }
4147
4148        return NULL;
4149}
4150
4151static void
4152mlxsw_sp_fib4_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
4153                                 struct mlxsw_sp_fib_entry *fib_entry)
4154{
4155        struct fib_info *fi = mlxsw_sp_nexthop4_group_fi(fib_entry->nh_group);
4156        u32 *p_dst = (u32 *) fib_entry->fib_node->key.addr;
4157        int dst_len = fib_entry->fib_node->key.prefix_len;
4158        struct mlxsw_sp_fib4_entry *fib4_entry;
4159        struct fib_rt_info fri;
4160        bool should_offload;
4161
4162        should_offload = mlxsw_sp_fib_entry_should_offload(fib_entry);
4163        fib4_entry = container_of(fib_entry, struct mlxsw_sp_fib4_entry,
4164                                  common);
4165        fri.fi = fi;
4166        fri.tb_id = fib4_entry->tb_id;
4167        fri.dst = cpu_to_be32(*p_dst);
4168        fri.dst_len = dst_len;
4169        fri.tos = fib4_entry->tos;
4170        fri.type = fib4_entry->type;
4171        fri.offload = should_offload;
4172        fri.trap = !should_offload;
4173        fib_alias_hw_flags_set(mlxsw_sp_net(mlxsw_sp), &fri);
4174}
4175
4176static void
4177mlxsw_sp_fib4_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
4178                                   struct mlxsw_sp_fib_entry *fib_entry)
4179{
4180        struct fib_info *fi = mlxsw_sp_nexthop4_group_fi(fib_entry->nh_group);
4181        u32 *p_dst = (u32 *) fib_entry->fib_node->key.addr;
4182        int dst_len = fib_entry->fib_node->key.prefix_len;
4183        struct mlxsw_sp_fib4_entry *fib4_entry;
4184        struct fib_rt_info fri;
4185
4186        fib4_entry = container_of(fib_entry, struct mlxsw_sp_fib4_entry,
4187                                  common);
4188        fri.fi = fi;
4189        fri.tb_id = fib4_entry->tb_id;
4190        fri.dst = cpu_to_be32(*p_dst);
4191        fri.dst_len = dst_len;
4192        fri.tos = fib4_entry->tos;
4193        fri.type = fib4_entry->type;
4194        fri.offload = false;
4195        fri.trap = false;
4196        fib_alias_hw_flags_set(mlxsw_sp_net(mlxsw_sp), &fri);
4197}
4198
4199static void
4200mlxsw_sp_fib6_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
4201                                 struct mlxsw_sp_fib_entry *fib_entry)
4202{
4203        struct mlxsw_sp_fib6_entry *fib6_entry;
4204        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
4205        bool should_offload;
4206
4207        should_offload = mlxsw_sp_fib_entry_should_offload(fib_entry);
4208
4209        /* In IPv6 a multipath route is represented using multiple routes, so
4210         * we need to set the flags on all of them.
4211         */
4212        fib6_entry = container_of(fib_entry, struct mlxsw_sp_fib6_entry,
4213                                  common);
4214        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list)
4215                fib6_info_hw_flags_set(mlxsw_sp_rt6->rt, should_offload,
4216                                       !should_offload);
4217}
4218
4219static void
4220mlxsw_sp_fib6_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
4221                                   struct mlxsw_sp_fib_entry *fib_entry)
4222{
4223        struct mlxsw_sp_fib6_entry *fib6_entry;
4224        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
4225
4226        fib6_entry = container_of(fib_entry, struct mlxsw_sp_fib6_entry,
4227                                  common);
4228        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list)
4229                fib6_info_hw_flags_set(mlxsw_sp_rt6->rt, false, false);
4230}
4231
4232static void
4233mlxsw_sp_fib_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
4234                                struct mlxsw_sp_fib_entry *fib_entry)
4235{
4236        switch (fib_entry->fib_node->fib->proto) {
4237        case MLXSW_SP_L3_PROTO_IPV4:
4238                mlxsw_sp_fib4_entry_hw_flags_set(mlxsw_sp, fib_entry);
4239                break;
4240        case MLXSW_SP_L3_PROTO_IPV6:
4241                mlxsw_sp_fib6_entry_hw_flags_set(mlxsw_sp, fib_entry);
4242                break;
4243        }
4244}
4245
4246static void
4247mlxsw_sp_fib_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
4248                                  struct mlxsw_sp_fib_entry *fib_entry)
4249{
4250        switch (fib_entry->fib_node->fib->proto) {
4251        case MLXSW_SP_L3_PROTO_IPV4:
4252                mlxsw_sp_fib4_entry_hw_flags_clear(mlxsw_sp, fib_entry);
4253                break;
4254        case MLXSW_SP_L3_PROTO_IPV6:
4255                mlxsw_sp_fib6_entry_hw_flags_clear(mlxsw_sp, fib_entry);
4256                break;
4257        }
4258}
4259
4260static void
4261mlxsw_sp_fib_entry_hw_flags_refresh(struct mlxsw_sp *mlxsw_sp,
4262                                    struct mlxsw_sp_fib_entry *fib_entry,
4263                                    enum mlxsw_reg_ralue_op op)
4264{
4265        switch (op) {
4266        case MLXSW_REG_RALUE_OP_WRITE_WRITE:
4267                mlxsw_sp_fib_entry_hw_flags_set(mlxsw_sp, fib_entry);
4268                break;
4269        case MLXSW_REG_RALUE_OP_WRITE_DELETE:
4270                mlxsw_sp_fib_entry_hw_flags_clear(mlxsw_sp, fib_entry);
4271                break;
4272        default:
4273                break;
4274        }
4275}
4276
4277static void
4278mlxsw_sp_fib_entry_ralue_pack(char *ralue_pl,
4279                              const struct mlxsw_sp_fib_entry *fib_entry,
4280                              enum mlxsw_reg_ralue_op op)
4281{
4282        struct mlxsw_sp_fib *fib = fib_entry->fib_node->fib;
4283        enum mlxsw_reg_ralxx_protocol proto;
4284        u32 *p_dip;
4285
4286        proto = (enum mlxsw_reg_ralxx_protocol) fib->proto;
4287
4288        switch (fib->proto) {
4289        case MLXSW_SP_L3_PROTO_IPV4:
4290                p_dip = (u32 *) fib_entry->fib_node->key.addr;
4291                mlxsw_reg_ralue_pack4(ralue_pl, proto, op, fib->vr->id,
4292                                      fib_entry->fib_node->key.prefix_len,
4293                                      *p_dip);
4294                break;
4295        case MLXSW_SP_L3_PROTO_IPV6:
4296                mlxsw_reg_ralue_pack6(ralue_pl, proto, op, fib->vr->id,
4297                                      fib_entry->fib_node->key.prefix_len,
4298                                      fib_entry->fib_node->key.addr);
4299                break;
4300        }
4301}
4302
4303static int mlxsw_sp_adj_discard_write(struct mlxsw_sp *mlxsw_sp, u16 rif_index)
4304{
4305        enum mlxsw_reg_ratr_trap_action trap_action;
4306        char ratr_pl[MLXSW_REG_RATR_LEN];
4307        int err;
4308
4309        if (mlxsw_sp->router->adj_discard_index_valid)
4310                return 0;
4311
4312        err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
4313                                  &mlxsw_sp->router->adj_discard_index);
4314        if (err)
4315                return err;
4316
4317        trap_action = MLXSW_REG_RATR_TRAP_ACTION_DISCARD_ERRORS;
4318        mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,
4319                            MLXSW_REG_RATR_TYPE_ETHERNET,
4320                            mlxsw_sp->router->adj_discard_index, rif_index);
4321        mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);
4322        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
4323        if (err)
4324                goto err_ratr_write;
4325
4326        mlxsw_sp->router->adj_discard_index_valid = true;
4327
4328        return 0;
4329
4330err_ratr_write:
4331        mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
4332                           mlxsw_sp->router->adj_discard_index);
4333        return err;
4334}
4335
4336static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp,
4337                                        struct mlxsw_sp_fib_entry *fib_entry,
4338                                        enum mlxsw_reg_ralue_op op)
4339{
4340        struct mlxsw_sp_nexthop_group *nh_group = fib_entry->nh_group;
4341        char ralue_pl[MLXSW_REG_RALUE_LEN];
4342        enum mlxsw_reg_ralue_trap_action trap_action;
4343        u16 trap_id = 0;
4344        u32 adjacency_index = 0;
4345        u16 ecmp_size = 0;
4346        int err;
4347
4348        /* In case the nexthop group adjacency index is valid, use it
4349         * with provided ECMP size. Otherwise, setup trap and pass
4350         * traffic to kernel.
4351         */
4352        if (mlxsw_sp_fib_entry_should_offload(fib_entry)) {
4353                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
4354                adjacency_index = fib_entry->nh_group->adj_index;
4355                ecmp_size = fib_entry->nh_group->ecmp_size;
4356        } else if (!nh_group->adj_index_valid && nh_group->count &&
4357                   nh_group->nh_rif) {
4358                err = mlxsw_sp_adj_discard_write(mlxsw_sp,
4359                                                 nh_group->nh_rif->rif_index);
4360                if (err)
4361                        return err;
4362                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
4363                adjacency_index = mlxsw_sp->router->adj_discard_index;
4364                ecmp_size = 1;
4365        } else {
4366                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
4367                trap_id = MLXSW_TRAP_ID_RTR_INGRESS0;
4368        }
4369
4370        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4371        mlxsw_reg_ralue_act_remote_pack(ralue_pl, trap_action, trap_id,
4372                                        adjacency_index, ecmp_size);
4373        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4374}
4375
4376static int mlxsw_sp_fib_entry_op_local(struct mlxsw_sp *mlxsw_sp,
4377                                       struct mlxsw_sp_fib_entry *fib_entry,
4378                                       enum mlxsw_reg_ralue_op op)
4379{
4380        struct mlxsw_sp_rif *rif = fib_entry->nh_group->nh_rif;
4381        enum mlxsw_reg_ralue_trap_action trap_action;
4382        char ralue_pl[MLXSW_REG_RALUE_LEN];
4383        u16 trap_id = 0;
4384        u16 rif_index = 0;
4385
4386        if (mlxsw_sp_fib_entry_should_offload(fib_entry)) {
4387                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP;
4388                rif_index = rif->rif_index;
4389        } else {
4390                trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
4391                trap_id = MLXSW_TRAP_ID_RTR_INGRESS0;
4392        }
4393
4394        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4395        mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, trap_id,
4396                                       rif_index);
4397        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4398}
4399
4400static int mlxsw_sp_fib_entry_op_trap(struct mlxsw_sp *mlxsw_sp,
4401                                      struct mlxsw_sp_fib_entry *fib_entry,
4402                                      enum mlxsw_reg_ralue_op op)
4403{
4404        char ralue_pl[MLXSW_REG_RALUE_LEN];
4405
4406        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4407        mlxsw_reg_ralue_act_ip2me_pack(ralue_pl);
4408        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4409}
4410
4411static int mlxsw_sp_fib_entry_op_blackhole(struct mlxsw_sp *mlxsw_sp,
4412                                           struct mlxsw_sp_fib_entry *fib_entry,
4413                                           enum mlxsw_reg_ralue_op op)
4414{
4415        enum mlxsw_reg_ralue_trap_action trap_action;
4416        char ralue_pl[MLXSW_REG_RALUE_LEN];
4417
4418        trap_action = MLXSW_REG_RALUE_TRAP_ACTION_DISCARD_ERROR;
4419        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4420        mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, 0, 0);
4421        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4422}
4423
4424static int
4425mlxsw_sp_fib_entry_op_unreachable(struct mlxsw_sp *mlxsw_sp,
4426                                  struct mlxsw_sp_fib_entry *fib_entry,
4427                                  enum mlxsw_reg_ralue_op op)
4428{
4429        enum mlxsw_reg_ralue_trap_action trap_action;
4430        char ralue_pl[MLXSW_REG_RALUE_LEN];
4431        u16 trap_id;
4432
4433        trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP;
4434        trap_id = MLXSW_TRAP_ID_RTR_INGRESS1;
4435
4436        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4437        mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, trap_id, 0);
4438        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4439}
4440
4441static int
4442mlxsw_sp_fib_entry_op_ipip_decap(struct mlxsw_sp *mlxsw_sp,
4443                                 struct mlxsw_sp_fib_entry *fib_entry,
4444                                 enum mlxsw_reg_ralue_op op)
4445{
4446        struct mlxsw_sp_ipip_entry *ipip_entry = fib_entry->decap.ipip_entry;
4447        const struct mlxsw_sp_ipip_ops *ipip_ops;
4448
4449        if (WARN_ON(!ipip_entry))
4450                return -EINVAL;
4451
4452        ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
4453        return ipip_ops->fib_entry_op(mlxsw_sp, ipip_entry, op,
4454                                      fib_entry->decap.tunnel_index);
4455}
4456
4457static int mlxsw_sp_fib_entry_op_nve_decap(struct mlxsw_sp *mlxsw_sp,
4458                                           struct mlxsw_sp_fib_entry *fib_entry,
4459                                           enum mlxsw_reg_ralue_op op)
4460{
4461        char ralue_pl[MLXSW_REG_RALUE_LEN];
4462
4463        mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op);
4464        mlxsw_reg_ralue_act_ip2me_tun_pack(ralue_pl,
4465                                           fib_entry->decap.tunnel_index);
4466        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl);
4467}
4468
4469static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
4470                                   struct mlxsw_sp_fib_entry *fib_entry,
4471                                   enum mlxsw_reg_ralue_op op)
4472{
4473        switch (fib_entry->type) {
4474        case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE:
4475                return mlxsw_sp_fib_entry_op_remote(mlxsw_sp, fib_entry, op);
4476        case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL:
4477                return mlxsw_sp_fib_entry_op_local(mlxsw_sp, fib_entry, op);
4478        case MLXSW_SP_FIB_ENTRY_TYPE_TRAP:
4479                return mlxsw_sp_fib_entry_op_trap(mlxsw_sp, fib_entry, op);
4480        case MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE:
4481                return mlxsw_sp_fib_entry_op_blackhole(mlxsw_sp, fib_entry, op);
4482        case MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE:
4483                return mlxsw_sp_fib_entry_op_unreachable(mlxsw_sp, fib_entry,
4484                                                         op);
4485        case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
4486                return mlxsw_sp_fib_entry_op_ipip_decap(mlxsw_sp,
4487                                                        fib_entry, op);
4488        case MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP:
4489                return mlxsw_sp_fib_entry_op_nve_decap(mlxsw_sp, fib_entry, op);
4490        }
4491        return -EINVAL;
4492}
4493
4494static int mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp,
4495                                 struct mlxsw_sp_fib_entry *fib_entry,
4496                                 enum mlxsw_reg_ralue_op op)
4497{
4498        int err = __mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, op);
4499
4500        if (err)
4501                return err;
4502
4503        mlxsw_sp_fib_entry_hw_flags_refresh(mlxsw_sp, fib_entry, op);
4504
4505        return err;
4506}
4507
4508static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp,
4509                                     struct mlxsw_sp_fib_entry *fib_entry)
4510{
4511        return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry,
4512                                     MLXSW_REG_RALUE_OP_WRITE_WRITE);
4513}
4514
4515static int mlxsw_sp_fib_entry_del(struct mlxsw_sp *mlxsw_sp,
4516                                  struct mlxsw_sp_fib_entry *fib_entry)
4517{
4518        return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry,
4519                                     MLXSW_REG_RALUE_OP_WRITE_DELETE);
4520}
4521
4522static int
4523mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
4524                             const struct fib_entry_notifier_info *fen_info,
4525                             struct mlxsw_sp_fib_entry *fib_entry)
4526{
4527        struct net_device *dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
4528        union mlxsw_sp_l3addr dip = { .addr4 = htonl(fen_info->dst) };
4529        struct mlxsw_sp_router *router = mlxsw_sp->router;
4530        u32 tb_id = mlxsw_sp_fix_tb_id(fen_info->tb_id);
4531        struct mlxsw_sp_ipip_entry *ipip_entry;
4532        struct fib_info *fi = fen_info->fi;
4533
4534        switch (fen_info->type) {
4535        case RTN_LOCAL:
4536                ipip_entry = mlxsw_sp_ipip_entry_find_by_decap(mlxsw_sp, dev,
4537                                                 MLXSW_SP_L3_PROTO_IPV4, dip);
4538                if (ipip_entry && ipip_entry->ol_dev->flags & IFF_UP) {
4539                        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP;
4540                        return mlxsw_sp_fib_entry_decap_init(mlxsw_sp,
4541                                                             fib_entry,
4542                                                             ipip_entry);
4543                }
4544                if (mlxsw_sp_router_nve_is_decap(mlxsw_sp, tb_id,
4545                                                 MLXSW_SP_L3_PROTO_IPV4,
4546                                                 &dip)) {
4547                        u32 tunnel_index;
4548
4549                        tunnel_index = router->nve_decap_config.tunnel_index;
4550                        fib_entry->decap.tunnel_index = tunnel_index;
4551                        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_NVE_DECAP;
4552                        return 0;
4553                }
4554                /* fall through */
4555        case RTN_BROADCAST:
4556                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
4557                return 0;
4558        case RTN_BLACKHOLE:
4559                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE;
4560                return 0;
4561        case RTN_UNREACHABLE: /* fall through */
4562        case RTN_PROHIBIT:
4563                /* Packets hitting these routes need to be trapped, but
4564                 * can do so with a lower priority than packets directed
4565                 * at the host, so use action type local instead of trap.
4566                 */
4567                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE;
4568                return 0;
4569        case RTN_UNICAST:
4570                if (mlxsw_sp_fi_is_gateway(mlxsw_sp, fi))
4571                        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
4572                else
4573                        fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
4574                return 0;
4575        default:
4576                return -EINVAL;
4577        }
4578}
4579
4580static void
4581mlxsw_sp_fib4_entry_type_unset(struct mlxsw_sp *mlxsw_sp,
4582                               struct mlxsw_sp_fib_entry *fib_entry)
4583{
4584        switch (fib_entry->type) {
4585        case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP:
4586                mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, fib_entry);
4587                break;
4588        default:
4589                break;
4590        }
4591}
4592
4593static struct mlxsw_sp_fib4_entry *
4594mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp,
4595                           struct mlxsw_sp_fib_node *fib_node,
4596                           const struct fib_entry_notifier_info *fen_info)
4597{
4598        struct mlxsw_sp_fib4_entry *fib4_entry;
4599        struct mlxsw_sp_fib_entry *fib_entry;
4600        int err;
4601
4602        fib4_entry = kzalloc(sizeof(*fib4_entry), GFP_KERNEL);
4603        if (!fib4_entry)
4604                return ERR_PTR(-ENOMEM);
4605        fib_entry = &fib4_entry->common;
4606
4607        err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry);
4608        if (err)
4609                goto err_fib4_entry_type_set;
4610
4611        err = mlxsw_sp_nexthop4_group_get(mlxsw_sp, fib_entry, fen_info->fi);
4612        if (err)
4613                goto err_nexthop4_group_get;
4614
4615        fib4_entry->prio = fen_info->fi->fib_priority;
4616        fib4_entry->tb_id = fen_info->tb_id;
4617        fib4_entry->type = fen_info->type;
4618        fib4_entry->tos = fen_info->tos;
4619
4620        fib_entry->fib_node = fib_node;
4621
4622        return fib4_entry;
4623
4624err_nexthop4_group_get:
4625        mlxsw_sp_fib4_entry_type_unset(mlxsw_sp, fib_entry);
4626err_fib4_entry_type_set:
4627        kfree(fib4_entry);
4628        return ERR_PTR(err);
4629}
4630
4631static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp,
4632                                        struct mlxsw_sp_fib4_entry *fib4_entry)
4633{
4634        mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common);
4635        mlxsw_sp_fib4_entry_type_unset(mlxsw_sp, &fib4_entry->common);
4636        kfree(fib4_entry);
4637}
4638
4639static struct mlxsw_sp_fib4_entry *
4640mlxsw_sp_fib4_entry_lookup(struct mlxsw_sp *mlxsw_sp,
4641                           const struct fib_entry_notifier_info *fen_info)
4642{
4643        struct mlxsw_sp_fib4_entry *fib4_entry;
4644        struct mlxsw_sp_fib_node *fib_node;
4645        struct mlxsw_sp_fib *fib;
4646        struct mlxsw_sp_vr *vr;
4647
4648        vr = mlxsw_sp_vr_find(mlxsw_sp, fen_info->tb_id);
4649        if (!vr)
4650                return NULL;
4651        fib = mlxsw_sp_vr_fib(vr, MLXSW_SP_L3_PROTO_IPV4);
4652
4653        fib_node = mlxsw_sp_fib_node_lookup(fib, &fen_info->dst,
4654                                            sizeof(fen_info->dst),
4655                                            fen_info->dst_len);
4656        if (!fib_node)
4657                return NULL;
4658
4659        fib4_entry = container_of(fib_node->fib_entry,
4660                                  struct mlxsw_sp_fib4_entry, common);
4661        if (fib4_entry->tb_id == fen_info->tb_id &&
4662            fib4_entry->tos == fen_info->tos &&
4663            fib4_entry->type == fen_info->type &&
4664            mlxsw_sp_nexthop4_group_fi(fib4_entry->common.nh_group) ==
4665            fen_info->fi)
4666                return fib4_entry;
4667
4668        return NULL;
4669}
4670
4671static const struct rhashtable_params mlxsw_sp_fib_ht_params = {
4672        .key_offset = offsetof(struct mlxsw_sp_fib_node, key),
4673        .head_offset = offsetof(struct mlxsw_sp_fib_node, ht_node),
4674        .key_len = sizeof(struct mlxsw_sp_fib_key),
4675        .automatic_shrinking = true,
4676};
4677
4678static int mlxsw_sp_fib_node_insert(struct mlxsw_sp_fib *fib,
4679                                    struct mlxsw_sp_fib_node *fib_node)
4680{
4681        return rhashtable_insert_fast(&fib->ht, &fib_node->ht_node,
4682                                      mlxsw_sp_fib_ht_params);
4683}
4684
4685static void mlxsw_sp_fib_node_remove(struct mlxsw_sp_fib *fib,
4686                                     struct mlxsw_sp_fib_node *fib_node)
4687{
4688        rhashtable_remove_fast(&fib->ht, &fib_node->ht_node,
4689                               mlxsw_sp_fib_ht_params);
4690}
4691
4692static struct mlxsw_sp_fib_node *
4693mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr,
4694                         size_t addr_len, unsigned char prefix_len)
4695{
4696        struct mlxsw_sp_fib_key key;
4697
4698        memset(&key, 0, sizeof(key));
4699        memcpy(key.addr, addr, addr_len);
4700        key.prefix_len = prefix_len;
4701        return rhashtable_lookup_fast(&fib->ht, &key, mlxsw_sp_fib_ht_params);
4702}
4703
4704static struct mlxsw_sp_fib_node *
4705mlxsw_sp_fib_node_create(struct mlxsw_sp_fib *fib, const void *addr,
4706                         size_t addr_len, unsigned char prefix_len)
4707{
4708        struct mlxsw_sp_fib_node *fib_node;
4709
4710        fib_node = kzalloc(sizeof(*fib_node), GFP_KERNEL);
4711        if (!fib_node)
4712                return NULL;
4713
4714        list_add(&fib_node->list, &fib->node_list);
4715        memcpy(fib_node->key.addr, addr, addr_len);
4716        fib_node->key.prefix_len = prefix_len;
4717
4718        return fib_node;
4719}
4720
4721static void mlxsw_sp_fib_node_destroy(struct mlxsw_sp_fib_node *fib_node)
4722{
4723        list_del(&fib_node->list);
4724        kfree(fib_node);
4725}
4726
4727static int mlxsw_sp_fib_lpm_tree_link(struct mlxsw_sp *mlxsw_sp,
4728                                      struct mlxsw_sp_fib_node *fib_node)
4729{
4730        struct mlxsw_sp_prefix_usage req_prefix_usage;
4731        struct mlxsw_sp_fib *fib = fib_node->fib;
4732        struct mlxsw_sp_lpm_tree *lpm_tree;
4733        int err;
4734
4735        lpm_tree = mlxsw_sp->router->lpm.proto_trees[fib->proto];
4736        if (lpm_tree->prefix_ref_count[fib_node->key.prefix_len] != 0)
4737                goto out;
4738
4739        mlxsw_sp_prefix_usage_cpy(&req_prefix_usage, &lpm_tree->prefix_usage);
4740        mlxsw_sp_prefix_usage_set(&req_prefix_usage, fib_node->key.prefix_len);
4741        lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage,
4742                                         fib->proto);
4743        if (IS_ERR(lpm_tree))
4744                return PTR_ERR(lpm_tree);
4745
4746        err = mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree);
4747        if (err)
4748                goto err_lpm_tree_replace;
4749
4750out:
4751        lpm_tree->prefix_ref_count[fib_node->key.prefix_len]++;
4752        return 0;
4753
4754err_lpm_tree_replace:
4755        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
4756        return err;
4757}
4758
4759static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp,
4760                                         struct mlxsw_sp_fib_node *fib_node)
4761{
4762        struct mlxsw_sp_lpm_tree *lpm_tree = fib_node->fib->lpm_tree;
4763        struct mlxsw_sp_prefix_usage req_prefix_usage;
4764        struct mlxsw_sp_fib *fib = fib_node->fib;
4765        int err;
4766
4767        if (--lpm_tree->prefix_ref_count[fib_node->key.prefix_len] != 0)
4768                return;
4769        /* Try to construct a new LPM tree from the current prefix usage
4770         * minus the unused one. If we fail, continue using the old one.
4771         */
4772        mlxsw_sp_prefix_usage_cpy(&req_prefix_usage, &lpm_tree->prefix_usage);
4773        mlxsw_sp_prefix_usage_clear(&req_prefix_usage,
4774                                    fib_node->key.prefix_len);
4775        lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage,
4776                                         fib->proto);
4777        if (IS_ERR(lpm_tree))
4778                return;
4779
4780        err = mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree);
4781        if (err)
4782                goto err_lpm_tree_replace;
4783
4784        return;
4785
4786err_lpm_tree_replace:
4787        mlxsw_sp_lpm_tree_put(mlxsw_sp, lpm_tree);
4788}
4789
4790static int mlxsw_sp_fib_node_init(struct mlxsw_sp *mlxsw_sp,
4791                                  struct mlxsw_sp_fib_node *fib_node,
4792                                  struct mlxsw_sp_fib *fib)
4793{
4794        int err;
4795
4796        err = mlxsw_sp_fib_node_insert(fib, fib_node);
4797        if (err)
4798                return err;
4799        fib_node->fib = fib;
4800
4801        err = mlxsw_sp_fib_lpm_tree_link(mlxsw_sp, fib_node);
4802        if (err)
4803                goto err_fib_lpm_tree_link;
4804
4805        return 0;
4806
4807err_fib_lpm_tree_link:
4808        fib_node->fib = NULL;
4809        mlxsw_sp_fib_node_remove(fib, fib_node);
4810        return err;
4811}
4812
4813static void mlxsw_sp_fib_node_fini(struct mlxsw_sp *mlxsw_sp,
4814                                   struct mlxsw_sp_fib_node *fib_node)
4815{
4816        struct mlxsw_sp_fib *fib = fib_node->fib;
4817
4818        mlxsw_sp_fib_lpm_tree_unlink(mlxsw_sp, fib_node);
4819        fib_node->fib = NULL;
4820        mlxsw_sp_fib_node_remove(fib, fib_node);
4821}
4822
4823static struct mlxsw_sp_fib_node *
4824mlxsw_sp_fib_node_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id, const void *addr,
4825                      size_t addr_len, unsigned char prefix_len,
4826                      enum mlxsw_sp_l3proto proto)
4827{
4828        struct mlxsw_sp_fib_node *fib_node;
4829        struct mlxsw_sp_fib *fib;
4830        struct mlxsw_sp_vr *vr;
4831        int err;
4832
4833        vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id, NULL);
4834        if (IS_ERR(vr))
4835                return ERR_CAST(vr);
4836        fib = mlxsw_sp_vr_fib(vr, proto);
4837
4838        fib_node = mlxsw_sp_fib_node_lookup(fib, addr, addr_len, prefix_len);
4839        if (fib_node)
4840                return fib_node;
4841
4842        fib_node = mlxsw_sp_fib_node_create(fib, addr, addr_len, prefix_len);
4843        if (!fib_node) {
4844                err = -ENOMEM;
4845                goto err_fib_node_create;
4846        }
4847
4848        err = mlxsw_sp_fib_node_init(mlxsw_sp, fib_node, fib);
4849        if (err)
4850                goto err_fib_node_init;
4851
4852        return fib_node;
4853
4854err_fib_node_init:
4855        mlxsw_sp_fib_node_destroy(fib_node);
4856err_fib_node_create:
4857        mlxsw_sp_vr_put(mlxsw_sp, vr);
4858        return ERR_PTR(err);
4859}
4860
4861static void mlxsw_sp_fib_node_put(struct mlxsw_sp *mlxsw_sp,
4862                                  struct mlxsw_sp_fib_node *fib_node)
4863{
4864        struct mlxsw_sp_vr *vr = fib_node->fib->vr;
4865
4866        if (fib_node->fib_entry)
4867                return;
4868        mlxsw_sp_fib_node_fini(mlxsw_sp, fib_node);
4869        mlxsw_sp_fib_node_destroy(fib_node);
4870        mlxsw_sp_vr_put(mlxsw_sp, vr);
4871}
4872
4873static int mlxsw_sp_fib_node_entry_link(struct mlxsw_sp *mlxsw_sp,
4874                                        struct mlxsw_sp_fib_entry *fib_entry)
4875{
4876        struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
4877        int err;
4878
4879        fib_node->fib_entry = fib_entry;
4880
4881        err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
4882        if (err)
4883                goto err_fib_entry_update;
4884
4885        return 0;
4886
4887err_fib_entry_update:
4888        fib_node->fib_entry = NULL;
4889        return err;
4890}
4891
4892static void
4893mlxsw_sp_fib_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
4894                               struct mlxsw_sp_fib_entry *fib_entry)
4895{
4896        struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node;
4897
4898        mlxsw_sp_fib_entry_del(mlxsw_sp, fib_entry);
4899        fib_node->fib_entry = NULL;
4900}
4901
4902static bool mlxsw_sp_fib4_allow_replace(struct mlxsw_sp_fib4_entry *fib4_entry)
4903{
4904        struct mlxsw_sp_fib_node *fib_node = fib4_entry->common.fib_node;
4905        struct mlxsw_sp_fib4_entry *fib4_replaced;
4906
4907        if (!fib_node->fib_entry)
4908                return true;
4909
4910        fib4_replaced = container_of(fib_node->fib_entry,
4911                                     struct mlxsw_sp_fib4_entry, common);
4912        if (fib4_entry->tb_id == RT_TABLE_MAIN &&
4913            fib4_replaced->tb_id == RT_TABLE_LOCAL)
4914                return false;
4915
4916        return true;
4917}
4918
4919static int
4920mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
4921                             const struct fib_entry_notifier_info *fen_info)
4922{
4923        struct mlxsw_sp_fib4_entry *fib4_entry, *fib4_replaced;
4924        struct mlxsw_sp_fib_entry *replaced;
4925        struct mlxsw_sp_fib_node *fib_node;
4926        int err;
4927
4928        if (mlxsw_sp->router->aborted)
4929                return 0;
4930
4931        fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, fen_info->tb_id,
4932                                         &fen_info->dst, sizeof(fen_info->dst),
4933                                         fen_info->dst_len,
4934                                         MLXSW_SP_L3_PROTO_IPV4);
4935        if (IS_ERR(fib_node)) {
4936                dev_warn(mlxsw_sp->bus_info->dev, "Failed to get FIB node\n");
4937                return PTR_ERR(fib_node);
4938        }
4939
4940        fib4_entry = mlxsw_sp_fib4_entry_create(mlxsw_sp, fib_node, fen_info);
4941        if (IS_ERR(fib4_entry)) {
4942                dev_warn(mlxsw_sp->bus_info->dev, "Failed to create FIB entry\n");
4943                err = PTR_ERR(fib4_entry);
4944                goto err_fib4_entry_create;
4945        }
4946
4947        if (!mlxsw_sp_fib4_allow_replace(fib4_entry)) {
4948                mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
4949                mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
4950                return 0;
4951        }
4952
4953        replaced = fib_node->fib_entry;
4954        err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib4_entry->common);
4955        if (err) {
4956                dev_warn(mlxsw_sp->bus_info->dev, "Failed to link FIB entry to node\n");
4957                goto err_fib_node_entry_link;
4958        }
4959
4960        /* Nothing to replace */
4961        if (!replaced)
4962                return 0;
4963
4964        mlxsw_sp_fib_entry_hw_flags_clear(mlxsw_sp, replaced);
4965        fib4_replaced = container_of(replaced, struct mlxsw_sp_fib4_entry,
4966                                     common);
4967        mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_replaced);
4968
4969        return 0;
4970
4971err_fib_node_entry_link:
4972        fib_node->fib_entry = replaced;
4973        mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
4974err_fib4_entry_create:
4975        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
4976        return err;
4977}
4978
4979static void mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp,
4980                                     struct fib_entry_notifier_info *fen_info)
4981{
4982        struct mlxsw_sp_fib4_entry *fib4_entry;
4983        struct mlxsw_sp_fib_node *fib_node;
4984
4985        if (mlxsw_sp->router->aborted)
4986                return;
4987
4988        fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info);
4989        if (!fib4_entry)
4990                return;
4991        fib_node = fib4_entry->common.fib_node;
4992
4993        mlxsw_sp_fib_node_entry_unlink(mlxsw_sp, &fib4_entry->common);
4994        mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
4995        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
4996}
4997
4998static bool mlxsw_sp_fib6_rt_should_ignore(const struct fib6_info *rt)
4999{
5000        /* Packets with link-local destination IP arriving to the router
5001         * are trapped to the CPU, so no need to program specific routes
5002         * for them.
5003         */
5004        if (ipv6_addr_type(&rt->fib6_dst.addr) & IPV6_ADDR_LINKLOCAL)
5005                return true;
5006
5007        /* Multicast routes aren't supported, so ignore them. Neighbour
5008         * Discovery packets are specifically trapped.
5009         */
5010        if (ipv6_addr_type(&rt->fib6_dst.addr) & IPV6_ADDR_MULTICAST)
5011                return true;
5012
5013        /* Cloned routes are irrelevant in the forwarding path. */
5014        if (rt->fib6_flags & RTF_CACHE)
5015                return true;
5016
5017        return false;
5018}
5019
5020static struct mlxsw_sp_rt6 *mlxsw_sp_rt6_create(struct fib6_info *rt)
5021{
5022        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5023
5024        mlxsw_sp_rt6 = kzalloc(sizeof(*mlxsw_sp_rt6), GFP_KERNEL);
5025        if (!mlxsw_sp_rt6)
5026                return ERR_PTR(-ENOMEM);
5027
5028        /* In case of route replace, replaced route is deleted with
5029         * no notification. Take reference to prevent accessing freed
5030         * memory.
5031         */
5032        mlxsw_sp_rt6->rt = rt;
5033        fib6_info_hold(rt);
5034
5035        return mlxsw_sp_rt6;
5036}
5037
5038#if IS_ENABLED(CONFIG_IPV6)
5039static void mlxsw_sp_rt6_release(struct fib6_info *rt)
5040{
5041        fib6_info_release(rt);
5042}
5043#else
5044static void mlxsw_sp_rt6_release(struct fib6_info *rt)
5045{
5046}
5047#endif
5048
5049static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
5050{
5051        struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh;
5052
5053        fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
5054        mlxsw_sp_rt6_release(mlxsw_sp_rt6->rt);
5055        kfree(mlxsw_sp_rt6);
5056}
5057
5058static struct fib6_info *
5059mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
5060{
5061        return list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6,
5062                                list)->rt;
5063}
5064
5065static struct mlxsw_sp_rt6 *
5066mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,
5067                            const struct fib6_info *rt)
5068{
5069        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5070
5071        list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) {
5072                if (mlxsw_sp_rt6->rt == rt)
5073                        return mlxsw_sp_rt6;
5074        }
5075
5076        return NULL;
5077}
5078
5079static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp,
5080                                        const struct fib6_info *rt,
5081                                        enum mlxsw_sp_ipip_type *ret)
5082{
5083        return rt->fib6_nh->fib_nh_dev &&
5084               mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->fib6_nh->fib_nh_dev, ret);
5085}
5086
5087static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
5088                                       struct mlxsw_sp_nexthop_group *nh_grp,
5089                                       struct mlxsw_sp_nexthop *nh,
5090                                       const struct fib6_info *rt)
5091{
5092        const struct mlxsw_sp_ipip_ops *ipip_ops;
5093        struct mlxsw_sp_ipip_entry *ipip_entry;
5094        struct net_device *dev = rt->fib6_nh->fib_nh_dev;
5095        struct mlxsw_sp_rif *rif;
5096        int err;
5097
5098        ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, dev);
5099        if (ipip_entry) {
5100                ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt];
5101                if (ipip_ops->can_offload(mlxsw_sp, dev,
5102                                          MLXSW_SP_L3_PROTO_IPV6)) {
5103                        nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
5104                        mlxsw_sp_nexthop_ipip_init(mlxsw_sp, nh, ipip_entry);
5105                        return 0;
5106                }
5107        }
5108
5109        nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
5110        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
5111        if (!rif)
5112                return 0;
5113        mlxsw_sp_nexthop_rif_init(nh, rif);
5114
5115        err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
5116        if (err)
5117                goto err_nexthop_neigh_init;
5118
5119        return 0;
5120
5121err_nexthop_neigh_init:
5122        mlxsw_sp_nexthop_rif_fini(nh);
5123        return err;
5124}
5125
5126static void mlxsw_sp_nexthop6_type_fini(struct mlxsw_sp *mlxsw_sp,
5127                                        struct mlxsw_sp_nexthop *nh)
5128{
5129        mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
5130}
5131
5132static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,
5133                                  struct mlxsw_sp_nexthop_group *nh_grp,
5134                                  struct mlxsw_sp_nexthop *nh,
5135                                  const struct fib6_info *rt)
5136{
5137        struct net_device *dev = rt->fib6_nh->fib_nh_dev;
5138
5139        nh->nh_grp = nh_grp;
5140        nh->nh_weight = rt->fib6_nh->fib_nh_weight;
5141        memcpy(&nh->gw_addr, &rt->fib6_nh->fib_nh_gw6, sizeof(nh->gw_addr));
5142        mlxsw_sp_nexthop_counter_alloc(mlxsw_sp, nh);
5143
5144        list_add_tail(&nh->router_list_node, &mlxsw_sp->router->nexthop_list);
5145
5146        if (!dev)
5147                return 0;
5148        nh->ifindex = dev->ifindex;
5149
5150        return mlxsw_sp_nexthop6_type_init(mlxsw_sp, nh_grp, nh, rt);
5151}
5152
5153static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,
5154                                   struct mlxsw_sp_nexthop *nh)
5155{
5156        mlxsw_sp_nexthop6_type_fini(mlxsw_sp, nh);
5157        list_del(&nh->router_list_node);
5158        mlxsw_sp_nexthop_counter_free(mlxsw_sp, nh);
5159}
5160
5161static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
5162                                    const struct fib6_info *rt)
5163{
5164        return rt->fib6_nh->fib_nh_gw_family ||
5165               mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, NULL);
5166}
5167
5168static struct mlxsw_sp_nexthop_group *
5169mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,
5170                               struct mlxsw_sp_fib6_entry *fib6_entry)
5171{
5172        struct mlxsw_sp_nexthop_group *nh_grp;
5173        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5174        struct mlxsw_sp_nexthop *nh;
5175        int i = 0;
5176        int err;
5177
5178        nh_grp = kzalloc(struct_size(nh_grp, nexthops, fib6_entry->nrt6),
5179                         GFP_KERNEL);
5180        if (!nh_grp)
5181                return ERR_PTR(-ENOMEM);
5182        INIT_LIST_HEAD(&nh_grp->fib_list);
5183#if IS_ENABLED(CONFIG_IPV6)
5184        nh_grp->neigh_tbl = &nd_tbl;
5185#endif
5186        mlxsw_sp_rt6 = list_first_entry(&fib6_entry->rt6_list,
5187                                        struct mlxsw_sp_rt6, list);
5188        nh_grp->gateway = mlxsw_sp_rt6_is_gateway(mlxsw_sp, mlxsw_sp_rt6->rt);
5189        nh_grp->count = fib6_entry->nrt6;
5190        for (i = 0; i < nh_grp->count; i++) {
5191                struct fib6_info *rt = mlxsw_sp_rt6->rt;
5192
5193                nh = &nh_grp->nexthops[i];
5194                err = mlxsw_sp_nexthop6_init(mlxsw_sp, nh_grp, nh, rt);
5195                if (err)
5196                        goto err_nexthop6_init;
5197                mlxsw_sp_rt6 = list_next_entry(mlxsw_sp_rt6, list);
5198        }
5199
5200        err = mlxsw_sp_nexthop_group_insert(mlxsw_sp, nh_grp);
5201        if (err)
5202                goto err_nexthop_group_insert;
5203
5204        mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
5205        return nh_grp;
5206
5207err_nexthop_group_insert:
5208err_nexthop6_init:
5209        for (i--; i >= 0; i--) {
5210                nh = &nh_grp->nexthops[i];
5211                mlxsw_sp_nexthop6_fini(mlxsw_sp, nh);
5212        }
5213        kfree(nh_grp);
5214        return ERR_PTR(err);
5215}
5216
5217static void
5218mlxsw_sp_nexthop6_group_destroy(struct mlxsw_sp *mlxsw_sp,
5219                                struct mlxsw_sp_nexthop_group *nh_grp)
5220{
5221        struct mlxsw_sp_nexthop *nh;
5222        int i = nh_grp->count;
5223
5224        mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp);
5225        for (i--; i >= 0; i--) {
5226                nh = &nh_grp->nexthops[i];
5227                mlxsw_sp_nexthop6_fini(mlxsw_sp, nh);
5228        }
5229        mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
5230        WARN_ON(nh_grp->adj_index_valid);
5231        kfree(nh_grp);
5232}
5233
5234static int mlxsw_sp_nexthop6_group_get(struct mlxsw_sp *mlxsw_sp,
5235                                       struct mlxsw_sp_fib6_entry *fib6_entry)
5236{
5237        struct mlxsw_sp_nexthop_group *nh_grp;
5238
5239        nh_grp = mlxsw_sp_nexthop6_group_lookup(mlxsw_sp, fib6_entry);
5240        if (!nh_grp) {
5241                nh_grp = mlxsw_sp_nexthop6_group_create(mlxsw_sp, fib6_entry);
5242                if (IS_ERR(nh_grp))
5243                        return PTR_ERR(nh_grp);
5244        }
5245
5246        list_add_tail(&fib6_entry->common.nexthop_group_node,
5247                      &nh_grp->fib_list);
5248        fib6_entry->common.nh_group = nh_grp;
5249
5250        /* The route and the nexthop are described by the same struct, so we
5251         * need to the update the nexthop offload indication for the new route.
5252         */
5253        __mlxsw_sp_nexthop6_group_offload_refresh(nh_grp, fib6_entry);
5254
5255        return 0;
5256}
5257
5258static void mlxsw_sp_nexthop6_group_put(struct mlxsw_sp *mlxsw_sp,
5259                                        struct mlxsw_sp_fib_entry *fib_entry)
5260{
5261        struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group;
5262
5263        list_del(&fib_entry->nexthop_group_node);
5264        if (!list_empty(&nh_grp->fib_list))
5265                return;
5266        mlxsw_sp_nexthop6_group_destroy(mlxsw_sp, nh_grp);
5267}
5268
5269static int
5270mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp,
5271                               struct mlxsw_sp_fib6_entry *fib6_entry)
5272{
5273        struct mlxsw_sp_nexthop_group *old_nh_grp = fib6_entry->common.nh_group;
5274        int err;
5275
5276        fib6_entry->common.nh_group = NULL;
5277        list_del(&fib6_entry->common.nexthop_group_node);
5278
5279        err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry);
5280        if (err)
5281                goto err_nexthop6_group_get;
5282
5283        /* In case this entry is offloaded, then the adjacency index
5284         * currently associated with it in the device's table is that
5285         * of the old group. Start using the new one instead.
5286         */
5287        err = mlxsw_sp_fib_entry_update(mlxsw_sp, &fib6_entry->common);
5288        if (err)
5289                goto err_fib_entry_update;
5290
5291        if (list_empty(&old_nh_grp->fib_list))
5292                mlxsw_sp_nexthop6_group_destroy(mlxsw_sp, old_nh_grp);
5293
5294        return 0;
5295
5296err_fib_entry_update:
5297        mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common);
5298err_nexthop6_group_get:
5299        list_add_tail(&fib6_entry->common.nexthop_group_node,
5300                      &old_nh_grp->fib_list);
5301        fib6_entry->common.nh_group = old_nh_grp;
5302        return err;
5303}
5304
5305static int
5306mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp,
5307                                struct mlxsw_sp_fib6_entry *fib6_entry,
5308                                struct fib6_info **rt_arr, unsigned int nrt6)
5309{
5310        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5311        int err, i;
5312
5313        for (i = 0; i < nrt6; i++) {
5314                mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt_arr[i]);
5315                if (IS_ERR(mlxsw_sp_rt6)) {
5316                        err = PTR_ERR(mlxsw_sp_rt6);
5317                        goto err_rt6_create;
5318                }
5319
5320                list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
5321                fib6_entry->nrt6++;
5322        }
5323
5324        err = mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
5325        if (err)
5326                goto err_nexthop6_group_update;
5327
5328        return 0;
5329
5330err_nexthop6_group_update:
5331        i = nrt6;
5332err_rt6_create:
5333        for (i--; i >= 0; i--) {
5334                fib6_entry->nrt6--;
5335                mlxsw_sp_rt6 = list_last_entry(&fib6_entry->rt6_list,
5336                                               struct mlxsw_sp_rt6, list);
5337                list_del(&mlxsw_sp_rt6->list);
5338                mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
5339        }
5340        return err;
5341}
5342
5343static void
5344mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,
5345                                struct mlxsw_sp_fib6_entry *fib6_entry,
5346                                struct fib6_info **rt_arr, unsigned int nrt6)
5347{
5348        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5349        int i;
5350
5351        for (i = 0; i < nrt6; i++) {
5352                mlxsw_sp_rt6 = mlxsw_sp_fib6_entry_rt_find(fib6_entry,
5353                                                           rt_arr[i]);
5354                if (WARN_ON_ONCE(!mlxsw_sp_rt6))
5355                        continue;
5356
5357                fib6_entry->nrt6--;
5358                list_del(&mlxsw_sp_rt6->list);
5359                mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
5360        }
5361
5362        mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry);
5363}
5364
5365static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp,
5366                                         struct mlxsw_sp_fib_entry *fib_entry,
5367                                         const struct fib6_info *rt)
5368{
5369        /* Packets hitting RTF_REJECT routes need to be discarded by the
5370         * stack. We can rely on their destination device not having a
5371         * RIF (it's the loopback device) and can thus use action type
5372         * local, which will cause them to be trapped with a lower
5373         * priority than packets that need to be locally received.
5374         */
5375        if (rt->fib6_flags & (RTF_LOCAL | RTF_ANYCAST))
5376                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
5377        else if (rt->fib6_type == RTN_BLACKHOLE)
5378                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE;
5379        else if (rt->fib6_flags & RTF_REJECT)
5380                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE;
5381        else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt))
5382                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
5383        else
5384                fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
5385}
5386
5387static void
5388mlxsw_sp_fib6_entry_rt_destroy_all(struct mlxsw_sp_fib6_entry *fib6_entry)
5389{
5390        struct mlxsw_sp_rt6 *mlxsw_sp_rt6, *tmp;
5391
5392        list_for_each_entry_safe(mlxsw_sp_rt6, tmp, &fib6_entry->rt6_list,
5393                                 list) {
5394                fib6_entry->nrt6--;
5395                list_del(&mlxsw_sp_rt6->list);
5396                mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
5397        }
5398}
5399
5400static struct mlxsw_sp_fib6_entry *
5401mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
5402                           struct mlxsw_sp_fib_node *fib_node,
5403                           struct fib6_info **rt_arr, unsigned int nrt6)
5404{
5405        struct mlxsw_sp_fib6_entry *fib6_entry;
5406        struct mlxsw_sp_fib_entry *fib_entry;
5407        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
5408        int err, i;
5409
5410        fib6_entry = kzalloc(sizeof(*fib6_entry), GFP_KERNEL);
5411        if (!fib6_entry)
5412                return ERR_PTR(-ENOMEM);
5413        fib_entry = &fib6_entry->common;
5414
5415        INIT_LIST_HEAD(&fib6_entry->rt6_list);
5416
5417        for (i = 0; i < nrt6; i++) {
5418                mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt_arr[i]);
5419                if (IS_ERR(mlxsw_sp_rt6)) {
5420                        err = PTR_ERR(mlxsw_sp_rt6);
5421                        goto err_rt6_create;
5422                }
5423                list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
5424                fib6_entry->nrt6++;
5425        }
5426
5427        mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, rt_arr[0]);
5428
5429        err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry);
5430        if (err)
5431                goto err_nexthop6_group_get;
5432
5433        fib_entry->fib_node = fib_node;
5434
5435        return fib6_entry;
5436
5437err_nexthop6_group_get:
5438        i = nrt6;
5439err_rt6_create:
5440        for (i--; i >= 0; i--) {
5441                fib6_entry->nrt6--;
5442                mlxsw_sp_rt6 = list_last_entry(&fib6_entry->rt6_list,
5443                                               struct mlxsw_sp_rt6, list);
5444                list_del(&mlxsw_sp_rt6->list);
5445                mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
5446        }
5447        kfree(fib6_entry);
5448        return ERR_PTR(err);
5449}
5450
5451static void mlxsw_sp_fib6_entry_destroy(struct mlxsw_sp *mlxsw_sp,
5452                                        struct mlxsw_sp_fib6_entry *fib6_entry)
5453{
5454        mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common);
5455        mlxsw_sp_fib6_entry_rt_destroy_all(fib6_entry);
5456        WARN_ON(fib6_entry->nrt6);
5457        kfree(fib6_entry);
5458}
5459
5460static struct mlxsw_sp_fib6_entry *
5461mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,
5462                           const struct fib6_info *rt)
5463{
5464        struct mlxsw_sp_fib6_entry *fib6_entry;
5465        struct mlxsw_sp_fib_node *fib_node;
5466        struct mlxsw_sp_fib *fib;
5467        struct fib6_info *cmp_rt;
5468        struct mlxsw_sp_vr *vr;
5469
5470        vr = mlxsw_sp_vr_find(mlxsw_sp, rt->fib6_table->tb6_id);
5471        if (!vr)
5472                return NULL;
5473        fib = mlxsw_sp_vr_fib(vr, MLXSW_SP_L3_PROTO_IPV6);
5474
5475        fib_node = mlxsw_sp_fib_node_lookup(fib, &rt->fib6_dst.addr,
5476                                            sizeof(rt->fib6_dst.addr),
5477                                            rt->fib6_dst.plen);
5478        if (!fib_node)
5479                return NULL;
5480
5481        fib6_entry = container_of(fib_node->fib_entry,
5482                                  struct mlxsw_sp_fib6_entry, common);
5483        cmp_rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
5484        if (rt->fib6_table->tb6_id == cmp_rt->fib6_table->tb6_id &&
5485            rt->fib6_metric == cmp_rt->fib6_metric &&
5486            mlxsw_sp_fib6_entry_rt_find(fib6_entry, rt))
5487                return fib6_entry;
5488
5489        return NULL;
5490}
5491
5492static bool mlxsw_sp_fib6_allow_replace(struct mlxsw_sp_fib6_entry *fib6_entry)
5493{
5494        struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
5495        struct mlxsw_sp_fib6_entry *fib6_replaced;
5496        struct fib6_info *rt, *rt_replaced;
5497
5498        if (!fib_node->fib_entry)
5499                return true;
5500
5501        fib6_replaced = container_of(fib_node->fib_entry,
5502                                     struct mlxsw_sp_fib6_entry,
5503                                     common);
5504        rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
5505        rt_replaced = mlxsw_sp_fib6_entry_rt(fib6_replaced);
5506        if (rt->fib6_table->tb6_id == RT_TABLE_MAIN &&
5507            rt_replaced->fib6_table->tb6_id == RT_TABLE_LOCAL)
5508                return false;
5509
5510        return true;
5511}
5512
5513static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
5514                                        struct fib6_info **rt_arr,
5515                                        unsigned int nrt6)
5516{
5517        struct mlxsw_sp_fib6_entry *fib6_entry, *fib6_replaced;
5518        struct mlxsw_sp_fib_entry *replaced;
5519        struct mlxsw_sp_fib_node *fib_node;
5520        struct fib6_info *rt = rt_arr[0];
5521        int err;
5522
5523        if (mlxsw_sp->router->aborted)
5524                return 0;
5525
5526        if (rt->fib6_src.plen)
5527                return -EINVAL;
5528
5529        if (mlxsw_sp_fib6_rt_should_ignore(rt))
5530                return 0;
5531
5532        fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, rt->fib6_table->tb6_id,
5533                                         &rt->fib6_dst.addr,
5534                                         sizeof(rt->fib6_dst.addr),
5535                                         rt->fib6_dst.plen,
5536                                         MLXSW_SP_L3_PROTO_IPV6);
5537        if (IS_ERR(fib_node))
5538                return PTR_ERR(fib_node);
5539
5540        fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt_arr,
5541                                                nrt6);
5542        if (IS_ERR(fib6_entry)) {
5543                err = PTR_ERR(fib6_entry);
5544                goto err_fib6_entry_create;
5545        }
5546
5547        if (!mlxsw_sp_fib6_allow_replace(fib6_entry)) {
5548                mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
5549                mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5550                return 0;
5551        }
5552
5553        replaced = fib_node->fib_entry;
5554        err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib6_entry->common);
5555        if (err)
5556                goto err_fib_node_entry_link;
5557
5558        /* Nothing to replace */
5559        if (!replaced)
5560                return 0;
5561
5562        mlxsw_sp_fib_entry_hw_flags_clear(mlxsw_sp, replaced);
5563        fib6_replaced = container_of(replaced, struct mlxsw_sp_fib6_entry,
5564                                     common);
5565        mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_replaced);
5566
5567        return 0;
5568
5569err_fib_node_entry_link:
5570        fib_node->fib_entry = replaced;
5571        mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
5572err_fib6_entry_create:
5573        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5574        return err;
5575}
5576
5577static int mlxsw_sp_router_fib6_append(struct mlxsw_sp *mlxsw_sp,
5578                                       struct fib6_info **rt_arr,
5579                                       unsigned int nrt6)
5580{
5581        struct mlxsw_sp_fib6_entry *fib6_entry;
5582        struct mlxsw_sp_fib_node *fib_node;
5583        struct fib6_info *rt = rt_arr[0];
5584        int err;
5585
5586        if (mlxsw_sp->router->aborted)
5587                return 0;
5588
5589        if (rt->fib6_src.plen)
5590                return -EINVAL;
5591
5592        if (mlxsw_sp_fib6_rt_should_ignore(rt))
5593                return 0;
5594
5595        fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, rt->fib6_table->tb6_id,
5596                                         &rt->fib6_dst.addr,
5597                                         sizeof(rt->fib6_dst.addr),
5598                                         rt->fib6_dst.plen,
5599                                         MLXSW_SP_L3_PROTO_IPV6);
5600        if (IS_ERR(fib_node))
5601                return PTR_ERR(fib_node);
5602
5603        if (WARN_ON_ONCE(!fib_node->fib_entry)) {
5604                mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5605                return -EINVAL;
5606        }
5607
5608        fib6_entry = container_of(fib_node->fib_entry,
5609                                  struct mlxsw_sp_fib6_entry, common);
5610        err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt_arr,
5611                                              nrt6);
5612        if (err)
5613                goto err_fib6_entry_nexthop_add;
5614
5615        return 0;
5616
5617err_fib6_entry_nexthop_add:
5618        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5619        return err;
5620}
5621
5622static void mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp,
5623                                     struct fib6_info **rt_arr,
5624                                     unsigned int nrt6)
5625{
5626        struct mlxsw_sp_fib6_entry *fib6_entry;
5627        struct mlxsw_sp_fib_node *fib_node;
5628        struct fib6_info *rt = rt_arr[0];
5629
5630        if (mlxsw_sp->router->aborted)
5631                return;
5632
5633        if (mlxsw_sp_fib6_rt_should_ignore(rt))
5634                return;
5635
5636        /* Multipath routes are first added to the FIB trie and only then
5637         * notified. If we vetoed the addition, we will get a delete
5638         * notification for a route we do not have. Therefore, do not warn if
5639         * route was not found.
5640         */
5641        fib6_entry = mlxsw_sp_fib6_entry_lookup(mlxsw_sp, rt);
5642        if (!fib6_entry)
5643                return;
5644
5645        /* If not all the nexthops are deleted, then only reduce the nexthop
5646         * group.
5647         */
5648        if (nrt6 != fib6_entry->nrt6) {
5649                mlxsw_sp_fib6_entry_nexthop_del(mlxsw_sp, fib6_entry, rt_arr,
5650                                                nrt6);
5651                return;
5652        }
5653
5654        fib_node = fib6_entry->common.fib_node;
5655
5656        mlxsw_sp_fib_node_entry_unlink(mlxsw_sp, &fib6_entry->common);
5657        mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
5658        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5659}
5660
5661static int __mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp,
5662                                            enum mlxsw_reg_ralxx_protocol proto,
5663                                            u8 tree_id)
5664{
5665        char ralta_pl[MLXSW_REG_RALTA_LEN];
5666        char ralst_pl[MLXSW_REG_RALST_LEN];
5667        int i, err;
5668
5669        mlxsw_reg_ralta_pack(ralta_pl, true, proto, tree_id);
5670        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl);
5671        if (err)
5672                return err;
5673
5674        mlxsw_reg_ralst_pack(ralst_pl, 0xff, tree_id);
5675        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralst), ralst_pl);
5676        if (err)
5677                return err;
5678
5679        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
5680                struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i];
5681                char raltb_pl[MLXSW_REG_RALTB_LEN];
5682                char ralue_pl[MLXSW_REG_RALUE_LEN];
5683
5684                mlxsw_reg_raltb_pack(raltb_pl, vr->id, proto, tree_id);
5685                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb),
5686                                      raltb_pl);
5687                if (err)
5688                        return err;
5689
5690                mlxsw_reg_ralue_pack(ralue_pl, proto,
5691                                     MLXSW_REG_RALUE_OP_WRITE_WRITE, vr->id, 0);
5692                mlxsw_reg_ralue_act_ip2me_pack(ralue_pl);
5693                err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue),
5694                                      ralue_pl);
5695                if (err)
5696                        return err;
5697        }
5698
5699        return 0;
5700}
5701
5702static struct mlxsw_sp_mr_table *
5703mlxsw_sp_router_fibmr_family_to_table(struct mlxsw_sp_vr *vr, int family)
5704{
5705        if (family == RTNL_FAMILY_IPMR)
5706                return vr->mr_table[MLXSW_SP_L3_PROTO_IPV4];
5707        else
5708                return vr->mr_table[MLXSW_SP_L3_PROTO_IPV6];
5709}
5710
5711static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
5712                                     struct mfc_entry_notifier_info *men_info,
5713                                     bool replace)
5714{
5715        struct mlxsw_sp_mr_table *mrt;
5716        struct mlxsw_sp_vr *vr;
5717
5718        if (mlxsw_sp->router->aborted)
5719                return 0;
5720
5721        vr = mlxsw_sp_vr_get(mlxsw_sp, men_info->tb_id, NULL);
5722        if (IS_ERR(vr))
5723                return PTR_ERR(vr);
5724
5725        mrt = mlxsw_sp_router_fibmr_family_to_table(vr, men_info->info.family);
5726        return mlxsw_sp_mr_route_add(mrt, men_info->mfc, replace);
5727}
5728
5729static void mlxsw_sp_router_fibmr_del(struct mlxsw_sp *mlxsw_sp,
5730                                      struct mfc_entry_notifier_info *men_info)
5731{
5732        struct mlxsw_sp_mr_table *mrt;
5733        struct mlxsw_sp_vr *vr;
5734
5735        if (mlxsw_sp->router->aborted)
5736                return;
5737
5738        vr = mlxsw_sp_vr_find(mlxsw_sp, men_info->tb_id);
5739        if (WARN_ON(!vr))
5740                return;
5741
5742        mrt = mlxsw_sp_router_fibmr_family_to_table(vr, men_info->info.family);
5743        mlxsw_sp_mr_route_del(mrt, men_info->mfc);
5744        mlxsw_sp_vr_put(mlxsw_sp, vr);
5745}
5746
5747static int
5748mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
5749                              struct vif_entry_notifier_info *ven_info)
5750{
5751        struct mlxsw_sp_mr_table *mrt;
5752        struct mlxsw_sp_rif *rif;
5753        struct mlxsw_sp_vr *vr;
5754
5755        if (mlxsw_sp->router->aborted)
5756                return 0;
5757
5758        vr = mlxsw_sp_vr_get(mlxsw_sp, ven_info->tb_id, NULL);
5759        if (IS_ERR(vr))
5760                return PTR_ERR(vr);
5761
5762        mrt = mlxsw_sp_router_fibmr_family_to_table(vr, ven_info->info.family);
5763        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, ven_info->dev);
5764        return mlxsw_sp_mr_vif_add(mrt, ven_info->dev,
5765                                   ven_info->vif_index,
5766                                   ven_info->vif_flags, rif);
5767}
5768
5769static void
5770mlxsw_sp_router_fibmr_vif_del(struct mlxsw_sp *mlxsw_sp,
5771                              struct vif_entry_notifier_info *ven_info)
5772{
5773        struct mlxsw_sp_mr_table *mrt;
5774        struct mlxsw_sp_vr *vr;
5775
5776        if (mlxsw_sp->router->aborted)
5777                return;
5778
5779        vr = mlxsw_sp_vr_find(mlxsw_sp, ven_info->tb_id);
5780        if (WARN_ON(!vr))
5781                return;
5782
5783        mrt = mlxsw_sp_router_fibmr_family_to_table(vr, ven_info->info.family);
5784        mlxsw_sp_mr_vif_del(mrt, ven_info->vif_index);
5785        mlxsw_sp_vr_put(mlxsw_sp, vr);
5786}
5787
5788static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp)
5789{
5790        enum mlxsw_reg_ralxx_protocol proto = MLXSW_REG_RALXX_PROTOCOL_IPV4;
5791        int err;
5792
5793        err = __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto,
5794                                               MLXSW_SP_LPM_TREE_MIN);
5795        if (err)
5796                return err;
5797
5798        /* The multicast router code does not need an abort trap as by default,
5799         * packets that don't match any routes are trapped to the CPU.
5800         */
5801
5802        proto = MLXSW_REG_RALXX_PROTOCOL_IPV6;
5803        return __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto,
5804                                                MLXSW_SP_LPM_TREE_MIN + 1);
5805}
5806
5807static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp,
5808                                     struct mlxsw_sp_fib_node *fib_node)
5809{
5810        struct mlxsw_sp_fib4_entry *fib4_entry;
5811
5812        fib4_entry = container_of(fib_node->fib_entry,
5813                                  struct mlxsw_sp_fib4_entry, common);
5814        mlxsw_sp_fib_node_entry_unlink(mlxsw_sp, fib_node->fib_entry);
5815        mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
5816        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5817}
5818
5819static void mlxsw_sp_fib6_node_flush(struct mlxsw_sp *mlxsw_sp,
5820                                     struct mlxsw_sp_fib_node *fib_node)
5821{
5822        struct mlxsw_sp_fib6_entry *fib6_entry;
5823
5824        fib6_entry = container_of(fib_node->fib_entry,
5825                                  struct mlxsw_sp_fib6_entry, common);
5826        mlxsw_sp_fib_node_entry_unlink(mlxsw_sp, fib_node->fib_entry);
5827        mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
5828        mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
5829}
5830
5831static void mlxsw_sp_fib_node_flush(struct mlxsw_sp *mlxsw_sp,
5832                                    struct mlxsw_sp_fib_node *fib_node)
5833{
5834        switch (fib_node->fib->proto) {
5835        case MLXSW_SP_L3_PROTO_IPV4:
5836                mlxsw_sp_fib4_node_flush(mlxsw_sp, fib_node);
5837                break;
5838        case MLXSW_SP_L3_PROTO_IPV6:
5839                mlxsw_sp_fib6_node_flush(mlxsw_sp, fib_node);
5840                break;
5841        }
5842}
5843
5844static void mlxsw_sp_vr_fib_flush(struct mlxsw_sp *mlxsw_sp,
5845                                  struct mlxsw_sp_vr *vr,
5846                                  enum mlxsw_sp_l3proto proto)
5847{
5848        struct mlxsw_sp_fib *fib = mlxsw_sp_vr_fib(vr, proto);
5849        struct mlxsw_sp_fib_node *fib_node, *tmp;
5850
5851        list_for_each_entry_safe(fib_node, tmp, &fib->node_list, list) {
5852                bool do_break = &tmp->list == &fib->node_list;
5853
5854                mlxsw_sp_fib_node_flush(mlxsw_sp, fib_node);
5855                if (do_break)
5856                        break;
5857        }
5858}
5859
5860static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp)
5861{
5862        int i, j;
5863
5864        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) {
5865                struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i];
5866
5867                if (!mlxsw_sp_vr_is_used(vr))
5868                        continue;
5869
5870                for (j = 0; j < MLXSW_SP_L3_PROTO_MAX; j++)
5871                        mlxsw_sp_mr_table_flush(vr->mr_table[j]);
5872                mlxsw_sp_vr_fib_flush(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4);
5873
5874                /* If virtual router was only used for IPv4, then it's no
5875                 * longer used.
5876                 */
5877                if (!mlxsw_sp_vr_is_used(vr))
5878                        continue;
5879                mlxsw_sp_vr_fib_flush(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6);
5880        }
5881
5882        /* After flushing all the routes, it is not possible anyone is still
5883         * using the adjacency index that is discarding packets, so free it in
5884         * case it was allocated.
5885         */
5886        if (!mlxsw_sp->router->adj_discard_index_valid)
5887                return;
5888        mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
5889                           mlxsw_sp->router->adj_discard_index);
5890        mlxsw_sp->router->adj_discard_index_valid = false;
5891}
5892
5893static void mlxsw_sp_router_fib_abort(struct mlxsw_sp *mlxsw_sp)
5894{
5895        int err;
5896
5897        if (mlxsw_sp->router->aborted)
5898                return;
5899        dev_warn(mlxsw_sp->bus_info->dev, "FIB abort triggered. Note that FIB entries are no longer being offloaded to this device.\n");
5900        mlxsw_sp_router_fib_flush(mlxsw_sp);
5901        mlxsw_sp->router->aborted = true;
5902        err = mlxsw_sp_router_set_abort_trap(mlxsw_sp);
5903        if (err)
5904                dev_warn(mlxsw_sp->bus_info->dev, "Failed to set abort trap.\n");
5905}
5906
5907struct mlxsw_sp_fib6_event_work {
5908        struct fib6_info **rt_arr;
5909        unsigned int nrt6;
5910};
5911
5912struct mlxsw_sp_fib_event_work {
5913        struct work_struct work;
5914        union {
5915                struct mlxsw_sp_fib6_event_work fib6_work;
5916                struct fib_entry_notifier_info fen_info;
5917                struct fib_rule_notifier_info fr_info;
5918                struct fib_nh_notifier_info fnh_info;
5919                struct mfc_entry_notifier_info men_info;
5920                struct vif_entry_notifier_info ven_info;
5921        };
5922        struct mlxsw_sp *mlxsw_sp;
5923        unsigned long event;
5924};
5925
5926static int
5927mlxsw_sp_router_fib6_work_init(struct mlxsw_sp_fib6_event_work *fib6_work,
5928                               struct fib6_entry_notifier_info *fen6_info)
5929{
5930        struct fib6_info *rt = fen6_info->rt;
5931        struct fib6_info **rt_arr;
5932        struct fib6_info *iter;
5933        unsigned int nrt6;
5934        int i = 0;
5935
5936        nrt6 = fen6_info->nsiblings + 1;
5937
5938        rt_arr = kcalloc(nrt6, sizeof(struct fib6_info *), GFP_ATOMIC);
5939        if (!rt_arr)
5940                return -ENOMEM;
5941
5942        fib6_work->rt_arr = rt_arr;
5943        fib6_work->nrt6 = nrt6;
5944
5945        rt_arr[0] = rt;
5946        fib6_info_hold(rt);
5947
5948        if (!fen6_info->nsiblings)
5949                return 0;
5950
5951        list_for_each_entry(iter, &rt->fib6_siblings, fib6_siblings) {
5952                if (i == fen6_info->nsiblings)
5953                        break;
5954
5955                rt_arr[i + 1] = iter;
5956                fib6_info_hold(iter);
5957                i++;
5958        }
5959        WARN_ON_ONCE(i != fen6_info->nsiblings);
5960
5961        return 0;
5962}
5963
5964static void
5965mlxsw_sp_router_fib6_work_fini(struct mlxsw_sp_fib6_event_work *fib6_work)
5966{
5967        int i;
5968
5969        for (i = 0; i < fib6_work->nrt6; i++)
5970                mlxsw_sp_rt6_release(fib6_work->rt_arr[i]);
5971        kfree(fib6_work->rt_arr);
5972}
5973
5974static void mlxsw_sp_router_fib4_event_work(struct work_struct *work)
5975{
5976        struct mlxsw_sp_fib_event_work *fib_work =
5977                container_of(work, struct mlxsw_sp_fib_event_work, work);
5978        struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
5979        int err;
5980
5981        mutex_lock(&mlxsw_sp->router->lock);
5982        mlxsw_sp_span_respin(mlxsw_sp);
5983
5984        switch (fib_work->event) {
5985        case FIB_EVENT_ENTRY_REPLACE:
5986                err = mlxsw_sp_router_fib4_replace(mlxsw_sp,
5987                                                   &fib_work->fen_info);
5988                if (err)
5989                        mlxsw_sp_router_fib_abort(mlxsw_sp);
5990                fib_info_put(fib_work->fen_info.fi);
5991                break;
5992        case FIB_EVENT_ENTRY_DEL:
5993                mlxsw_sp_router_fib4_del(mlxsw_sp, &fib_work->fen_info);
5994                fib_info_put(fib_work->fen_info.fi);
5995                break;
5996        case FIB_EVENT_NH_ADD: /* fall through */
5997        case FIB_EVENT_NH_DEL:
5998                mlxsw_sp_nexthop4_event(mlxsw_sp, fib_work->event,
5999                                        fib_work->fnh_info.fib_nh);
6000                fib_info_put(fib_work->fnh_info.fib_nh->nh_parent);
6001                break;
6002        }
6003        mutex_unlock(&mlxsw_sp->router->lock);
6004        kfree(fib_work);
6005}
6006
6007static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
6008{
6009        struct mlxsw_sp_fib_event_work *fib_work =
6010                container_of(work, struct mlxsw_sp_fib_event_work, work);
6011        struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
6012        int err;
6013
6014        mutex_lock(&mlxsw_sp->router->lock);
6015        mlxsw_sp_span_respin(mlxsw_sp);
6016
6017        switch (fib_work->event) {
6018        case FIB_EVENT_ENTRY_REPLACE:
6019                err = mlxsw_sp_router_fib6_replace(mlxsw_sp,
6020                                                   fib_work->fib6_work.rt_arr,
6021                                                   fib_work->fib6_work.nrt6);
6022                if (err)
6023                        mlxsw_sp_router_fib_abort(mlxsw_sp);
6024                mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
6025                break;
6026        case FIB_EVENT_ENTRY_APPEND:
6027                err = mlxsw_sp_router_fib6_append(mlxsw_sp,
6028                                                  fib_work->fib6_work.rt_arr,
6029                                                  fib_work->fib6_work.nrt6);
6030                if (err)
6031                        mlxsw_sp_router_fib_abort(mlxsw_sp);
6032                mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
6033                break;
6034        case FIB_EVENT_ENTRY_DEL:
6035                mlxsw_sp_router_fib6_del(mlxsw_sp,
6036                                         fib_work->fib6_work.rt_arr,
6037                                         fib_work->fib6_work.nrt6);
6038                mlxsw_sp_router_fib6_work_fini(&fib_work->fib6_work);
6039                break;
6040        }
6041        mutex_unlock(&mlxsw_sp->router->lock);
6042        kfree(fib_work);
6043}
6044
6045static void mlxsw_sp_router_fibmr_event_work(struct work_struct *work)
6046{
6047        struct mlxsw_sp_fib_event_work *fib_work =
6048                container_of(work, struct mlxsw_sp_fib_event_work, work);
6049        struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
6050        bool replace;
6051        int err;
6052
6053        rtnl_lock();
6054        mutex_lock(&mlxsw_sp->router->lock);
6055        switch (fib_work->event) {
6056        case FIB_EVENT_ENTRY_REPLACE: /* fall through */
6057        case FIB_EVENT_ENTRY_ADD:
6058                replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
6059
6060                err = mlxsw_sp_router_fibmr_add(mlxsw_sp, &fib_work->men_info,
6061                                                replace);
6062                if (err)
6063                        mlxsw_sp_router_fib_abort(mlxsw_sp);
6064                mr_cache_put(fib_work->men_info.mfc);
6065                break;
6066        case FIB_EVENT_ENTRY_DEL:
6067                mlxsw_sp_router_fibmr_del(mlxsw_sp, &fib_work->men_info);
6068                mr_cache_put(fib_work->men_info.mfc);
6069                break;
6070        case FIB_EVENT_VIF_ADD:
6071                err = mlxsw_sp_router_fibmr_vif_add(mlxsw_sp,
6072                                                    &fib_work->ven_info);
6073                if (err)
6074                        mlxsw_sp_router_fib_abort(mlxsw_sp);
6075                dev_put(fib_work->ven_info.dev);
6076                break;
6077        case FIB_EVENT_VIF_DEL:
6078                mlxsw_sp_router_fibmr_vif_del(mlxsw_sp,
6079                                              &fib_work->ven_info);
6080                dev_put(fib_work->ven_info.dev);
6081                break;
6082        }
6083        mutex_unlock(&mlxsw_sp->router->lock);
6084        rtnl_unlock();
6085        kfree(fib_work);
6086}
6087
6088static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work,
6089                                       struct fib_notifier_info *info)
6090{
6091        struct fib_entry_notifier_info *fen_info;
6092        struct fib_nh_notifier_info *fnh_info;
6093
6094        switch (fib_work->event) {
6095        case FIB_EVENT_ENTRY_REPLACE: /* fall through */
6096        case FIB_EVENT_ENTRY_DEL:
6097                fen_info = container_of(info, struct fib_entry_notifier_info,
6098                                        info);
6099                fib_work->fen_info = *fen_info;
6100                /* Take reference on fib_info to prevent it from being
6101                 * freed while work is queued. Release it afterwards.
6102                 */
6103                fib_info_hold(fib_work->fen_info.fi);
6104                break;
6105        case FIB_EVENT_NH_ADD: /* fall through */
6106        case FIB_EVENT_NH_DEL:
6107                fnh_info = container_of(info, struct fib_nh_notifier_info,
6108                                        info);
6109                fib_work->fnh_info = *fnh_info;
6110                fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent);
6111                break;
6112        }
6113}
6114
6115static int mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work,
6116                                      struct fib_notifier_info *info)
6117{
6118        struct fib6_entry_notifier_info *fen6_info;
6119        int err;
6120
6121        switch (fib_work->event) {
6122        case FIB_EVENT_ENTRY_REPLACE: /* fall through */
6123        case FIB_EVENT_ENTRY_APPEND: /* fall through */
6124        case FIB_EVENT_ENTRY_DEL:
6125                fen6_info = container_of(info, struct fib6_entry_notifier_info,
6126                                         info);
6127                err = mlxsw_sp_router_fib6_work_init(&fib_work->fib6_work,
6128                                                     fen6_info);
6129                if (err)
6130                        return err;
6131                break;
6132        }
6133
6134        return 0;
6135}
6136
6137static void
6138mlxsw_sp_router_fibmr_event(struct mlxsw_sp_fib_event_work *fib_work,
6139                            struct fib_notifier_info *info)
6140{
6141        switch (fib_work->event) {
6142        case FIB_EVENT_ENTRY_REPLACE: /* fall through */
6143        case FIB_EVENT_ENTRY_ADD: /* fall through */
6144        case FIB_EVENT_ENTRY_DEL:
6145                memcpy(&fib_work->men_info, info, sizeof(fib_work->men_info));
6146                mr_cache_hold(fib_work->men_info.mfc);
6147                break;
6148        case FIB_EVENT_VIF_ADD: /* fall through */
6149        case FIB_EVENT_VIF_DEL:
6150                memcpy(&fib_work->ven_info, info, sizeof(fib_work->ven_info));
6151                dev_hold(fib_work->ven_info.dev);
6152                break;
6153        }
6154}
6155
6156static int mlxsw_sp_router_fib_rule_event(unsigned long event,
6157                                          struct fib_notifier_info *info,
6158                                          struct mlxsw_sp *mlxsw_sp)
6159{
6160        struct netlink_ext_ack *extack = info->extack;
6161        struct fib_rule_notifier_info *fr_info;
6162        struct fib_rule *rule;
6163        int err = 0;
6164
6165        /* nothing to do at the moment */
6166        if (event == FIB_EVENT_RULE_DEL)
6167                return 0;
6168
6169        if (mlxsw_sp->router->aborted)
6170                return 0;
6171
6172        fr_info = container_of(info, struct fib_rule_notifier_info, info);
6173        rule = fr_info->rule;
6174
6175        /* Rule only affects locally generated traffic */
6176        if (rule->iifindex == mlxsw_sp_net(mlxsw_sp)->loopback_dev->ifindex)
6177                return 0;
6178
6179        switch (info->family) {
6180        case AF_INET:
6181                if (!fib4_rule_default(rule) && !rule->l3mdev)
6182                        err = -EOPNOTSUPP;
6183                break;
6184        case AF_INET6:
6185                if (!fib6_rule_default(rule) && !rule->l3mdev)
6186                        err = -EOPNOTSUPP;
6187                break;
6188        case RTNL_FAMILY_IPMR:
6189                if (!ipmr_rule_default(rule) && !rule->l3mdev)
6190                        err = -EOPNOTSUPP;
6191                break;
6192        case RTNL_FAMILY_IP6MR:
6193                if (!ip6mr_rule_default(rule) && !rule->l3mdev)
6194                        err = -EOPNOTSUPP;
6195                break;
6196        }
6197
6198        if (err < 0)
6199                NL_SET_ERR_MSG_MOD(extack, "FIB rules not supported");
6200
6201        return err;
6202}
6203
6204/* Called with rcu_read_lock() */
6205static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
6206                                     unsigned long event, void *ptr)
6207{
6208        struct mlxsw_sp_fib_event_work *fib_work;
6209        struct fib_notifier_info *info = ptr;
6210        struct mlxsw_sp_router *router;
6211        int err;
6212
6213        if ((info->family != AF_INET && info->family != AF_INET6 &&
6214             info->family != RTNL_FAMILY_IPMR &&
6215             info->family != RTNL_FAMILY_IP6MR))
6216                return NOTIFY_DONE;
6217
6218        router = container_of(nb, struct mlxsw_sp_router, fib_nb);
6219
6220        switch (event) {
6221        case FIB_EVENT_RULE_ADD: /* fall through */
6222        case FIB_EVENT_RULE_DEL:
6223                err = mlxsw_sp_router_fib_rule_event(event, info,
6224                                                     router->mlxsw_sp);
6225                return notifier_from_errno(err);
6226        case FIB_EVENT_ENTRY_ADD: /* fall through */
6227        case FIB_EVENT_ENTRY_REPLACE: /* fall through */
6228        case FIB_EVENT_ENTRY_APPEND:
6229                if (router->aborted) {
6230                        NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
6231                        return notifier_from_errno(-EINVAL);
6232                }
6233                if (info->family == AF_INET) {
6234                        struct fib_entry_notifier_info *fen_info = ptr;
6235
6236                        if (fen_info->fi->fib_nh_is_v6) {
6237                                NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported");
6238                                return notifier_from_errno(-EINVAL);
6239                        }
6240                        if (fen_info->fi->nh) {
6241                                NL_SET_ERR_MSG_MOD(info->extack, "IPv4 route with nexthop objects is not supported");
6242                                return notifier_from_errno(-EINVAL);
6243                        }
6244                } else if (info->family == AF_INET6) {
6245                        struct fib6_entry_notifier_info *fen6_info;
6246
6247                        fen6_info = container_of(info,
6248                                                 struct fib6_entry_notifier_info,
6249                                                 info);
6250                        if (fen6_info->rt->nh) {
6251                                NL_SET_ERR_MSG_MOD(info->extack, "IPv6 route with nexthop objects is not supported");
6252                                return notifier_from_errno(-EINVAL);
6253                        }
6254                }
6255                break;
6256        }
6257
6258        fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC);
6259        if (WARN_ON(!fib_work))
6260                return NOTIFY_BAD;
6261
6262        fib_work->mlxsw_sp = router->mlxsw_sp;
6263        fib_work->event = event;
6264
6265        switch (info->family) {
6266        case AF_INET:
6267                INIT_WORK(&fib_work->work, mlxsw_sp_router_fib4_event_work);
6268                mlxsw_sp_router_fib4_event(fib_work, info);
6269                break;
6270        case AF_INET6:
6271                INIT_WORK(&fib_work->work, mlxsw_sp_router_fib6_event_work);
6272                err = mlxsw_sp_router_fib6_event(fib_work, info);
6273                if (err)
6274                        goto err_fib_event;
6275                break;
6276        case RTNL_FAMILY_IP6MR:
6277        case RTNL_FAMILY_IPMR:
6278                INIT_WORK(&fib_work->work, mlxsw_sp_router_fibmr_event_work);
6279                mlxsw_sp_router_fibmr_event(fib_work, info);
6280                break;
6281        }
6282
6283        mlxsw_core_schedule_work(&fib_work->work);
6284
6285        return NOTIFY_DONE;
6286
6287err_fib_event:
6288        kfree(fib_work);
6289        return NOTIFY_BAD;
6290}
6291
6292static struct mlxsw_sp_rif *
6293mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
6294                         const struct net_device *dev)
6295{
6296        int i;
6297
6298        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
6299                if (mlxsw_sp->router->rifs[i] &&
6300                    mlxsw_sp->router->rifs[i]->dev == dev)
6301                        return mlxsw_sp->router->rifs[i];
6302
6303        return NULL;
6304}
6305
6306bool mlxsw_sp_rif_exists(struct mlxsw_sp *mlxsw_sp,
6307                         const struct net_device *dev)
6308{
6309        struct mlxsw_sp_rif *rif;
6310
6311        mutex_lock(&mlxsw_sp->router->lock);
6312        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
6313        mutex_unlock(&mlxsw_sp->router->lock);
6314
6315        return rif;
6316}
6317
6318u16 mlxsw_sp_rif_vid(struct mlxsw_sp *mlxsw_sp, const struct net_device *dev)
6319{
6320        struct mlxsw_sp_rif *rif;
6321        u16 vid = 0;
6322
6323        mutex_lock(&mlxsw_sp->router->lock);
6324        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
6325        if (!rif)
6326                goto out;
6327
6328        /* We only return the VID for VLAN RIFs. Otherwise we return an
6329         * invalid value (0).
6330         */
6331        if (rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN)
6332                goto out;
6333
6334        vid = mlxsw_sp_fid_8021q_vid(rif->fid);
6335
6336out:
6337        mutex_unlock(&mlxsw_sp->router->lock);
6338        return vid;
6339}
6340
6341static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif)
6342{
6343        char ritr_pl[MLXSW_REG_RITR_LEN];
6344        int err;
6345
6346        mlxsw_reg_ritr_rif_pack(ritr_pl, rif);
6347        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
6348        if (err)
6349                return err;
6350
6351        mlxsw_reg_ritr_enable_set(ritr_pl, false);
6352        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
6353}
6354
6355static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
6356                                          struct mlxsw_sp_rif *rif)
6357{
6358        mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index);
6359        mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif);
6360        mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);
6361}
6362
6363static bool
6364mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *rif, struct net_device *dev,
6365                           unsigned long event)
6366{
6367        struct inet6_dev *inet6_dev;
6368        bool addr_list_empty = true;
6369        struct in_device *idev;
6370
6371        switch (event) {
6372        case NETDEV_UP:
6373                return rif == NULL;
6374        case NETDEV_DOWN:
6375                rcu_read_lock();
6376                idev = __in_dev_get_rcu(dev);
6377                if (idev && idev->ifa_list)
6378                        addr_list_empty = false;
6379
6380                inet6_dev = __in6_dev_get(dev);
6381                if (addr_list_empty && inet6_dev &&
6382                    !list_empty(&inet6_dev->addr_list))
6383                        addr_list_empty = false;
6384                rcu_read_unlock();
6385
6386                /* macvlans do not have a RIF, but rather piggy back on the
6387                 * RIF of their lower device.
6388                 */
6389                if (netif_is_macvlan(dev) && addr_list_empty)
6390                        return true;
6391
6392                if (rif && addr_list_empty &&
6393                    !netif_is_l3_slave(rif->dev))
6394                        return true;
6395                /* It is possible we already removed the RIF ourselves
6396                 * if it was assigned to a netdev that is now a bridge
6397                 * or LAG slave.
6398                 */
6399                return false;
6400        }
6401
6402        return false;
6403}
6404
6405static enum mlxsw_sp_rif_type
6406mlxsw_sp_dev_rif_type(const struct mlxsw_sp *mlxsw_sp,
6407                      const struct net_device *dev)
6408{
6409        enum mlxsw_sp_fid_type type;
6410
6411        if (mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL))
6412                return MLXSW_SP_RIF_TYPE_IPIP_LB;
6413
6414        /* Otherwise RIF type is derived from the type of the underlying FID. */
6415        if (is_vlan_dev(dev) && netif_is_bridge_master(vlan_dev_real_dev(dev)))
6416                type = MLXSW_SP_FID_TYPE_8021Q;
6417        else if (netif_is_bridge_master(dev) && br_vlan_enabled(dev))
6418                type = MLXSW_SP_FID_TYPE_8021Q;
6419        else if (netif_is_bridge_master(dev))
6420                type = MLXSW_SP_FID_TYPE_8021D;
6421        else
6422                type = MLXSW_SP_FID_TYPE_RFID;
6423
6424        return mlxsw_sp_fid_type_rif_type(mlxsw_sp, type);
6425}
6426
6427static int mlxsw_sp_rif_index_alloc(struct mlxsw_sp *mlxsw_sp, u16 *p_rif_index)
6428{
6429        int i;
6430
6431        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
6432                if (!mlxsw_sp->router->rifs[i]) {
6433                        *p_rif_index = i;
6434                        return 0;
6435                }
6436        }
6437
6438        return -ENOBUFS;
6439}
6440
6441static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index,
6442                                               u16 vr_id,
6443                                               struct net_device *l3_dev)
6444{
6445        struct mlxsw_sp_rif *rif;
6446
6447        rif = kzalloc(rif_size, GFP_KERNEL);
6448        if (!rif)
6449                return NULL;
6450
6451        INIT_LIST_HEAD(&rif->nexthop_list);
6452        INIT_LIST_HEAD(&rif->neigh_list);
6453        if (l3_dev) {
6454                ether_addr_copy(rif->addr, l3_dev->dev_addr);
6455                rif->mtu = l3_dev->mtu;
6456                rif->dev = l3_dev;
6457        }
6458        rif->vr_id = vr_id;
6459        rif->rif_index = rif_index;
6460
6461        return rif;
6462}
6463
6464struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
6465                                           u16 rif_index)
6466{
6467        return mlxsw_sp->router->rifs[rif_index];
6468}
6469
6470u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif)
6471{
6472        return rif->rif_index;
6473}
6474
6475u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
6476{
6477        return lb_rif->common.rif_index;
6478}
6479
6480u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
6481{
6482        u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(lb_rif->common.dev);
6483        struct mlxsw_sp_vr *ul_vr;
6484
6485        ul_vr = mlxsw_sp_vr_get(lb_rif->common.mlxsw_sp, ul_tb_id, NULL);
6486        if (WARN_ON(IS_ERR(ul_vr)))
6487                return 0;
6488
6489        return ul_vr->id;
6490}
6491
6492u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif)
6493{
6494        return lb_rif->ul_rif_id;
6495}
6496
6497int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
6498{
6499        return rif->dev->ifindex;
6500}
6501
6502const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
6503{
6504        return rif->dev;
6505}
6506
6507static struct mlxsw_sp_rif *
6508mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
6509                    const struct mlxsw_sp_rif_params *params,
6510                    struct netlink_ext_ack *extack)
6511{
6512        u32 tb_id = l3mdev_fib_table(params->dev);
6513        const struct mlxsw_sp_rif_ops *ops;
6514        struct mlxsw_sp_fid *fid = NULL;
6515        enum mlxsw_sp_rif_type type;
6516        struct mlxsw_sp_rif *rif;
6517        struct mlxsw_sp_vr *vr;
6518        u16 rif_index;
6519        int i, err;
6520
6521        type = mlxsw_sp_dev_rif_type(mlxsw_sp, params->dev);
6522        ops = mlxsw_sp->rif_ops_arr[type];
6523
6524        vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN, extack);
6525        if (IS_ERR(vr))
6526                return ERR_CAST(vr);
6527        vr->rif_count++;
6528
6529        err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
6530        if (err) {
6531                NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported router interfaces");
6532                goto err_rif_index_alloc;
6533        }
6534
6535        rif = mlxsw_sp_rif_alloc(ops->rif_size, rif_index, vr->id, params->dev);
6536        if (!rif) {
6537                err = -ENOMEM;
6538                goto err_rif_alloc;
6539        }
6540        dev_hold(rif->dev);
6541        mlxsw_sp->router->rifs[rif_index] = rif;
6542        rif->mlxsw_sp = mlxsw_sp;
6543        rif->ops = ops;
6544
6545        if (ops->fid_get) {
6546                fid = ops->fid_get(rif, extack);
6547                if (IS_ERR(fid)) {
6548                        err = PTR_ERR(fid);
6549                        goto err_fid_get;
6550                }
6551                rif->fid = fid;
6552        }
6553
6554        if (ops->setup)
6555                ops->setup(rif, params);
6556
6557        err = ops->configure(rif);
6558        if (err)
6559                goto err_configure;
6560
6561        for (i = 0; i < MLXSW_SP_L3_PROTO_MAX; i++) {
6562                err = mlxsw_sp_mr_rif_add(vr->mr_table[i], rif);
6563                if (err)
6564                        goto err_mr_rif_add;
6565        }
6566
6567        mlxsw_sp_rif_counters_alloc(rif);
6568
6569        return rif;
6570
6571err_mr_rif_add:
6572        for (i--; i >= 0; i--)
6573                mlxsw_sp_mr_rif_del(vr->mr_table[i], rif);
6574        ops->deconfigure(rif);
6575err_configure:
6576        if (fid)
6577                mlxsw_sp_fid_put(fid);
6578err_fid_get:
6579        mlxsw_sp->router->rifs[rif_index] = NULL;
6580        dev_put(rif->dev);
6581        kfree(rif);
6582err_rif_alloc:
6583err_rif_index_alloc:
6584        vr->rif_count--;
6585        mlxsw_sp_vr_put(mlxsw_sp, vr);
6586        return ERR_PTR(err);
6587}
6588
6589static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
6590{
6591        const struct mlxsw_sp_rif_ops *ops = rif->ops;
6592        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
6593        struct mlxsw_sp_fid *fid = rif->fid;
6594        struct mlxsw_sp_vr *vr;
6595        int i;
6596
6597        mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
6598        vr = &mlxsw_sp->router->vrs[rif->vr_id];
6599
6600        mlxsw_sp_rif_counters_free(rif);
6601        for (i = 0; i < MLXSW_SP_L3_PROTO_MAX; i++)
6602                mlxsw_sp_mr_rif_del(vr->mr_table[i], rif);
6603        ops->deconfigure(rif);
6604        if (fid)
6605                /* Loopback RIFs are not associated with a FID. */
6606                mlxsw_sp_fid_put(fid);
6607        mlxsw_sp->router->rifs[rif->rif_index] = NULL;
6608        dev_put(rif->dev);
6609        kfree(rif);
6610        vr->rif_count--;
6611        mlxsw_sp_vr_put(mlxsw_sp, vr);
6612}
6613
6614void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
6615                                 struct net_device *dev)
6616{
6617        struct mlxsw_sp_rif *rif;
6618
6619        mutex_lock(&mlxsw_sp->router->lock);
6620        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
6621        if (!rif)
6622                goto out;
6623        mlxsw_sp_rif_destroy(rif);
6624out:
6625        mutex_unlock(&mlxsw_sp->router->lock);
6626}
6627
6628static void
6629mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
6630                                 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
6631{
6632        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
6633
6634        params->vid = mlxsw_sp_port_vlan->vid;
6635        params->lag = mlxsw_sp_port->lagged;
6636        if (params->lag)
6637                params->lag_id = mlxsw_sp_port->lag_id;
6638        else
6639                params->system_port = mlxsw_sp_port->local_port;
6640}
6641
6642static struct mlxsw_sp_rif_subport *
6643mlxsw_sp_rif_subport_rif(const struct mlxsw_sp_rif *rif)
6644{
6645        return container_of(rif, struct mlxsw_sp_rif_subport, common);
6646}
6647
6648static struct mlxsw_sp_rif *
6649mlxsw_sp_rif_subport_get(struct mlxsw_sp *mlxsw_sp,
6650                         const struct mlxsw_sp_rif_params *params,
6651                         struct netlink_ext_ack *extack)
6652{
6653        struct mlxsw_sp_rif_subport *rif_subport;
6654        struct mlxsw_sp_rif *rif;
6655
6656        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, params->dev);
6657        if (!rif)
6658                return mlxsw_sp_rif_create(mlxsw_sp, params, extack);
6659
6660        rif_subport = mlxsw_sp_rif_subport_rif(rif);
6661        refcount_inc(&rif_subport->ref_count);
6662        return rif;
6663}
6664
6665static void mlxsw_sp_rif_subport_put(struct mlxsw_sp_rif *rif)
6666{
6667        struct mlxsw_sp_rif_subport *rif_subport;
6668
6669        rif_subport = mlxsw_sp_rif_subport_rif(rif);
6670        if (!refcount_dec_and_test(&rif_subport->ref_count))
6671                return;
6672
6673        mlxsw_sp_rif_destroy(rif);
6674}
6675
6676static int
6677mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
6678                               struct net_device *l3_dev,
6679                               struct netlink_ext_ack *extack)
6680{
6681        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
6682        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
6683        struct mlxsw_sp_rif_params params = {
6684                .dev = l3_dev,
6685        };
6686        u16 vid = mlxsw_sp_port_vlan->vid;
6687        struct mlxsw_sp_rif *rif;
6688        struct mlxsw_sp_fid *fid;
6689        int err;
6690
6691        mlxsw_sp_rif_subport_params_init(&params, mlxsw_sp_port_vlan);
6692        rif = mlxsw_sp_rif_subport_get(mlxsw_sp, &params, extack);
6693        if (IS_ERR(rif))
6694                return PTR_ERR(rif);
6695
6696        /* FID was already created, just take a reference */
6697        fid = rif->ops->fid_get(rif, extack);
6698        err = mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port, vid);
6699        if (err)
6700                goto err_fid_port_vid_map;
6701
6702        err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, false);
6703        if (err)
6704                goto err_port_vid_learning_set;
6705
6706        err = mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid,
6707                                        BR_STATE_FORWARDING);
6708        if (err)
6709                goto err_port_vid_stp_set;
6710
6711        mlxsw_sp_port_vlan->fid = fid;
6712
6713        return 0;
6714
6715err_port_vid_stp_set:
6716        mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true);
6717err_port_vid_learning_set:
6718        mlxsw_sp_fid_port_vid_unmap(fid, mlxsw_sp_port, vid);
6719err_fid_port_vid_map:
6720        mlxsw_sp_fid_put(fid);
6721        mlxsw_sp_rif_subport_put(rif);
6722        return err;
6723}
6724
6725static void
6726__mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
6727{
6728        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
6729        struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
6730        struct mlxsw_sp_rif *rif = mlxsw_sp_fid_rif(fid);
6731        u16 vid = mlxsw_sp_port_vlan->vid;
6732
6733        if (WARN_ON(mlxsw_sp_fid_type(fid) != MLXSW_SP_FID_TYPE_RFID))
6734                return;
6735
6736        mlxsw_sp_port_vlan->fid = NULL;
6737        mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid, BR_STATE_BLOCKING);
6738        mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true);
6739        mlxsw_sp_fid_port_vid_unmap(fid, mlxsw_sp_port, vid);
6740        mlxsw_sp_fid_put(fid);
6741        mlxsw_sp_rif_subport_put(rif);
6742}
6743
6744void
6745mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
6746{
6747        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port_vlan->mlxsw_sp_port->mlxsw_sp;
6748
6749        mutex_lock(&mlxsw_sp->router->lock);
6750        __mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
6751        mutex_unlock(&mlxsw_sp->router->lock);
6752}
6753
6754static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
6755                                             struct net_device *port_dev,
6756                                             unsigned long event, u16 vid,
6757                                             struct netlink_ext_ack *extack)
6758{
6759        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(port_dev);
6760        struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
6761
6762        mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
6763        if (WARN_ON(!mlxsw_sp_port_vlan))
6764                return -EINVAL;
6765
6766        switch (event) {
6767        case NETDEV_UP:
6768                return mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan,
6769                                                      l3_dev, extack);
6770        case NETDEV_DOWN:
6771                __mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
6772                break;
6773        }
6774
6775        return 0;
6776}
6777
6778static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
6779                                        unsigned long event,
6780                                        struct netlink_ext_ack *extack)
6781{
6782        if (netif_is_bridge_port(port_dev) ||
6783            netif_is_lag_port(port_dev) ||
6784            netif_is_ovs_port(port_dev))
6785                return 0;
6786
6787        return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event,
6788                                                 MLXSW_SP_DEFAULT_VID, extack);
6789}
6790
6791static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
6792                                         struct net_device *lag_dev,
6793                                         unsigned long event, u16 vid,
6794                                         struct netlink_ext_ack *extack)
6795{
6796        struct net_device *port_dev;
6797        struct list_head *iter;
6798        int err;
6799
6800        netdev_for_each_lower_dev(lag_dev, port_dev, iter) {
6801                if (mlxsw_sp_port_dev_check(port_dev)) {
6802                        err = mlxsw_sp_inetaddr_port_vlan_event(l3_dev,
6803                                                                port_dev,
6804                                                                event, vid,
6805                                                                extack);
6806                        if (err)
6807                                return err;
6808                }
6809        }
6810
6811        return 0;
6812}
6813
6814static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
6815                                       unsigned long event,
6816                                       struct netlink_ext_ack *extack)
6817{
6818        if (netif_is_bridge_port(lag_dev))
6819                return 0;
6820
6821        return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event,
6822                                             MLXSW_SP_DEFAULT_VID, extack);
6823}
6824
6825static int mlxsw_sp_inetaddr_bridge_event(struct mlxsw_sp *mlxsw_sp,
6826                                          struct net_device *l3_dev,
6827                                          unsigned long event,
6828                                          struct netlink_ext_ack *extack)
6829{
6830        struct mlxsw_sp_rif_params params = {
6831                .dev = l3_dev,
6832        };
6833        struct mlxsw_sp_rif *rif;
6834
6835        switch (event) {
6836        case NETDEV_UP:
6837                rif = mlxsw_sp_rif_create(mlxsw_sp, &params, extack);
6838                if (IS_ERR(rif))
6839                        return PTR_ERR(rif);
6840                break;
6841        case NETDEV_DOWN:
6842                rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
6843                mlxsw_sp_rif_destroy(rif);
6844                break;
6845        }
6846
6847        return 0;
6848}
6849
6850static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp,
6851                                        struct net_device *vlan_dev,
6852                                        unsigned long event,
6853                                        struct netlink_ext_ack *extack)
6854{
6855        struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
6856        u16 vid = vlan_dev_vlan_id(vlan_dev);
6857
6858        if (netif_is_bridge_port(vlan_dev))
6859                return 0;
6860
6861        if (mlxsw_sp_port_dev_check(real_dev))
6862                return mlxsw_sp_inetaddr_port_vlan_event(vlan_dev, real_dev,
6863                                                         event, vid, extack);
6864        else if (netif_is_lag_master(real_dev))
6865                return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event,
6866                                                     vid, extack);
6867        else if (netif_is_bridge_master(real_dev) && br_vlan_enabled(real_dev))
6868                return mlxsw_sp_inetaddr_bridge_event(mlxsw_sp, vlan_dev, event,
6869                                                      extack);
6870
6871        return 0;
6872}
6873
6874static bool mlxsw_sp_rif_macvlan_is_vrrp4(const u8 *mac)
6875{
6876        u8 vrrp4[ETH_ALEN] = { 0x00, 0x00, 0x5e, 0x00, 0x01, 0x00 };
6877        u8 mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
6878
6879        return ether_addr_equal_masked(mac, vrrp4, mask);
6880}
6881
6882static bool mlxsw_sp_rif_macvlan_is_vrrp6(const u8 *mac)
6883{
6884        u8 vrrp6[ETH_ALEN] = { 0x00, 0x00, 0x5e, 0x00, 0x02, 0x00 };
6885        u8 mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
6886
6887        return ether_addr_equal_masked(mac, vrrp6, mask);
6888}
6889
6890static int mlxsw_sp_rif_vrrp_op(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
6891                                const u8 *mac, bool adding)
6892{
6893        char ritr_pl[MLXSW_REG_RITR_LEN];
6894        u8 vrrp_id = adding ? mac[5] : 0;
6895        int err;
6896
6897        if (!mlxsw_sp_rif_macvlan_is_vrrp4(mac) &&
6898            !mlxsw_sp_rif_macvlan_is_vrrp6(mac))
6899                return 0;
6900
6901        mlxsw_reg_ritr_rif_pack(ritr_pl, rif_index);
6902        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
6903        if (err)
6904                return err;
6905
6906        if (mlxsw_sp_rif_macvlan_is_vrrp4(mac))
6907                mlxsw_reg_ritr_if_vrrp_id_ipv4_set(ritr_pl, vrrp_id);
6908        else
6909                mlxsw_reg_ritr_if_vrrp_id_ipv6_set(ritr_pl, vrrp_id);
6910
6911        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
6912}
6913
6914static int mlxsw_sp_rif_macvlan_add(struct mlxsw_sp *mlxsw_sp,
6915                                    const struct net_device *macvlan_dev,
6916                                    struct netlink_ext_ack *extack)
6917{
6918        struct macvlan_dev *vlan = netdev_priv(macvlan_dev);
6919        struct mlxsw_sp_rif *rif;
6920        int err;
6921
6922        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan->lowerdev);
6923        if (!rif) {
6924                NL_SET_ERR_MSG_MOD(extack, "macvlan is only supported on top of router interfaces");
6925                return -EOPNOTSUPP;
6926        }
6927
6928        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, macvlan_dev->dev_addr,
6929                                  mlxsw_sp_fid_index(rif->fid), true);
6930        if (err)
6931                return err;
6932
6933        err = mlxsw_sp_rif_vrrp_op(mlxsw_sp, rif->rif_index,
6934                                   macvlan_dev->dev_addr, true);
6935        if (err)
6936                goto err_rif_vrrp_add;
6937
6938        /* Make sure the bridge driver does not have this MAC pointing at
6939         * some other port.
6940         */
6941        if (rif->ops->fdb_del)
6942                rif->ops->fdb_del(rif, macvlan_dev->dev_addr);
6943
6944        return 0;
6945
6946err_rif_vrrp_add:
6947        mlxsw_sp_rif_fdb_op(mlxsw_sp, macvlan_dev->dev_addr,
6948                            mlxsw_sp_fid_index(rif->fid), false);
6949        return err;
6950}
6951
6952static void __mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp,
6953                                       const struct net_device *macvlan_dev)
6954{
6955        struct macvlan_dev *vlan = netdev_priv(macvlan_dev);
6956        struct mlxsw_sp_rif *rif;
6957
6958        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, vlan->lowerdev);
6959        /* If we do not have a RIF, then we already took care of
6960         * removing the macvlan's MAC during RIF deletion.
6961         */
6962        if (!rif)
6963                return;
6964        mlxsw_sp_rif_vrrp_op(mlxsw_sp, rif->rif_index, macvlan_dev->dev_addr,
6965                             false);
6966        mlxsw_sp_rif_fdb_op(mlxsw_sp, macvlan_dev->dev_addr,
6967                            mlxsw_sp_fid_index(rif->fid), false);
6968}
6969
6970void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp,
6971                              const struct net_device *macvlan_dev)
6972{
6973        mutex_lock(&mlxsw_sp->router->lock);
6974        __mlxsw_sp_rif_macvlan_del(mlxsw_sp, macvlan_dev);
6975        mutex_unlock(&mlxsw_sp->router->lock);
6976}
6977
6978static int mlxsw_sp_inetaddr_macvlan_event(struct mlxsw_sp *mlxsw_sp,
6979                                           struct net_device *macvlan_dev,
6980                                           unsigned long event,
6981                                           struct netlink_ext_ack *extack)
6982{
6983        switch (event) {
6984        case NETDEV_UP:
6985                return mlxsw_sp_rif_macvlan_add(mlxsw_sp, macvlan_dev, extack);
6986        case NETDEV_DOWN:
6987                __mlxsw_sp_rif_macvlan_del(mlxsw_sp, macvlan_dev);
6988                break;
6989        }
6990
6991        return 0;
6992}
6993
6994static int mlxsw_sp_router_port_check_rif_addr(struct mlxsw_sp *mlxsw_sp,
6995                                               struct net_device *dev,
6996                                               const unsigned char *dev_addr,
6997                                               struct netlink_ext_ack *extack)
6998{
6999        struct mlxsw_sp_rif *rif;
7000        int i;
7001
7002        /* A RIF is not created for macvlan netdevs. Their MAC is used to
7003         * populate the FDB
7004         */
7005        if (netif_is_macvlan(dev) || netif_is_l3_master(dev))
7006                return 0;
7007
7008        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
7009                rif = mlxsw_sp->router->rifs[i];
7010                if (rif && rif->ops &&
7011                    rif->ops->type == MLXSW_SP_RIF_TYPE_IPIP_LB)
7012                        continue;
7013                if (rif && rif->dev && rif->dev != dev &&
7014                    !ether_addr_equal_masked(rif->dev->dev_addr, dev_addr,
7015                                             mlxsw_sp->mac_mask)) {
7016                        NL_SET_ERR_MSG_MOD(extack, "All router interface MAC addresses must have the same prefix");
7017                        return -EINVAL;
7018                }
7019        }
7020
7021        return 0;
7022}
7023
7024static int __mlxsw_sp_inetaddr_event(struct mlxsw_sp *mlxsw_sp,
7025                                     struct net_device *dev,
7026                                     unsigned long event,
7027                                     struct netlink_ext_ack *extack)
7028{
7029        if (mlxsw_sp_port_dev_check(dev))
7030                return mlxsw_sp_inetaddr_port_event(dev, event, extack);
7031        else if (netif_is_lag_master(dev))
7032                return mlxsw_sp_inetaddr_lag_event(dev, event, extack);
7033        else if (netif_is_bridge_master(dev))
7034                return mlxsw_sp_inetaddr_bridge_event(mlxsw_sp, dev, event,
7035                                                      extack);
7036        else if (is_vlan_dev(dev))
7037                return mlxsw_sp_inetaddr_vlan_event(mlxsw_sp, dev, event,
7038                                                    extack);
7039        else if (netif_is_macvlan(dev))
7040                return mlxsw_sp_inetaddr_macvlan_event(mlxsw_sp, dev, event,
7041                                                       extack);
7042        else
7043                return 0;
7044}
7045
7046static int mlxsw_sp_inetaddr_event(struct notifier_block *nb,
7047                                   unsigned long event, void *ptr)
7048{
7049        struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
7050        struct net_device *dev = ifa->ifa_dev->dev;
7051        struct mlxsw_sp_router *router;
7052        struct mlxsw_sp_rif *rif;
7053        int err = 0;
7054
7055        /* NETDEV_UP event is handled by mlxsw_sp_inetaddr_valid_event */
7056        if (event == NETDEV_UP)
7057                return NOTIFY_DONE;
7058
7059        router = container_of(nb, struct mlxsw_sp_router, inetaddr_nb);
7060        mutex_lock(&router->lock);
7061        rif = mlxsw_sp_rif_find_by_dev(router->mlxsw_sp, dev);
7062        if (!mlxsw_sp_rif_should_config(rif, dev, event))
7063                goto out;
7064
7065        err = __mlxsw_sp_inetaddr_event(router->mlxsw_sp, dev, event, NULL);
7066out:
7067        mutex_unlock(&router->lock);
7068        return notifier_from_errno(err);
7069}
7070
7071int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
7072                                  unsigned long event, void *ptr)
7073{
7074        struct in_validator_info *ivi = (struct in_validator_info *) ptr;
7075        struct net_device *dev = ivi->ivi_dev->dev;
7076        struct mlxsw_sp *mlxsw_sp;
7077        struct mlxsw_sp_rif *rif;
7078        int err = 0;
7079
7080        mlxsw_sp = mlxsw_sp_lower_get(dev);
7081        if (!mlxsw_sp)
7082                return NOTIFY_DONE;
7083
7084        mutex_lock(&mlxsw_sp->router->lock);
7085        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
7086        if (!mlxsw_sp_rif_should_config(rif, dev, event))
7087                goto out;
7088
7089        err = mlxsw_sp_router_port_check_rif_addr(mlxsw_sp, dev, dev->dev_addr,
7090                                                  ivi->extack);
7091        if (err)
7092                goto out;
7093
7094        err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, ivi->extack);
7095out:
7096        mutex_unlock(&mlxsw_sp->router->lock);
7097        return notifier_from_errno(err);
7098}
7099
7100struct mlxsw_sp_inet6addr_event_work {
7101        struct work_struct work;
7102        struct mlxsw_sp *mlxsw_sp;
7103        struct net_device *dev;
7104        unsigned long event;
7105};
7106
7107static void mlxsw_sp_inet6addr_event_work(struct work_struct *work)
7108{
7109        struct mlxsw_sp_inet6addr_event_work *inet6addr_work =
7110                container_of(work, struct mlxsw_sp_inet6addr_event_work, work);
7111        struct mlxsw_sp *mlxsw_sp = inet6addr_work->mlxsw_sp;
7112        struct net_device *dev = inet6addr_work->dev;
7113        unsigned long event = inet6addr_work->event;
7114        struct mlxsw_sp_rif *rif;
7115
7116        rtnl_lock();
7117        mutex_lock(&mlxsw_sp->router->lock);
7118
7119        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
7120        if (!mlxsw_sp_rif_should_config(rif, dev, event))
7121                goto out;
7122
7123        __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, NULL);
7124out:
7125        mutex_unlock(&mlxsw_sp->router->lock);
7126        rtnl_unlock();
7127        dev_put(dev);
7128        kfree(inet6addr_work);
7129}
7130
7131/* Called with rcu_read_lock() */
7132static int mlxsw_sp_inet6addr_event(struct notifier_block *nb,
7133                                    unsigned long event, void *ptr)
7134{
7135        struct inet6_ifaddr *if6 = (struct inet6_ifaddr *) ptr;
7136        struct mlxsw_sp_inet6addr_event_work *inet6addr_work;
7137        struct net_device *dev = if6->idev->dev;
7138        struct mlxsw_sp_router *router;
7139
7140        /* NETDEV_UP event is handled by mlxsw_sp_inet6addr_valid_event */
7141        if (event == NETDEV_UP)
7142                return NOTIFY_DONE;
7143
7144        inet6addr_work = kzalloc(sizeof(*inet6addr_work), GFP_ATOMIC);
7145        if (!inet6addr_work)
7146                return NOTIFY_BAD;
7147
7148        router = container_of(nb, struct mlxsw_sp_router, inet6addr_nb);
7149        INIT_WORK(&inet6addr_work->work, mlxsw_sp_inet6addr_event_work);
7150        inet6addr_work->mlxsw_sp = router->mlxsw_sp;
7151        inet6addr_work->dev = dev;
7152        inet6addr_work->event = event;
7153        dev_hold(dev);
7154        mlxsw_core_schedule_work(&inet6addr_work->work);
7155
7156        return NOTIFY_DONE;
7157}
7158
7159int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
7160                                   unsigned long event, void *ptr)
7161{
7162        struct in6_validator_info *i6vi = (struct in6_validator_info *) ptr;
7163        struct net_device *dev = i6vi->i6vi_dev->dev;
7164        struct mlxsw_sp *mlxsw_sp;
7165        struct mlxsw_sp_rif *rif;
7166        int err = 0;
7167
7168        mlxsw_sp = mlxsw_sp_lower_get(dev);
7169        if (!mlxsw_sp)
7170                return NOTIFY_DONE;
7171
7172        mutex_lock(&mlxsw_sp->router->lock);
7173        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
7174        if (!mlxsw_sp_rif_should_config(rif, dev, event))
7175                goto out;
7176
7177        err = mlxsw_sp_router_port_check_rif_addr(mlxsw_sp, dev, dev->dev_addr,
7178                                                  i6vi->extack);
7179        if (err)
7180                goto out;
7181
7182        err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, i6vi->extack);
7183out:
7184        mutex_unlock(&mlxsw_sp->router->lock);
7185        return notifier_from_errno(err);
7186}
7187
7188static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
7189                             const char *mac, int mtu)
7190{
7191        char ritr_pl[MLXSW_REG_RITR_LEN];
7192        int err;
7193
7194        mlxsw_reg_ritr_rif_pack(ritr_pl, rif_index);
7195        err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
7196        if (err)
7197                return err;
7198
7199        mlxsw_reg_ritr_mtu_set(ritr_pl, mtu);
7200        mlxsw_reg_ritr_if_mac_memcpy_to(ritr_pl, mac);
7201        mlxsw_reg_ritr_op_set(ritr_pl, MLXSW_REG_RITR_RIF_CREATE);
7202        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
7203}
7204
7205static int
7206mlxsw_sp_router_port_change_event(struct mlxsw_sp *mlxsw_sp,
7207                                  struct mlxsw_sp_rif *rif)
7208{
7209        struct net_device *dev = rif->dev;
7210        u16 fid_index;
7211        int err;
7212
7213        fid_index = mlxsw_sp_fid_index(rif->fid);
7214
7215        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, rif->addr, fid_index, false);
7216        if (err)
7217                return err;
7218
7219        err = mlxsw_sp_rif_edit(mlxsw_sp, rif->rif_index, dev->dev_addr,
7220                                dev->mtu);
7221        if (err)
7222                goto err_rif_edit;
7223
7224        err = mlxsw_sp_rif_fdb_op(mlxsw_sp, dev->dev_addr, fid_index, true);
7225        if (err)
7226                goto err_rif_fdb_op;
7227
7228        if (rif->mtu != dev->mtu) {
7229                struct mlxsw_sp_vr *vr;
7230                int i;
7231
7232                /* The RIF is relevant only to its mr_table instance, as unlike
7233                 * unicast routing, in multicast routing a RIF cannot be shared
7234                 * between several multicast routing tables.
7235                 */
7236                vr = &mlxsw_sp->router->vrs[rif->vr_id];
7237                for (i = 0; i < MLXSW_SP_L3_PROTO_MAX; i++)
7238                        mlxsw_sp_mr_rif_mtu_update(vr->mr_table[i],
7239                                                   rif, dev->mtu);
7240        }
7241
7242        ether_addr_copy(rif->addr, dev->dev_addr);
7243        rif->mtu = dev->mtu;
7244
7245        netdev_dbg(dev, "Updated RIF=%d\n", rif->rif_index);
7246
7247        return 0;
7248
7249err_rif_fdb_op:
7250        mlxsw_sp_rif_edit(mlxsw_sp, rif->rif_index, rif->addr, rif->mtu);
7251err_rif_edit:
7252        mlxsw_sp_rif_fdb_op(mlxsw_sp, rif->addr, fid_index, true);
7253        return err;
7254}
7255
7256static int mlxsw_sp_router_port_pre_changeaddr_event(struct mlxsw_sp_rif *rif,
7257                            struct netdev_notifier_pre_changeaddr_info *info)
7258{
7259        struct netlink_ext_ack *extack;
7260
7261        extack = netdev_notifier_info_to_extack(&info->info);
7262        return mlxsw_sp_router_port_check_rif_addr(rif->mlxsw_sp, rif->dev,
7263                                                   info->dev_addr, extack);
7264}
7265
7266int mlxsw_sp_netdevice_router_port_event(struct net_device *dev,
7267                                         unsigned long event, void *ptr)
7268{
7269        struct mlxsw_sp *mlxsw_sp;
7270        struct mlxsw_sp_rif *rif;
7271        int err = 0;
7272
7273        mlxsw_sp = mlxsw_sp_lower_get(dev);
7274        if (!mlxsw_sp)
7275                return 0;
7276
7277        mutex_lock(&mlxsw_sp->router->lock);
7278        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
7279        if (!rif)
7280                goto out;
7281
7282        switch (event) {
7283        case NETDEV_CHANGEMTU: /* fall through */
7284        case NETDEV_CHANGEADDR:
7285                err = mlxsw_sp_router_port_change_event(mlxsw_sp, rif);
7286                break;
7287        case NETDEV_PRE_CHANGEADDR:
7288                err = mlxsw_sp_router_port_pre_changeaddr_event(rif, ptr);
7289                break;
7290        }
7291
7292out:
7293        mutex_unlock(&mlxsw_sp->router->lock);
7294        return err;
7295}
7296
7297static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp,
7298                                  struct net_device *l3_dev,
7299                                  struct netlink_ext_ack *extack)
7300{
7301        struct mlxsw_sp_rif *rif;
7302
7303        /* If netdev is already associated with a RIF, then we need to
7304         * destroy it and create a new one with the new virtual router ID.
7305         */
7306        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
7307        if (rif)
7308                __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN,
7309                                          extack);
7310
7311        return __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_UP, extack);
7312}
7313
7314static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
7315                                    struct net_device *l3_dev)
7316{
7317        struct mlxsw_sp_rif *rif;
7318
7319        rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
7320        if (!rif)
7321                return;
7322        __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN, NULL);
7323}
7324
7325int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
7326                                 struct netdev_notifier_changeupper_info *info)
7327{
7328        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev);
7329        int err = 0;
7330
7331        /* We do not create a RIF for a macvlan, but only use it to
7332         * direct more MAC addresses to the router.
7333         */
7334        if (!mlxsw_sp || netif_is_macvlan(l3_dev))
7335                return 0;
7336
7337        mutex_lock(&mlxsw_sp->router->lock);
7338        switch (event) {
7339        case NETDEV_PRECHANGEUPPER:
7340                break;
7341        case NETDEV_CHANGEUPPER:
7342                if (info->linking) {
7343                        struct netlink_ext_ack *extack;
7344
7345                        extack = netdev_notifier_info_to_extack(&info->info);
7346                        err = mlxsw_sp_port_vrf_join(mlxsw_sp, l3_dev, extack);
7347                } else {
7348                        mlxsw_sp_port_vrf_leave(mlxsw_sp, l3_dev);
7349                }
7350                break;
7351        }
7352        mutex_unlock(&mlxsw_sp->router->lock);
7353
7354        return err;
7355}
7356
7357static int __mlxsw_sp_rif_macvlan_flush(struct net_device *dev, void *data)
7358{
7359        struct mlxsw_sp_rif *rif = data;
7360
7361        if (!netif_is_macvlan(dev))
7362                return 0;
7363
7364        return mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, dev->dev_addr,
7365                                   mlxsw_sp_fid_index(rif->fid), false);
7366}
7367
7368static int mlxsw_sp_rif_macvlan_flush(struct mlxsw_sp_rif *rif)
7369{
7370        if (!netif_is_macvlan_port(rif->dev))
7371                return 0;
7372
7373        netdev_warn(rif->dev, "Router interface is deleted. Upper macvlans will not work\n");
7374        return netdev_walk_all_upper_dev_rcu(rif->dev,
7375                                             __mlxsw_sp_rif_macvlan_flush, rif);
7376}
7377
7378static void mlxsw_sp_rif_subport_setup(struct mlxsw_sp_rif *rif,
7379                                       const struct mlxsw_sp_rif_params *params)
7380{
7381        struct mlxsw_sp_rif_subport *rif_subport;
7382
7383        rif_subport = mlxsw_sp_rif_subport_rif(rif);
7384        refcount_set(&rif_subport->ref_count, 1);
7385        rif_subport->vid = params->vid;
7386        rif_subport->lag = params->lag;
7387        if (params->lag)
7388                rif_subport->lag_id = params->lag_id;
7389        else
7390                rif_subport->system_port = params->system_port;
7391}
7392
7393static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable)
7394{
7395        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7396        struct mlxsw_sp_rif_subport *rif_subport;
7397        char ritr_pl[MLXSW_REG_RITR_LEN];
7398
7399        rif_subport = mlxsw_sp_rif_subport_rif(rif);
7400        mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_SP_IF,
7401                            rif->rif_index, rif->vr_id, rif->dev->mtu);
7402        mlxsw_reg_ritr_mac_pack(ritr_pl, rif->dev->dev_addr);
7403        mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag,
7404                                  rif_subport->lag ? rif_subport->lag_id :
7405                                                     rif_subport->system_port,
7406                                  rif_subport->vid);
7407
7408        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
7409}
7410
7411static int mlxsw_sp_rif_subport_configure(struct mlxsw_sp_rif *rif)
7412{
7413        int err;
7414
7415        err = mlxsw_sp_rif_subport_op(rif, true);
7416        if (err)
7417                return err;
7418
7419        err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
7420                                  mlxsw_sp_fid_index(rif->fid), true);
7421        if (err)
7422                goto err_rif_fdb_op;
7423
7424        mlxsw_sp_fid_rif_set(rif->fid, rif);
7425        return 0;
7426
7427err_rif_fdb_op:
7428        mlxsw_sp_rif_subport_op(rif, false);
7429        return err;
7430}
7431
7432static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif)
7433{
7434        struct mlxsw_sp_fid *fid = rif->fid;
7435
7436        mlxsw_sp_fid_rif_set(fid, NULL);
7437        mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
7438                            mlxsw_sp_fid_index(fid), false);
7439        mlxsw_sp_rif_macvlan_flush(rif);
7440        mlxsw_sp_rif_subport_op(rif, false);
7441}
7442
7443static struct mlxsw_sp_fid *
7444mlxsw_sp_rif_subport_fid_get(struct mlxsw_sp_rif *rif,
7445                             struct netlink_ext_ack *extack)
7446{
7447        return mlxsw_sp_fid_rfid_get(rif->mlxsw_sp, rif->rif_index);
7448}
7449
7450static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_subport_ops = {
7451        .type                   = MLXSW_SP_RIF_TYPE_SUBPORT,
7452        .rif_size               = sizeof(struct mlxsw_sp_rif_subport),
7453        .setup                  = mlxsw_sp_rif_subport_setup,
7454        .configure              = mlxsw_sp_rif_subport_configure,
7455        .deconfigure            = mlxsw_sp_rif_subport_deconfigure,
7456        .fid_get                = mlxsw_sp_rif_subport_fid_get,
7457};
7458
7459static int mlxsw_sp_rif_vlan_fid_op(struct mlxsw_sp_rif *rif,
7460                                    enum mlxsw_reg_ritr_if_type type,
7461                                    u16 vid_fid, bool enable)
7462{
7463        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7464        char ritr_pl[MLXSW_REG_RITR_LEN];
7465
7466        mlxsw_reg_ritr_pack(ritr_pl, enable, type, rif->rif_index, rif->vr_id,
7467                            rif->dev->mtu);
7468        mlxsw_reg_ritr_mac_pack(ritr_pl, rif->dev->dev_addr);
7469        mlxsw_reg_ritr_fid_set(ritr_pl, type, vid_fid);
7470
7471        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
7472}
7473
7474u8 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp)
7475{
7476        return mlxsw_core_max_ports(mlxsw_sp->core) + 1;
7477}
7478
7479static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)
7480{
7481        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7482        u16 fid_index = mlxsw_sp_fid_index(rif->fid);
7483        int err;
7484
7485        err = mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index,
7486                                       true);
7487        if (err)
7488                return err;
7489
7490        err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
7491                                     mlxsw_sp_router_port(mlxsw_sp), true);
7492        if (err)
7493                goto err_fid_mc_flood_set;
7494
7495        err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
7496                                     mlxsw_sp_router_port(mlxsw_sp), true);
7497        if (err)
7498                goto err_fid_bc_flood_set;
7499
7500        err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
7501                                  mlxsw_sp_fid_index(rif->fid), true);
7502        if (err)
7503                goto err_rif_fdb_op;
7504
7505        mlxsw_sp_fid_rif_set(rif->fid, rif);
7506        return 0;
7507
7508err_rif_fdb_op:
7509        mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
7510                               mlxsw_sp_router_port(mlxsw_sp), false);
7511err_fid_bc_flood_set:
7512        mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
7513                               mlxsw_sp_router_port(mlxsw_sp), false);
7514err_fid_mc_flood_set:
7515        mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false);
7516        return err;
7517}
7518
7519static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif)
7520{
7521        u16 fid_index = mlxsw_sp_fid_index(rif->fid);
7522        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7523        struct mlxsw_sp_fid *fid = rif->fid;
7524
7525        mlxsw_sp_fid_rif_set(fid, NULL);
7526        mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr,
7527                            mlxsw_sp_fid_index(fid), false);
7528        mlxsw_sp_rif_macvlan_flush(rif);
7529        mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC,
7530                               mlxsw_sp_router_port(mlxsw_sp), false);
7531        mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
7532                               mlxsw_sp_router_port(mlxsw_sp), false);
7533        mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false);
7534}
7535
7536static struct mlxsw_sp_fid *
7537mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif,
7538                         struct netlink_ext_ack *extack)
7539{
7540        return mlxsw_sp_fid_8021d_get(rif->mlxsw_sp, rif->dev->ifindex);
7541}
7542
7543static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
7544{
7545        struct switchdev_notifier_fdb_info info;
7546        struct net_device *dev;
7547
7548        dev = br_fdb_find_port(rif->dev, mac, 0);
7549        if (!dev)
7550                return;
7551
7552        info.addr = mac;
7553        info.vid = 0;
7554        call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
7555                                 NULL);
7556}
7557
7558static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = {
7559        .type                   = MLXSW_SP_RIF_TYPE_FID,
7560        .rif_size               = sizeof(struct mlxsw_sp_rif),
7561        .configure              = mlxsw_sp_rif_fid_configure,
7562        .deconfigure            = mlxsw_sp_rif_fid_deconfigure,
7563        .fid_get                = mlxsw_sp_rif_fid_fid_get,
7564        .fdb_del                = mlxsw_sp_rif_fid_fdb_del,
7565};
7566
7567static struct mlxsw_sp_fid *
7568mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
7569                          struct netlink_ext_ack *extack)
7570{
7571        struct net_device *br_dev = rif->dev;
7572        u16 vid;
7573        int err;
7574
7575        if (is_vlan_dev(rif->dev)) {
7576                vid = vlan_dev_vlan_id(rif->dev);
7577                br_dev = vlan_dev_real_dev(rif->dev);
7578                if (WARN_ON(!netif_is_bridge_master(br_dev)))
7579                        return ERR_PTR(-EINVAL);
7580        } else {
7581                err = br_vlan_get_pvid(rif->dev, &vid);
7582                if (err < 0 || !vid) {
7583                        NL_SET_ERR_MSG_MOD(extack, "Couldn't determine bridge PVID");
7584                        return ERR_PTR(-EINVAL);
7585                }
7586        }
7587
7588        return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid);
7589}
7590
7591static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
7592{
7593        u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
7594        struct switchdev_notifier_fdb_info info;
7595        struct net_device *br_dev;
7596        struct net_device *dev;
7597
7598        br_dev = is_vlan_dev(rif->dev) ? vlan_dev_real_dev(rif->dev) : rif->dev;
7599        dev = br_fdb_find_port(br_dev, mac, vid);
7600        if (!dev)
7601                return;
7602
7603        info.addr = mac;
7604        info.vid = vid;
7605        call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE, dev, &info.info,
7606                                 NULL);
7607}
7608
7609static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = {
7610        .type                   = MLXSW_SP_RIF_TYPE_VLAN,
7611        .rif_size               = sizeof(struct mlxsw_sp_rif),
7612        .configure              = mlxsw_sp_rif_fid_configure,
7613        .deconfigure            = mlxsw_sp_rif_fid_deconfigure,
7614        .fid_get                = mlxsw_sp_rif_vlan_fid_get,
7615        .fdb_del                = mlxsw_sp_rif_vlan_fdb_del,
7616};
7617
7618static struct mlxsw_sp_rif_ipip_lb *
7619mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif)
7620{
7621        return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);
7622}
7623
7624static void
7625mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif,
7626                           const struct mlxsw_sp_rif_params *params)
7627{
7628        struct mlxsw_sp_rif_params_ipip_lb *params_lb;
7629        struct mlxsw_sp_rif_ipip_lb *rif_lb;
7630
7631        params_lb = container_of(params, struct mlxsw_sp_rif_params_ipip_lb,
7632                                 common);
7633        rif_lb = mlxsw_sp_rif_ipip_lb_rif(rif);
7634        rif_lb->lb_config = params_lb->lb_config;
7635}
7636
7637static int
7638mlxsw_sp1_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
7639{
7640        struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
7641        u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(rif->dev);
7642        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7643        struct mlxsw_sp_vr *ul_vr;
7644        int err;
7645
7646        ul_vr = mlxsw_sp_vr_get(mlxsw_sp, ul_tb_id, NULL);
7647        if (IS_ERR(ul_vr))
7648                return PTR_ERR(ul_vr);
7649
7650        err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr->id, 0, true);
7651        if (err)
7652                goto err_loopback_op;
7653
7654        lb_rif->ul_vr_id = ul_vr->id;
7655        lb_rif->ul_rif_id = 0;
7656        ++ul_vr->rif_count;
7657        return 0;
7658
7659err_loopback_op:
7660        mlxsw_sp_vr_put(mlxsw_sp, ul_vr);
7661        return err;
7662}
7663
7664static void mlxsw_sp1_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif)
7665{
7666        struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
7667        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7668        struct mlxsw_sp_vr *ul_vr;
7669
7670        ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id];
7671        mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr->id, 0, false);
7672
7673        --ul_vr->rif_count;
7674        mlxsw_sp_vr_put(mlxsw_sp, ul_vr);
7675}
7676
7677static const struct mlxsw_sp_rif_ops mlxsw_sp1_rif_ipip_lb_ops = {
7678        .type                   = MLXSW_SP_RIF_TYPE_IPIP_LB,
7679        .rif_size               = sizeof(struct mlxsw_sp_rif_ipip_lb),
7680        .setup                  = mlxsw_sp_rif_ipip_lb_setup,
7681        .configure              = mlxsw_sp1_rif_ipip_lb_configure,
7682        .deconfigure            = mlxsw_sp1_rif_ipip_lb_deconfigure,
7683};
7684
7685const struct mlxsw_sp_rif_ops *mlxsw_sp1_rif_ops_arr[] = {
7686        [MLXSW_SP_RIF_TYPE_SUBPORT]     = &mlxsw_sp_rif_subport_ops,
7687        [MLXSW_SP_RIF_TYPE_VLAN]        = &mlxsw_sp_rif_vlan_emu_ops,
7688        [MLXSW_SP_RIF_TYPE_FID]         = &mlxsw_sp_rif_fid_ops,
7689        [MLXSW_SP_RIF_TYPE_IPIP_LB]     = &mlxsw_sp1_rif_ipip_lb_ops,
7690};
7691
7692static int
7693mlxsw_sp_rif_ipip_lb_ul_rif_op(struct mlxsw_sp_rif *ul_rif, bool enable)
7694{
7695        struct mlxsw_sp *mlxsw_sp = ul_rif->mlxsw_sp;
7696        char ritr_pl[MLXSW_REG_RITR_LEN];
7697
7698        mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF,
7699                            ul_rif->rif_index, ul_rif->vr_id, IP_MAX_MTU);
7700        mlxsw_reg_ritr_loopback_protocol_set(ritr_pl,
7701                                             MLXSW_REG_RITR_LOOPBACK_GENERIC);
7702
7703        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
7704}
7705
7706static struct mlxsw_sp_rif *
7707mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
7708                       struct netlink_ext_ack *extack)
7709{
7710        struct mlxsw_sp_rif *ul_rif;
7711        u16 rif_index;
7712        int err;
7713
7714        err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
7715        if (err) {
7716                NL_SET_ERR_MSG_MOD(extack, "Exceeded number of supported router interfaces");
7717                return ERR_PTR(err);
7718        }
7719
7720        ul_rif = mlxsw_sp_rif_alloc(sizeof(*ul_rif), rif_index, vr->id, NULL);
7721        if (!ul_rif)
7722                return ERR_PTR(-ENOMEM);
7723
7724        mlxsw_sp->router->rifs[rif_index] = ul_rif;
7725        ul_rif->mlxsw_sp = mlxsw_sp;
7726        err = mlxsw_sp_rif_ipip_lb_ul_rif_op(ul_rif, true);
7727        if (err)
7728                goto ul_rif_op_err;
7729
7730        return ul_rif;
7731
7732ul_rif_op_err:
7733        mlxsw_sp->router->rifs[rif_index] = NULL;
7734        kfree(ul_rif);
7735        return ERR_PTR(err);
7736}
7737
7738static void mlxsw_sp_ul_rif_destroy(struct mlxsw_sp_rif *ul_rif)
7739{
7740        struct mlxsw_sp *mlxsw_sp = ul_rif->mlxsw_sp;
7741
7742        mlxsw_sp_rif_ipip_lb_ul_rif_op(ul_rif, false);
7743        mlxsw_sp->router->rifs[ul_rif->rif_index] = NULL;
7744        kfree(ul_rif);
7745}
7746
7747static struct mlxsw_sp_rif *
7748mlxsw_sp_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
7749                    struct netlink_ext_ack *extack)
7750{
7751        struct mlxsw_sp_vr *vr;
7752        int err;
7753
7754        vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id, extack);
7755        if (IS_ERR(vr))
7756                return ERR_CAST(vr);
7757
7758        if (refcount_inc_not_zero(&vr->ul_rif_refcnt))
7759                return vr->ul_rif;
7760
7761        vr->ul_rif = mlxsw_sp_ul_rif_create(mlxsw_sp, vr, extack);
7762        if (IS_ERR(vr->ul_rif)) {
7763                err = PTR_ERR(vr->ul_rif);
7764                goto err_ul_rif_create;
7765        }
7766
7767        vr->rif_count++;
7768        refcount_set(&vr->ul_rif_refcnt, 1);
7769
7770        return vr->ul_rif;
7771
7772err_ul_rif_create:
7773        mlxsw_sp_vr_put(mlxsw_sp, vr);
7774        return ERR_PTR(err);
7775}
7776
7777static void mlxsw_sp_ul_rif_put(struct mlxsw_sp_rif *ul_rif)
7778{
7779        struct mlxsw_sp *mlxsw_sp = ul_rif->mlxsw_sp;
7780        struct mlxsw_sp_vr *vr;
7781
7782        vr = &mlxsw_sp->router->vrs[ul_rif->vr_id];
7783
7784        if (!refcount_dec_and_test(&vr->ul_rif_refcnt))
7785                return;
7786
7787        vr->rif_count--;
7788        mlxsw_sp_ul_rif_destroy(ul_rif);
7789        mlxsw_sp_vr_put(mlxsw_sp, vr);
7790}
7791
7792int mlxsw_sp_router_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id,
7793                               u16 *ul_rif_index)
7794{
7795        struct mlxsw_sp_rif *ul_rif;
7796        int err = 0;
7797
7798        mutex_lock(&mlxsw_sp->router->lock);
7799        ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL);
7800        if (IS_ERR(ul_rif)) {
7801                err = PTR_ERR(ul_rif);
7802                goto out;
7803        }
7804        *ul_rif_index = ul_rif->rif_index;
7805out:
7806        mutex_unlock(&mlxsw_sp->router->lock);
7807        return err;
7808}
7809
7810void mlxsw_sp_router_ul_rif_put(struct mlxsw_sp *mlxsw_sp, u16 ul_rif_index)
7811{
7812        struct mlxsw_sp_rif *ul_rif;
7813
7814        mutex_lock(&mlxsw_sp->router->lock);
7815        ul_rif = mlxsw_sp->router->rifs[ul_rif_index];
7816        if (WARN_ON(!ul_rif))
7817                goto out;
7818
7819        mlxsw_sp_ul_rif_put(ul_rif);
7820out:
7821        mutex_unlock(&mlxsw_sp->router->lock);
7822}
7823
7824static int
7825mlxsw_sp2_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
7826{
7827        struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
7828        u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(rif->dev);
7829        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7830        struct mlxsw_sp_rif *ul_rif;
7831        int err;
7832
7833        ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL);
7834        if (IS_ERR(ul_rif))
7835                return PTR_ERR(ul_rif);
7836
7837        err = mlxsw_sp_rif_ipip_lb_op(lb_rif, 0, ul_rif->rif_index, true);
7838        if (err)
7839                goto err_loopback_op;
7840
7841        lb_rif->ul_vr_id = 0;
7842        lb_rif->ul_rif_id = ul_rif->rif_index;
7843
7844        return 0;
7845
7846err_loopback_op:
7847        mlxsw_sp_ul_rif_put(ul_rif);
7848        return err;
7849}
7850
7851static void mlxsw_sp2_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif)
7852{
7853        struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif);
7854        struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
7855        struct mlxsw_sp_rif *ul_rif;
7856
7857        ul_rif = mlxsw_sp_rif_by_index(mlxsw_sp, lb_rif->ul_rif_id);
7858        mlxsw_sp_rif_ipip_lb_op(lb_rif, 0, lb_rif->ul_rif_id, false);
7859        mlxsw_sp_ul_rif_put(ul_rif);
7860}
7861
7862static const struct mlxsw_sp_rif_ops mlxsw_sp2_rif_ipip_lb_ops = {
7863        .type                   = MLXSW_SP_RIF_TYPE_IPIP_LB,
7864        .rif_size               = sizeof(struct mlxsw_sp_rif_ipip_lb),
7865        .setup                  = mlxsw_sp_rif_ipip_lb_setup,
7866        .configure              = mlxsw_sp2_rif_ipip_lb_configure,
7867        .deconfigure            = mlxsw_sp2_rif_ipip_lb_deconfigure,
7868};
7869
7870const struct mlxsw_sp_rif_ops *mlxsw_sp2_rif_ops_arr[] = {
7871        [MLXSW_SP_RIF_TYPE_SUBPORT]     = &mlxsw_sp_rif_subport_ops,
7872        [MLXSW_SP_RIF_TYPE_VLAN]        = &mlxsw_sp_rif_vlan_emu_ops,
7873        [MLXSW_SP_RIF_TYPE_FID]         = &mlxsw_sp_rif_fid_ops,
7874        [MLXSW_SP_RIF_TYPE_IPIP_LB]     = &mlxsw_sp2_rif_ipip_lb_ops,
7875};
7876
7877static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp)
7878{
7879        u64 max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
7880
7881        mlxsw_sp->router->rifs = kcalloc(max_rifs,
7882                                         sizeof(struct mlxsw_sp_rif *),
7883                                         GFP_KERNEL);
7884        if (!mlxsw_sp->router->rifs)
7885                return -ENOMEM;
7886
7887        return 0;
7888}
7889
7890static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)
7891{
7892        int i;
7893
7894        for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++)
7895                WARN_ON_ONCE(mlxsw_sp->router->rifs[i]);
7896
7897        kfree(mlxsw_sp->router->rifs);
7898}
7899
7900static int
7901mlxsw_sp_ipip_config_tigcr(struct mlxsw_sp *mlxsw_sp)
7902{
7903        char tigcr_pl[MLXSW_REG_TIGCR_LEN];
7904
7905        mlxsw_reg_tigcr_pack(tigcr_pl, true, 0);
7906        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tigcr), tigcr_pl);
7907}
7908
7909static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp)
7910{
7911        int err;
7912
7913        mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr;
7914        INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list);
7915
7916        err = mlxsw_sp_ipip_ecn_encap_init(mlxsw_sp);
7917        if (err)
7918                return err;
7919        err = mlxsw_sp_ipip_ecn_decap_init(mlxsw_sp);
7920        if (err)
7921                return err;
7922
7923        return mlxsw_sp_ipip_config_tigcr(mlxsw_sp);
7924}
7925
7926static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
7927{
7928        WARN_ON(!list_empty(&mlxsw_sp->router->ipip_list));
7929}
7930
7931static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb)
7932{
7933        struct mlxsw_sp_router *router;
7934
7935        /* Flush pending FIB notifications and then flush the device's
7936         * table before requesting another dump. The FIB notification
7937         * block is unregistered, so no need to take RTNL.
7938         */
7939        mlxsw_core_flush_owq();
7940        router = container_of(nb, struct mlxsw_sp_router, fib_nb);
7941        mlxsw_sp_router_fib_flush(router->mlxsw_sp);
7942}
7943
7944#ifdef CONFIG_IP_ROUTE_MULTIPATH
7945static void mlxsw_sp_mp_hash_header_set(char *recr2_pl, int header)
7946{
7947        mlxsw_reg_recr2_outer_header_enables_set(recr2_pl, header, true);
7948}
7949
7950static void mlxsw_sp_mp_hash_field_set(char *recr2_pl, int field)
7951{
7952        mlxsw_reg_recr2_outer_header_fields_enable_set(recr2_pl, field, true);
7953}
7954
7955static void mlxsw_sp_mp4_hash_init(struct mlxsw_sp *mlxsw_sp, char *recr2_pl)
7956{
7957        struct net *net = mlxsw_sp_net(mlxsw_sp);
7958        bool only_l3 = !net->ipv4.sysctl_fib_multipath_hash_policy;
7959
7960        mlxsw_sp_mp_hash_header_set(recr2_pl,
7961                                    MLXSW_REG_RECR2_IPV4_EN_NOT_TCP_NOT_UDP);
7962        mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV4_EN_TCP_UDP);
7963        mlxsw_reg_recr2_ipv4_sip_enable(recr2_pl);
7964        mlxsw_reg_recr2_ipv4_dip_enable(recr2_pl);
7965        if (only_l3)
7966                return;
7967        mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_EN_IPV4);
7968        mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV4_PROTOCOL);
7969        mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_SPORT);
7970        mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_TCP_UDP_DPORT);
7971}
7972
7973static void mlxsw_sp_mp6_hash_init(struct mlxsw_sp *mlxsw_sp, char *recr2_pl)
7974{
7975        bool only_l3 = !ip6_multipath_hash_policy(mlxsw_sp_net(mlxsw_sp));
7976
7977        mlxsw_sp_mp_hash_header_set(recr2_pl,
7978                                    MLXSW_REG_RECR2_IPV6_EN_NOT_TCP_NOT_UDP);
7979        mlxsw_sp_mp_hash_header_set(recr2_pl, MLXSW_REG_RECR2_IPV6_EN_TCP_UDP);
7980        mlxsw_reg_recr2_ipv6_sip_enable(recr2_pl);
7981        mlxsw_reg_recr2_ipv6_dip_enable(recr2_pl);
7982        mlxsw_sp_mp_hash_field_set(recr2_pl, MLXSW_REG_RECR2_IPV6_NEXT_HEADER);
7983        if (only_l3) {
7984                mlxsw_sp_mp_hash_field_set(recr2_pl,
7985                                           MLXSW_REG_RECR2_IPV6_FLOW_LABEL);
7986        } else {
7987                mlxsw_sp_mp_hash_header_set(recr2_pl,
7988                                            MLXSW_REG_RECR2_TCP_UDP_EN_IPV6);
7989                mlxsw_sp_mp_hash_field_set(recr2_pl,
7990                                           MLXSW_REG_RECR2_TCP_UDP_SPORT);
7991                mlxsw_sp_mp_hash_field_set(recr2_pl,
7992                                           MLXSW_REG_RECR2_TCP_UDP_DPORT);
7993        }
7994}
7995
7996static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
7997{
7998        char recr2_pl[MLXSW_REG_RECR2_LEN];
7999        u32 seed;
8000
8001        seed = jhash(mlxsw_sp->base_mac, sizeof(mlxsw_sp->base_mac), 0);
8002        mlxsw_reg_recr2_pack(recr2_pl, seed);
8003        mlxsw_sp_mp4_hash_init(mlxsw_sp, recr2_pl);
8004        mlxsw_sp_mp6_hash_init(mlxsw_sp, recr2_pl);
8005
8006        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(recr2), recr2_pl);
8007}
8008#else
8009static int mlxsw_sp_mp_hash_init(struct mlxsw_sp *mlxsw_sp)
8010{
8011        return 0;
8012}
8013#endif
8014
8015static int mlxsw_sp_dscp_init(struct mlxsw_sp *mlxsw_sp)
8016{
8017        char rdpm_pl[MLXSW_REG_RDPM_LEN];
8018        unsigned int i;
8019
8020        MLXSW_REG_ZERO(rdpm, rdpm_pl);
8021
8022        /* HW is determining switch priority based on DSCP-bits, but the
8023         * kernel is still doing that based on the ToS. Since there's a
8024         * mismatch in bits we need to make sure to translate the right
8025         * value ToS would observe, skipping the 2 least-significant ECN bits.
8026         */
8027        for (i = 0; i < MLXSW_REG_RDPM_DSCP_ENTRY_REC_MAX_COUNT; i++)
8028                mlxsw_reg_rdpm_pack(rdpm_pl, i, rt_tos2priority(i << 2));
8029
8030        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rdpm), rdpm_pl);
8031}
8032
8033static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)
8034{
8035        struct net *net = mlxsw_sp_net(mlxsw_sp);
8036        bool usp = net->ipv4.sysctl_ip_fwd_update_priority;
8037        char rgcr_pl[MLXSW_REG_RGCR_LEN];
8038        u64 max_rifs;
8039        int err;
8040
8041        if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS))
8042                return -EIO;
8043        max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
8044
8045        mlxsw_reg_rgcr_pack(rgcr_pl, true, true);
8046        mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs);
8047        mlxsw_reg_rgcr_usp_set(rgcr_pl, usp);
8048        err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);
8049        if (err)
8050                return err;
8051        return 0;
8052}
8053
8054static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
8055{
8056        char rgcr_pl[MLXSW_REG_RGCR_LEN];
8057
8058        mlxsw_reg_rgcr_pack(rgcr_pl, false, false);
8059        mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);
8060}
8061
8062int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
8063                         struct netlink_ext_ack *extack)
8064{
8065        struct mlxsw_sp_router *router;
8066        int err;
8067
8068        router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL);
8069        if (!router)
8070                return -ENOMEM;
8071        mutex_init(&router->lock);
8072        mlxsw_sp->router = router;
8073        router->mlxsw_sp = mlxsw_sp;
8074
8075        router->inetaddr_nb.notifier_call = mlxsw_sp_inetaddr_event;
8076        err = register_inetaddr_notifier(&router->inetaddr_nb);
8077        if (err)
8078                goto err_register_inetaddr_notifier;
8079
8080        router->inet6addr_nb.notifier_call = mlxsw_sp_inet6addr_event;
8081        err = register_inet6addr_notifier(&router->inet6addr_nb);
8082        if (err)
8083                goto err_register_inet6addr_notifier;
8084
8085        INIT_LIST_HEAD(&mlxsw_sp->router->nexthop_neighs_list);
8086        err = __mlxsw_sp_router_init(mlxsw_sp);
8087        if (err)
8088                goto err_router_init;
8089
8090        err = mlxsw_sp_rifs_init(mlxsw_sp);
8091        if (err)
8092                goto err_rifs_init;
8093
8094        err = mlxsw_sp_ipips_init(mlxsw_sp);
8095        if (err)
8096                goto err_ipips_init;
8097
8098        err = rhashtable_init(&mlxsw_sp->router->nexthop_ht,
8099                              &mlxsw_sp_nexthop_ht_params);
8100        if (err)
8101                goto err_nexthop_ht_init;
8102
8103        err = rhashtable_init(&mlxsw_sp->router->nexthop_group_ht,
8104                              &mlxsw_sp_nexthop_group_ht_params);
8105        if (err)
8106                goto err_nexthop_group_ht_init;
8107
8108        INIT_LIST_HEAD(&mlxsw_sp->router->nexthop_list);
8109        err = mlxsw_sp_lpm_init(mlxsw_sp);
8110        if (err)
8111                goto err_lpm_init;
8112
8113        err = mlxsw_sp_mr_init(mlxsw_sp, &mlxsw_sp_mr_tcam_ops);
8114        if (err)
8115                goto err_mr_init;
8116
8117        err = mlxsw_sp_vrs_init(mlxsw_sp);
8118        if (err)
8119                goto err_vrs_init;
8120
8121        err = mlxsw_sp_neigh_init(mlxsw_sp);
8122        if (err)
8123                goto err_neigh_init;
8124
8125        mlxsw_sp->router->netevent_nb.notifier_call =
8126                mlxsw_sp_router_netevent_event;
8127        err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8128        if (err)
8129                goto err_register_netevent_notifier;
8130
8131        err = mlxsw_sp_mp_hash_init(mlxsw_sp);
8132        if (err)
8133                goto err_mp_hash_init;
8134
8135        err = mlxsw_sp_dscp_init(mlxsw_sp);
8136        if (err)
8137                goto err_dscp_init;
8138
8139        mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event;
8140        err = register_fib_notifier(mlxsw_sp_net(mlxsw_sp),
8141                                    &mlxsw_sp->router->fib_nb,
8142                                    mlxsw_sp_router_fib_dump_flush, extack);
8143        if (err)
8144                goto err_register_fib_notifier;
8145
8146        return 0;
8147
8148err_register_fib_notifier:
8149err_dscp_init:
8150err_mp_hash_init:
8151        unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8152err_register_netevent_notifier:
8153        mlxsw_sp_neigh_fini(mlxsw_sp);
8154err_neigh_init:
8155        mlxsw_sp_vrs_fini(mlxsw_sp);
8156err_vrs_init:
8157        mlxsw_sp_mr_fini(mlxsw_sp);
8158err_mr_init:
8159        mlxsw_sp_lpm_fini(mlxsw_sp);
8160err_lpm_init:
8161        rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht);
8162err_nexthop_group_ht_init:
8163        rhashtable_destroy(&mlxsw_sp->router->nexthop_ht);
8164err_nexthop_ht_init:
8165        mlxsw_sp_ipips_fini(mlxsw_sp);
8166err_ipips_init:
8167        mlxsw_sp_rifs_fini(mlxsw_sp);
8168err_rifs_init:
8169        __mlxsw_sp_router_fini(mlxsw_sp);
8170err_router_init:
8171        unregister_inet6addr_notifier(&router->inet6addr_nb);
8172err_register_inet6addr_notifier:
8173        unregister_inetaddr_notifier(&router->inetaddr_nb);
8174err_register_inetaddr_notifier:
8175        mutex_destroy(&mlxsw_sp->router->lock);
8176        kfree(mlxsw_sp->router);
8177        return err;
8178}
8179
8180void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
8181{
8182        unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp),
8183                                &mlxsw_sp->router->fib_nb);
8184        unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
8185        mlxsw_sp_neigh_fini(mlxsw_sp);
8186        mlxsw_sp_vrs_fini(mlxsw_sp);
8187        mlxsw_sp_mr_fini(mlxsw_sp);
8188        mlxsw_sp_lpm_fini(mlxsw_sp);
8189        rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht);
8190        rhashtable_destroy(&mlxsw_sp->router->nexthop_ht);
8191        mlxsw_sp_ipips_fini(mlxsw_sp);
8192        mlxsw_sp_rifs_fini(mlxsw_sp);
8193        __mlxsw_sp_router_fini(mlxsw_sp);
8194        unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb);
8195        unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb);
8196        mutex_destroy(&mlxsw_sp->router->lock);
8197        kfree(mlxsw_sp->router);
8198}
8199