1 /* 2 * drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c 3 * Copyright (c) 2016-2017 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 * Copyright (c) 2016 Ido Schimmel <idosch@mellanox.com> 6 * Copyright (c) 2016 Yotam Gigi <yotamg@mellanox.com> 7 * Copyright (c) 2017 Petr Machata <petrm@mellanox.com> 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the names of the copyright holders nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * Alternatively, this software may be distributed under the terms of the 22 * GNU General Public License ("GPL") version 2 as published by the Free 23 * Software Foundation. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <linux/kernel.h> 39 #include <linux/types.h> 40 #include <linux/rhashtable.h> 41 #include <linux/bitops.h> 42 #include <linux/in6.h> 43 #include <linux/notifier.h> 44 #include <linux/inetdevice.h> 45 #include <linux/netdevice.h> 46 #include <linux/if_bridge.h> 47 #include <linux/socket.h> 48 #include <linux/route.h> 49 #include <net/netevent.h> 50 #include <net/neighbour.h> 51 #include <net/arp.h> 52 #include <net/ip_fib.h> 53 #include <net/ip6_fib.h> 54 #include <net/fib_rules.h> 55 #include <net/ip_tunnels.h> 56 #include <net/l3mdev.h> 57 #include <net/addrconf.h> 58 #include <net/ndisc.h> 59 #include <net/ipv6.h> 60 #include <net/fib_notifier.h> 61 62 #include "spectrum.h" 63 #include "core.h" 64 #include "reg.h" 65 #include "spectrum_cnt.h" 66 #include "spectrum_dpipe.h" 67 #include "spectrum_ipip.h" 68 #include "spectrum_router.h" 69 70 struct mlxsw_sp_vr; 71 struct mlxsw_sp_lpm_tree; 72 struct mlxsw_sp_rif_ops; 73 74 struct mlxsw_sp_router { 75 struct mlxsw_sp *mlxsw_sp; 76 struct mlxsw_sp_rif **rifs; 77 struct mlxsw_sp_vr *vrs; 78 struct rhashtable neigh_ht; 79 struct rhashtable nexthop_group_ht; 80 struct rhashtable nexthop_ht; 81 struct { 82 struct mlxsw_sp_lpm_tree *trees; 83 unsigned int tree_count; 84 } lpm; 85 struct { 86 struct delayed_work dw; 87 unsigned long interval; /* ms */ 88 } neighs_update; 89 struct delayed_work nexthop_probe_dw; 90 #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ 91 struct list_head nexthop_neighs_list; 92 struct list_head ipip_list; 93 bool aborted; 94 struct notifier_block fib_nb; 95 const struct mlxsw_sp_rif_ops **rif_ops_arr; 96 const struct mlxsw_sp_ipip_ops **ipip_ops_arr; 97 }; 98 99 struct mlxsw_sp_rif { 100 struct list_head nexthop_list; 101 struct list_head neigh_list; 102 struct net_device *dev; 103 struct mlxsw_sp_fid *fid; 104 unsigned char addr[ETH_ALEN]; 105 int mtu; 106 u16 rif_index; 107 u16 vr_id; 108 const struct mlxsw_sp_rif_ops *ops; 109 struct mlxsw_sp *mlxsw_sp; 110 111 unsigned int counter_ingress; 112 bool counter_ingress_valid; 113 unsigned int counter_egress; 114 bool counter_egress_valid; 115 }; 116 117 struct mlxsw_sp_rif_params { 118 struct net_device *dev; 119 union { 120 u16 system_port; 121 u16 lag_id; 122 }; 123 u16 vid; 124 bool lag; 125 }; 126 127 struct mlxsw_sp_rif_subport { 128 struct mlxsw_sp_rif common; 129 union { 130 u16 system_port; 131 u16 lag_id; 132 }; 133 u16 vid; 134 bool lag; 135 }; 136 137 struct mlxsw_sp_rif_ipip_lb { 138 struct mlxsw_sp_rif common; 139 struct mlxsw_sp_rif_ipip_lb_config lb_config; 140 u16 ul_vr_id; /* Reserved for Spectrum-2. */ 141 }; 142 143 struct mlxsw_sp_rif_params_ipip_lb { 144 struct mlxsw_sp_rif_params common; 145 struct mlxsw_sp_rif_ipip_lb_config lb_config; 146 }; 147 148 struct mlxsw_sp_rif_ops { 149 enum mlxsw_sp_rif_type type; 150 size_t rif_size; 151 152 void (*setup)(struct mlxsw_sp_rif *rif, 153 const struct mlxsw_sp_rif_params *params); 154 int (*configure)(struct mlxsw_sp_rif *rif); 155 void (*deconfigure)(struct mlxsw_sp_rif *rif); 156 struct mlxsw_sp_fid * (*fid_get)(struct mlxsw_sp_rif *rif); 157 }; 158 159 static unsigned int * 160 mlxsw_sp_rif_p_counter_get(struct mlxsw_sp_rif *rif, 161 enum mlxsw_sp_rif_counter_dir dir) 162 { 163 switch (dir) { 164 case MLXSW_SP_RIF_COUNTER_EGRESS: 165 return &rif->counter_egress; 166 case MLXSW_SP_RIF_COUNTER_INGRESS: 167 return &rif->counter_ingress; 168 } 169 return NULL; 170 } 171 172 static bool 173 mlxsw_sp_rif_counter_valid_get(struct mlxsw_sp_rif *rif, 174 enum mlxsw_sp_rif_counter_dir dir) 175 { 176 switch (dir) { 177 case MLXSW_SP_RIF_COUNTER_EGRESS: 178 return rif->counter_egress_valid; 179 case MLXSW_SP_RIF_COUNTER_INGRESS: 180 return rif->counter_ingress_valid; 181 } 182 return false; 183 } 184 185 static void 186 mlxsw_sp_rif_counter_valid_set(struct mlxsw_sp_rif *rif, 187 enum mlxsw_sp_rif_counter_dir dir, 188 bool valid) 189 { 190 switch (dir) { 191 case MLXSW_SP_RIF_COUNTER_EGRESS: 192 rif->counter_egress_valid = valid; 193 break; 194 case MLXSW_SP_RIF_COUNTER_INGRESS: 195 rif->counter_ingress_valid = valid; 196 break; 197 } 198 } 199 200 static int mlxsw_sp_rif_counter_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index, 201 unsigned int counter_index, bool enable, 202 enum mlxsw_sp_rif_counter_dir dir) 203 { 204 char ritr_pl[MLXSW_REG_RITR_LEN]; 205 bool is_egress = false; 206 int err; 207 208 if (dir == MLXSW_SP_RIF_COUNTER_EGRESS) 209 is_egress = true; 210 mlxsw_reg_ritr_rif_pack(ritr_pl, rif_index); 211 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 212 if (err) 213 return err; 214 215 mlxsw_reg_ritr_counter_pack(ritr_pl, counter_index, enable, 216 is_egress); 217 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 218 } 219 220 int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, 221 struct mlxsw_sp_rif *rif, 222 enum mlxsw_sp_rif_counter_dir dir, u64 *cnt) 223 { 224 char ricnt_pl[MLXSW_REG_RICNT_LEN]; 225 unsigned int *p_counter_index; 226 bool valid; 227 int err; 228 229 valid = mlxsw_sp_rif_counter_valid_get(rif, dir); 230 if (!valid) 231 return -EINVAL; 232 233 p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir); 234 if (!p_counter_index) 235 return -EINVAL; 236 mlxsw_reg_ricnt_pack(ricnt_pl, *p_counter_index, 237 MLXSW_REG_RICNT_OPCODE_NOP); 238 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl); 239 if (err) 240 return err; 241 *cnt = mlxsw_reg_ricnt_good_unicast_packets_get(ricnt_pl); 242 return 0; 243 } 244 245 static int mlxsw_sp_rif_counter_clear(struct mlxsw_sp *mlxsw_sp, 246 unsigned int counter_index) 247 { 248 char ricnt_pl[MLXSW_REG_RICNT_LEN]; 249 250 mlxsw_reg_ricnt_pack(ricnt_pl, counter_index, 251 MLXSW_REG_RICNT_OPCODE_CLEAR); 252 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl); 253 } 254 255 int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp, 256 struct mlxsw_sp_rif *rif, 257 enum mlxsw_sp_rif_counter_dir dir) 258 { 259 unsigned int *p_counter_index; 260 int err; 261 262 p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir); 263 if (!p_counter_index) 264 return -EINVAL; 265 err = mlxsw_sp_counter_alloc(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF, 266 p_counter_index); 267 if (err) 268 return err; 269 270 err = mlxsw_sp_rif_counter_clear(mlxsw_sp, *p_counter_index); 271 if (err) 272 goto err_counter_clear; 273 274 err = mlxsw_sp_rif_counter_edit(mlxsw_sp, rif->rif_index, 275 *p_counter_index, true, dir); 276 if (err) 277 goto err_counter_edit; 278 mlxsw_sp_rif_counter_valid_set(rif, dir, true); 279 return 0; 280 281 err_counter_edit: 282 err_counter_clear: 283 mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF, 284 *p_counter_index); 285 return err; 286 } 287 288 void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp, 289 struct mlxsw_sp_rif *rif, 290 enum mlxsw_sp_rif_counter_dir dir) 291 { 292 unsigned int *p_counter_index; 293 294 if (!mlxsw_sp_rif_counter_valid_get(rif, dir)) 295 return; 296 297 p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir); 298 if (WARN_ON(!p_counter_index)) 299 return; 300 mlxsw_sp_rif_counter_edit(mlxsw_sp, rif->rif_index, 301 *p_counter_index, false, dir); 302 mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF, 303 *p_counter_index); 304 mlxsw_sp_rif_counter_valid_set(rif, dir, false); 305 } 306 307 static void mlxsw_sp_rif_counters_alloc(struct mlxsw_sp_rif *rif) 308 { 309 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 310 struct devlink *devlink; 311 312 devlink = priv_to_devlink(mlxsw_sp->core); 313 if (!devlink_dpipe_table_counter_enabled(devlink, 314 MLXSW_SP_DPIPE_TABLE_NAME_ERIF)) 315 return; 316 mlxsw_sp_rif_counter_alloc(mlxsw_sp, rif, MLXSW_SP_RIF_COUNTER_EGRESS); 317 } 318 319 static void mlxsw_sp_rif_counters_free(struct mlxsw_sp_rif *rif) 320 { 321 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 322 323 mlxsw_sp_rif_counter_free(mlxsw_sp, rif, MLXSW_SP_RIF_COUNTER_EGRESS); 324 } 325 326 static struct mlxsw_sp_rif * 327 mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp, 328 const struct net_device *dev); 329 330 #define MLXSW_SP_PREFIX_COUNT (sizeof(struct in6_addr) * BITS_PER_BYTE + 1) 331 332 struct mlxsw_sp_prefix_usage { 333 DECLARE_BITMAP(b, MLXSW_SP_PREFIX_COUNT); 334 }; 335 336 #define mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) \ 337 for_each_set_bit(prefix, (prefix_usage)->b, MLXSW_SP_PREFIX_COUNT) 338 339 static bool 340 mlxsw_sp_prefix_usage_eq(struct mlxsw_sp_prefix_usage *prefix_usage1, 341 struct mlxsw_sp_prefix_usage *prefix_usage2) 342 { 343 return !memcmp(prefix_usage1, prefix_usage2, sizeof(*prefix_usage1)); 344 } 345 346 static bool 347 mlxsw_sp_prefix_usage_none(struct mlxsw_sp_prefix_usage *prefix_usage) 348 { 349 struct mlxsw_sp_prefix_usage prefix_usage_none = {{ 0 } }; 350 351 return mlxsw_sp_prefix_usage_eq(prefix_usage, &prefix_usage_none); 352 } 353 354 static void 355 mlxsw_sp_prefix_usage_cpy(struct mlxsw_sp_prefix_usage *prefix_usage1, 356 struct mlxsw_sp_prefix_usage *prefix_usage2) 357 { 358 memcpy(prefix_usage1, prefix_usage2, sizeof(*prefix_usage1)); 359 } 360 361 static void 362 mlxsw_sp_prefix_usage_set(struct mlxsw_sp_prefix_usage *prefix_usage, 363 unsigned char prefix_len) 364 { 365 set_bit(prefix_len, prefix_usage->b); 366 } 367 368 static void 369 mlxsw_sp_prefix_usage_clear(struct mlxsw_sp_prefix_usage *prefix_usage, 370 unsigned char prefix_len) 371 { 372 clear_bit(prefix_len, prefix_usage->b); 373 } 374 375 struct mlxsw_sp_fib_key { 376 unsigned char addr[sizeof(struct in6_addr)]; 377 unsigned char prefix_len; 378 }; 379 380 enum mlxsw_sp_fib_entry_type { 381 MLXSW_SP_FIB_ENTRY_TYPE_REMOTE, 382 MLXSW_SP_FIB_ENTRY_TYPE_LOCAL, 383 MLXSW_SP_FIB_ENTRY_TYPE_TRAP, 384 385 /* This is a special case of local delivery, where a packet should be 386 * decapsulated on reception. Note that there is no corresponding ENCAP, 387 * because that's a type of next hop, not of FIB entry. (There can be 388 * several next hops in a REMOTE entry, and some of them may be 389 * encapsulating entries.) 390 */ 391 MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP, 392 }; 393 394 struct mlxsw_sp_nexthop_group; 395 struct mlxsw_sp_fib; 396 397 struct mlxsw_sp_fib_node { 398 struct list_head entry_list; 399 struct list_head list; 400 struct rhash_head ht_node; 401 struct mlxsw_sp_fib *fib; 402 struct mlxsw_sp_fib_key key; 403 }; 404 405 struct mlxsw_sp_fib_entry_decap { 406 struct mlxsw_sp_ipip_entry *ipip_entry; 407 u32 tunnel_index; 408 }; 409 410 struct mlxsw_sp_fib_entry { 411 struct list_head list; 412 struct mlxsw_sp_fib_node *fib_node; 413 enum mlxsw_sp_fib_entry_type type; 414 struct list_head nexthop_group_node; 415 struct mlxsw_sp_nexthop_group *nh_group; 416 struct mlxsw_sp_fib_entry_decap decap; /* Valid for decap entries. */ 417 }; 418 419 struct mlxsw_sp_fib4_entry { 420 struct mlxsw_sp_fib_entry common; 421 u32 tb_id; 422 u32 prio; 423 u8 tos; 424 u8 type; 425 }; 426 427 struct mlxsw_sp_fib6_entry { 428 struct mlxsw_sp_fib_entry common; 429 struct list_head rt6_list; 430 unsigned int nrt6; 431 }; 432 433 struct mlxsw_sp_rt6 { 434 struct list_head list; 435 struct rt6_info *rt; 436 }; 437 438 struct mlxsw_sp_lpm_tree { 439 u8 id; /* tree ID */ 440 unsigned int ref_count; 441 enum mlxsw_sp_l3proto proto; 442 struct mlxsw_sp_prefix_usage prefix_usage; 443 }; 444 445 struct mlxsw_sp_fib { 446 struct rhashtable ht; 447 struct list_head node_list; 448 struct mlxsw_sp_vr *vr; 449 struct mlxsw_sp_lpm_tree *lpm_tree; 450 unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT]; 451 struct mlxsw_sp_prefix_usage prefix_usage; 452 enum mlxsw_sp_l3proto proto; 453 }; 454 455 struct mlxsw_sp_vr { 456 u16 id; /* virtual router ID */ 457 u32 tb_id; /* kernel fib table id */ 458 unsigned int rif_count; 459 struct mlxsw_sp_fib *fib4; 460 struct mlxsw_sp_fib *fib6; 461 }; 462 463 static const struct rhashtable_params mlxsw_sp_fib_ht_params; 464 465 static struct mlxsw_sp_fib *mlxsw_sp_fib_create(struct mlxsw_sp_vr *vr, 466 enum mlxsw_sp_l3proto proto) 467 { 468 struct mlxsw_sp_fib *fib; 469 int err; 470 471 fib = kzalloc(sizeof(*fib), GFP_KERNEL); 472 if (!fib) 473 return ERR_PTR(-ENOMEM); 474 err = rhashtable_init(&fib->ht, &mlxsw_sp_fib_ht_params); 475 if (err) 476 goto err_rhashtable_init; 477 INIT_LIST_HEAD(&fib->node_list); 478 fib->proto = proto; 479 fib->vr = vr; 480 return fib; 481 482 err_rhashtable_init: 483 kfree(fib); 484 return ERR_PTR(err); 485 } 486 487 static void mlxsw_sp_fib_destroy(struct mlxsw_sp_fib *fib) 488 { 489 WARN_ON(!list_empty(&fib->node_list)); 490 WARN_ON(fib->lpm_tree); 491 rhashtable_destroy(&fib->ht); 492 kfree(fib); 493 } 494 495 static struct mlxsw_sp_lpm_tree * 496 mlxsw_sp_lpm_tree_find_unused(struct mlxsw_sp *mlxsw_sp) 497 { 498 static struct mlxsw_sp_lpm_tree *lpm_tree; 499 int i; 500 501 for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) { 502 lpm_tree = &mlxsw_sp->router->lpm.trees[i]; 503 if (lpm_tree->ref_count == 0) 504 return lpm_tree; 505 } 506 return NULL; 507 } 508 509 static int mlxsw_sp_lpm_tree_alloc(struct mlxsw_sp *mlxsw_sp, 510 struct mlxsw_sp_lpm_tree *lpm_tree) 511 { 512 char ralta_pl[MLXSW_REG_RALTA_LEN]; 513 514 mlxsw_reg_ralta_pack(ralta_pl, true, 515 (enum mlxsw_reg_ralxx_protocol) lpm_tree->proto, 516 lpm_tree->id); 517 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl); 518 } 519 520 static void mlxsw_sp_lpm_tree_free(struct mlxsw_sp *mlxsw_sp, 521 struct mlxsw_sp_lpm_tree *lpm_tree) 522 { 523 char ralta_pl[MLXSW_REG_RALTA_LEN]; 524 525 mlxsw_reg_ralta_pack(ralta_pl, false, 526 (enum mlxsw_reg_ralxx_protocol) lpm_tree->proto, 527 lpm_tree->id); 528 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl); 529 } 530 531 static int 532 mlxsw_sp_lpm_tree_left_struct_set(struct mlxsw_sp *mlxsw_sp, 533 struct mlxsw_sp_prefix_usage *prefix_usage, 534 struct mlxsw_sp_lpm_tree *lpm_tree) 535 { 536 char ralst_pl[MLXSW_REG_RALST_LEN]; 537 u8 root_bin = 0; 538 u8 prefix; 539 u8 last_prefix = MLXSW_REG_RALST_BIN_NO_CHILD; 540 541 mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) 542 root_bin = prefix; 543 544 mlxsw_reg_ralst_pack(ralst_pl, root_bin, lpm_tree->id); 545 mlxsw_sp_prefix_usage_for_each(prefix, prefix_usage) { 546 if (prefix == 0) 547 continue; 548 mlxsw_reg_ralst_bin_pack(ralst_pl, prefix, last_prefix, 549 MLXSW_REG_RALST_BIN_NO_CHILD); 550 last_prefix = prefix; 551 } 552 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralst), ralst_pl); 553 } 554 555 static struct mlxsw_sp_lpm_tree * 556 mlxsw_sp_lpm_tree_create(struct mlxsw_sp *mlxsw_sp, 557 struct mlxsw_sp_prefix_usage *prefix_usage, 558 enum mlxsw_sp_l3proto proto) 559 { 560 struct mlxsw_sp_lpm_tree *lpm_tree; 561 int err; 562 563 lpm_tree = mlxsw_sp_lpm_tree_find_unused(mlxsw_sp); 564 if (!lpm_tree) 565 return ERR_PTR(-EBUSY); 566 lpm_tree->proto = proto; 567 err = mlxsw_sp_lpm_tree_alloc(mlxsw_sp, lpm_tree); 568 if (err) 569 return ERR_PTR(err); 570 571 err = mlxsw_sp_lpm_tree_left_struct_set(mlxsw_sp, prefix_usage, 572 lpm_tree); 573 if (err) 574 goto err_left_struct_set; 575 memcpy(&lpm_tree->prefix_usage, prefix_usage, 576 sizeof(lpm_tree->prefix_usage)); 577 return lpm_tree; 578 579 err_left_struct_set: 580 mlxsw_sp_lpm_tree_free(mlxsw_sp, lpm_tree); 581 return ERR_PTR(err); 582 } 583 584 static void mlxsw_sp_lpm_tree_destroy(struct mlxsw_sp *mlxsw_sp, 585 struct mlxsw_sp_lpm_tree *lpm_tree) 586 { 587 mlxsw_sp_lpm_tree_free(mlxsw_sp, lpm_tree); 588 } 589 590 static struct mlxsw_sp_lpm_tree * 591 mlxsw_sp_lpm_tree_get(struct mlxsw_sp *mlxsw_sp, 592 struct mlxsw_sp_prefix_usage *prefix_usage, 593 enum mlxsw_sp_l3proto proto) 594 { 595 struct mlxsw_sp_lpm_tree *lpm_tree; 596 int i; 597 598 for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) { 599 lpm_tree = &mlxsw_sp->router->lpm.trees[i]; 600 if (lpm_tree->ref_count != 0 && 601 lpm_tree->proto == proto && 602 mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage, 603 prefix_usage)) 604 return lpm_tree; 605 } 606 return mlxsw_sp_lpm_tree_create(mlxsw_sp, prefix_usage, proto); 607 } 608 609 static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree) 610 { 611 lpm_tree->ref_count++; 612 } 613 614 static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp, 615 struct mlxsw_sp_lpm_tree *lpm_tree) 616 { 617 if (--lpm_tree->ref_count == 0) 618 mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree); 619 } 620 621 #define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */ 622 623 static int mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp) 624 { 625 struct mlxsw_sp_lpm_tree *lpm_tree; 626 u64 max_trees; 627 int i; 628 629 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_LPM_TREES)) 630 return -EIO; 631 632 max_trees = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LPM_TREES); 633 mlxsw_sp->router->lpm.tree_count = max_trees - MLXSW_SP_LPM_TREE_MIN; 634 mlxsw_sp->router->lpm.trees = kcalloc(mlxsw_sp->router->lpm.tree_count, 635 sizeof(struct mlxsw_sp_lpm_tree), 636 GFP_KERNEL); 637 if (!mlxsw_sp->router->lpm.trees) 638 return -ENOMEM; 639 640 for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) { 641 lpm_tree = &mlxsw_sp->router->lpm.trees[i]; 642 lpm_tree->id = i + MLXSW_SP_LPM_TREE_MIN; 643 } 644 645 return 0; 646 } 647 648 static void mlxsw_sp_lpm_fini(struct mlxsw_sp *mlxsw_sp) 649 { 650 kfree(mlxsw_sp->router->lpm.trees); 651 } 652 653 static bool mlxsw_sp_vr_is_used(const struct mlxsw_sp_vr *vr) 654 { 655 return !!vr->fib4 || !!vr->fib6; 656 } 657 658 static struct mlxsw_sp_vr *mlxsw_sp_vr_find_unused(struct mlxsw_sp *mlxsw_sp) 659 { 660 struct mlxsw_sp_vr *vr; 661 int i; 662 663 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 664 vr = &mlxsw_sp->router->vrs[i]; 665 if (!mlxsw_sp_vr_is_used(vr)) 666 return vr; 667 } 668 return NULL; 669 } 670 671 static int mlxsw_sp_vr_lpm_tree_bind(struct mlxsw_sp *mlxsw_sp, 672 const struct mlxsw_sp_fib *fib, u8 tree_id) 673 { 674 char raltb_pl[MLXSW_REG_RALTB_LEN]; 675 676 mlxsw_reg_raltb_pack(raltb_pl, fib->vr->id, 677 (enum mlxsw_reg_ralxx_protocol) fib->proto, 678 tree_id); 679 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), raltb_pl); 680 } 681 682 static int mlxsw_sp_vr_lpm_tree_unbind(struct mlxsw_sp *mlxsw_sp, 683 const struct mlxsw_sp_fib *fib) 684 { 685 char raltb_pl[MLXSW_REG_RALTB_LEN]; 686 687 /* Bind to tree 0 which is default */ 688 mlxsw_reg_raltb_pack(raltb_pl, fib->vr->id, 689 (enum mlxsw_reg_ralxx_protocol) fib->proto, 0); 690 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), raltb_pl); 691 } 692 693 static u32 mlxsw_sp_fix_tb_id(u32 tb_id) 694 { 695 /* For our purpose, squash main and local table into one */ 696 if (tb_id == RT_TABLE_LOCAL) 697 tb_id = RT_TABLE_MAIN; 698 return tb_id; 699 } 700 701 static struct mlxsw_sp_vr *mlxsw_sp_vr_find(struct mlxsw_sp *mlxsw_sp, 702 u32 tb_id) 703 { 704 struct mlxsw_sp_vr *vr; 705 int i; 706 707 tb_id = mlxsw_sp_fix_tb_id(tb_id); 708 709 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 710 vr = &mlxsw_sp->router->vrs[i]; 711 if (mlxsw_sp_vr_is_used(vr) && vr->tb_id == tb_id) 712 return vr; 713 } 714 return NULL; 715 } 716 717 static struct mlxsw_sp_fib *mlxsw_sp_vr_fib(const struct mlxsw_sp_vr *vr, 718 enum mlxsw_sp_l3proto proto) 719 { 720 switch (proto) { 721 case MLXSW_SP_L3_PROTO_IPV4: 722 return vr->fib4; 723 case MLXSW_SP_L3_PROTO_IPV6: 724 return vr->fib6; 725 } 726 return NULL; 727 } 728 729 static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp, 730 u32 tb_id) 731 { 732 struct mlxsw_sp_vr *vr; 733 int err; 734 735 vr = mlxsw_sp_vr_find_unused(mlxsw_sp); 736 if (!vr) 737 return ERR_PTR(-EBUSY); 738 vr->fib4 = mlxsw_sp_fib_create(vr, MLXSW_SP_L3_PROTO_IPV4); 739 if (IS_ERR(vr->fib4)) 740 return ERR_CAST(vr->fib4); 741 vr->fib6 = mlxsw_sp_fib_create(vr, MLXSW_SP_L3_PROTO_IPV6); 742 if (IS_ERR(vr->fib6)) { 743 err = PTR_ERR(vr->fib6); 744 goto err_fib6_create; 745 } 746 vr->tb_id = tb_id; 747 return vr; 748 749 err_fib6_create: 750 mlxsw_sp_fib_destroy(vr->fib4); 751 vr->fib4 = NULL; 752 return ERR_PTR(err); 753 } 754 755 static void mlxsw_sp_vr_destroy(struct mlxsw_sp_vr *vr) 756 { 757 mlxsw_sp_fib_destroy(vr->fib6); 758 vr->fib6 = NULL; 759 mlxsw_sp_fib_destroy(vr->fib4); 760 vr->fib4 = NULL; 761 } 762 763 static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id) 764 { 765 struct mlxsw_sp_vr *vr; 766 767 tb_id = mlxsw_sp_fix_tb_id(tb_id); 768 vr = mlxsw_sp_vr_find(mlxsw_sp, tb_id); 769 if (!vr) 770 vr = mlxsw_sp_vr_create(mlxsw_sp, tb_id); 771 return vr; 772 } 773 774 static void mlxsw_sp_vr_put(struct mlxsw_sp_vr *vr) 775 { 776 if (!vr->rif_count && list_empty(&vr->fib4->node_list) && 777 list_empty(&vr->fib6->node_list)) 778 mlxsw_sp_vr_destroy(vr); 779 } 780 781 static bool 782 mlxsw_sp_vr_lpm_tree_should_replace(struct mlxsw_sp_vr *vr, 783 enum mlxsw_sp_l3proto proto, u8 tree_id) 784 { 785 struct mlxsw_sp_fib *fib = mlxsw_sp_vr_fib(vr, proto); 786 787 if (!mlxsw_sp_vr_is_used(vr)) 788 return false; 789 if (fib->lpm_tree && fib->lpm_tree->id == tree_id) 790 return true; 791 return false; 792 } 793 794 static int mlxsw_sp_vr_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp, 795 struct mlxsw_sp_fib *fib, 796 struct mlxsw_sp_lpm_tree *new_tree) 797 { 798 struct mlxsw_sp_lpm_tree *old_tree = fib->lpm_tree; 799 int err; 800 801 err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id); 802 if (err) 803 return err; 804 fib->lpm_tree = new_tree; 805 mlxsw_sp_lpm_tree_hold(new_tree); 806 mlxsw_sp_lpm_tree_put(mlxsw_sp, old_tree); 807 return 0; 808 } 809 810 static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp, 811 struct mlxsw_sp_fib *fib, 812 struct mlxsw_sp_lpm_tree *new_tree) 813 { 814 struct mlxsw_sp_lpm_tree *old_tree = fib->lpm_tree; 815 enum mlxsw_sp_l3proto proto = fib->proto; 816 u8 old_id, new_id = new_tree->id; 817 struct mlxsw_sp_vr *vr; 818 int i, err; 819 820 if (!old_tree) 821 goto no_replace; 822 old_id = old_tree->id; 823 824 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 825 vr = &mlxsw_sp->router->vrs[i]; 826 if (!mlxsw_sp_vr_lpm_tree_should_replace(vr, proto, old_id)) 827 continue; 828 err = mlxsw_sp_vr_lpm_tree_replace(mlxsw_sp, 829 mlxsw_sp_vr_fib(vr, proto), 830 new_tree); 831 if (err) 832 goto err_tree_replace; 833 } 834 835 return 0; 836 837 err_tree_replace: 838 for (i--; i >= 0; i--) { 839 if (!mlxsw_sp_vr_lpm_tree_should_replace(vr, proto, new_id)) 840 continue; 841 mlxsw_sp_vr_lpm_tree_replace(mlxsw_sp, 842 mlxsw_sp_vr_fib(vr, proto), 843 old_tree); 844 } 845 return err; 846 847 no_replace: 848 err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id); 849 if (err) 850 return err; 851 fib->lpm_tree = new_tree; 852 mlxsw_sp_lpm_tree_hold(new_tree); 853 return 0; 854 } 855 856 static void 857 mlxsw_sp_vrs_prefixes(struct mlxsw_sp *mlxsw_sp, 858 enum mlxsw_sp_l3proto proto, 859 struct mlxsw_sp_prefix_usage *req_prefix_usage) 860 { 861 int i; 862 863 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 864 struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i]; 865 struct mlxsw_sp_fib *fib = mlxsw_sp_vr_fib(vr, proto); 866 unsigned char prefix; 867 868 if (!mlxsw_sp_vr_is_used(vr)) 869 continue; 870 mlxsw_sp_prefix_usage_for_each(prefix, &fib->prefix_usage) 871 mlxsw_sp_prefix_usage_set(req_prefix_usage, prefix); 872 } 873 } 874 875 static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp) 876 { 877 struct mlxsw_sp_vr *vr; 878 u64 max_vrs; 879 int i; 880 881 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_VRS)) 882 return -EIO; 883 884 max_vrs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); 885 mlxsw_sp->router->vrs = kcalloc(max_vrs, sizeof(struct mlxsw_sp_vr), 886 GFP_KERNEL); 887 if (!mlxsw_sp->router->vrs) 888 return -ENOMEM; 889 890 for (i = 0; i < max_vrs; i++) { 891 vr = &mlxsw_sp->router->vrs[i]; 892 vr->id = i; 893 } 894 895 return 0; 896 } 897 898 static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp); 899 900 static void mlxsw_sp_vrs_fini(struct mlxsw_sp *mlxsw_sp) 901 { 902 /* At this stage we're guaranteed not to have new incoming 903 * FIB notifications and the work queue is free from FIBs 904 * sitting on top of mlxsw netdevs. However, we can still 905 * have other FIBs queued. Flush the queue before flushing 906 * the device's tables. No need for locks, as we're the only 907 * writer. 908 */ 909 mlxsw_core_flush_owq(); 910 mlxsw_sp_router_fib_flush(mlxsw_sp); 911 kfree(mlxsw_sp->router->vrs); 912 } 913 914 static struct net_device * 915 __mlxsw_sp_ipip_netdev_ul_dev_get(const struct net_device *ol_dev) 916 { 917 struct ip_tunnel *tun = netdev_priv(ol_dev); 918 struct net *net = dev_net(ol_dev); 919 920 return __dev_get_by_index(net, tun->parms.link); 921 } 922 923 static u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev) 924 { 925 struct net_device *d = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev); 926 927 if (d) 928 return l3mdev_fib_table(d) ? : RT_TABLE_MAIN; 929 else 930 return l3mdev_fib_table(ol_dev) ? : RT_TABLE_MAIN; 931 } 932 933 static struct mlxsw_sp_rif * 934 mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, 935 const struct mlxsw_sp_rif_params *params); 936 937 static struct mlxsw_sp_rif_ipip_lb * 938 mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp, 939 enum mlxsw_sp_ipip_type ipipt, 940 struct net_device *ol_dev) 941 { 942 struct mlxsw_sp_rif_params_ipip_lb lb_params; 943 const struct mlxsw_sp_ipip_ops *ipip_ops; 944 struct mlxsw_sp_rif *rif; 945 946 ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt]; 947 lb_params = (struct mlxsw_sp_rif_params_ipip_lb) { 948 .common.dev = ol_dev, 949 .common.lag = false, 950 .lb_config = ipip_ops->ol_loopback_config(mlxsw_sp, ol_dev), 951 }; 952 953 rif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common); 954 if (IS_ERR(rif)) 955 return ERR_CAST(rif); 956 return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common); 957 } 958 959 static struct mlxsw_sp_ipip_entry * 960 mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp, 961 enum mlxsw_sp_ipip_type ipipt, 962 struct net_device *ol_dev) 963 { 964 struct mlxsw_sp_ipip_entry *ipip_entry; 965 struct mlxsw_sp_ipip_entry *ret = NULL; 966 967 ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL); 968 if (!ipip_entry) 969 return ERR_PTR(-ENOMEM); 970 971 ipip_entry->ol_lb = mlxsw_sp_ipip_ol_ipip_lb_create(mlxsw_sp, ipipt, 972 ol_dev); 973 if (IS_ERR(ipip_entry->ol_lb)) { 974 ret = ERR_CAST(ipip_entry->ol_lb); 975 goto err_ol_ipip_lb_create; 976 } 977 978 ipip_entry->ipipt = ipipt; 979 ipip_entry->ol_dev = ol_dev; 980 981 return ipip_entry; 982 983 err_ol_ipip_lb_create: 984 kfree(ipip_entry); 985 return ret; 986 } 987 988 static void 989 mlxsw_sp_ipip_entry_destroy(struct mlxsw_sp_ipip_entry *ipip_entry) 990 { 991 WARN_ON(ipip_entry->ref_count > 0); 992 mlxsw_sp_rif_destroy(&ipip_entry->ol_lb->common); 993 kfree(ipip_entry); 994 } 995 996 static __be32 997 mlxsw_sp_ipip_netdev_saddr4(const struct net_device *ol_dev) 998 { 999 struct ip_tunnel *tun = netdev_priv(ol_dev); 1000 1001 return tun->parms.iph.saddr; 1002 } 1003 1004 union mlxsw_sp_l3addr 1005 mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto, 1006 const struct net_device *ol_dev) 1007 { 1008 switch (proto) { 1009 case MLXSW_SP_L3_PROTO_IPV4: 1010 return (union mlxsw_sp_l3addr) { 1011 .addr4 = mlxsw_sp_ipip_netdev_saddr4(ol_dev), 1012 }; 1013 case MLXSW_SP_L3_PROTO_IPV6: 1014 break; 1015 }; 1016 1017 WARN_ON(1); 1018 return (union mlxsw_sp_l3addr) { 1019 .addr4 = 0, 1020 }; 1021 } 1022 1023 __be32 mlxsw_sp_ipip_netdev_daddr4(const struct net_device *ol_dev) 1024 { 1025 struct ip_tunnel *tun = netdev_priv(ol_dev); 1026 1027 return tun->parms.iph.daddr; 1028 } 1029 1030 union mlxsw_sp_l3addr 1031 mlxsw_sp_ipip_netdev_daddr(enum mlxsw_sp_l3proto proto, 1032 const struct net_device *ol_dev) 1033 { 1034 switch (proto) { 1035 case MLXSW_SP_L3_PROTO_IPV4: 1036 return (union mlxsw_sp_l3addr) { 1037 .addr4 = mlxsw_sp_ipip_netdev_daddr4(ol_dev), 1038 }; 1039 case MLXSW_SP_L3_PROTO_IPV6: 1040 break; 1041 }; 1042 1043 WARN_ON(1); 1044 return (union mlxsw_sp_l3addr) { 1045 .addr4 = 0, 1046 }; 1047 } 1048 1049 static bool mlxsw_sp_l3addr_eq(const union mlxsw_sp_l3addr *addr1, 1050 const union mlxsw_sp_l3addr *addr2) 1051 { 1052 return !memcmp(addr1, addr2, sizeof(*addr1)); 1053 } 1054 1055 static bool 1056 mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp, 1057 const enum mlxsw_sp_l3proto ul_proto, 1058 union mlxsw_sp_l3addr saddr, 1059 u32 ul_tb_id, 1060 struct mlxsw_sp_ipip_entry *ipip_entry) 1061 { 1062 u32 tun_ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev); 1063 enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt; 1064 union mlxsw_sp_l3addr tun_saddr; 1065 1066 if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto) 1067 return false; 1068 1069 tun_saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ipip_entry->ol_dev); 1070 return tun_ul_tb_id == ul_tb_id && 1071 mlxsw_sp_l3addr_eq(&tun_saddr, &saddr); 1072 } 1073 1074 static int 1075 mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp, 1076 struct mlxsw_sp_fib_entry *fib_entry, 1077 struct mlxsw_sp_ipip_entry *ipip_entry) 1078 { 1079 u32 tunnel_index; 1080 int err; 1081 1082 err = mlxsw_sp_kvdl_alloc(mlxsw_sp, 1, &tunnel_index); 1083 if (err) 1084 return err; 1085 1086 ipip_entry->decap_fib_entry = fib_entry; 1087 fib_entry->decap.ipip_entry = ipip_entry; 1088 fib_entry->decap.tunnel_index = tunnel_index; 1089 return 0; 1090 } 1091 1092 static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp, 1093 struct mlxsw_sp_fib_entry *fib_entry) 1094 { 1095 /* Unlink this node from the IPIP entry that it's the decap entry of. */ 1096 fib_entry->decap.ipip_entry->decap_fib_entry = NULL; 1097 fib_entry->decap.ipip_entry = NULL; 1098 mlxsw_sp_kvdl_free(mlxsw_sp, fib_entry->decap.tunnel_index); 1099 } 1100 1101 static struct mlxsw_sp_fib_node * 1102 mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr, 1103 size_t addr_len, unsigned char prefix_len); 1104 static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp, 1105 struct mlxsw_sp_fib_entry *fib_entry); 1106 1107 static void 1108 mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp, 1109 struct mlxsw_sp_ipip_entry *ipip_entry) 1110 { 1111 struct mlxsw_sp_fib_entry *fib_entry = ipip_entry->decap_fib_entry; 1112 1113 mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, fib_entry); 1114 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP; 1115 1116 mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry); 1117 } 1118 1119 static void 1120 mlxsw_sp_ipip_entry_promote_decap(struct mlxsw_sp *mlxsw_sp, 1121 struct mlxsw_sp_ipip_entry *ipip_entry, 1122 struct mlxsw_sp_fib_entry *decap_fib_entry) 1123 { 1124 if (mlxsw_sp_fib_entry_decap_init(mlxsw_sp, decap_fib_entry, 1125 ipip_entry)) 1126 return; 1127 decap_fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP; 1128 1129 if (mlxsw_sp_fib_entry_update(mlxsw_sp, decap_fib_entry)) 1130 mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry); 1131 } 1132 1133 /* Given an IPIP entry, find the corresponding decap route. */ 1134 static struct mlxsw_sp_fib_entry * 1135 mlxsw_sp_ipip_entry_find_decap(struct mlxsw_sp *mlxsw_sp, 1136 struct mlxsw_sp_ipip_entry *ipip_entry) 1137 { 1138 static struct mlxsw_sp_fib_node *fib_node; 1139 const struct mlxsw_sp_ipip_ops *ipip_ops; 1140 struct mlxsw_sp_fib_entry *fib_entry; 1141 unsigned char saddr_prefix_len; 1142 union mlxsw_sp_l3addr saddr; 1143 struct mlxsw_sp_fib *ul_fib; 1144 struct mlxsw_sp_vr *ul_vr; 1145 const void *saddrp; 1146 size_t saddr_len; 1147 u32 ul_tb_id; 1148 u32 saddr4; 1149 1150 ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt]; 1151 1152 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ipip_entry->ol_dev); 1153 ul_vr = mlxsw_sp_vr_find(mlxsw_sp, ul_tb_id); 1154 if (!ul_vr) 1155 return NULL; 1156 1157 ul_fib = mlxsw_sp_vr_fib(ul_vr, ipip_ops->ul_proto); 1158 saddr = mlxsw_sp_ipip_netdev_saddr(ipip_ops->ul_proto, 1159 ipip_entry->ol_dev); 1160 1161 switch (ipip_ops->ul_proto) { 1162 case MLXSW_SP_L3_PROTO_IPV4: 1163 saddr4 = be32_to_cpu(saddr.addr4); 1164 saddrp = &saddr4; 1165 saddr_len = 4; 1166 saddr_prefix_len = 32; 1167 break; 1168 case MLXSW_SP_L3_PROTO_IPV6: 1169 WARN_ON(1); 1170 return NULL; 1171 } 1172 1173 fib_node = mlxsw_sp_fib_node_lookup(ul_fib, saddrp, saddr_len, 1174 saddr_prefix_len); 1175 if (!fib_node || list_empty(&fib_node->entry_list)) 1176 return NULL; 1177 1178 fib_entry = list_first_entry(&fib_node->entry_list, 1179 struct mlxsw_sp_fib_entry, list); 1180 if (fib_entry->type != MLXSW_SP_FIB_ENTRY_TYPE_TRAP) 1181 return NULL; 1182 1183 return fib_entry; 1184 } 1185 1186 static struct mlxsw_sp_ipip_entry * 1187 mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp, 1188 enum mlxsw_sp_ipip_type ipipt, 1189 struct net_device *ol_dev) 1190 { 1191 u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(ol_dev); 1192 struct mlxsw_sp_router *router = mlxsw_sp->router; 1193 struct mlxsw_sp_fib_entry *decap_fib_entry; 1194 struct mlxsw_sp_ipip_entry *ipip_entry; 1195 enum mlxsw_sp_l3proto ul_proto; 1196 union mlxsw_sp_l3addr saddr; 1197 1198 list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list, 1199 ipip_list_node) { 1200 if (ipip_entry->ol_dev == ol_dev) 1201 goto inc_ref_count; 1202 1203 /* The configuration where several tunnels have the same local 1204 * address in the same underlay table needs special treatment in 1205 * the HW. That is currently not implemented in the driver. 1206 */ 1207 ul_proto = router->ipip_ops_arr[ipip_entry->ipipt]->ul_proto; 1208 saddr = mlxsw_sp_ipip_netdev_saddr(ul_proto, ol_dev); 1209 if (mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, saddr, 1210 ul_tb_id, ipip_entry)) 1211 return ERR_PTR(-EEXIST); 1212 } 1213 1214 ipip_entry = mlxsw_sp_ipip_entry_alloc(mlxsw_sp, ipipt, ol_dev); 1215 if (IS_ERR(ipip_entry)) 1216 return ipip_entry; 1217 1218 decap_fib_entry = mlxsw_sp_ipip_entry_find_decap(mlxsw_sp, ipip_entry); 1219 if (decap_fib_entry) 1220 mlxsw_sp_ipip_entry_promote_decap(mlxsw_sp, ipip_entry, 1221 decap_fib_entry); 1222 1223 list_add_tail(&ipip_entry->ipip_list_node, 1224 &mlxsw_sp->router->ipip_list); 1225 1226 inc_ref_count: 1227 ++ipip_entry->ref_count; 1228 return ipip_entry; 1229 } 1230 1231 static void 1232 mlxsw_sp_ipip_entry_put(struct mlxsw_sp *mlxsw_sp, 1233 struct mlxsw_sp_ipip_entry *ipip_entry) 1234 { 1235 if (--ipip_entry->ref_count == 0) { 1236 list_del(&ipip_entry->ipip_list_node); 1237 if (ipip_entry->decap_fib_entry) 1238 mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry); 1239 mlxsw_sp_ipip_entry_destroy(ipip_entry); 1240 } 1241 } 1242 1243 static bool 1244 mlxsw_sp_ipip_entry_matches_decap(struct mlxsw_sp *mlxsw_sp, 1245 const struct net_device *ul_dev, 1246 enum mlxsw_sp_l3proto ul_proto, 1247 union mlxsw_sp_l3addr ul_dip, 1248 struct mlxsw_sp_ipip_entry *ipip_entry) 1249 { 1250 u32 ul_tb_id = l3mdev_fib_table(ul_dev) ? : RT_TABLE_MAIN; 1251 enum mlxsw_sp_ipip_type ipipt = ipip_entry->ipipt; 1252 struct net_device *ipip_ul_dev; 1253 1254 if (mlxsw_sp->router->ipip_ops_arr[ipipt]->ul_proto != ul_proto) 1255 return false; 1256 1257 ipip_ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ipip_entry->ol_dev); 1258 return mlxsw_sp_ipip_entry_saddr_matches(mlxsw_sp, ul_proto, ul_dip, 1259 ul_tb_id, ipip_entry) && 1260 (!ipip_ul_dev || ipip_ul_dev == ul_dev); 1261 } 1262 1263 /* Given decap parameters, find the corresponding IPIP entry. */ 1264 static struct mlxsw_sp_ipip_entry * 1265 mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp, 1266 const struct net_device *ul_dev, 1267 enum mlxsw_sp_l3proto ul_proto, 1268 union mlxsw_sp_l3addr ul_dip) 1269 { 1270 struct mlxsw_sp_ipip_entry *ipip_entry; 1271 1272 list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list, 1273 ipip_list_node) 1274 if (mlxsw_sp_ipip_entry_matches_decap(mlxsw_sp, ul_dev, 1275 ul_proto, ul_dip, 1276 ipip_entry)) 1277 return ipip_entry; 1278 1279 return NULL; 1280 } 1281 1282 struct mlxsw_sp_neigh_key { 1283 struct neighbour *n; 1284 }; 1285 1286 struct mlxsw_sp_neigh_entry { 1287 struct list_head rif_list_node; 1288 struct rhash_head ht_node; 1289 struct mlxsw_sp_neigh_key key; 1290 u16 rif; 1291 bool connected; 1292 unsigned char ha[ETH_ALEN]; 1293 struct list_head nexthop_list; /* list of nexthops using 1294 * this neigh entry 1295 */ 1296 struct list_head nexthop_neighs_list_node; 1297 unsigned int counter_index; 1298 bool counter_valid; 1299 }; 1300 1301 static const struct rhashtable_params mlxsw_sp_neigh_ht_params = { 1302 .key_offset = offsetof(struct mlxsw_sp_neigh_entry, key), 1303 .head_offset = offsetof(struct mlxsw_sp_neigh_entry, ht_node), 1304 .key_len = sizeof(struct mlxsw_sp_neigh_key), 1305 }; 1306 1307 struct mlxsw_sp_neigh_entry * 1308 mlxsw_sp_rif_neigh_next(struct mlxsw_sp_rif *rif, 1309 struct mlxsw_sp_neigh_entry *neigh_entry) 1310 { 1311 if (!neigh_entry) { 1312 if (list_empty(&rif->neigh_list)) 1313 return NULL; 1314 else 1315 return list_first_entry(&rif->neigh_list, 1316 typeof(*neigh_entry), 1317 rif_list_node); 1318 } 1319 if (neigh_entry->rif_list_node.next == &rif->neigh_list) 1320 return NULL; 1321 return list_next_entry(neigh_entry, rif_list_node); 1322 } 1323 1324 int mlxsw_sp_neigh_entry_type(struct mlxsw_sp_neigh_entry *neigh_entry) 1325 { 1326 return neigh_entry->key.n->tbl->family; 1327 } 1328 1329 unsigned char * 1330 mlxsw_sp_neigh_entry_ha(struct mlxsw_sp_neigh_entry *neigh_entry) 1331 { 1332 return neigh_entry->ha; 1333 } 1334 1335 u32 mlxsw_sp_neigh4_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry) 1336 { 1337 struct neighbour *n; 1338 1339 n = neigh_entry->key.n; 1340 return ntohl(*((__be32 *) n->primary_key)); 1341 } 1342 1343 struct in6_addr * 1344 mlxsw_sp_neigh6_entry_dip(struct mlxsw_sp_neigh_entry *neigh_entry) 1345 { 1346 struct neighbour *n; 1347 1348 n = neigh_entry->key.n; 1349 return (struct in6_addr *) &n->primary_key; 1350 } 1351 1352 int mlxsw_sp_neigh_counter_get(struct mlxsw_sp *mlxsw_sp, 1353 struct mlxsw_sp_neigh_entry *neigh_entry, 1354 u64 *p_counter) 1355 { 1356 if (!neigh_entry->counter_valid) 1357 return -EINVAL; 1358 1359 return mlxsw_sp_flow_counter_get(mlxsw_sp, neigh_entry->counter_index, 1360 p_counter, NULL); 1361 } 1362 1363 static struct mlxsw_sp_neigh_entry * 1364 mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n, 1365 u16 rif) 1366 { 1367 struct mlxsw_sp_neigh_entry *neigh_entry; 1368 1369 neigh_entry = kzalloc(sizeof(*neigh_entry), GFP_KERNEL); 1370 if (!neigh_entry) 1371 return NULL; 1372 1373 neigh_entry->key.n = n; 1374 neigh_entry->rif = rif; 1375 INIT_LIST_HEAD(&neigh_entry->nexthop_list); 1376 1377 return neigh_entry; 1378 } 1379 1380 static void mlxsw_sp_neigh_entry_free(struct mlxsw_sp_neigh_entry *neigh_entry) 1381 { 1382 kfree(neigh_entry); 1383 } 1384 1385 static int 1386 mlxsw_sp_neigh_entry_insert(struct mlxsw_sp *mlxsw_sp, 1387 struct mlxsw_sp_neigh_entry *neigh_entry) 1388 { 1389 return rhashtable_insert_fast(&mlxsw_sp->router->neigh_ht, 1390 &neigh_entry->ht_node, 1391 mlxsw_sp_neigh_ht_params); 1392 } 1393 1394 static void 1395 mlxsw_sp_neigh_entry_remove(struct mlxsw_sp *mlxsw_sp, 1396 struct mlxsw_sp_neigh_entry *neigh_entry) 1397 { 1398 rhashtable_remove_fast(&mlxsw_sp->router->neigh_ht, 1399 &neigh_entry->ht_node, 1400 mlxsw_sp_neigh_ht_params); 1401 } 1402 1403 static bool 1404 mlxsw_sp_neigh_counter_should_alloc(struct mlxsw_sp *mlxsw_sp, 1405 struct mlxsw_sp_neigh_entry *neigh_entry) 1406 { 1407 struct devlink *devlink; 1408 const char *table_name; 1409 1410 switch (mlxsw_sp_neigh_entry_type(neigh_entry)) { 1411 case AF_INET: 1412 table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST4; 1413 break; 1414 case AF_INET6: 1415 table_name = MLXSW_SP_DPIPE_TABLE_NAME_HOST6; 1416 break; 1417 default: 1418 WARN_ON(1); 1419 return false; 1420 } 1421 1422 devlink = priv_to_devlink(mlxsw_sp->core); 1423 return devlink_dpipe_table_counter_enabled(devlink, table_name); 1424 } 1425 1426 static void 1427 mlxsw_sp_neigh_counter_alloc(struct mlxsw_sp *mlxsw_sp, 1428 struct mlxsw_sp_neigh_entry *neigh_entry) 1429 { 1430 if (!mlxsw_sp_neigh_counter_should_alloc(mlxsw_sp, neigh_entry)) 1431 return; 1432 1433 if (mlxsw_sp_flow_counter_alloc(mlxsw_sp, &neigh_entry->counter_index)) 1434 return; 1435 1436 neigh_entry->counter_valid = true; 1437 } 1438 1439 static void 1440 mlxsw_sp_neigh_counter_free(struct mlxsw_sp *mlxsw_sp, 1441 struct mlxsw_sp_neigh_entry *neigh_entry) 1442 { 1443 if (!neigh_entry->counter_valid) 1444 return; 1445 mlxsw_sp_flow_counter_free(mlxsw_sp, 1446 neigh_entry->counter_index); 1447 neigh_entry->counter_valid = false; 1448 } 1449 1450 static struct mlxsw_sp_neigh_entry * 1451 mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n) 1452 { 1453 struct mlxsw_sp_neigh_entry *neigh_entry; 1454 struct mlxsw_sp_rif *rif; 1455 int err; 1456 1457 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, n->dev); 1458 if (!rif) 1459 return ERR_PTR(-EINVAL); 1460 1461 neigh_entry = mlxsw_sp_neigh_entry_alloc(mlxsw_sp, n, rif->rif_index); 1462 if (!neigh_entry) 1463 return ERR_PTR(-ENOMEM); 1464 1465 err = mlxsw_sp_neigh_entry_insert(mlxsw_sp, neigh_entry); 1466 if (err) 1467 goto err_neigh_entry_insert; 1468 1469 mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry); 1470 list_add(&neigh_entry->rif_list_node, &rif->neigh_list); 1471 1472 return neigh_entry; 1473 1474 err_neigh_entry_insert: 1475 mlxsw_sp_neigh_entry_free(neigh_entry); 1476 return ERR_PTR(err); 1477 } 1478 1479 static void 1480 mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp, 1481 struct mlxsw_sp_neigh_entry *neigh_entry) 1482 { 1483 list_del(&neigh_entry->rif_list_node); 1484 mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry); 1485 mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry); 1486 mlxsw_sp_neigh_entry_free(neigh_entry); 1487 } 1488 1489 static struct mlxsw_sp_neigh_entry * 1490 mlxsw_sp_neigh_entry_lookup(struct mlxsw_sp *mlxsw_sp, struct neighbour *n) 1491 { 1492 struct mlxsw_sp_neigh_key key; 1493 1494 key.n = n; 1495 return rhashtable_lookup_fast(&mlxsw_sp->router->neigh_ht, 1496 &key, mlxsw_sp_neigh_ht_params); 1497 } 1498 1499 static void 1500 mlxsw_sp_router_neighs_update_interval_init(struct mlxsw_sp *mlxsw_sp) 1501 { 1502 unsigned long interval; 1503 1504 #if IS_ENABLED(CONFIG_IPV6) 1505 interval = min_t(unsigned long, 1506 NEIGH_VAR(&arp_tbl.parms, DELAY_PROBE_TIME), 1507 NEIGH_VAR(&nd_tbl.parms, DELAY_PROBE_TIME)); 1508 #else 1509 interval = NEIGH_VAR(&arp_tbl.parms, DELAY_PROBE_TIME); 1510 #endif 1511 mlxsw_sp->router->neighs_update.interval = jiffies_to_msecs(interval); 1512 } 1513 1514 static void mlxsw_sp_router_neigh_ent_ipv4_process(struct mlxsw_sp *mlxsw_sp, 1515 char *rauhtd_pl, 1516 int ent_index) 1517 { 1518 struct net_device *dev; 1519 struct neighbour *n; 1520 __be32 dipn; 1521 u32 dip; 1522 u16 rif; 1523 1524 mlxsw_reg_rauhtd_ent_ipv4_unpack(rauhtd_pl, ent_index, &rif, &dip); 1525 1526 if (!mlxsw_sp->router->rifs[rif]) { 1527 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect RIF in neighbour entry\n"); 1528 return; 1529 } 1530 1531 dipn = htonl(dip); 1532 dev = mlxsw_sp->router->rifs[rif]->dev; 1533 n = neigh_lookup(&arp_tbl, &dipn, dev); 1534 if (!n) { 1535 netdev_err(dev, "Failed to find matching neighbour for IP=%pI4h\n", 1536 &dip); 1537 return; 1538 } 1539 1540 netdev_dbg(dev, "Updating neighbour with IP=%pI4h\n", &dip); 1541 neigh_event_send(n, NULL); 1542 neigh_release(n); 1543 } 1544 1545 #if IS_ENABLED(CONFIG_IPV6) 1546 static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp, 1547 char *rauhtd_pl, 1548 int rec_index) 1549 { 1550 struct net_device *dev; 1551 struct neighbour *n; 1552 struct in6_addr dip; 1553 u16 rif; 1554 1555 mlxsw_reg_rauhtd_ent_ipv6_unpack(rauhtd_pl, rec_index, &rif, 1556 (char *) &dip); 1557 1558 if (!mlxsw_sp->router->rifs[rif]) { 1559 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect RIF in neighbour entry\n"); 1560 return; 1561 } 1562 1563 dev = mlxsw_sp->router->rifs[rif]->dev; 1564 n = neigh_lookup(&nd_tbl, &dip, dev); 1565 if (!n) { 1566 netdev_err(dev, "Failed to find matching neighbour for IP=%pI6c\n", 1567 &dip); 1568 return; 1569 } 1570 1571 netdev_dbg(dev, "Updating neighbour with IP=%pI6c\n", &dip); 1572 neigh_event_send(n, NULL); 1573 neigh_release(n); 1574 } 1575 #else 1576 static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp, 1577 char *rauhtd_pl, 1578 int rec_index) 1579 { 1580 } 1581 #endif 1582 1583 static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp, 1584 char *rauhtd_pl, 1585 int rec_index) 1586 { 1587 u8 num_entries; 1588 int i; 1589 1590 num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl, 1591 rec_index); 1592 /* Hardware starts counting at 0, so add 1. */ 1593 num_entries++; 1594 1595 /* Each record consists of several neighbour entries. */ 1596 for (i = 0; i < num_entries; i++) { 1597 int ent_index; 1598 1599 ent_index = rec_index * MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC + i; 1600 mlxsw_sp_router_neigh_ent_ipv4_process(mlxsw_sp, rauhtd_pl, 1601 ent_index); 1602 } 1603 1604 } 1605 1606 static void mlxsw_sp_router_neigh_rec_ipv6_process(struct mlxsw_sp *mlxsw_sp, 1607 char *rauhtd_pl, 1608 int rec_index) 1609 { 1610 /* One record contains one entry. */ 1611 mlxsw_sp_router_neigh_ent_ipv6_process(mlxsw_sp, rauhtd_pl, 1612 rec_index); 1613 } 1614 1615 static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp, 1616 char *rauhtd_pl, int rec_index) 1617 { 1618 switch (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, rec_index)) { 1619 case MLXSW_REG_RAUHTD_TYPE_IPV4: 1620 mlxsw_sp_router_neigh_rec_ipv4_process(mlxsw_sp, rauhtd_pl, 1621 rec_index); 1622 break; 1623 case MLXSW_REG_RAUHTD_TYPE_IPV6: 1624 mlxsw_sp_router_neigh_rec_ipv6_process(mlxsw_sp, rauhtd_pl, 1625 rec_index); 1626 break; 1627 } 1628 } 1629 1630 static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl) 1631 { 1632 u8 num_rec, last_rec_index, num_entries; 1633 1634 num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl); 1635 last_rec_index = num_rec - 1; 1636 1637 if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM) 1638 return false; 1639 if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) == 1640 MLXSW_REG_RAUHTD_TYPE_IPV6) 1641 return true; 1642 1643 num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl, 1644 last_rec_index); 1645 if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC) 1646 return true; 1647 return false; 1648 } 1649 1650 static int 1651 __mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp, 1652 char *rauhtd_pl, 1653 enum mlxsw_reg_rauhtd_type type) 1654 { 1655 int i, num_rec; 1656 int err; 1657 1658 /* Make sure the neighbour's netdev isn't removed in the 1659 * process. 1660 */ 1661 rtnl_lock(); 1662 do { 1663 mlxsw_reg_rauhtd_pack(rauhtd_pl, type); 1664 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(rauhtd), 1665 rauhtd_pl); 1666 if (err) { 1667 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to dump neighbour talbe\n"); 1668 break; 1669 } 1670 num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl); 1671 for (i = 0; i < num_rec; i++) 1672 mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl, 1673 i); 1674 } while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl)); 1675 rtnl_unlock(); 1676 1677 return err; 1678 } 1679 1680 static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp) 1681 { 1682 enum mlxsw_reg_rauhtd_type type; 1683 char *rauhtd_pl; 1684 int err; 1685 1686 rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL); 1687 if (!rauhtd_pl) 1688 return -ENOMEM; 1689 1690 type = MLXSW_REG_RAUHTD_TYPE_IPV4; 1691 err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type); 1692 if (err) 1693 goto out; 1694 1695 type = MLXSW_REG_RAUHTD_TYPE_IPV6; 1696 err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type); 1697 out: 1698 kfree(rauhtd_pl); 1699 return err; 1700 } 1701 1702 static void mlxsw_sp_router_neighs_update_nh(struct mlxsw_sp *mlxsw_sp) 1703 { 1704 struct mlxsw_sp_neigh_entry *neigh_entry; 1705 1706 /* Take RTNL mutex here to prevent lists from changes */ 1707 rtnl_lock(); 1708 list_for_each_entry(neigh_entry, &mlxsw_sp->router->nexthop_neighs_list, 1709 nexthop_neighs_list_node) 1710 /* If this neigh have nexthops, make the kernel think this neigh 1711 * is active regardless of the traffic. 1712 */ 1713 neigh_event_send(neigh_entry->key.n, NULL); 1714 rtnl_unlock(); 1715 } 1716 1717 static void 1718 mlxsw_sp_router_neighs_update_work_schedule(struct mlxsw_sp *mlxsw_sp) 1719 { 1720 unsigned long interval = mlxsw_sp->router->neighs_update.interval; 1721 1722 mlxsw_core_schedule_dw(&mlxsw_sp->router->neighs_update.dw, 1723 msecs_to_jiffies(interval)); 1724 } 1725 1726 static void mlxsw_sp_router_neighs_update_work(struct work_struct *work) 1727 { 1728 struct mlxsw_sp_router *router; 1729 int err; 1730 1731 router = container_of(work, struct mlxsw_sp_router, 1732 neighs_update.dw.work); 1733 err = mlxsw_sp_router_neighs_update_rauhtd(router->mlxsw_sp); 1734 if (err) 1735 dev_err(router->mlxsw_sp->bus_info->dev, "Could not update kernel for neigh activity"); 1736 1737 mlxsw_sp_router_neighs_update_nh(router->mlxsw_sp); 1738 1739 mlxsw_sp_router_neighs_update_work_schedule(router->mlxsw_sp); 1740 } 1741 1742 static void mlxsw_sp_router_probe_unresolved_nexthops(struct work_struct *work) 1743 { 1744 struct mlxsw_sp_neigh_entry *neigh_entry; 1745 struct mlxsw_sp_router *router; 1746 1747 router = container_of(work, struct mlxsw_sp_router, 1748 nexthop_probe_dw.work); 1749 /* Iterate over nexthop neighbours, find those who are unresolved and 1750 * send arp on them. This solves the chicken-egg problem when 1751 * the nexthop wouldn't get offloaded until the neighbor is resolved 1752 * but it wouldn't get resolved ever in case traffic is flowing in HW 1753 * using different nexthop. 1754 * 1755 * Take RTNL mutex here to prevent lists from changes. 1756 */ 1757 rtnl_lock(); 1758 list_for_each_entry(neigh_entry, &router->nexthop_neighs_list, 1759 nexthop_neighs_list_node) 1760 if (!neigh_entry->connected) 1761 neigh_event_send(neigh_entry->key.n, NULL); 1762 rtnl_unlock(); 1763 1764 mlxsw_core_schedule_dw(&router->nexthop_probe_dw, 1765 MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL); 1766 } 1767 1768 static void 1769 mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, 1770 struct mlxsw_sp_neigh_entry *neigh_entry, 1771 bool removing); 1772 1773 static enum mlxsw_reg_rauht_op mlxsw_sp_rauht_op(bool adding) 1774 { 1775 return adding ? MLXSW_REG_RAUHT_OP_WRITE_ADD : 1776 MLXSW_REG_RAUHT_OP_WRITE_DELETE; 1777 } 1778 1779 static void 1780 mlxsw_sp_router_neigh_entry_op4(struct mlxsw_sp *mlxsw_sp, 1781 struct mlxsw_sp_neigh_entry *neigh_entry, 1782 enum mlxsw_reg_rauht_op op) 1783 { 1784 struct neighbour *n = neigh_entry->key.n; 1785 u32 dip = ntohl(*((__be32 *) n->primary_key)); 1786 char rauht_pl[MLXSW_REG_RAUHT_LEN]; 1787 1788 mlxsw_reg_rauht_pack4(rauht_pl, op, neigh_entry->rif, neigh_entry->ha, 1789 dip); 1790 if (neigh_entry->counter_valid) 1791 mlxsw_reg_rauht_pack_counter(rauht_pl, 1792 neigh_entry->counter_index); 1793 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); 1794 } 1795 1796 static void 1797 mlxsw_sp_router_neigh_entry_op6(struct mlxsw_sp *mlxsw_sp, 1798 struct mlxsw_sp_neigh_entry *neigh_entry, 1799 enum mlxsw_reg_rauht_op op) 1800 { 1801 struct neighbour *n = neigh_entry->key.n; 1802 char rauht_pl[MLXSW_REG_RAUHT_LEN]; 1803 const char *dip = n->primary_key; 1804 1805 mlxsw_reg_rauht_pack6(rauht_pl, op, neigh_entry->rif, neigh_entry->ha, 1806 dip); 1807 if (neigh_entry->counter_valid) 1808 mlxsw_reg_rauht_pack_counter(rauht_pl, 1809 neigh_entry->counter_index); 1810 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rauht), rauht_pl); 1811 } 1812 1813 bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry) 1814 { 1815 struct neighbour *n = neigh_entry->key.n; 1816 1817 /* Packets with a link-local destination address are trapped 1818 * after LPM lookup and never reach the neighbour table, so 1819 * there is no need to program such neighbours to the device. 1820 */ 1821 if (ipv6_addr_type((struct in6_addr *) &n->primary_key) & 1822 IPV6_ADDR_LINKLOCAL) 1823 return true; 1824 return false; 1825 } 1826 1827 static void 1828 mlxsw_sp_neigh_entry_update(struct mlxsw_sp *mlxsw_sp, 1829 struct mlxsw_sp_neigh_entry *neigh_entry, 1830 bool adding) 1831 { 1832 if (!adding && !neigh_entry->connected) 1833 return; 1834 neigh_entry->connected = adding; 1835 if (neigh_entry->key.n->tbl->family == AF_INET) { 1836 mlxsw_sp_router_neigh_entry_op4(mlxsw_sp, neigh_entry, 1837 mlxsw_sp_rauht_op(adding)); 1838 } else if (neigh_entry->key.n->tbl->family == AF_INET6) { 1839 if (mlxsw_sp_neigh_ipv6_ignore(neigh_entry)) 1840 return; 1841 mlxsw_sp_router_neigh_entry_op6(mlxsw_sp, neigh_entry, 1842 mlxsw_sp_rauht_op(adding)); 1843 } else { 1844 WARN_ON_ONCE(1); 1845 } 1846 } 1847 1848 void 1849 mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp, 1850 struct mlxsw_sp_neigh_entry *neigh_entry, 1851 bool adding) 1852 { 1853 if (adding) 1854 mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry); 1855 else 1856 mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry); 1857 mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, true); 1858 } 1859 1860 struct mlxsw_sp_neigh_event_work { 1861 struct work_struct work; 1862 struct mlxsw_sp *mlxsw_sp; 1863 struct neighbour *n; 1864 }; 1865 1866 static void mlxsw_sp_router_neigh_event_work(struct work_struct *work) 1867 { 1868 struct mlxsw_sp_neigh_event_work *neigh_work = 1869 container_of(work, struct mlxsw_sp_neigh_event_work, work); 1870 struct mlxsw_sp *mlxsw_sp = neigh_work->mlxsw_sp; 1871 struct mlxsw_sp_neigh_entry *neigh_entry; 1872 struct neighbour *n = neigh_work->n; 1873 unsigned char ha[ETH_ALEN]; 1874 bool entry_connected; 1875 u8 nud_state, dead; 1876 1877 /* If these parameters are changed after we release the lock, 1878 * then we are guaranteed to receive another event letting us 1879 * know about it. 1880 */ 1881 read_lock_bh(&n->lock); 1882 memcpy(ha, n->ha, ETH_ALEN); 1883 nud_state = n->nud_state; 1884 dead = n->dead; 1885 read_unlock_bh(&n->lock); 1886 1887 rtnl_lock(); 1888 entry_connected = nud_state & NUD_VALID && !dead; 1889 neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); 1890 if (!entry_connected && !neigh_entry) 1891 goto out; 1892 if (!neigh_entry) { 1893 neigh_entry = mlxsw_sp_neigh_entry_create(mlxsw_sp, n); 1894 if (IS_ERR(neigh_entry)) 1895 goto out; 1896 } 1897 1898 memcpy(neigh_entry->ha, ha, ETH_ALEN); 1899 mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, entry_connected); 1900 mlxsw_sp_nexthop_neigh_update(mlxsw_sp, neigh_entry, !entry_connected); 1901 1902 if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list)) 1903 mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); 1904 1905 out: 1906 rtnl_unlock(); 1907 neigh_release(n); 1908 kfree(neigh_work); 1909 } 1910 1911 int mlxsw_sp_router_netevent_event(struct notifier_block *unused, 1912 unsigned long event, void *ptr) 1913 { 1914 struct mlxsw_sp_neigh_event_work *neigh_work; 1915 struct mlxsw_sp_port *mlxsw_sp_port; 1916 struct mlxsw_sp *mlxsw_sp; 1917 unsigned long interval; 1918 struct neigh_parms *p; 1919 struct neighbour *n; 1920 1921 switch (event) { 1922 case NETEVENT_DELAY_PROBE_TIME_UPDATE: 1923 p = ptr; 1924 1925 /* We don't care about changes in the default table. */ 1926 if (!p->dev || (p->tbl->family != AF_INET && 1927 p->tbl->family != AF_INET6)) 1928 return NOTIFY_DONE; 1929 1930 /* We are in atomic context and can't take RTNL mutex, 1931 * so use RCU variant to walk the device chain. 1932 */ 1933 mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(p->dev); 1934 if (!mlxsw_sp_port) 1935 return NOTIFY_DONE; 1936 1937 mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 1938 interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME)); 1939 mlxsw_sp->router->neighs_update.interval = interval; 1940 1941 mlxsw_sp_port_dev_put(mlxsw_sp_port); 1942 break; 1943 case NETEVENT_NEIGH_UPDATE: 1944 n = ptr; 1945 1946 if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6) 1947 return NOTIFY_DONE; 1948 1949 mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(n->dev); 1950 if (!mlxsw_sp_port) 1951 return NOTIFY_DONE; 1952 1953 neigh_work = kzalloc(sizeof(*neigh_work), GFP_ATOMIC); 1954 if (!neigh_work) { 1955 mlxsw_sp_port_dev_put(mlxsw_sp_port); 1956 return NOTIFY_BAD; 1957 } 1958 1959 INIT_WORK(&neigh_work->work, mlxsw_sp_router_neigh_event_work); 1960 neigh_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 1961 neigh_work->n = n; 1962 1963 /* Take a reference to ensure the neighbour won't be 1964 * destructed until we drop the reference in delayed 1965 * work. 1966 */ 1967 neigh_clone(n); 1968 mlxsw_core_schedule_work(&neigh_work->work); 1969 mlxsw_sp_port_dev_put(mlxsw_sp_port); 1970 break; 1971 } 1972 1973 return NOTIFY_DONE; 1974 } 1975 1976 static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) 1977 { 1978 int err; 1979 1980 err = rhashtable_init(&mlxsw_sp->router->neigh_ht, 1981 &mlxsw_sp_neigh_ht_params); 1982 if (err) 1983 return err; 1984 1985 /* Initialize the polling interval according to the default 1986 * table. 1987 */ 1988 mlxsw_sp_router_neighs_update_interval_init(mlxsw_sp); 1989 1990 /* Create the delayed works for the activity_update */ 1991 INIT_DELAYED_WORK(&mlxsw_sp->router->neighs_update.dw, 1992 mlxsw_sp_router_neighs_update_work); 1993 INIT_DELAYED_WORK(&mlxsw_sp->router->nexthop_probe_dw, 1994 mlxsw_sp_router_probe_unresolved_nexthops); 1995 mlxsw_core_schedule_dw(&mlxsw_sp->router->neighs_update.dw, 0); 1996 mlxsw_core_schedule_dw(&mlxsw_sp->router->nexthop_probe_dw, 0); 1997 return 0; 1998 } 1999 2000 static void mlxsw_sp_neigh_fini(struct mlxsw_sp *mlxsw_sp) 2001 { 2002 cancel_delayed_work_sync(&mlxsw_sp->router->neighs_update.dw); 2003 cancel_delayed_work_sync(&mlxsw_sp->router->nexthop_probe_dw); 2004 rhashtable_destroy(&mlxsw_sp->router->neigh_ht); 2005 } 2006 2007 static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, 2008 struct mlxsw_sp_rif *rif) 2009 { 2010 struct mlxsw_sp_neigh_entry *neigh_entry, *tmp; 2011 2012 list_for_each_entry_safe(neigh_entry, tmp, &rif->neigh_list, 2013 rif_list_node) { 2014 mlxsw_sp_neigh_entry_update(mlxsw_sp, neigh_entry, false); 2015 mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); 2016 } 2017 } 2018 2019 enum mlxsw_sp_nexthop_type { 2020 MLXSW_SP_NEXTHOP_TYPE_ETH, 2021 MLXSW_SP_NEXTHOP_TYPE_IPIP, 2022 }; 2023 2024 struct mlxsw_sp_nexthop_key { 2025 struct fib_nh *fib_nh; 2026 }; 2027 2028 struct mlxsw_sp_nexthop { 2029 struct list_head neigh_list_node; /* member of neigh entry list */ 2030 struct list_head rif_list_node; 2031 struct mlxsw_sp_nexthop_group *nh_grp; /* pointer back to the group 2032 * this belongs to 2033 */ 2034 struct rhash_head ht_node; 2035 struct mlxsw_sp_nexthop_key key; 2036 unsigned char gw_addr[sizeof(struct in6_addr)]; 2037 int ifindex; 2038 struct mlxsw_sp_rif *rif; 2039 u8 should_offload:1, /* set indicates this neigh is connected and 2040 * should be put to KVD linear area of this group. 2041 */ 2042 offloaded:1, /* set in case the neigh is actually put into 2043 * KVD linear area of this group. 2044 */ 2045 update:1; /* set indicates that MAC of this neigh should be 2046 * updated in HW 2047 */ 2048 enum mlxsw_sp_nexthop_type type; 2049 union { 2050 struct mlxsw_sp_neigh_entry *neigh_entry; 2051 struct mlxsw_sp_ipip_entry *ipip_entry; 2052 }; 2053 }; 2054 2055 struct mlxsw_sp_nexthop_group { 2056 void *priv; 2057 struct rhash_head ht_node; 2058 struct list_head fib_list; /* list of fib entries that use this group */ 2059 struct neigh_table *neigh_tbl; 2060 u8 adj_index_valid:1, 2061 gateway:1; /* routes using the group use a gateway */ 2062 u32 adj_index; 2063 u16 ecmp_size; 2064 u16 count; 2065 struct mlxsw_sp_nexthop nexthops[0]; 2066 #define nh_rif nexthops[0].rif 2067 }; 2068 2069 static struct fib_info * 2070 mlxsw_sp_nexthop4_group_fi(const struct mlxsw_sp_nexthop_group *nh_grp) 2071 { 2072 return nh_grp->priv; 2073 } 2074 2075 struct mlxsw_sp_nexthop_group_cmp_arg { 2076 enum mlxsw_sp_l3proto proto; 2077 union { 2078 struct fib_info *fi; 2079 struct mlxsw_sp_fib6_entry *fib6_entry; 2080 }; 2081 }; 2082 2083 static bool 2084 mlxsw_sp_nexthop6_group_has_nexthop(const struct mlxsw_sp_nexthop_group *nh_grp, 2085 const struct in6_addr *gw, int ifindex) 2086 { 2087 int i; 2088 2089 for (i = 0; i < nh_grp->count; i++) { 2090 const struct mlxsw_sp_nexthop *nh; 2091 2092 nh = &nh_grp->nexthops[i]; 2093 if (nh->ifindex == ifindex && 2094 ipv6_addr_equal(gw, (struct in6_addr *) nh->gw_addr)) 2095 return true; 2096 } 2097 2098 return false; 2099 } 2100 2101 static bool 2102 mlxsw_sp_nexthop6_group_cmp(const struct mlxsw_sp_nexthop_group *nh_grp, 2103 const struct mlxsw_sp_fib6_entry *fib6_entry) 2104 { 2105 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 2106 2107 if (nh_grp->count != fib6_entry->nrt6) 2108 return false; 2109 2110 list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { 2111 struct in6_addr *gw; 2112 int ifindex; 2113 2114 ifindex = mlxsw_sp_rt6->rt->dst.dev->ifindex; 2115 gw = &mlxsw_sp_rt6->rt->rt6i_gateway; 2116 if (!mlxsw_sp_nexthop6_group_has_nexthop(nh_grp, gw, ifindex)) 2117 return false; 2118 } 2119 2120 return true; 2121 } 2122 2123 static int 2124 mlxsw_sp_nexthop_group_cmp(struct rhashtable_compare_arg *arg, const void *ptr) 2125 { 2126 const struct mlxsw_sp_nexthop_group_cmp_arg *cmp_arg = arg->key; 2127 const struct mlxsw_sp_nexthop_group *nh_grp = ptr; 2128 2129 switch (cmp_arg->proto) { 2130 case MLXSW_SP_L3_PROTO_IPV4: 2131 return cmp_arg->fi != mlxsw_sp_nexthop4_group_fi(nh_grp); 2132 case MLXSW_SP_L3_PROTO_IPV6: 2133 return !mlxsw_sp_nexthop6_group_cmp(nh_grp, 2134 cmp_arg->fib6_entry); 2135 default: 2136 WARN_ON(1); 2137 return 1; 2138 } 2139 } 2140 2141 static int 2142 mlxsw_sp_nexthop_group_type(const struct mlxsw_sp_nexthop_group *nh_grp) 2143 { 2144 return nh_grp->neigh_tbl->family; 2145 } 2146 2147 static u32 mlxsw_sp_nexthop_group_hash_obj(const void *data, u32 len, u32 seed) 2148 { 2149 const struct mlxsw_sp_nexthop_group *nh_grp = data; 2150 const struct mlxsw_sp_nexthop *nh; 2151 struct fib_info *fi; 2152 unsigned int val; 2153 int i; 2154 2155 switch (mlxsw_sp_nexthop_group_type(nh_grp)) { 2156 case AF_INET: 2157 fi = mlxsw_sp_nexthop4_group_fi(nh_grp); 2158 return jhash(&fi, sizeof(fi), seed); 2159 case AF_INET6: 2160 val = nh_grp->count; 2161 for (i = 0; i < nh_grp->count; i++) { 2162 nh = &nh_grp->nexthops[i]; 2163 val ^= nh->ifindex; 2164 } 2165 return jhash(&val, sizeof(val), seed); 2166 default: 2167 WARN_ON(1); 2168 return 0; 2169 } 2170 } 2171 2172 static u32 2173 mlxsw_sp_nexthop6_group_hash(struct mlxsw_sp_fib6_entry *fib6_entry, u32 seed) 2174 { 2175 unsigned int val = fib6_entry->nrt6; 2176 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 2177 struct net_device *dev; 2178 2179 list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { 2180 dev = mlxsw_sp_rt6->rt->dst.dev; 2181 val ^= dev->ifindex; 2182 } 2183 2184 return jhash(&val, sizeof(val), seed); 2185 } 2186 2187 static u32 2188 mlxsw_sp_nexthop_group_hash(const void *data, u32 len, u32 seed) 2189 { 2190 const struct mlxsw_sp_nexthop_group_cmp_arg *cmp_arg = data; 2191 2192 switch (cmp_arg->proto) { 2193 case MLXSW_SP_L3_PROTO_IPV4: 2194 return jhash(&cmp_arg->fi, sizeof(cmp_arg->fi), seed); 2195 case MLXSW_SP_L3_PROTO_IPV6: 2196 return mlxsw_sp_nexthop6_group_hash(cmp_arg->fib6_entry, seed); 2197 default: 2198 WARN_ON(1); 2199 return 0; 2200 } 2201 } 2202 2203 static const struct rhashtable_params mlxsw_sp_nexthop_group_ht_params = { 2204 .head_offset = offsetof(struct mlxsw_sp_nexthop_group, ht_node), 2205 .hashfn = mlxsw_sp_nexthop_group_hash, 2206 .obj_hashfn = mlxsw_sp_nexthop_group_hash_obj, 2207 .obj_cmpfn = mlxsw_sp_nexthop_group_cmp, 2208 }; 2209 2210 static int mlxsw_sp_nexthop_group_insert(struct mlxsw_sp *mlxsw_sp, 2211 struct mlxsw_sp_nexthop_group *nh_grp) 2212 { 2213 if (mlxsw_sp_nexthop_group_type(nh_grp) == AF_INET6 && 2214 !nh_grp->gateway) 2215 return 0; 2216 2217 return rhashtable_insert_fast(&mlxsw_sp->router->nexthop_group_ht, 2218 &nh_grp->ht_node, 2219 mlxsw_sp_nexthop_group_ht_params); 2220 } 2221 2222 static void mlxsw_sp_nexthop_group_remove(struct mlxsw_sp *mlxsw_sp, 2223 struct mlxsw_sp_nexthop_group *nh_grp) 2224 { 2225 if (mlxsw_sp_nexthop_group_type(nh_grp) == AF_INET6 && 2226 !nh_grp->gateway) 2227 return; 2228 2229 rhashtable_remove_fast(&mlxsw_sp->router->nexthop_group_ht, 2230 &nh_grp->ht_node, 2231 mlxsw_sp_nexthop_group_ht_params); 2232 } 2233 2234 static struct mlxsw_sp_nexthop_group * 2235 mlxsw_sp_nexthop4_group_lookup(struct mlxsw_sp *mlxsw_sp, 2236 struct fib_info *fi) 2237 { 2238 struct mlxsw_sp_nexthop_group_cmp_arg cmp_arg; 2239 2240 cmp_arg.proto = MLXSW_SP_L3_PROTO_IPV4; 2241 cmp_arg.fi = fi; 2242 return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_group_ht, 2243 &cmp_arg, 2244 mlxsw_sp_nexthop_group_ht_params); 2245 } 2246 2247 static struct mlxsw_sp_nexthop_group * 2248 mlxsw_sp_nexthop6_group_lookup(struct mlxsw_sp *mlxsw_sp, 2249 struct mlxsw_sp_fib6_entry *fib6_entry) 2250 { 2251 struct mlxsw_sp_nexthop_group_cmp_arg cmp_arg; 2252 2253 cmp_arg.proto = MLXSW_SP_L3_PROTO_IPV6; 2254 cmp_arg.fib6_entry = fib6_entry; 2255 return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_group_ht, 2256 &cmp_arg, 2257 mlxsw_sp_nexthop_group_ht_params); 2258 } 2259 2260 static const struct rhashtable_params mlxsw_sp_nexthop_ht_params = { 2261 .key_offset = offsetof(struct mlxsw_sp_nexthop, key), 2262 .head_offset = offsetof(struct mlxsw_sp_nexthop, ht_node), 2263 .key_len = sizeof(struct mlxsw_sp_nexthop_key), 2264 }; 2265 2266 static int mlxsw_sp_nexthop_insert(struct mlxsw_sp *mlxsw_sp, 2267 struct mlxsw_sp_nexthop *nh) 2268 { 2269 return rhashtable_insert_fast(&mlxsw_sp->router->nexthop_ht, 2270 &nh->ht_node, mlxsw_sp_nexthop_ht_params); 2271 } 2272 2273 static void mlxsw_sp_nexthop_remove(struct mlxsw_sp *mlxsw_sp, 2274 struct mlxsw_sp_nexthop *nh) 2275 { 2276 rhashtable_remove_fast(&mlxsw_sp->router->nexthop_ht, &nh->ht_node, 2277 mlxsw_sp_nexthop_ht_params); 2278 } 2279 2280 static struct mlxsw_sp_nexthop * 2281 mlxsw_sp_nexthop_lookup(struct mlxsw_sp *mlxsw_sp, 2282 struct mlxsw_sp_nexthop_key key) 2283 { 2284 return rhashtable_lookup_fast(&mlxsw_sp->router->nexthop_ht, &key, 2285 mlxsw_sp_nexthop_ht_params); 2286 } 2287 2288 static int mlxsw_sp_adj_index_mass_update_vr(struct mlxsw_sp *mlxsw_sp, 2289 const struct mlxsw_sp_fib *fib, 2290 u32 adj_index, u16 ecmp_size, 2291 u32 new_adj_index, 2292 u16 new_ecmp_size) 2293 { 2294 char raleu_pl[MLXSW_REG_RALEU_LEN]; 2295 2296 mlxsw_reg_raleu_pack(raleu_pl, 2297 (enum mlxsw_reg_ralxx_protocol) fib->proto, 2298 fib->vr->id, adj_index, ecmp_size, new_adj_index, 2299 new_ecmp_size); 2300 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raleu), raleu_pl); 2301 } 2302 2303 static int mlxsw_sp_adj_index_mass_update(struct mlxsw_sp *mlxsw_sp, 2304 struct mlxsw_sp_nexthop_group *nh_grp, 2305 u32 old_adj_index, u16 old_ecmp_size) 2306 { 2307 struct mlxsw_sp_fib_entry *fib_entry; 2308 struct mlxsw_sp_fib *fib = NULL; 2309 int err; 2310 2311 list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) { 2312 if (fib == fib_entry->fib_node->fib) 2313 continue; 2314 fib = fib_entry->fib_node->fib; 2315 err = mlxsw_sp_adj_index_mass_update_vr(mlxsw_sp, fib, 2316 old_adj_index, 2317 old_ecmp_size, 2318 nh_grp->adj_index, 2319 nh_grp->ecmp_size); 2320 if (err) 2321 return err; 2322 } 2323 return 0; 2324 } 2325 2326 static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index, 2327 struct mlxsw_sp_nexthop *nh) 2328 { 2329 struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; 2330 char ratr_pl[MLXSW_REG_RATR_LEN]; 2331 2332 mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, 2333 true, MLXSW_REG_RATR_TYPE_ETHERNET, 2334 adj_index, neigh_entry->rif); 2335 mlxsw_reg_ratr_eth_entry_pack(ratr_pl, neigh_entry->ha); 2336 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl); 2337 } 2338 2339 static int mlxsw_sp_nexthop_ipip_update(struct mlxsw_sp *mlxsw_sp, 2340 u32 adj_index, 2341 struct mlxsw_sp_nexthop *nh) 2342 { 2343 const struct mlxsw_sp_ipip_ops *ipip_ops; 2344 2345 ipip_ops = mlxsw_sp->router->ipip_ops_arr[nh->ipip_entry->ipipt]; 2346 return ipip_ops->nexthop_update(mlxsw_sp, adj_index, nh->ipip_entry); 2347 } 2348 2349 static int 2350 mlxsw_sp_nexthop_group_update(struct mlxsw_sp *mlxsw_sp, 2351 struct mlxsw_sp_nexthop_group *nh_grp, 2352 bool reallocate) 2353 { 2354 u32 adj_index = nh_grp->adj_index; /* base */ 2355 struct mlxsw_sp_nexthop *nh; 2356 int i; 2357 int err; 2358 2359 for (i = 0; i < nh_grp->count; i++) { 2360 nh = &nh_grp->nexthops[i]; 2361 2362 if (!nh->should_offload) { 2363 nh->offloaded = 0; 2364 continue; 2365 } 2366 2367 if (nh->update || reallocate) { 2368 switch (nh->type) { 2369 case MLXSW_SP_NEXTHOP_TYPE_ETH: 2370 err = mlxsw_sp_nexthop_mac_update 2371 (mlxsw_sp, adj_index, nh); 2372 break; 2373 case MLXSW_SP_NEXTHOP_TYPE_IPIP: 2374 err = mlxsw_sp_nexthop_ipip_update 2375 (mlxsw_sp, adj_index, nh); 2376 break; 2377 } 2378 if (err) 2379 return err; 2380 nh->update = 0; 2381 nh->offloaded = 1; 2382 } 2383 adj_index++; 2384 } 2385 return 0; 2386 } 2387 2388 static bool 2389 mlxsw_sp_fib_node_entry_is_first(const struct mlxsw_sp_fib_node *fib_node, 2390 const struct mlxsw_sp_fib_entry *fib_entry); 2391 2392 static int 2393 mlxsw_sp_nexthop_fib_entries_update(struct mlxsw_sp *mlxsw_sp, 2394 struct mlxsw_sp_nexthop_group *nh_grp) 2395 { 2396 struct mlxsw_sp_fib_entry *fib_entry; 2397 int err; 2398 2399 list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) { 2400 if (!mlxsw_sp_fib_node_entry_is_first(fib_entry->fib_node, 2401 fib_entry)) 2402 continue; 2403 err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry); 2404 if (err) 2405 return err; 2406 } 2407 return 0; 2408 } 2409 2410 static void 2411 mlxsw_sp_fib_entry_offload_refresh(struct mlxsw_sp_fib_entry *fib_entry, 2412 enum mlxsw_reg_ralue_op op, int err); 2413 2414 static void 2415 mlxsw_sp_nexthop_fib_entries_refresh(struct mlxsw_sp_nexthop_group *nh_grp) 2416 { 2417 enum mlxsw_reg_ralue_op op = MLXSW_REG_RALUE_OP_WRITE_WRITE; 2418 struct mlxsw_sp_fib_entry *fib_entry; 2419 2420 list_for_each_entry(fib_entry, &nh_grp->fib_list, nexthop_group_node) { 2421 if (!mlxsw_sp_fib_node_entry_is_first(fib_entry->fib_node, 2422 fib_entry)) 2423 continue; 2424 mlxsw_sp_fib_entry_offload_refresh(fib_entry, op, 0); 2425 } 2426 } 2427 2428 static void 2429 mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp, 2430 struct mlxsw_sp_nexthop_group *nh_grp) 2431 { 2432 struct mlxsw_sp_nexthop *nh; 2433 bool offload_change = false; 2434 u32 adj_index; 2435 u16 ecmp_size = 0; 2436 bool old_adj_index_valid; 2437 u32 old_adj_index; 2438 u16 old_ecmp_size; 2439 int i; 2440 int err; 2441 2442 if (!nh_grp->gateway) { 2443 mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 2444 return; 2445 } 2446 2447 for (i = 0; i < nh_grp->count; i++) { 2448 nh = &nh_grp->nexthops[i]; 2449 2450 if (nh->should_offload != nh->offloaded) { 2451 offload_change = true; 2452 if (nh->should_offload) 2453 nh->update = 1; 2454 } 2455 if (nh->should_offload) 2456 ecmp_size++; 2457 } 2458 if (!offload_change) { 2459 /* Nothing was added or removed, so no need to reallocate. Just 2460 * update MAC on existing adjacency indexes. 2461 */ 2462 err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, false); 2463 if (err) { 2464 dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n"); 2465 goto set_trap; 2466 } 2467 return; 2468 } 2469 if (!ecmp_size) 2470 /* No neigh of this group is connected so we just set 2471 * the trap and let everthing flow through kernel. 2472 */ 2473 goto set_trap; 2474 2475 err = mlxsw_sp_kvdl_alloc(mlxsw_sp, ecmp_size, &adj_index); 2476 if (err) { 2477 /* We ran out of KVD linear space, just set the 2478 * trap and let everything flow through kernel. 2479 */ 2480 dev_warn(mlxsw_sp->bus_info->dev, "Failed to allocate KVD linear area for nexthop group.\n"); 2481 goto set_trap; 2482 } 2483 old_adj_index_valid = nh_grp->adj_index_valid; 2484 old_adj_index = nh_grp->adj_index; 2485 old_ecmp_size = nh_grp->ecmp_size; 2486 nh_grp->adj_index_valid = 1; 2487 nh_grp->adj_index = adj_index; 2488 nh_grp->ecmp_size = ecmp_size; 2489 err = mlxsw_sp_nexthop_group_update(mlxsw_sp, nh_grp, true); 2490 if (err) { 2491 dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n"); 2492 goto set_trap; 2493 } 2494 2495 if (!old_adj_index_valid) { 2496 /* The trap was set for fib entries, so we have to call 2497 * fib entry update to unset it and use adjacency index. 2498 */ 2499 err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 2500 if (err) { 2501 dev_warn(mlxsw_sp->bus_info->dev, "Failed to add adjacency index to fib entries.\n"); 2502 goto set_trap; 2503 } 2504 return; 2505 } 2506 2507 err = mlxsw_sp_adj_index_mass_update(mlxsw_sp, nh_grp, 2508 old_adj_index, old_ecmp_size); 2509 mlxsw_sp_kvdl_free(mlxsw_sp, old_adj_index); 2510 if (err) { 2511 dev_warn(mlxsw_sp->bus_info->dev, "Failed to mass-update adjacency index for nexthop group.\n"); 2512 goto set_trap; 2513 } 2514 2515 /* Offload state within the group changed, so update the flags. */ 2516 mlxsw_sp_nexthop_fib_entries_refresh(nh_grp); 2517 2518 return; 2519 2520 set_trap: 2521 old_adj_index_valid = nh_grp->adj_index_valid; 2522 nh_grp->adj_index_valid = 0; 2523 for (i = 0; i < nh_grp->count; i++) { 2524 nh = &nh_grp->nexthops[i]; 2525 nh->offloaded = 0; 2526 } 2527 err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 2528 if (err) 2529 dev_warn(mlxsw_sp->bus_info->dev, "Failed to set traps for fib entries.\n"); 2530 if (old_adj_index_valid) 2531 mlxsw_sp_kvdl_free(mlxsw_sp, nh_grp->adj_index); 2532 } 2533 2534 static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh, 2535 bool removing) 2536 { 2537 if (!removing) 2538 nh->should_offload = 1; 2539 else if (nh->offloaded) 2540 nh->should_offload = 0; 2541 nh->update = 1; 2542 } 2543 2544 static void 2545 mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, 2546 struct mlxsw_sp_neigh_entry *neigh_entry, 2547 bool removing) 2548 { 2549 struct mlxsw_sp_nexthop *nh; 2550 2551 list_for_each_entry(nh, &neigh_entry->nexthop_list, 2552 neigh_list_node) { 2553 __mlxsw_sp_nexthop_neigh_update(nh, removing); 2554 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); 2555 } 2556 } 2557 2558 static void mlxsw_sp_nexthop_rif_init(struct mlxsw_sp_nexthop *nh, 2559 struct mlxsw_sp_rif *rif) 2560 { 2561 if (nh->rif) 2562 return; 2563 2564 nh->rif = rif; 2565 list_add(&nh->rif_list_node, &rif->nexthop_list); 2566 } 2567 2568 static void mlxsw_sp_nexthop_rif_fini(struct mlxsw_sp_nexthop *nh) 2569 { 2570 if (!nh->rif) 2571 return; 2572 2573 list_del(&nh->rif_list_node); 2574 nh->rif = NULL; 2575 } 2576 2577 static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, 2578 struct mlxsw_sp_nexthop *nh) 2579 { 2580 struct mlxsw_sp_neigh_entry *neigh_entry; 2581 struct neighbour *n; 2582 u8 nud_state, dead; 2583 int err; 2584 2585 if (!nh->nh_grp->gateway || nh->neigh_entry) 2586 return 0; 2587 2588 /* Take a reference of neigh here ensuring that neigh would 2589 * not be destructed before the nexthop entry is finished. 2590 * The reference is taken either in neigh_lookup() or 2591 * in neigh_create() in case n is not found. 2592 */ 2593 n = neigh_lookup(nh->nh_grp->neigh_tbl, &nh->gw_addr, nh->rif->dev); 2594 if (!n) { 2595 n = neigh_create(nh->nh_grp->neigh_tbl, &nh->gw_addr, 2596 nh->rif->dev); 2597 if (IS_ERR(n)) 2598 return PTR_ERR(n); 2599 neigh_event_send(n, NULL); 2600 } 2601 neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n); 2602 if (!neigh_entry) { 2603 neigh_entry = mlxsw_sp_neigh_entry_create(mlxsw_sp, n); 2604 if (IS_ERR(neigh_entry)) { 2605 err = -EINVAL; 2606 goto err_neigh_entry_create; 2607 } 2608 } 2609 2610 /* If that is the first nexthop connected to that neigh, add to 2611 * nexthop_neighs_list 2612 */ 2613 if (list_empty(&neigh_entry->nexthop_list)) 2614 list_add_tail(&neigh_entry->nexthop_neighs_list_node, 2615 &mlxsw_sp->router->nexthop_neighs_list); 2616 2617 nh->neigh_entry = neigh_entry; 2618 list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list); 2619 read_lock_bh(&n->lock); 2620 nud_state = n->nud_state; 2621 dead = n->dead; 2622 read_unlock_bh(&n->lock); 2623 __mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID && !dead)); 2624 2625 return 0; 2626 2627 err_neigh_entry_create: 2628 neigh_release(n); 2629 return err; 2630 } 2631 2632 static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp, 2633 struct mlxsw_sp_nexthop *nh) 2634 { 2635 struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; 2636 struct neighbour *n; 2637 2638 if (!neigh_entry) 2639 return; 2640 n = neigh_entry->key.n; 2641 2642 __mlxsw_sp_nexthop_neigh_update(nh, true); 2643 list_del(&nh->neigh_list_node); 2644 nh->neigh_entry = NULL; 2645 2646 /* If that is the last nexthop connected to that neigh, remove from 2647 * nexthop_neighs_list 2648 */ 2649 if (list_empty(&neigh_entry->nexthop_list)) 2650 list_del(&neigh_entry->nexthop_neighs_list_node); 2651 2652 if (!neigh_entry->connected && list_empty(&neigh_entry->nexthop_list)) 2653 mlxsw_sp_neigh_entry_destroy(mlxsw_sp, neigh_entry); 2654 2655 neigh_release(n); 2656 } 2657 2658 static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp, 2659 const struct net_device *dev, 2660 enum mlxsw_sp_ipip_type *p_type) 2661 { 2662 struct mlxsw_sp_router *router = mlxsw_sp->router; 2663 const struct mlxsw_sp_ipip_ops *ipip_ops; 2664 enum mlxsw_sp_ipip_type ipipt; 2665 2666 for (ipipt = 0; ipipt < MLXSW_SP_IPIP_TYPE_MAX; ++ipipt) { 2667 ipip_ops = router->ipip_ops_arr[ipipt]; 2668 if (dev->type == ipip_ops->dev_type) { 2669 if (p_type) 2670 *p_type = ipipt; 2671 return true; 2672 } 2673 } 2674 return false; 2675 } 2676 2677 static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp, 2678 enum mlxsw_sp_ipip_type ipipt, 2679 struct mlxsw_sp_nexthop *nh, 2680 struct net_device *ol_dev) 2681 { 2682 if (!nh->nh_grp->gateway || nh->ipip_entry) 2683 return 0; 2684 2685 nh->ipip_entry = mlxsw_sp_ipip_entry_get(mlxsw_sp, ipipt, ol_dev); 2686 if (IS_ERR(nh->ipip_entry)) 2687 return PTR_ERR(nh->ipip_entry); 2688 2689 __mlxsw_sp_nexthop_neigh_update(nh, false); 2690 return 0; 2691 } 2692 2693 static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp, 2694 struct mlxsw_sp_nexthop *nh) 2695 { 2696 struct mlxsw_sp_ipip_entry *ipip_entry = nh->ipip_entry; 2697 2698 if (!ipip_entry) 2699 return; 2700 2701 __mlxsw_sp_nexthop_neigh_update(nh, true); 2702 mlxsw_sp_ipip_entry_put(mlxsw_sp, ipip_entry); 2703 nh->ipip_entry = NULL; 2704 } 2705 2706 static bool mlxsw_sp_nexthop4_ipip_type(const struct mlxsw_sp *mlxsw_sp, 2707 const struct fib_nh *fib_nh, 2708 enum mlxsw_sp_ipip_type *p_ipipt) 2709 { 2710 struct net_device *dev = fib_nh->nh_dev; 2711 2712 return dev && 2713 fib_nh->nh_parent->fib_type == RTN_UNICAST && 2714 mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, p_ipipt); 2715 } 2716 2717 static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, 2718 struct mlxsw_sp_nexthop *nh) 2719 { 2720 switch (nh->type) { 2721 case MLXSW_SP_NEXTHOP_TYPE_ETH: 2722 mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh); 2723 mlxsw_sp_nexthop_rif_fini(nh); 2724 break; 2725 case MLXSW_SP_NEXTHOP_TYPE_IPIP: 2726 mlxsw_sp_nexthop_rif_fini(nh); 2727 mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh); 2728 break; 2729 } 2730 } 2731 2732 static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp, 2733 struct mlxsw_sp_nexthop *nh, 2734 struct fib_nh *fib_nh) 2735 { 2736 struct mlxsw_sp_router *router = mlxsw_sp->router; 2737 struct net_device *dev = fib_nh->nh_dev; 2738 enum mlxsw_sp_ipip_type ipipt; 2739 struct mlxsw_sp_rif *rif; 2740 int err; 2741 2742 if (mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fib_nh, &ipipt) && 2743 router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, 2744 MLXSW_SP_L3_PROTO_IPV4)) { 2745 nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; 2746 err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); 2747 if (err) 2748 return err; 2749 mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); 2750 return 0; 2751 } 2752 2753 nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; 2754 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); 2755 if (!rif) 2756 return 0; 2757 2758 mlxsw_sp_nexthop_rif_init(nh, rif); 2759 err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh); 2760 if (err) 2761 goto err_neigh_init; 2762 2763 return 0; 2764 2765 err_neigh_init: 2766 mlxsw_sp_nexthop_rif_fini(nh); 2767 return err; 2768 } 2769 2770 static void mlxsw_sp_nexthop4_type_fini(struct mlxsw_sp *mlxsw_sp, 2771 struct mlxsw_sp_nexthop *nh) 2772 { 2773 mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh); 2774 } 2775 2776 static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp, 2777 struct mlxsw_sp_nexthop_group *nh_grp, 2778 struct mlxsw_sp_nexthop *nh, 2779 struct fib_nh *fib_nh) 2780 { 2781 struct net_device *dev = fib_nh->nh_dev; 2782 struct in_device *in_dev; 2783 int err; 2784 2785 nh->nh_grp = nh_grp; 2786 nh->key.fib_nh = fib_nh; 2787 memcpy(&nh->gw_addr, &fib_nh->nh_gw, sizeof(fib_nh->nh_gw)); 2788 err = mlxsw_sp_nexthop_insert(mlxsw_sp, nh); 2789 if (err) 2790 return err; 2791 2792 if (!dev) 2793 return 0; 2794 2795 in_dev = __in_dev_get_rtnl(dev); 2796 if (in_dev && IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) && 2797 fib_nh->nh_flags & RTNH_F_LINKDOWN) 2798 return 0; 2799 2800 err = mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh); 2801 if (err) 2802 goto err_nexthop_neigh_init; 2803 2804 return 0; 2805 2806 err_nexthop_neigh_init: 2807 mlxsw_sp_nexthop_remove(mlxsw_sp, nh); 2808 return err; 2809 } 2810 2811 static void mlxsw_sp_nexthop4_fini(struct mlxsw_sp *mlxsw_sp, 2812 struct mlxsw_sp_nexthop *nh) 2813 { 2814 mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh); 2815 mlxsw_sp_nexthop_remove(mlxsw_sp, nh); 2816 } 2817 2818 static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp, 2819 unsigned long event, struct fib_nh *fib_nh) 2820 { 2821 struct mlxsw_sp_nexthop_key key; 2822 struct mlxsw_sp_nexthop *nh; 2823 2824 if (mlxsw_sp->router->aborted) 2825 return; 2826 2827 key.fib_nh = fib_nh; 2828 nh = mlxsw_sp_nexthop_lookup(mlxsw_sp, key); 2829 if (WARN_ON_ONCE(!nh)) 2830 return; 2831 2832 switch (event) { 2833 case FIB_EVENT_NH_ADD: 2834 mlxsw_sp_nexthop4_type_init(mlxsw_sp, nh, fib_nh); 2835 break; 2836 case FIB_EVENT_NH_DEL: 2837 mlxsw_sp_nexthop4_type_fini(mlxsw_sp, nh); 2838 break; 2839 } 2840 2841 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); 2842 } 2843 2844 static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, 2845 struct mlxsw_sp_rif *rif) 2846 { 2847 struct mlxsw_sp_nexthop *nh, *tmp; 2848 2849 list_for_each_entry_safe(nh, tmp, &rif->nexthop_list, rif_list_node) { 2850 mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh); 2851 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); 2852 } 2853 } 2854 2855 static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp, 2856 const struct fib_info *fi) 2857 { 2858 return fi->fib_nh->nh_scope == RT_SCOPE_LINK || 2859 mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fi->fib_nh, NULL); 2860 } 2861 2862 static struct mlxsw_sp_nexthop_group * 2863 mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi) 2864 { 2865 struct mlxsw_sp_nexthop_group *nh_grp; 2866 struct mlxsw_sp_nexthop *nh; 2867 struct fib_nh *fib_nh; 2868 size_t alloc_size; 2869 int i; 2870 int err; 2871 2872 alloc_size = sizeof(*nh_grp) + 2873 fi->fib_nhs * sizeof(struct mlxsw_sp_nexthop); 2874 nh_grp = kzalloc(alloc_size, GFP_KERNEL); 2875 if (!nh_grp) 2876 return ERR_PTR(-ENOMEM); 2877 nh_grp->priv = fi; 2878 INIT_LIST_HEAD(&nh_grp->fib_list); 2879 nh_grp->neigh_tbl = &arp_tbl; 2880 2881 nh_grp->gateway = mlxsw_sp_fi_is_gateway(mlxsw_sp, fi); 2882 nh_grp->count = fi->fib_nhs; 2883 fib_info_hold(fi); 2884 for (i = 0; i < nh_grp->count; i++) { 2885 nh = &nh_grp->nexthops[i]; 2886 fib_nh = &fi->fib_nh[i]; 2887 err = mlxsw_sp_nexthop4_init(mlxsw_sp, nh_grp, nh, fib_nh); 2888 if (err) 2889 goto err_nexthop4_init; 2890 } 2891 err = mlxsw_sp_nexthop_group_insert(mlxsw_sp, nh_grp); 2892 if (err) 2893 goto err_nexthop_group_insert; 2894 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 2895 return nh_grp; 2896 2897 err_nexthop_group_insert: 2898 err_nexthop4_init: 2899 for (i--; i >= 0; i--) { 2900 nh = &nh_grp->nexthops[i]; 2901 mlxsw_sp_nexthop4_fini(mlxsw_sp, nh); 2902 } 2903 fib_info_put(fi); 2904 kfree(nh_grp); 2905 return ERR_PTR(err); 2906 } 2907 2908 static void 2909 mlxsw_sp_nexthop4_group_destroy(struct mlxsw_sp *mlxsw_sp, 2910 struct mlxsw_sp_nexthop_group *nh_grp) 2911 { 2912 struct mlxsw_sp_nexthop *nh; 2913 int i; 2914 2915 mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp); 2916 for (i = 0; i < nh_grp->count; i++) { 2917 nh = &nh_grp->nexthops[i]; 2918 mlxsw_sp_nexthop4_fini(mlxsw_sp, nh); 2919 } 2920 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 2921 WARN_ON_ONCE(nh_grp->adj_index_valid); 2922 fib_info_put(mlxsw_sp_nexthop4_group_fi(nh_grp)); 2923 kfree(nh_grp); 2924 } 2925 2926 static int mlxsw_sp_nexthop4_group_get(struct mlxsw_sp *mlxsw_sp, 2927 struct mlxsw_sp_fib_entry *fib_entry, 2928 struct fib_info *fi) 2929 { 2930 struct mlxsw_sp_nexthop_group *nh_grp; 2931 2932 nh_grp = mlxsw_sp_nexthop4_group_lookup(mlxsw_sp, fi); 2933 if (!nh_grp) { 2934 nh_grp = mlxsw_sp_nexthop4_group_create(mlxsw_sp, fi); 2935 if (IS_ERR(nh_grp)) 2936 return PTR_ERR(nh_grp); 2937 } 2938 list_add_tail(&fib_entry->nexthop_group_node, &nh_grp->fib_list); 2939 fib_entry->nh_group = nh_grp; 2940 return 0; 2941 } 2942 2943 static void mlxsw_sp_nexthop4_group_put(struct mlxsw_sp *mlxsw_sp, 2944 struct mlxsw_sp_fib_entry *fib_entry) 2945 { 2946 struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; 2947 2948 list_del(&fib_entry->nexthop_group_node); 2949 if (!list_empty(&nh_grp->fib_list)) 2950 return; 2951 mlxsw_sp_nexthop4_group_destroy(mlxsw_sp, nh_grp); 2952 } 2953 2954 static bool 2955 mlxsw_sp_fib4_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry) 2956 { 2957 struct mlxsw_sp_fib4_entry *fib4_entry; 2958 2959 fib4_entry = container_of(fib_entry, struct mlxsw_sp_fib4_entry, 2960 common); 2961 return !fib4_entry->tos; 2962 } 2963 2964 static bool 2965 mlxsw_sp_fib_entry_should_offload(const struct mlxsw_sp_fib_entry *fib_entry) 2966 { 2967 struct mlxsw_sp_nexthop_group *nh_group = fib_entry->nh_group; 2968 2969 switch (fib_entry->fib_node->fib->proto) { 2970 case MLXSW_SP_L3_PROTO_IPV4: 2971 if (!mlxsw_sp_fib4_entry_should_offload(fib_entry)) 2972 return false; 2973 break; 2974 case MLXSW_SP_L3_PROTO_IPV6: 2975 break; 2976 } 2977 2978 switch (fib_entry->type) { 2979 case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE: 2980 return !!nh_group->adj_index_valid; 2981 case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL: 2982 return !!nh_group->nh_rif; 2983 case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP: 2984 return true; 2985 default: 2986 return false; 2987 } 2988 } 2989 2990 static struct mlxsw_sp_nexthop * 2991 mlxsw_sp_rt6_nexthop(struct mlxsw_sp_nexthop_group *nh_grp, 2992 const struct mlxsw_sp_rt6 *mlxsw_sp_rt6) 2993 { 2994 int i; 2995 2996 for (i = 0; i < nh_grp->count; i++) { 2997 struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; 2998 struct rt6_info *rt = mlxsw_sp_rt6->rt; 2999 3000 if (nh->rif && nh->rif->dev == rt->dst.dev && 3001 ipv6_addr_equal((const struct in6_addr *) &nh->gw_addr, 3002 &rt->rt6i_gateway)) 3003 return nh; 3004 continue; 3005 } 3006 3007 return NULL; 3008 } 3009 3010 static void 3011 mlxsw_sp_fib4_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry) 3012 { 3013 struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; 3014 int i; 3015 3016 if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL || 3017 fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP) { 3018 nh_grp->nexthops->key.fib_nh->nh_flags |= RTNH_F_OFFLOAD; 3019 return; 3020 } 3021 3022 for (i = 0; i < nh_grp->count; i++) { 3023 struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; 3024 3025 if (nh->offloaded) 3026 nh->key.fib_nh->nh_flags |= RTNH_F_OFFLOAD; 3027 else 3028 nh->key.fib_nh->nh_flags &= ~RTNH_F_OFFLOAD; 3029 } 3030 } 3031 3032 static void 3033 mlxsw_sp_fib4_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry) 3034 { 3035 struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; 3036 int i; 3037 3038 for (i = 0; i < nh_grp->count; i++) { 3039 struct mlxsw_sp_nexthop *nh = &nh_grp->nexthops[i]; 3040 3041 nh->key.fib_nh->nh_flags &= ~RTNH_F_OFFLOAD; 3042 } 3043 } 3044 3045 static void 3046 mlxsw_sp_fib6_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry) 3047 { 3048 struct mlxsw_sp_fib6_entry *fib6_entry; 3049 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 3050 3051 fib6_entry = container_of(fib_entry, struct mlxsw_sp_fib6_entry, 3052 common); 3053 3054 if (fib_entry->type == MLXSW_SP_FIB_ENTRY_TYPE_LOCAL) { 3055 list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6, 3056 list)->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD; 3057 return; 3058 } 3059 3060 list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { 3061 struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; 3062 struct mlxsw_sp_nexthop *nh; 3063 3064 nh = mlxsw_sp_rt6_nexthop(nh_grp, mlxsw_sp_rt6); 3065 if (nh && nh->offloaded) 3066 mlxsw_sp_rt6->rt->rt6i_nh_flags |= RTNH_F_OFFLOAD; 3067 else 3068 mlxsw_sp_rt6->rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD; 3069 } 3070 } 3071 3072 static void 3073 mlxsw_sp_fib6_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry) 3074 { 3075 struct mlxsw_sp_fib6_entry *fib6_entry; 3076 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 3077 3078 fib6_entry = container_of(fib_entry, struct mlxsw_sp_fib6_entry, 3079 common); 3080 list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { 3081 struct rt6_info *rt = mlxsw_sp_rt6->rt; 3082 3083 rt->rt6i_nh_flags &= ~RTNH_F_OFFLOAD; 3084 } 3085 } 3086 3087 static void mlxsw_sp_fib_entry_offload_set(struct mlxsw_sp_fib_entry *fib_entry) 3088 { 3089 switch (fib_entry->fib_node->fib->proto) { 3090 case MLXSW_SP_L3_PROTO_IPV4: 3091 mlxsw_sp_fib4_entry_offload_set(fib_entry); 3092 break; 3093 case MLXSW_SP_L3_PROTO_IPV6: 3094 mlxsw_sp_fib6_entry_offload_set(fib_entry); 3095 break; 3096 } 3097 } 3098 3099 static void 3100 mlxsw_sp_fib_entry_offload_unset(struct mlxsw_sp_fib_entry *fib_entry) 3101 { 3102 switch (fib_entry->fib_node->fib->proto) { 3103 case MLXSW_SP_L3_PROTO_IPV4: 3104 mlxsw_sp_fib4_entry_offload_unset(fib_entry); 3105 break; 3106 case MLXSW_SP_L3_PROTO_IPV6: 3107 mlxsw_sp_fib6_entry_offload_unset(fib_entry); 3108 break; 3109 } 3110 } 3111 3112 static void 3113 mlxsw_sp_fib_entry_offload_refresh(struct mlxsw_sp_fib_entry *fib_entry, 3114 enum mlxsw_reg_ralue_op op, int err) 3115 { 3116 switch (op) { 3117 case MLXSW_REG_RALUE_OP_WRITE_DELETE: 3118 return mlxsw_sp_fib_entry_offload_unset(fib_entry); 3119 case MLXSW_REG_RALUE_OP_WRITE_WRITE: 3120 if (err) 3121 return; 3122 if (mlxsw_sp_fib_entry_should_offload(fib_entry)) 3123 mlxsw_sp_fib_entry_offload_set(fib_entry); 3124 else if (!mlxsw_sp_fib_entry_should_offload(fib_entry)) 3125 mlxsw_sp_fib_entry_offload_unset(fib_entry); 3126 return; 3127 default: 3128 return; 3129 } 3130 } 3131 3132 static void 3133 mlxsw_sp_fib_entry_ralue_pack(char *ralue_pl, 3134 const struct mlxsw_sp_fib_entry *fib_entry, 3135 enum mlxsw_reg_ralue_op op) 3136 { 3137 struct mlxsw_sp_fib *fib = fib_entry->fib_node->fib; 3138 enum mlxsw_reg_ralxx_protocol proto; 3139 u32 *p_dip; 3140 3141 proto = (enum mlxsw_reg_ralxx_protocol) fib->proto; 3142 3143 switch (fib->proto) { 3144 case MLXSW_SP_L3_PROTO_IPV4: 3145 p_dip = (u32 *) fib_entry->fib_node->key.addr; 3146 mlxsw_reg_ralue_pack4(ralue_pl, proto, op, fib->vr->id, 3147 fib_entry->fib_node->key.prefix_len, 3148 *p_dip); 3149 break; 3150 case MLXSW_SP_L3_PROTO_IPV6: 3151 mlxsw_reg_ralue_pack6(ralue_pl, proto, op, fib->vr->id, 3152 fib_entry->fib_node->key.prefix_len, 3153 fib_entry->fib_node->key.addr); 3154 break; 3155 } 3156 } 3157 3158 static int mlxsw_sp_fib_entry_op_remote(struct mlxsw_sp *mlxsw_sp, 3159 struct mlxsw_sp_fib_entry *fib_entry, 3160 enum mlxsw_reg_ralue_op op) 3161 { 3162 char ralue_pl[MLXSW_REG_RALUE_LEN]; 3163 enum mlxsw_reg_ralue_trap_action trap_action; 3164 u16 trap_id = 0; 3165 u32 adjacency_index = 0; 3166 u16 ecmp_size = 0; 3167 3168 /* In case the nexthop group adjacency index is valid, use it 3169 * with provided ECMP size. Otherwise, setup trap and pass 3170 * traffic to kernel. 3171 */ 3172 if (mlxsw_sp_fib_entry_should_offload(fib_entry)) { 3173 trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP; 3174 adjacency_index = fib_entry->nh_group->adj_index; 3175 ecmp_size = fib_entry->nh_group->ecmp_size; 3176 } else { 3177 trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP; 3178 trap_id = MLXSW_TRAP_ID_RTR_INGRESS0; 3179 } 3180 3181 mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op); 3182 mlxsw_reg_ralue_act_remote_pack(ralue_pl, trap_action, trap_id, 3183 adjacency_index, ecmp_size); 3184 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl); 3185 } 3186 3187 static int mlxsw_sp_fib_entry_op_local(struct mlxsw_sp *mlxsw_sp, 3188 struct mlxsw_sp_fib_entry *fib_entry, 3189 enum mlxsw_reg_ralue_op op) 3190 { 3191 struct mlxsw_sp_rif *rif = fib_entry->nh_group->nh_rif; 3192 enum mlxsw_reg_ralue_trap_action trap_action; 3193 char ralue_pl[MLXSW_REG_RALUE_LEN]; 3194 u16 trap_id = 0; 3195 u16 rif_index = 0; 3196 3197 if (mlxsw_sp_fib_entry_should_offload(fib_entry)) { 3198 trap_action = MLXSW_REG_RALUE_TRAP_ACTION_NOP; 3199 rif_index = rif->rif_index; 3200 } else { 3201 trap_action = MLXSW_REG_RALUE_TRAP_ACTION_TRAP; 3202 trap_id = MLXSW_TRAP_ID_RTR_INGRESS0; 3203 } 3204 3205 mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op); 3206 mlxsw_reg_ralue_act_local_pack(ralue_pl, trap_action, trap_id, 3207 rif_index); 3208 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl); 3209 } 3210 3211 static int mlxsw_sp_fib_entry_op_trap(struct mlxsw_sp *mlxsw_sp, 3212 struct mlxsw_sp_fib_entry *fib_entry, 3213 enum mlxsw_reg_ralue_op op) 3214 { 3215 char ralue_pl[MLXSW_REG_RALUE_LEN]; 3216 3217 mlxsw_sp_fib_entry_ralue_pack(ralue_pl, fib_entry, op); 3218 mlxsw_reg_ralue_act_ip2me_pack(ralue_pl); 3219 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), ralue_pl); 3220 } 3221 3222 static int 3223 mlxsw_sp_fib_entry_op_ipip_decap(struct mlxsw_sp *mlxsw_sp, 3224 struct mlxsw_sp_fib_entry *fib_entry, 3225 enum mlxsw_reg_ralue_op op) 3226 { 3227 struct mlxsw_sp_ipip_entry *ipip_entry = fib_entry->decap.ipip_entry; 3228 const struct mlxsw_sp_ipip_ops *ipip_ops; 3229 3230 if (WARN_ON(!ipip_entry)) 3231 return -EINVAL; 3232 3233 ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt]; 3234 return ipip_ops->fib_entry_op(mlxsw_sp, ipip_entry, op, 3235 fib_entry->decap.tunnel_index); 3236 } 3237 3238 static int __mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp, 3239 struct mlxsw_sp_fib_entry *fib_entry, 3240 enum mlxsw_reg_ralue_op op) 3241 { 3242 switch (fib_entry->type) { 3243 case MLXSW_SP_FIB_ENTRY_TYPE_REMOTE: 3244 return mlxsw_sp_fib_entry_op_remote(mlxsw_sp, fib_entry, op); 3245 case MLXSW_SP_FIB_ENTRY_TYPE_LOCAL: 3246 return mlxsw_sp_fib_entry_op_local(mlxsw_sp, fib_entry, op); 3247 case MLXSW_SP_FIB_ENTRY_TYPE_TRAP: 3248 return mlxsw_sp_fib_entry_op_trap(mlxsw_sp, fib_entry, op); 3249 case MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP: 3250 return mlxsw_sp_fib_entry_op_ipip_decap(mlxsw_sp, 3251 fib_entry, op); 3252 } 3253 return -EINVAL; 3254 } 3255 3256 static int mlxsw_sp_fib_entry_op(struct mlxsw_sp *mlxsw_sp, 3257 struct mlxsw_sp_fib_entry *fib_entry, 3258 enum mlxsw_reg_ralue_op op) 3259 { 3260 int err = __mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, op); 3261 3262 mlxsw_sp_fib_entry_offload_refresh(fib_entry, op, err); 3263 3264 return err; 3265 } 3266 3267 static int mlxsw_sp_fib_entry_update(struct mlxsw_sp *mlxsw_sp, 3268 struct mlxsw_sp_fib_entry *fib_entry) 3269 { 3270 return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, 3271 MLXSW_REG_RALUE_OP_WRITE_WRITE); 3272 } 3273 3274 static int mlxsw_sp_fib_entry_del(struct mlxsw_sp *mlxsw_sp, 3275 struct mlxsw_sp_fib_entry *fib_entry) 3276 { 3277 return mlxsw_sp_fib_entry_op(mlxsw_sp, fib_entry, 3278 MLXSW_REG_RALUE_OP_WRITE_DELETE); 3279 } 3280 3281 static int 3282 mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp, 3283 const struct fib_entry_notifier_info *fen_info, 3284 struct mlxsw_sp_fib_entry *fib_entry) 3285 { 3286 union mlxsw_sp_l3addr dip = { .addr4 = htonl(fen_info->dst) }; 3287 struct net_device *dev = fen_info->fi->fib_dev; 3288 struct mlxsw_sp_ipip_entry *ipip_entry; 3289 struct fib_info *fi = fen_info->fi; 3290 3291 switch (fen_info->type) { 3292 case RTN_LOCAL: 3293 ipip_entry = mlxsw_sp_ipip_entry_find_by_decap(mlxsw_sp, dev, 3294 MLXSW_SP_L3_PROTO_IPV4, dip); 3295 if (ipip_entry) { 3296 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP; 3297 return mlxsw_sp_fib_entry_decap_init(mlxsw_sp, 3298 fib_entry, 3299 ipip_entry); 3300 } 3301 /* fall through */ 3302 case RTN_BROADCAST: 3303 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP; 3304 return 0; 3305 case RTN_UNREACHABLE: /* fall through */ 3306 case RTN_BLACKHOLE: /* fall through */ 3307 case RTN_PROHIBIT: 3308 /* Packets hitting these routes need to be trapped, but 3309 * can do so with a lower priority than packets directed 3310 * at the host, so use action type local instead of trap. 3311 */ 3312 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; 3313 return 0; 3314 case RTN_UNICAST: 3315 if (mlxsw_sp_fi_is_gateway(mlxsw_sp, fi)) 3316 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE; 3317 else 3318 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; 3319 return 0; 3320 default: 3321 return -EINVAL; 3322 } 3323 } 3324 3325 static struct mlxsw_sp_fib4_entry * 3326 mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp, 3327 struct mlxsw_sp_fib_node *fib_node, 3328 const struct fib_entry_notifier_info *fen_info) 3329 { 3330 struct mlxsw_sp_fib4_entry *fib4_entry; 3331 struct mlxsw_sp_fib_entry *fib_entry; 3332 int err; 3333 3334 fib4_entry = kzalloc(sizeof(*fib4_entry), GFP_KERNEL); 3335 if (!fib4_entry) 3336 return ERR_PTR(-ENOMEM); 3337 fib_entry = &fib4_entry->common; 3338 3339 err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry); 3340 if (err) 3341 goto err_fib4_entry_type_set; 3342 3343 err = mlxsw_sp_nexthop4_group_get(mlxsw_sp, fib_entry, fen_info->fi); 3344 if (err) 3345 goto err_nexthop4_group_get; 3346 3347 fib4_entry->prio = fen_info->fi->fib_priority; 3348 fib4_entry->tb_id = fen_info->tb_id; 3349 fib4_entry->type = fen_info->type; 3350 fib4_entry->tos = fen_info->tos; 3351 3352 fib_entry->fib_node = fib_node; 3353 3354 return fib4_entry; 3355 3356 err_nexthop4_group_get: 3357 err_fib4_entry_type_set: 3358 kfree(fib4_entry); 3359 return ERR_PTR(err); 3360 } 3361 3362 static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp, 3363 struct mlxsw_sp_fib4_entry *fib4_entry) 3364 { 3365 mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common); 3366 kfree(fib4_entry); 3367 } 3368 3369 static struct mlxsw_sp_fib4_entry * 3370 mlxsw_sp_fib4_entry_lookup(struct mlxsw_sp *mlxsw_sp, 3371 const struct fib_entry_notifier_info *fen_info) 3372 { 3373 struct mlxsw_sp_fib4_entry *fib4_entry; 3374 struct mlxsw_sp_fib_node *fib_node; 3375 struct mlxsw_sp_fib *fib; 3376 struct mlxsw_sp_vr *vr; 3377 3378 vr = mlxsw_sp_vr_find(mlxsw_sp, fen_info->tb_id); 3379 if (!vr) 3380 return NULL; 3381 fib = mlxsw_sp_vr_fib(vr, MLXSW_SP_L3_PROTO_IPV4); 3382 3383 fib_node = mlxsw_sp_fib_node_lookup(fib, &fen_info->dst, 3384 sizeof(fen_info->dst), 3385 fen_info->dst_len); 3386 if (!fib_node) 3387 return NULL; 3388 3389 list_for_each_entry(fib4_entry, &fib_node->entry_list, common.list) { 3390 if (fib4_entry->tb_id == fen_info->tb_id && 3391 fib4_entry->tos == fen_info->tos && 3392 fib4_entry->type == fen_info->type && 3393 mlxsw_sp_nexthop4_group_fi(fib4_entry->common.nh_group) == 3394 fen_info->fi) { 3395 return fib4_entry; 3396 } 3397 } 3398 3399 return NULL; 3400 } 3401 3402 static const struct rhashtable_params mlxsw_sp_fib_ht_params = { 3403 .key_offset = offsetof(struct mlxsw_sp_fib_node, key), 3404 .head_offset = offsetof(struct mlxsw_sp_fib_node, ht_node), 3405 .key_len = sizeof(struct mlxsw_sp_fib_key), 3406 .automatic_shrinking = true, 3407 }; 3408 3409 static int mlxsw_sp_fib_node_insert(struct mlxsw_sp_fib *fib, 3410 struct mlxsw_sp_fib_node *fib_node) 3411 { 3412 return rhashtable_insert_fast(&fib->ht, &fib_node->ht_node, 3413 mlxsw_sp_fib_ht_params); 3414 } 3415 3416 static void mlxsw_sp_fib_node_remove(struct mlxsw_sp_fib *fib, 3417 struct mlxsw_sp_fib_node *fib_node) 3418 { 3419 rhashtable_remove_fast(&fib->ht, &fib_node->ht_node, 3420 mlxsw_sp_fib_ht_params); 3421 } 3422 3423 static struct mlxsw_sp_fib_node * 3424 mlxsw_sp_fib_node_lookup(struct mlxsw_sp_fib *fib, const void *addr, 3425 size_t addr_len, unsigned char prefix_len) 3426 { 3427 struct mlxsw_sp_fib_key key; 3428 3429 memset(&key, 0, sizeof(key)); 3430 memcpy(key.addr, addr, addr_len); 3431 key.prefix_len = prefix_len; 3432 return rhashtable_lookup_fast(&fib->ht, &key, mlxsw_sp_fib_ht_params); 3433 } 3434 3435 static struct mlxsw_sp_fib_node * 3436 mlxsw_sp_fib_node_create(struct mlxsw_sp_fib *fib, const void *addr, 3437 size_t addr_len, unsigned char prefix_len) 3438 { 3439 struct mlxsw_sp_fib_node *fib_node; 3440 3441 fib_node = kzalloc(sizeof(*fib_node), GFP_KERNEL); 3442 if (!fib_node) 3443 return NULL; 3444 3445 INIT_LIST_HEAD(&fib_node->entry_list); 3446 list_add(&fib_node->list, &fib->node_list); 3447 memcpy(fib_node->key.addr, addr, addr_len); 3448 fib_node->key.prefix_len = prefix_len; 3449 3450 return fib_node; 3451 } 3452 3453 static void mlxsw_sp_fib_node_destroy(struct mlxsw_sp_fib_node *fib_node) 3454 { 3455 list_del(&fib_node->list); 3456 WARN_ON(!list_empty(&fib_node->entry_list)); 3457 kfree(fib_node); 3458 } 3459 3460 static bool 3461 mlxsw_sp_fib_node_entry_is_first(const struct mlxsw_sp_fib_node *fib_node, 3462 const struct mlxsw_sp_fib_entry *fib_entry) 3463 { 3464 return list_first_entry(&fib_node->entry_list, 3465 struct mlxsw_sp_fib_entry, list) == fib_entry; 3466 } 3467 3468 static int mlxsw_sp_fib_lpm_tree_link(struct mlxsw_sp *mlxsw_sp, 3469 struct mlxsw_sp_fib *fib, 3470 struct mlxsw_sp_fib_node *fib_node) 3471 { 3472 struct mlxsw_sp_prefix_usage req_prefix_usage = {{ 0 } }; 3473 struct mlxsw_sp_lpm_tree *lpm_tree; 3474 int err; 3475 3476 /* Since the tree is shared between all virtual routers we must 3477 * make sure it contains all the required prefix lengths. This 3478 * can be computed by either adding the new prefix length to the 3479 * existing prefix usage of a bound tree, or by aggregating the 3480 * prefix lengths across all virtual routers and adding the new 3481 * one as well. 3482 */ 3483 if (fib->lpm_tree) 3484 mlxsw_sp_prefix_usage_cpy(&req_prefix_usage, 3485 &fib->lpm_tree->prefix_usage); 3486 else 3487 mlxsw_sp_vrs_prefixes(mlxsw_sp, fib->proto, &req_prefix_usage); 3488 mlxsw_sp_prefix_usage_set(&req_prefix_usage, fib_node->key.prefix_len); 3489 3490 lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage, 3491 fib->proto); 3492 if (IS_ERR(lpm_tree)) 3493 return PTR_ERR(lpm_tree); 3494 3495 if (fib->lpm_tree && fib->lpm_tree->id == lpm_tree->id) 3496 return 0; 3497 3498 err = mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree); 3499 if (err) 3500 return err; 3501 3502 return 0; 3503 } 3504 3505 static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp, 3506 struct mlxsw_sp_fib *fib) 3507 { 3508 struct mlxsw_sp_prefix_usage req_prefix_usage = {{ 0 } }; 3509 struct mlxsw_sp_lpm_tree *lpm_tree; 3510 3511 /* Aggregate prefix lengths across all virtual routers to make 3512 * sure we only have used prefix lengths in the LPM tree. 3513 */ 3514 mlxsw_sp_vrs_prefixes(mlxsw_sp, fib->proto, &req_prefix_usage); 3515 lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage, 3516 fib->proto); 3517 if (IS_ERR(lpm_tree)) 3518 goto err_tree_get; 3519 mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree); 3520 3521 err_tree_get: 3522 if (!mlxsw_sp_prefix_usage_none(&fib->prefix_usage)) 3523 return; 3524 mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, fib); 3525 mlxsw_sp_lpm_tree_put(mlxsw_sp, fib->lpm_tree); 3526 fib->lpm_tree = NULL; 3527 } 3528 3529 static void mlxsw_sp_fib_node_prefix_inc(struct mlxsw_sp_fib_node *fib_node) 3530 { 3531 unsigned char prefix_len = fib_node->key.prefix_len; 3532 struct mlxsw_sp_fib *fib = fib_node->fib; 3533 3534 if (fib->prefix_ref_count[prefix_len]++ == 0) 3535 mlxsw_sp_prefix_usage_set(&fib->prefix_usage, prefix_len); 3536 } 3537 3538 static void mlxsw_sp_fib_node_prefix_dec(struct mlxsw_sp_fib_node *fib_node) 3539 { 3540 unsigned char prefix_len = fib_node->key.prefix_len; 3541 struct mlxsw_sp_fib *fib = fib_node->fib; 3542 3543 if (--fib->prefix_ref_count[prefix_len] == 0) 3544 mlxsw_sp_prefix_usage_clear(&fib->prefix_usage, prefix_len); 3545 } 3546 3547 static int mlxsw_sp_fib_node_init(struct mlxsw_sp *mlxsw_sp, 3548 struct mlxsw_sp_fib_node *fib_node, 3549 struct mlxsw_sp_fib *fib) 3550 { 3551 int err; 3552 3553 err = mlxsw_sp_fib_node_insert(fib, fib_node); 3554 if (err) 3555 return err; 3556 fib_node->fib = fib; 3557 3558 err = mlxsw_sp_fib_lpm_tree_link(mlxsw_sp, fib, fib_node); 3559 if (err) 3560 goto err_fib_lpm_tree_link; 3561 3562 mlxsw_sp_fib_node_prefix_inc(fib_node); 3563 3564 return 0; 3565 3566 err_fib_lpm_tree_link: 3567 fib_node->fib = NULL; 3568 mlxsw_sp_fib_node_remove(fib, fib_node); 3569 return err; 3570 } 3571 3572 static void mlxsw_sp_fib_node_fini(struct mlxsw_sp *mlxsw_sp, 3573 struct mlxsw_sp_fib_node *fib_node) 3574 { 3575 struct mlxsw_sp_fib *fib = fib_node->fib; 3576 3577 mlxsw_sp_fib_node_prefix_dec(fib_node); 3578 mlxsw_sp_fib_lpm_tree_unlink(mlxsw_sp, fib); 3579 fib_node->fib = NULL; 3580 mlxsw_sp_fib_node_remove(fib, fib_node); 3581 } 3582 3583 static struct mlxsw_sp_fib_node * 3584 mlxsw_sp_fib_node_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id, const void *addr, 3585 size_t addr_len, unsigned char prefix_len, 3586 enum mlxsw_sp_l3proto proto) 3587 { 3588 struct mlxsw_sp_fib_node *fib_node; 3589 struct mlxsw_sp_fib *fib; 3590 struct mlxsw_sp_vr *vr; 3591 int err; 3592 3593 vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id); 3594 if (IS_ERR(vr)) 3595 return ERR_CAST(vr); 3596 fib = mlxsw_sp_vr_fib(vr, proto); 3597 3598 fib_node = mlxsw_sp_fib_node_lookup(fib, addr, addr_len, prefix_len); 3599 if (fib_node) 3600 return fib_node; 3601 3602 fib_node = mlxsw_sp_fib_node_create(fib, addr, addr_len, prefix_len); 3603 if (!fib_node) { 3604 err = -ENOMEM; 3605 goto err_fib_node_create; 3606 } 3607 3608 err = mlxsw_sp_fib_node_init(mlxsw_sp, fib_node, fib); 3609 if (err) 3610 goto err_fib_node_init; 3611 3612 return fib_node; 3613 3614 err_fib_node_init: 3615 mlxsw_sp_fib_node_destroy(fib_node); 3616 err_fib_node_create: 3617 mlxsw_sp_vr_put(vr); 3618 return ERR_PTR(err); 3619 } 3620 3621 static void mlxsw_sp_fib_node_put(struct mlxsw_sp *mlxsw_sp, 3622 struct mlxsw_sp_fib_node *fib_node) 3623 { 3624 struct mlxsw_sp_vr *vr = fib_node->fib->vr; 3625 3626 if (!list_empty(&fib_node->entry_list)) 3627 return; 3628 mlxsw_sp_fib_node_fini(mlxsw_sp, fib_node); 3629 mlxsw_sp_fib_node_destroy(fib_node); 3630 mlxsw_sp_vr_put(vr); 3631 } 3632 3633 static struct mlxsw_sp_fib4_entry * 3634 mlxsw_sp_fib4_node_entry_find(const struct mlxsw_sp_fib_node *fib_node, 3635 const struct mlxsw_sp_fib4_entry *new4_entry) 3636 { 3637 struct mlxsw_sp_fib4_entry *fib4_entry; 3638 3639 list_for_each_entry(fib4_entry, &fib_node->entry_list, common.list) { 3640 if (fib4_entry->tb_id > new4_entry->tb_id) 3641 continue; 3642 if (fib4_entry->tb_id != new4_entry->tb_id) 3643 break; 3644 if (fib4_entry->tos > new4_entry->tos) 3645 continue; 3646 if (fib4_entry->prio >= new4_entry->prio || 3647 fib4_entry->tos < new4_entry->tos) 3648 return fib4_entry; 3649 } 3650 3651 return NULL; 3652 } 3653 3654 static int 3655 mlxsw_sp_fib4_node_list_append(struct mlxsw_sp_fib4_entry *fib4_entry, 3656 struct mlxsw_sp_fib4_entry *new4_entry) 3657 { 3658 struct mlxsw_sp_fib_node *fib_node; 3659 3660 if (WARN_ON(!fib4_entry)) 3661 return -EINVAL; 3662 3663 fib_node = fib4_entry->common.fib_node; 3664 list_for_each_entry_from(fib4_entry, &fib_node->entry_list, 3665 common.list) { 3666 if (fib4_entry->tb_id != new4_entry->tb_id || 3667 fib4_entry->tos != new4_entry->tos || 3668 fib4_entry->prio != new4_entry->prio) 3669 break; 3670 } 3671 3672 list_add_tail(&new4_entry->common.list, &fib4_entry->common.list); 3673 return 0; 3674 } 3675 3676 static int 3677 mlxsw_sp_fib4_node_list_insert(struct mlxsw_sp_fib4_entry *new4_entry, 3678 bool replace, bool append) 3679 { 3680 struct mlxsw_sp_fib_node *fib_node = new4_entry->common.fib_node; 3681 struct mlxsw_sp_fib4_entry *fib4_entry; 3682 3683 fib4_entry = mlxsw_sp_fib4_node_entry_find(fib_node, new4_entry); 3684 3685 if (append) 3686 return mlxsw_sp_fib4_node_list_append(fib4_entry, new4_entry); 3687 if (replace && WARN_ON(!fib4_entry)) 3688 return -EINVAL; 3689 3690 /* Insert new entry before replaced one, so that we can later 3691 * remove the second. 3692 */ 3693 if (fib4_entry) { 3694 list_add_tail(&new4_entry->common.list, 3695 &fib4_entry->common.list); 3696 } else { 3697 struct mlxsw_sp_fib4_entry *last; 3698 3699 list_for_each_entry(last, &fib_node->entry_list, common.list) { 3700 if (new4_entry->tb_id > last->tb_id) 3701 break; 3702 fib4_entry = last; 3703 } 3704 3705 if (fib4_entry) 3706 list_add(&new4_entry->common.list, 3707 &fib4_entry->common.list); 3708 else 3709 list_add(&new4_entry->common.list, 3710 &fib_node->entry_list); 3711 } 3712 3713 return 0; 3714 } 3715 3716 static void 3717 mlxsw_sp_fib4_node_list_remove(struct mlxsw_sp_fib4_entry *fib4_entry) 3718 { 3719 list_del(&fib4_entry->common.list); 3720 } 3721 3722 static int mlxsw_sp_fib_node_entry_add(struct mlxsw_sp *mlxsw_sp, 3723 struct mlxsw_sp_fib_entry *fib_entry) 3724 { 3725 struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node; 3726 3727 if (!mlxsw_sp_fib_node_entry_is_first(fib_node, fib_entry)) 3728 return 0; 3729 3730 /* To prevent packet loss, overwrite the previously offloaded 3731 * entry. 3732 */ 3733 if (!list_is_singular(&fib_node->entry_list)) { 3734 enum mlxsw_reg_ralue_op op = MLXSW_REG_RALUE_OP_WRITE_DELETE; 3735 struct mlxsw_sp_fib_entry *n = list_next_entry(fib_entry, list); 3736 3737 mlxsw_sp_fib_entry_offload_refresh(n, op, 0); 3738 } 3739 3740 return mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry); 3741 } 3742 3743 static void mlxsw_sp_fib_node_entry_del(struct mlxsw_sp *mlxsw_sp, 3744 struct mlxsw_sp_fib_entry *fib_entry) 3745 { 3746 struct mlxsw_sp_fib_node *fib_node = fib_entry->fib_node; 3747 3748 if (!mlxsw_sp_fib_node_entry_is_first(fib_node, fib_entry)) 3749 return; 3750 3751 /* Promote the next entry by overwriting the deleted entry */ 3752 if (!list_is_singular(&fib_node->entry_list)) { 3753 struct mlxsw_sp_fib_entry *n = list_next_entry(fib_entry, list); 3754 enum mlxsw_reg_ralue_op op = MLXSW_REG_RALUE_OP_WRITE_DELETE; 3755 3756 mlxsw_sp_fib_entry_update(mlxsw_sp, n); 3757 mlxsw_sp_fib_entry_offload_refresh(fib_entry, op, 0); 3758 return; 3759 } 3760 3761 mlxsw_sp_fib_entry_del(mlxsw_sp, fib_entry); 3762 } 3763 3764 static int mlxsw_sp_fib4_node_entry_link(struct mlxsw_sp *mlxsw_sp, 3765 struct mlxsw_sp_fib4_entry *fib4_entry, 3766 bool replace, bool append) 3767 { 3768 int err; 3769 3770 err = mlxsw_sp_fib4_node_list_insert(fib4_entry, replace, append); 3771 if (err) 3772 return err; 3773 3774 err = mlxsw_sp_fib_node_entry_add(mlxsw_sp, &fib4_entry->common); 3775 if (err) 3776 goto err_fib_node_entry_add; 3777 3778 return 0; 3779 3780 err_fib_node_entry_add: 3781 mlxsw_sp_fib4_node_list_remove(fib4_entry); 3782 return err; 3783 } 3784 3785 static void 3786 mlxsw_sp_fib4_node_entry_unlink(struct mlxsw_sp *mlxsw_sp, 3787 struct mlxsw_sp_fib4_entry *fib4_entry) 3788 { 3789 mlxsw_sp_fib_node_entry_del(mlxsw_sp, &fib4_entry->common); 3790 mlxsw_sp_fib4_node_list_remove(fib4_entry); 3791 3792 if (fib4_entry->common.type == MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP) 3793 mlxsw_sp_fib_entry_decap_fini(mlxsw_sp, &fib4_entry->common); 3794 } 3795 3796 static void mlxsw_sp_fib4_entry_replace(struct mlxsw_sp *mlxsw_sp, 3797 struct mlxsw_sp_fib4_entry *fib4_entry, 3798 bool replace) 3799 { 3800 struct mlxsw_sp_fib_node *fib_node = fib4_entry->common.fib_node; 3801 struct mlxsw_sp_fib4_entry *replaced; 3802 3803 if (!replace) 3804 return; 3805 3806 /* We inserted the new entry before replaced one */ 3807 replaced = list_next_entry(fib4_entry, common.list); 3808 3809 mlxsw_sp_fib4_node_entry_unlink(mlxsw_sp, replaced); 3810 mlxsw_sp_fib4_entry_destroy(mlxsw_sp, replaced); 3811 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 3812 } 3813 3814 static int 3815 mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp, 3816 const struct fib_entry_notifier_info *fen_info, 3817 bool replace, bool append) 3818 { 3819 struct mlxsw_sp_fib4_entry *fib4_entry; 3820 struct mlxsw_sp_fib_node *fib_node; 3821 int err; 3822 3823 if (mlxsw_sp->router->aborted) 3824 return 0; 3825 3826 fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, fen_info->tb_id, 3827 &fen_info->dst, sizeof(fen_info->dst), 3828 fen_info->dst_len, 3829 MLXSW_SP_L3_PROTO_IPV4); 3830 if (IS_ERR(fib_node)) { 3831 dev_warn(mlxsw_sp->bus_info->dev, "Failed to get FIB node\n"); 3832 return PTR_ERR(fib_node); 3833 } 3834 3835 fib4_entry = mlxsw_sp_fib4_entry_create(mlxsw_sp, fib_node, fen_info); 3836 if (IS_ERR(fib4_entry)) { 3837 dev_warn(mlxsw_sp->bus_info->dev, "Failed to create FIB entry\n"); 3838 err = PTR_ERR(fib4_entry); 3839 goto err_fib4_entry_create; 3840 } 3841 3842 err = mlxsw_sp_fib4_node_entry_link(mlxsw_sp, fib4_entry, replace, 3843 append); 3844 if (err) { 3845 dev_warn(mlxsw_sp->bus_info->dev, "Failed to link FIB entry to node\n"); 3846 goto err_fib4_node_entry_link; 3847 } 3848 3849 mlxsw_sp_fib4_entry_replace(mlxsw_sp, fib4_entry, replace); 3850 3851 return 0; 3852 3853 err_fib4_node_entry_link: 3854 mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry); 3855 err_fib4_entry_create: 3856 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 3857 return err; 3858 } 3859 3860 static void mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp, 3861 struct fib_entry_notifier_info *fen_info) 3862 { 3863 struct mlxsw_sp_fib4_entry *fib4_entry; 3864 struct mlxsw_sp_fib_node *fib_node; 3865 3866 if (mlxsw_sp->router->aborted) 3867 return; 3868 3869 fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info); 3870 if (WARN_ON(!fib4_entry)) 3871 return; 3872 fib_node = fib4_entry->common.fib_node; 3873 3874 mlxsw_sp_fib4_node_entry_unlink(mlxsw_sp, fib4_entry); 3875 mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry); 3876 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 3877 } 3878 3879 static bool mlxsw_sp_fib6_rt_should_ignore(const struct rt6_info *rt) 3880 { 3881 /* Packets with link-local destination IP arriving to the router 3882 * are trapped to the CPU, so no need to program specific routes 3883 * for them. 3884 */ 3885 if (ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LINKLOCAL) 3886 return true; 3887 3888 /* Multicast routes aren't supported, so ignore them. Neighbour 3889 * Discovery packets are specifically trapped. 3890 */ 3891 if (ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_MULTICAST) 3892 return true; 3893 3894 /* Cloned routes are irrelevant in the forwarding path. */ 3895 if (rt->rt6i_flags & RTF_CACHE) 3896 return true; 3897 3898 return false; 3899 } 3900 3901 static struct mlxsw_sp_rt6 *mlxsw_sp_rt6_create(struct rt6_info *rt) 3902 { 3903 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 3904 3905 mlxsw_sp_rt6 = kzalloc(sizeof(*mlxsw_sp_rt6), GFP_KERNEL); 3906 if (!mlxsw_sp_rt6) 3907 return ERR_PTR(-ENOMEM); 3908 3909 /* In case of route replace, replaced route is deleted with 3910 * no notification. Take reference to prevent accessing freed 3911 * memory. 3912 */ 3913 mlxsw_sp_rt6->rt = rt; 3914 rt6_hold(rt); 3915 3916 return mlxsw_sp_rt6; 3917 } 3918 3919 #if IS_ENABLED(CONFIG_IPV6) 3920 static void mlxsw_sp_rt6_release(struct rt6_info *rt) 3921 { 3922 rt6_release(rt); 3923 } 3924 #else 3925 static void mlxsw_sp_rt6_release(struct rt6_info *rt) 3926 { 3927 } 3928 #endif 3929 3930 static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6) 3931 { 3932 mlxsw_sp_rt6_release(mlxsw_sp_rt6->rt); 3933 kfree(mlxsw_sp_rt6); 3934 } 3935 3936 static bool mlxsw_sp_fib6_rt_can_mp(const struct rt6_info *rt) 3937 { 3938 /* RTF_CACHE routes are ignored */ 3939 return (rt->rt6i_flags & (RTF_GATEWAY | RTF_ADDRCONF)) == RTF_GATEWAY; 3940 } 3941 3942 static struct rt6_info * 3943 mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry) 3944 { 3945 return list_first_entry(&fib6_entry->rt6_list, struct mlxsw_sp_rt6, 3946 list)->rt; 3947 } 3948 3949 static struct mlxsw_sp_fib6_entry * 3950 mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node, 3951 const struct rt6_info *nrt, bool replace) 3952 { 3953 struct mlxsw_sp_fib6_entry *fib6_entry; 3954 3955 if (!mlxsw_sp_fib6_rt_can_mp(nrt) || replace) 3956 return NULL; 3957 3958 list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) { 3959 struct rt6_info *rt = mlxsw_sp_fib6_entry_rt(fib6_entry); 3960 3961 /* RT6_TABLE_LOCAL and RT6_TABLE_MAIN share the same 3962 * virtual router. 3963 */ 3964 if (rt->rt6i_table->tb6_id > nrt->rt6i_table->tb6_id) 3965 continue; 3966 if (rt->rt6i_table->tb6_id != nrt->rt6i_table->tb6_id) 3967 break; 3968 if (rt->rt6i_metric < nrt->rt6i_metric) 3969 continue; 3970 if (rt->rt6i_metric == nrt->rt6i_metric && 3971 mlxsw_sp_fib6_rt_can_mp(rt)) 3972 return fib6_entry; 3973 if (rt->rt6i_metric > nrt->rt6i_metric) 3974 break; 3975 } 3976 3977 return NULL; 3978 } 3979 3980 static struct mlxsw_sp_rt6 * 3981 mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry, 3982 const struct rt6_info *rt) 3983 { 3984 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 3985 3986 list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list) { 3987 if (mlxsw_sp_rt6->rt == rt) 3988 return mlxsw_sp_rt6; 3989 } 3990 3991 return NULL; 3992 } 3993 3994 static bool mlxsw_sp_nexthop6_ipip_type(const struct mlxsw_sp *mlxsw_sp, 3995 const struct rt6_info *rt, 3996 enum mlxsw_sp_ipip_type *ret) 3997 { 3998 return rt->dst.dev && 3999 mlxsw_sp_netdev_ipip_type(mlxsw_sp, rt->dst.dev, ret); 4000 } 4001 4002 static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, 4003 struct mlxsw_sp_nexthop_group *nh_grp, 4004 struct mlxsw_sp_nexthop *nh, 4005 const struct rt6_info *rt) 4006 { 4007 struct mlxsw_sp_router *router = mlxsw_sp->router; 4008 struct net_device *dev = rt->dst.dev; 4009 enum mlxsw_sp_ipip_type ipipt; 4010 struct mlxsw_sp_rif *rif; 4011 int err; 4012 4013 if (mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, &ipipt) && 4014 router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, 4015 MLXSW_SP_L3_PROTO_IPV6)) { 4016 nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; 4017 err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); 4018 if (err) 4019 return err; 4020 mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); 4021 return 0; 4022 } 4023 4024 nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; 4025 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); 4026 if (!rif) 4027 return 0; 4028 mlxsw_sp_nexthop_rif_init(nh, rif); 4029 4030 err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh); 4031 if (err) 4032 goto err_nexthop_neigh_init; 4033 4034 return 0; 4035 4036 err_nexthop_neigh_init: 4037 mlxsw_sp_nexthop_rif_fini(nh); 4038 return err; 4039 } 4040 4041 static void mlxsw_sp_nexthop6_type_fini(struct mlxsw_sp *mlxsw_sp, 4042 struct mlxsw_sp_nexthop *nh) 4043 { 4044 mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh); 4045 } 4046 4047 static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp, 4048 struct mlxsw_sp_nexthop_group *nh_grp, 4049 struct mlxsw_sp_nexthop *nh, 4050 const struct rt6_info *rt) 4051 { 4052 struct net_device *dev = rt->dst.dev; 4053 4054 nh->nh_grp = nh_grp; 4055 memcpy(&nh->gw_addr, &rt->rt6i_gateway, sizeof(nh->gw_addr)); 4056 4057 if (!dev) 4058 return 0; 4059 nh->ifindex = dev->ifindex; 4060 4061 return mlxsw_sp_nexthop6_type_init(mlxsw_sp, nh_grp, nh, rt); 4062 } 4063 4064 static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp, 4065 struct mlxsw_sp_nexthop *nh) 4066 { 4067 mlxsw_sp_nexthop6_type_fini(mlxsw_sp, nh); 4068 } 4069 4070 static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp, 4071 const struct rt6_info *rt) 4072 { 4073 return rt->rt6i_flags & RTF_GATEWAY || 4074 mlxsw_sp_nexthop6_ipip_type(mlxsw_sp, rt, NULL); 4075 } 4076 4077 static struct mlxsw_sp_nexthop_group * 4078 mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp, 4079 struct mlxsw_sp_fib6_entry *fib6_entry) 4080 { 4081 struct mlxsw_sp_nexthop_group *nh_grp; 4082 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 4083 struct mlxsw_sp_nexthop *nh; 4084 size_t alloc_size; 4085 int i = 0; 4086 int err; 4087 4088 alloc_size = sizeof(*nh_grp) + 4089 fib6_entry->nrt6 * sizeof(struct mlxsw_sp_nexthop); 4090 nh_grp = kzalloc(alloc_size, GFP_KERNEL); 4091 if (!nh_grp) 4092 return ERR_PTR(-ENOMEM); 4093 INIT_LIST_HEAD(&nh_grp->fib_list); 4094 #if IS_ENABLED(CONFIG_IPV6) 4095 nh_grp->neigh_tbl = &nd_tbl; 4096 #endif 4097 mlxsw_sp_rt6 = list_first_entry(&fib6_entry->rt6_list, 4098 struct mlxsw_sp_rt6, list); 4099 nh_grp->gateway = mlxsw_sp_rt6_is_gateway(mlxsw_sp, mlxsw_sp_rt6->rt); 4100 nh_grp->count = fib6_entry->nrt6; 4101 for (i = 0; i < nh_grp->count; i++) { 4102 struct rt6_info *rt = mlxsw_sp_rt6->rt; 4103 4104 nh = &nh_grp->nexthops[i]; 4105 err = mlxsw_sp_nexthop6_init(mlxsw_sp, nh_grp, nh, rt); 4106 if (err) 4107 goto err_nexthop6_init; 4108 mlxsw_sp_rt6 = list_next_entry(mlxsw_sp_rt6, list); 4109 } 4110 4111 err = mlxsw_sp_nexthop_group_insert(mlxsw_sp, nh_grp); 4112 if (err) 4113 goto err_nexthop_group_insert; 4114 4115 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 4116 return nh_grp; 4117 4118 err_nexthop_group_insert: 4119 err_nexthop6_init: 4120 for (i--; i >= 0; i--) { 4121 nh = &nh_grp->nexthops[i]; 4122 mlxsw_sp_nexthop6_fini(mlxsw_sp, nh); 4123 } 4124 kfree(nh_grp); 4125 return ERR_PTR(err); 4126 } 4127 4128 static void 4129 mlxsw_sp_nexthop6_group_destroy(struct mlxsw_sp *mlxsw_sp, 4130 struct mlxsw_sp_nexthop_group *nh_grp) 4131 { 4132 struct mlxsw_sp_nexthop *nh; 4133 int i = nh_grp->count; 4134 4135 mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp); 4136 for (i--; i >= 0; i--) { 4137 nh = &nh_grp->nexthops[i]; 4138 mlxsw_sp_nexthop6_fini(mlxsw_sp, nh); 4139 } 4140 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 4141 WARN_ON(nh_grp->adj_index_valid); 4142 kfree(nh_grp); 4143 } 4144 4145 static int mlxsw_sp_nexthop6_group_get(struct mlxsw_sp *mlxsw_sp, 4146 struct mlxsw_sp_fib6_entry *fib6_entry) 4147 { 4148 struct mlxsw_sp_nexthop_group *nh_grp; 4149 4150 nh_grp = mlxsw_sp_nexthop6_group_lookup(mlxsw_sp, fib6_entry); 4151 if (!nh_grp) { 4152 nh_grp = mlxsw_sp_nexthop6_group_create(mlxsw_sp, fib6_entry); 4153 if (IS_ERR(nh_grp)) 4154 return PTR_ERR(nh_grp); 4155 } 4156 4157 list_add_tail(&fib6_entry->common.nexthop_group_node, 4158 &nh_grp->fib_list); 4159 fib6_entry->common.nh_group = nh_grp; 4160 4161 return 0; 4162 } 4163 4164 static void mlxsw_sp_nexthop6_group_put(struct mlxsw_sp *mlxsw_sp, 4165 struct mlxsw_sp_fib_entry *fib_entry) 4166 { 4167 struct mlxsw_sp_nexthop_group *nh_grp = fib_entry->nh_group; 4168 4169 list_del(&fib_entry->nexthop_group_node); 4170 if (!list_empty(&nh_grp->fib_list)) 4171 return; 4172 mlxsw_sp_nexthop6_group_destroy(mlxsw_sp, nh_grp); 4173 } 4174 4175 static int 4176 mlxsw_sp_nexthop6_group_update(struct mlxsw_sp *mlxsw_sp, 4177 struct mlxsw_sp_fib6_entry *fib6_entry) 4178 { 4179 struct mlxsw_sp_nexthop_group *old_nh_grp = fib6_entry->common.nh_group; 4180 int err; 4181 4182 fib6_entry->common.nh_group = NULL; 4183 list_del(&fib6_entry->common.nexthop_group_node); 4184 4185 err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry); 4186 if (err) 4187 goto err_nexthop6_group_get; 4188 4189 /* In case this entry is offloaded, then the adjacency index 4190 * currently associated with it in the device's table is that 4191 * of the old group. Start using the new one instead. 4192 */ 4193 err = mlxsw_sp_fib_node_entry_add(mlxsw_sp, &fib6_entry->common); 4194 if (err) 4195 goto err_fib_node_entry_add; 4196 4197 if (list_empty(&old_nh_grp->fib_list)) 4198 mlxsw_sp_nexthop6_group_destroy(mlxsw_sp, old_nh_grp); 4199 4200 return 0; 4201 4202 err_fib_node_entry_add: 4203 mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common); 4204 err_nexthop6_group_get: 4205 list_add_tail(&fib6_entry->common.nexthop_group_node, 4206 &old_nh_grp->fib_list); 4207 fib6_entry->common.nh_group = old_nh_grp; 4208 return err; 4209 } 4210 4211 static int 4212 mlxsw_sp_fib6_entry_nexthop_add(struct mlxsw_sp *mlxsw_sp, 4213 struct mlxsw_sp_fib6_entry *fib6_entry, 4214 struct rt6_info *rt) 4215 { 4216 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 4217 int err; 4218 4219 mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt); 4220 if (IS_ERR(mlxsw_sp_rt6)) 4221 return PTR_ERR(mlxsw_sp_rt6); 4222 4223 list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list); 4224 fib6_entry->nrt6++; 4225 4226 err = mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry); 4227 if (err) 4228 goto err_nexthop6_group_update; 4229 4230 return 0; 4231 4232 err_nexthop6_group_update: 4233 fib6_entry->nrt6--; 4234 list_del(&mlxsw_sp_rt6->list); 4235 mlxsw_sp_rt6_destroy(mlxsw_sp_rt6); 4236 return err; 4237 } 4238 4239 static void 4240 mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp, 4241 struct mlxsw_sp_fib6_entry *fib6_entry, 4242 struct rt6_info *rt) 4243 { 4244 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 4245 4246 mlxsw_sp_rt6 = mlxsw_sp_fib6_entry_rt_find(fib6_entry, rt); 4247 if (WARN_ON(!mlxsw_sp_rt6)) 4248 return; 4249 4250 fib6_entry->nrt6--; 4251 list_del(&mlxsw_sp_rt6->list); 4252 mlxsw_sp_nexthop6_group_update(mlxsw_sp, fib6_entry); 4253 mlxsw_sp_rt6_destroy(mlxsw_sp_rt6); 4254 } 4255 4256 static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp *mlxsw_sp, 4257 struct mlxsw_sp_fib_entry *fib_entry, 4258 const struct rt6_info *rt) 4259 { 4260 /* Packets hitting RTF_REJECT routes need to be discarded by the 4261 * stack. We can rely on their destination device not having a 4262 * RIF (it's the loopback device) and can thus use action type 4263 * local, which will cause them to be trapped with a lower 4264 * priority than packets that need to be locally received. 4265 */ 4266 if (rt->rt6i_flags & (RTF_LOCAL | RTF_ANYCAST)) 4267 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP; 4268 else if (rt->rt6i_flags & RTF_REJECT) 4269 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; 4270 else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt)) 4271 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE; 4272 else 4273 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; 4274 } 4275 4276 static void 4277 mlxsw_sp_fib6_entry_rt_destroy_all(struct mlxsw_sp_fib6_entry *fib6_entry) 4278 { 4279 struct mlxsw_sp_rt6 *mlxsw_sp_rt6, *tmp; 4280 4281 list_for_each_entry_safe(mlxsw_sp_rt6, tmp, &fib6_entry->rt6_list, 4282 list) { 4283 fib6_entry->nrt6--; 4284 list_del(&mlxsw_sp_rt6->list); 4285 mlxsw_sp_rt6_destroy(mlxsw_sp_rt6); 4286 } 4287 } 4288 4289 static struct mlxsw_sp_fib6_entry * 4290 mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp, 4291 struct mlxsw_sp_fib_node *fib_node, 4292 struct rt6_info *rt) 4293 { 4294 struct mlxsw_sp_fib6_entry *fib6_entry; 4295 struct mlxsw_sp_fib_entry *fib_entry; 4296 struct mlxsw_sp_rt6 *mlxsw_sp_rt6; 4297 int err; 4298 4299 fib6_entry = kzalloc(sizeof(*fib6_entry), GFP_KERNEL); 4300 if (!fib6_entry) 4301 return ERR_PTR(-ENOMEM); 4302 fib_entry = &fib6_entry->common; 4303 4304 mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt); 4305 if (IS_ERR(mlxsw_sp_rt6)) { 4306 err = PTR_ERR(mlxsw_sp_rt6); 4307 goto err_rt6_create; 4308 } 4309 4310 mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, mlxsw_sp_rt6->rt); 4311 4312 INIT_LIST_HEAD(&fib6_entry->rt6_list); 4313 list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list); 4314 fib6_entry->nrt6 = 1; 4315 err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry); 4316 if (err) 4317 goto err_nexthop6_group_get; 4318 4319 fib_entry->fib_node = fib_node; 4320 4321 return fib6_entry; 4322 4323 err_nexthop6_group_get: 4324 list_del(&mlxsw_sp_rt6->list); 4325 mlxsw_sp_rt6_destroy(mlxsw_sp_rt6); 4326 err_rt6_create: 4327 kfree(fib6_entry); 4328 return ERR_PTR(err); 4329 } 4330 4331 static void mlxsw_sp_fib6_entry_destroy(struct mlxsw_sp *mlxsw_sp, 4332 struct mlxsw_sp_fib6_entry *fib6_entry) 4333 { 4334 mlxsw_sp_nexthop6_group_put(mlxsw_sp, &fib6_entry->common); 4335 mlxsw_sp_fib6_entry_rt_destroy_all(fib6_entry); 4336 WARN_ON(fib6_entry->nrt6); 4337 kfree(fib6_entry); 4338 } 4339 4340 static struct mlxsw_sp_fib6_entry * 4341 mlxsw_sp_fib6_node_entry_find(const struct mlxsw_sp_fib_node *fib_node, 4342 const struct rt6_info *nrt, bool replace) 4343 { 4344 struct mlxsw_sp_fib6_entry *fib6_entry, *fallback = NULL; 4345 4346 list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) { 4347 struct rt6_info *rt = mlxsw_sp_fib6_entry_rt(fib6_entry); 4348 4349 if (rt->rt6i_table->tb6_id > nrt->rt6i_table->tb6_id) 4350 continue; 4351 if (rt->rt6i_table->tb6_id != nrt->rt6i_table->tb6_id) 4352 break; 4353 if (replace && rt->rt6i_metric == nrt->rt6i_metric) { 4354 if (mlxsw_sp_fib6_rt_can_mp(rt) == 4355 mlxsw_sp_fib6_rt_can_mp(nrt)) 4356 return fib6_entry; 4357 if (mlxsw_sp_fib6_rt_can_mp(nrt)) 4358 fallback = fallback ?: fib6_entry; 4359 } 4360 if (rt->rt6i_metric > nrt->rt6i_metric) 4361 return fallback ?: fib6_entry; 4362 } 4363 4364 return fallback; 4365 } 4366 4367 static int 4368 mlxsw_sp_fib6_node_list_insert(struct mlxsw_sp_fib6_entry *new6_entry, 4369 bool replace) 4370 { 4371 struct mlxsw_sp_fib_node *fib_node = new6_entry->common.fib_node; 4372 struct rt6_info *nrt = mlxsw_sp_fib6_entry_rt(new6_entry); 4373 struct mlxsw_sp_fib6_entry *fib6_entry; 4374 4375 fib6_entry = mlxsw_sp_fib6_node_entry_find(fib_node, nrt, replace); 4376 4377 if (replace && WARN_ON(!fib6_entry)) 4378 return -EINVAL; 4379 4380 if (fib6_entry) { 4381 list_add_tail(&new6_entry->common.list, 4382 &fib6_entry->common.list); 4383 } else { 4384 struct mlxsw_sp_fib6_entry *last; 4385 4386 list_for_each_entry(last, &fib_node->entry_list, common.list) { 4387 struct rt6_info *rt = mlxsw_sp_fib6_entry_rt(last); 4388 4389 if (nrt->rt6i_table->tb6_id > rt->rt6i_table->tb6_id) 4390 break; 4391 fib6_entry = last; 4392 } 4393 4394 if (fib6_entry) 4395 list_add(&new6_entry->common.list, 4396 &fib6_entry->common.list); 4397 else 4398 list_add(&new6_entry->common.list, 4399 &fib_node->entry_list); 4400 } 4401 4402 return 0; 4403 } 4404 4405 static void 4406 mlxsw_sp_fib6_node_list_remove(struct mlxsw_sp_fib6_entry *fib6_entry) 4407 { 4408 list_del(&fib6_entry->common.list); 4409 } 4410 4411 static int mlxsw_sp_fib6_node_entry_link(struct mlxsw_sp *mlxsw_sp, 4412 struct mlxsw_sp_fib6_entry *fib6_entry, 4413 bool replace) 4414 { 4415 int err; 4416 4417 err = mlxsw_sp_fib6_node_list_insert(fib6_entry, replace); 4418 if (err) 4419 return err; 4420 4421 err = mlxsw_sp_fib_node_entry_add(mlxsw_sp, &fib6_entry->common); 4422 if (err) 4423 goto err_fib_node_entry_add; 4424 4425 return 0; 4426 4427 err_fib_node_entry_add: 4428 mlxsw_sp_fib6_node_list_remove(fib6_entry); 4429 return err; 4430 } 4431 4432 static void 4433 mlxsw_sp_fib6_node_entry_unlink(struct mlxsw_sp *mlxsw_sp, 4434 struct mlxsw_sp_fib6_entry *fib6_entry) 4435 { 4436 mlxsw_sp_fib_node_entry_del(mlxsw_sp, &fib6_entry->common); 4437 mlxsw_sp_fib6_node_list_remove(fib6_entry); 4438 } 4439 4440 static struct mlxsw_sp_fib6_entry * 4441 mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp, 4442 const struct rt6_info *rt) 4443 { 4444 struct mlxsw_sp_fib6_entry *fib6_entry; 4445 struct mlxsw_sp_fib_node *fib_node; 4446 struct mlxsw_sp_fib *fib; 4447 struct mlxsw_sp_vr *vr; 4448 4449 vr = mlxsw_sp_vr_find(mlxsw_sp, rt->rt6i_table->tb6_id); 4450 if (!vr) 4451 return NULL; 4452 fib = mlxsw_sp_vr_fib(vr, MLXSW_SP_L3_PROTO_IPV6); 4453 4454 fib_node = mlxsw_sp_fib_node_lookup(fib, &rt->rt6i_dst.addr, 4455 sizeof(rt->rt6i_dst.addr), 4456 rt->rt6i_dst.plen); 4457 if (!fib_node) 4458 return NULL; 4459 4460 list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) { 4461 struct rt6_info *iter_rt = mlxsw_sp_fib6_entry_rt(fib6_entry); 4462 4463 if (rt->rt6i_table->tb6_id == iter_rt->rt6i_table->tb6_id && 4464 rt->rt6i_metric == iter_rt->rt6i_metric && 4465 mlxsw_sp_fib6_entry_rt_find(fib6_entry, rt)) 4466 return fib6_entry; 4467 } 4468 4469 return NULL; 4470 } 4471 4472 static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp, 4473 struct mlxsw_sp_fib6_entry *fib6_entry, 4474 bool replace) 4475 { 4476 struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node; 4477 struct mlxsw_sp_fib6_entry *replaced; 4478 4479 if (!replace) 4480 return; 4481 4482 replaced = list_next_entry(fib6_entry, common.list); 4483 4484 mlxsw_sp_fib6_node_entry_unlink(mlxsw_sp, replaced); 4485 mlxsw_sp_fib6_entry_destroy(mlxsw_sp, replaced); 4486 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 4487 } 4488 4489 static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp, 4490 struct rt6_info *rt, bool replace) 4491 { 4492 struct mlxsw_sp_fib6_entry *fib6_entry; 4493 struct mlxsw_sp_fib_node *fib_node; 4494 int err; 4495 4496 if (mlxsw_sp->router->aborted) 4497 return 0; 4498 4499 if (rt->rt6i_src.plen) 4500 return -EINVAL; 4501 4502 if (mlxsw_sp_fib6_rt_should_ignore(rt)) 4503 return 0; 4504 4505 fib_node = mlxsw_sp_fib_node_get(mlxsw_sp, rt->rt6i_table->tb6_id, 4506 &rt->rt6i_dst.addr, 4507 sizeof(rt->rt6i_dst.addr), 4508 rt->rt6i_dst.plen, 4509 MLXSW_SP_L3_PROTO_IPV6); 4510 if (IS_ERR(fib_node)) 4511 return PTR_ERR(fib_node); 4512 4513 /* Before creating a new entry, try to append route to an existing 4514 * multipath entry. 4515 */ 4516 fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace); 4517 if (fib6_entry) { 4518 err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt); 4519 if (err) 4520 goto err_fib6_entry_nexthop_add; 4521 return 0; 4522 } 4523 4524 fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt); 4525 if (IS_ERR(fib6_entry)) { 4526 err = PTR_ERR(fib6_entry); 4527 goto err_fib6_entry_create; 4528 } 4529 4530 err = mlxsw_sp_fib6_node_entry_link(mlxsw_sp, fib6_entry, replace); 4531 if (err) 4532 goto err_fib6_node_entry_link; 4533 4534 mlxsw_sp_fib6_entry_replace(mlxsw_sp, fib6_entry, replace); 4535 4536 return 0; 4537 4538 err_fib6_node_entry_link: 4539 mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry); 4540 err_fib6_entry_create: 4541 err_fib6_entry_nexthop_add: 4542 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 4543 return err; 4544 } 4545 4546 static void mlxsw_sp_router_fib6_del(struct mlxsw_sp *mlxsw_sp, 4547 struct rt6_info *rt) 4548 { 4549 struct mlxsw_sp_fib6_entry *fib6_entry; 4550 struct mlxsw_sp_fib_node *fib_node; 4551 4552 if (mlxsw_sp->router->aborted) 4553 return; 4554 4555 if (mlxsw_sp_fib6_rt_should_ignore(rt)) 4556 return; 4557 4558 fib6_entry = mlxsw_sp_fib6_entry_lookup(mlxsw_sp, rt); 4559 if (WARN_ON(!fib6_entry)) 4560 return; 4561 4562 /* If route is part of a multipath entry, but not the last one 4563 * removed, then only reduce its nexthop group. 4564 */ 4565 if (!list_is_singular(&fib6_entry->rt6_list)) { 4566 mlxsw_sp_fib6_entry_nexthop_del(mlxsw_sp, fib6_entry, rt); 4567 return; 4568 } 4569 4570 fib_node = fib6_entry->common.fib_node; 4571 4572 mlxsw_sp_fib6_node_entry_unlink(mlxsw_sp, fib6_entry); 4573 mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry); 4574 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 4575 } 4576 4577 static int __mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp, 4578 enum mlxsw_reg_ralxx_protocol proto, 4579 u8 tree_id) 4580 { 4581 char ralta_pl[MLXSW_REG_RALTA_LEN]; 4582 char ralst_pl[MLXSW_REG_RALST_LEN]; 4583 int i, err; 4584 4585 mlxsw_reg_ralta_pack(ralta_pl, true, proto, tree_id); 4586 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralta), ralta_pl); 4587 if (err) 4588 return err; 4589 4590 mlxsw_reg_ralst_pack(ralst_pl, 0xff, tree_id); 4591 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralst), ralst_pl); 4592 if (err) 4593 return err; 4594 4595 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 4596 struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i]; 4597 char raltb_pl[MLXSW_REG_RALTB_LEN]; 4598 char ralue_pl[MLXSW_REG_RALUE_LEN]; 4599 4600 mlxsw_reg_raltb_pack(raltb_pl, vr->id, proto, tree_id); 4601 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(raltb), 4602 raltb_pl); 4603 if (err) 4604 return err; 4605 4606 mlxsw_reg_ralue_pack(ralue_pl, proto, 4607 MLXSW_REG_RALUE_OP_WRITE_WRITE, vr->id, 0); 4608 mlxsw_reg_ralue_act_ip2me_pack(ralue_pl); 4609 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ralue), 4610 ralue_pl); 4611 if (err) 4612 return err; 4613 } 4614 4615 return 0; 4616 } 4617 4618 static int mlxsw_sp_router_set_abort_trap(struct mlxsw_sp *mlxsw_sp) 4619 { 4620 enum mlxsw_reg_ralxx_protocol proto = MLXSW_REG_RALXX_PROTOCOL_IPV4; 4621 int err; 4622 4623 err = __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto, 4624 MLXSW_SP_LPM_TREE_MIN); 4625 if (err) 4626 return err; 4627 4628 proto = MLXSW_REG_RALXX_PROTOCOL_IPV6; 4629 return __mlxsw_sp_router_set_abort_trap(mlxsw_sp, proto, 4630 MLXSW_SP_LPM_TREE_MIN + 1); 4631 } 4632 4633 static void mlxsw_sp_fib4_node_flush(struct mlxsw_sp *mlxsw_sp, 4634 struct mlxsw_sp_fib_node *fib_node) 4635 { 4636 struct mlxsw_sp_fib4_entry *fib4_entry, *tmp; 4637 4638 list_for_each_entry_safe(fib4_entry, tmp, &fib_node->entry_list, 4639 common.list) { 4640 bool do_break = &tmp->common.list == &fib_node->entry_list; 4641 4642 mlxsw_sp_fib4_node_entry_unlink(mlxsw_sp, fib4_entry); 4643 mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry); 4644 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 4645 /* Break when entry list is empty and node was freed. 4646 * Otherwise, we'll access freed memory in the next 4647 * iteration. 4648 */ 4649 if (do_break) 4650 break; 4651 } 4652 } 4653 4654 static void mlxsw_sp_fib6_node_flush(struct mlxsw_sp *mlxsw_sp, 4655 struct mlxsw_sp_fib_node *fib_node) 4656 { 4657 struct mlxsw_sp_fib6_entry *fib6_entry, *tmp; 4658 4659 list_for_each_entry_safe(fib6_entry, tmp, &fib_node->entry_list, 4660 common.list) { 4661 bool do_break = &tmp->common.list == &fib_node->entry_list; 4662 4663 mlxsw_sp_fib6_node_entry_unlink(mlxsw_sp, fib6_entry); 4664 mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry); 4665 mlxsw_sp_fib_node_put(mlxsw_sp, fib_node); 4666 if (do_break) 4667 break; 4668 } 4669 } 4670 4671 static void mlxsw_sp_fib_node_flush(struct mlxsw_sp *mlxsw_sp, 4672 struct mlxsw_sp_fib_node *fib_node) 4673 { 4674 switch (fib_node->fib->proto) { 4675 case MLXSW_SP_L3_PROTO_IPV4: 4676 mlxsw_sp_fib4_node_flush(mlxsw_sp, fib_node); 4677 break; 4678 case MLXSW_SP_L3_PROTO_IPV6: 4679 mlxsw_sp_fib6_node_flush(mlxsw_sp, fib_node); 4680 break; 4681 } 4682 } 4683 4684 static void mlxsw_sp_vr_fib_flush(struct mlxsw_sp *mlxsw_sp, 4685 struct mlxsw_sp_vr *vr, 4686 enum mlxsw_sp_l3proto proto) 4687 { 4688 struct mlxsw_sp_fib *fib = mlxsw_sp_vr_fib(vr, proto); 4689 struct mlxsw_sp_fib_node *fib_node, *tmp; 4690 4691 list_for_each_entry_safe(fib_node, tmp, &fib->node_list, list) { 4692 bool do_break = &tmp->list == &fib->node_list; 4693 4694 mlxsw_sp_fib_node_flush(mlxsw_sp, fib_node); 4695 if (do_break) 4696 break; 4697 } 4698 } 4699 4700 static void mlxsw_sp_router_fib_flush(struct mlxsw_sp *mlxsw_sp) 4701 { 4702 int i; 4703 4704 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); i++) { 4705 struct mlxsw_sp_vr *vr = &mlxsw_sp->router->vrs[i]; 4706 4707 if (!mlxsw_sp_vr_is_used(vr)) 4708 continue; 4709 mlxsw_sp_vr_fib_flush(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV4); 4710 4711 /* If virtual router was only used for IPv4, then it's no 4712 * longer used. 4713 */ 4714 if (!mlxsw_sp_vr_is_used(vr)) 4715 continue; 4716 mlxsw_sp_vr_fib_flush(mlxsw_sp, vr, MLXSW_SP_L3_PROTO_IPV6); 4717 } 4718 } 4719 4720 static void mlxsw_sp_router_fib_abort(struct mlxsw_sp *mlxsw_sp) 4721 { 4722 int err; 4723 4724 if (mlxsw_sp->router->aborted) 4725 return; 4726 dev_warn(mlxsw_sp->bus_info->dev, "FIB abort triggered. Note that FIB entries are no longer being offloaded to this device.\n"); 4727 mlxsw_sp_router_fib_flush(mlxsw_sp); 4728 mlxsw_sp->router->aborted = true; 4729 err = mlxsw_sp_router_set_abort_trap(mlxsw_sp); 4730 if (err) 4731 dev_warn(mlxsw_sp->bus_info->dev, "Failed to set abort trap.\n"); 4732 } 4733 4734 struct mlxsw_sp_fib_event_work { 4735 struct work_struct work; 4736 union { 4737 struct fib6_entry_notifier_info fen6_info; 4738 struct fib_entry_notifier_info fen_info; 4739 struct fib_rule_notifier_info fr_info; 4740 struct fib_nh_notifier_info fnh_info; 4741 }; 4742 struct mlxsw_sp *mlxsw_sp; 4743 unsigned long event; 4744 }; 4745 4746 static void mlxsw_sp_router_fib4_event_work(struct work_struct *work) 4747 { 4748 struct mlxsw_sp_fib_event_work *fib_work = 4749 container_of(work, struct mlxsw_sp_fib_event_work, work); 4750 struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp; 4751 struct fib_rule *rule; 4752 bool replace, append; 4753 int err; 4754 4755 /* Protect internal structures from changes */ 4756 rtnl_lock(); 4757 switch (fib_work->event) { 4758 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 4759 case FIB_EVENT_ENTRY_APPEND: /* fall through */ 4760 case FIB_EVENT_ENTRY_ADD: 4761 replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE; 4762 append = fib_work->event == FIB_EVENT_ENTRY_APPEND; 4763 err = mlxsw_sp_router_fib4_add(mlxsw_sp, &fib_work->fen_info, 4764 replace, append); 4765 if (err) 4766 mlxsw_sp_router_fib_abort(mlxsw_sp); 4767 fib_info_put(fib_work->fen_info.fi); 4768 break; 4769 case FIB_EVENT_ENTRY_DEL: 4770 mlxsw_sp_router_fib4_del(mlxsw_sp, &fib_work->fen_info); 4771 fib_info_put(fib_work->fen_info.fi); 4772 break; 4773 case FIB_EVENT_RULE_ADD: /* fall through */ 4774 case FIB_EVENT_RULE_DEL: 4775 rule = fib_work->fr_info.rule; 4776 if (!fib4_rule_default(rule) && !rule->l3mdev) 4777 mlxsw_sp_router_fib_abort(mlxsw_sp); 4778 fib_rule_put(rule); 4779 break; 4780 case FIB_EVENT_NH_ADD: /* fall through */ 4781 case FIB_EVENT_NH_DEL: 4782 mlxsw_sp_nexthop4_event(mlxsw_sp, fib_work->event, 4783 fib_work->fnh_info.fib_nh); 4784 fib_info_put(fib_work->fnh_info.fib_nh->nh_parent); 4785 break; 4786 } 4787 rtnl_unlock(); 4788 kfree(fib_work); 4789 } 4790 4791 static void mlxsw_sp_router_fib6_event_work(struct work_struct *work) 4792 { 4793 struct mlxsw_sp_fib_event_work *fib_work = 4794 container_of(work, struct mlxsw_sp_fib_event_work, work); 4795 struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp; 4796 struct fib_rule *rule; 4797 bool replace; 4798 int err; 4799 4800 rtnl_lock(); 4801 switch (fib_work->event) { 4802 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 4803 case FIB_EVENT_ENTRY_ADD: 4804 replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE; 4805 err = mlxsw_sp_router_fib6_add(mlxsw_sp, 4806 fib_work->fen6_info.rt, replace); 4807 if (err) 4808 mlxsw_sp_router_fib_abort(mlxsw_sp); 4809 mlxsw_sp_rt6_release(fib_work->fen6_info.rt); 4810 break; 4811 case FIB_EVENT_ENTRY_DEL: 4812 mlxsw_sp_router_fib6_del(mlxsw_sp, fib_work->fen6_info.rt); 4813 mlxsw_sp_rt6_release(fib_work->fen6_info.rt); 4814 break; 4815 case FIB_EVENT_RULE_ADD: /* fall through */ 4816 case FIB_EVENT_RULE_DEL: 4817 rule = fib_work->fr_info.rule; 4818 if (!fib6_rule_default(rule) && !rule->l3mdev) 4819 mlxsw_sp_router_fib_abort(mlxsw_sp); 4820 fib_rule_put(rule); 4821 break; 4822 } 4823 rtnl_unlock(); 4824 kfree(fib_work); 4825 } 4826 4827 static void mlxsw_sp_router_fib4_event(struct mlxsw_sp_fib_event_work *fib_work, 4828 struct fib_notifier_info *info) 4829 { 4830 switch (fib_work->event) { 4831 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 4832 case FIB_EVENT_ENTRY_APPEND: /* fall through */ 4833 case FIB_EVENT_ENTRY_ADD: /* fall through */ 4834 case FIB_EVENT_ENTRY_DEL: 4835 memcpy(&fib_work->fen_info, info, sizeof(fib_work->fen_info)); 4836 /* Take referece on fib_info to prevent it from being 4837 * freed while work is queued. Release it afterwards. 4838 */ 4839 fib_info_hold(fib_work->fen_info.fi); 4840 break; 4841 case FIB_EVENT_RULE_ADD: /* fall through */ 4842 case FIB_EVENT_RULE_DEL: 4843 memcpy(&fib_work->fr_info, info, sizeof(fib_work->fr_info)); 4844 fib_rule_get(fib_work->fr_info.rule); 4845 break; 4846 case FIB_EVENT_NH_ADD: /* fall through */ 4847 case FIB_EVENT_NH_DEL: 4848 memcpy(&fib_work->fnh_info, info, sizeof(fib_work->fnh_info)); 4849 fib_info_hold(fib_work->fnh_info.fib_nh->nh_parent); 4850 break; 4851 } 4852 } 4853 4854 static void mlxsw_sp_router_fib6_event(struct mlxsw_sp_fib_event_work *fib_work, 4855 struct fib_notifier_info *info) 4856 { 4857 switch (fib_work->event) { 4858 case FIB_EVENT_ENTRY_REPLACE: /* fall through */ 4859 case FIB_EVENT_ENTRY_ADD: /* fall through */ 4860 case FIB_EVENT_ENTRY_DEL: 4861 memcpy(&fib_work->fen6_info, info, sizeof(fib_work->fen6_info)); 4862 rt6_hold(fib_work->fen6_info.rt); 4863 break; 4864 case FIB_EVENT_RULE_ADD: /* fall through */ 4865 case FIB_EVENT_RULE_DEL: 4866 memcpy(&fib_work->fr_info, info, sizeof(fib_work->fr_info)); 4867 fib_rule_get(fib_work->fr_info.rule); 4868 break; 4869 } 4870 } 4871 4872 /* Called with rcu_read_lock() */ 4873 static int mlxsw_sp_router_fib_event(struct notifier_block *nb, 4874 unsigned long event, void *ptr) 4875 { 4876 struct mlxsw_sp_fib_event_work *fib_work; 4877 struct fib_notifier_info *info = ptr; 4878 struct mlxsw_sp_router *router; 4879 4880 if (!net_eq(info->net, &init_net) || 4881 (info->family != AF_INET && info->family != AF_INET6)) 4882 return NOTIFY_DONE; 4883 4884 fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); 4885 if (WARN_ON(!fib_work)) 4886 return NOTIFY_BAD; 4887 4888 router = container_of(nb, struct mlxsw_sp_router, fib_nb); 4889 fib_work->mlxsw_sp = router->mlxsw_sp; 4890 fib_work->event = event; 4891 4892 switch (info->family) { 4893 case AF_INET: 4894 INIT_WORK(&fib_work->work, mlxsw_sp_router_fib4_event_work); 4895 mlxsw_sp_router_fib4_event(fib_work, info); 4896 break; 4897 case AF_INET6: 4898 INIT_WORK(&fib_work->work, mlxsw_sp_router_fib6_event_work); 4899 mlxsw_sp_router_fib6_event(fib_work, info); 4900 break; 4901 } 4902 4903 mlxsw_core_schedule_work(&fib_work->work); 4904 4905 return NOTIFY_DONE; 4906 } 4907 4908 static struct mlxsw_sp_rif * 4909 mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp, 4910 const struct net_device *dev) 4911 { 4912 int i; 4913 4914 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) 4915 if (mlxsw_sp->router->rifs[i] && 4916 mlxsw_sp->router->rifs[i]->dev == dev) 4917 return mlxsw_sp->router->rifs[i]; 4918 4919 return NULL; 4920 } 4921 4922 static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif) 4923 { 4924 char ritr_pl[MLXSW_REG_RITR_LEN]; 4925 int err; 4926 4927 mlxsw_reg_ritr_rif_pack(ritr_pl, rif); 4928 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 4929 if (WARN_ON_ONCE(err)) 4930 return err; 4931 4932 mlxsw_reg_ritr_enable_set(ritr_pl, false); 4933 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 4934 } 4935 4936 static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, 4937 struct mlxsw_sp_rif *rif) 4938 { 4939 mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index); 4940 mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif); 4941 mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif); 4942 } 4943 4944 static bool 4945 mlxsw_sp_rif_should_config(struct mlxsw_sp_rif *rif, struct net_device *dev, 4946 unsigned long event) 4947 { 4948 struct inet6_dev *inet6_dev; 4949 bool addr_list_empty = true; 4950 struct in_device *idev; 4951 4952 switch (event) { 4953 case NETDEV_UP: 4954 return rif == NULL; 4955 case NETDEV_DOWN: 4956 idev = __in_dev_get_rtnl(dev); 4957 if (idev && idev->ifa_list) 4958 addr_list_empty = false; 4959 4960 inet6_dev = __in6_dev_get(dev); 4961 if (addr_list_empty && inet6_dev && 4962 !list_empty(&inet6_dev->addr_list)) 4963 addr_list_empty = false; 4964 4965 if (rif && addr_list_empty && 4966 !netif_is_l3_slave(rif->dev)) 4967 return true; 4968 /* It is possible we already removed the RIF ourselves 4969 * if it was assigned to a netdev that is now a bridge 4970 * or LAG slave. 4971 */ 4972 return false; 4973 } 4974 4975 return false; 4976 } 4977 4978 static enum mlxsw_sp_rif_type 4979 mlxsw_sp_dev_rif_type(const struct mlxsw_sp *mlxsw_sp, 4980 const struct net_device *dev) 4981 { 4982 enum mlxsw_sp_fid_type type; 4983 4984 if (mlxsw_sp_netdev_ipip_type(mlxsw_sp, dev, NULL)) 4985 return MLXSW_SP_RIF_TYPE_IPIP_LB; 4986 4987 /* Otherwise RIF type is derived from the type of the underlying FID. */ 4988 if (is_vlan_dev(dev) && netif_is_bridge_master(vlan_dev_real_dev(dev))) 4989 type = MLXSW_SP_FID_TYPE_8021Q; 4990 else if (netif_is_bridge_master(dev) && br_vlan_enabled(dev)) 4991 type = MLXSW_SP_FID_TYPE_8021Q; 4992 else if (netif_is_bridge_master(dev)) 4993 type = MLXSW_SP_FID_TYPE_8021D; 4994 else 4995 type = MLXSW_SP_FID_TYPE_RFID; 4996 4997 return mlxsw_sp_fid_type_rif_type(mlxsw_sp, type); 4998 } 4999 5000 static int mlxsw_sp_rif_index_alloc(struct mlxsw_sp *mlxsw_sp, u16 *p_rif_index) 5001 { 5002 int i; 5003 5004 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) { 5005 if (!mlxsw_sp->router->rifs[i]) { 5006 *p_rif_index = i; 5007 return 0; 5008 } 5009 } 5010 5011 return -ENOBUFS; 5012 } 5013 5014 static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index, 5015 u16 vr_id, 5016 struct net_device *l3_dev) 5017 { 5018 struct mlxsw_sp_rif *rif; 5019 5020 rif = kzalloc(rif_size, GFP_KERNEL); 5021 if (!rif) 5022 return NULL; 5023 5024 INIT_LIST_HEAD(&rif->nexthop_list); 5025 INIT_LIST_HEAD(&rif->neigh_list); 5026 ether_addr_copy(rif->addr, l3_dev->dev_addr); 5027 rif->mtu = l3_dev->mtu; 5028 rif->vr_id = vr_id; 5029 rif->dev = l3_dev; 5030 rif->rif_index = rif_index; 5031 5032 return rif; 5033 } 5034 5035 struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, 5036 u16 rif_index) 5037 { 5038 return mlxsw_sp->router->rifs[rif_index]; 5039 } 5040 5041 u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif) 5042 { 5043 return rif->rif_index; 5044 } 5045 5046 u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *lb_rif) 5047 { 5048 return lb_rif->common.rif_index; 5049 } 5050 5051 u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif) 5052 { 5053 return lb_rif->ul_vr_id; 5054 } 5055 5056 int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif) 5057 { 5058 return rif->dev->ifindex; 5059 } 5060 5061 static struct mlxsw_sp_rif * 5062 mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, 5063 const struct mlxsw_sp_rif_params *params) 5064 { 5065 u32 tb_id = l3mdev_fib_table(params->dev); 5066 const struct mlxsw_sp_rif_ops *ops; 5067 struct mlxsw_sp_fid *fid = NULL; 5068 enum mlxsw_sp_rif_type type; 5069 struct mlxsw_sp_rif *rif; 5070 struct mlxsw_sp_vr *vr; 5071 u16 rif_index; 5072 int err; 5073 5074 type = mlxsw_sp_dev_rif_type(mlxsw_sp, params->dev); 5075 ops = mlxsw_sp->router->rif_ops_arr[type]; 5076 5077 vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN); 5078 if (IS_ERR(vr)) 5079 return ERR_CAST(vr); 5080 vr->rif_count++; 5081 5082 err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); 5083 if (err) 5084 goto err_rif_index_alloc; 5085 5086 rif = mlxsw_sp_rif_alloc(ops->rif_size, rif_index, vr->id, params->dev); 5087 if (!rif) { 5088 err = -ENOMEM; 5089 goto err_rif_alloc; 5090 } 5091 rif->mlxsw_sp = mlxsw_sp; 5092 rif->ops = ops; 5093 5094 if (ops->fid_get) { 5095 fid = ops->fid_get(rif); 5096 if (IS_ERR(fid)) { 5097 err = PTR_ERR(fid); 5098 goto err_fid_get; 5099 } 5100 rif->fid = fid; 5101 } 5102 5103 if (ops->setup) 5104 ops->setup(rif, params); 5105 5106 err = ops->configure(rif); 5107 if (err) 5108 goto err_configure; 5109 5110 mlxsw_sp_rif_counters_alloc(rif); 5111 mlxsw_sp->router->rifs[rif_index] = rif; 5112 5113 return rif; 5114 5115 err_configure: 5116 if (fid) 5117 mlxsw_sp_fid_put(fid); 5118 err_fid_get: 5119 kfree(rif); 5120 err_rif_alloc: 5121 err_rif_index_alloc: 5122 vr->rif_count--; 5123 mlxsw_sp_vr_put(vr); 5124 return ERR_PTR(err); 5125 } 5126 5127 void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) 5128 { 5129 const struct mlxsw_sp_rif_ops *ops = rif->ops; 5130 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5131 struct mlxsw_sp_fid *fid = rif->fid; 5132 struct mlxsw_sp_vr *vr; 5133 5134 mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif); 5135 vr = &mlxsw_sp->router->vrs[rif->vr_id]; 5136 5137 mlxsw_sp->router->rifs[rif->rif_index] = NULL; 5138 mlxsw_sp_rif_counters_free(rif); 5139 ops->deconfigure(rif); 5140 if (fid) 5141 /* Loopback RIFs are not associated with a FID. */ 5142 mlxsw_sp_fid_put(fid); 5143 kfree(rif); 5144 vr->rif_count--; 5145 mlxsw_sp_vr_put(vr); 5146 } 5147 5148 static void 5149 mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params, 5150 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan) 5151 { 5152 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port; 5153 5154 params->vid = mlxsw_sp_port_vlan->vid; 5155 params->lag = mlxsw_sp_port->lagged; 5156 if (params->lag) 5157 params->lag_id = mlxsw_sp_port->lag_id; 5158 else 5159 params->system_port = mlxsw_sp_port->local_port; 5160 } 5161 5162 static int 5163 mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan, 5164 struct net_device *l3_dev) 5165 { 5166 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port; 5167 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 5168 u16 vid = mlxsw_sp_port_vlan->vid; 5169 struct mlxsw_sp_rif *rif; 5170 struct mlxsw_sp_fid *fid; 5171 int err; 5172 5173 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); 5174 if (!rif) { 5175 struct mlxsw_sp_rif_params params = { 5176 .dev = l3_dev, 5177 }; 5178 5179 mlxsw_sp_rif_subport_params_init(¶ms, mlxsw_sp_port_vlan); 5180 rif = mlxsw_sp_rif_create(mlxsw_sp, ¶ms); 5181 if (IS_ERR(rif)) 5182 return PTR_ERR(rif); 5183 } 5184 5185 /* FID was already created, just take a reference */ 5186 fid = rif->ops->fid_get(rif); 5187 err = mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port, vid); 5188 if (err) 5189 goto err_fid_port_vid_map; 5190 5191 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, false); 5192 if (err) 5193 goto err_port_vid_learning_set; 5194 5195 err = mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid, 5196 BR_STATE_FORWARDING); 5197 if (err) 5198 goto err_port_vid_stp_set; 5199 5200 mlxsw_sp_port_vlan->fid = fid; 5201 5202 return 0; 5203 5204 err_port_vid_stp_set: 5205 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true); 5206 err_port_vid_learning_set: 5207 mlxsw_sp_fid_port_vid_unmap(fid, mlxsw_sp_port, vid); 5208 err_fid_port_vid_map: 5209 mlxsw_sp_fid_put(fid); 5210 return err; 5211 } 5212 5213 void 5214 mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan) 5215 { 5216 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port; 5217 struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid; 5218 u16 vid = mlxsw_sp_port_vlan->vid; 5219 5220 if (WARN_ON(mlxsw_sp_fid_type(fid) != MLXSW_SP_FID_TYPE_RFID)) 5221 return; 5222 5223 mlxsw_sp_port_vlan->fid = NULL; 5224 mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid, BR_STATE_BLOCKING); 5225 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true); 5226 mlxsw_sp_fid_port_vid_unmap(fid, mlxsw_sp_port, vid); 5227 /* If router port holds the last reference on the rFID, then the 5228 * associated Sub-port RIF will be destroyed. 5229 */ 5230 mlxsw_sp_fid_put(fid); 5231 } 5232 5233 static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev, 5234 struct net_device *port_dev, 5235 unsigned long event, u16 vid) 5236 { 5237 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(port_dev); 5238 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; 5239 5240 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid); 5241 if (WARN_ON(!mlxsw_sp_port_vlan)) 5242 return -EINVAL; 5243 5244 switch (event) { 5245 case NETDEV_UP: 5246 return mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan, 5247 l3_dev); 5248 case NETDEV_DOWN: 5249 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan); 5250 break; 5251 } 5252 5253 return 0; 5254 } 5255 5256 static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev, 5257 unsigned long event) 5258 { 5259 if (netif_is_bridge_port(port_dev) || 5260 netif_is_lag_port(port_dev) || 5261 netif_is_ovs_port(port_dev)) 5262 return 0; 5263 5264 return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event, 1); 5265 } 5266 5267 static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev, 5268 struct net_device *lag_dev, 5269 unsigned long event, u16 vid) 5270 { 5271 struct net_device *port_dev; 5272 struct list_head *iter; 5273 int err; 5274 5275 netdev_for_each_lower_dev(lag_dev, port_dev, iter) { 5276 if (mlxsw_sp_port_dev_check(port_dev)) { 5277 err = mlxsw_sp_inetaddr_port_vlan_event(l3_dev, 5278 port_dev, 5279 event, vid); 5280 if (err) 5281 return err; 5282 } 5283 } 5284 5285 return 0; 5286 } 5287 5288 static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev, 5289 unsigned long event) 5290 { 5291 if (netif_is_bridge_port(lag_dev)) 5292 return 0; 5293 5294 return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, 1); 5295 } 5296 5297 static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev, 5298 unsigned long event) 5299 { 5300 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev); 5301 struct mlxsw_sp_rif_params params = { 5302 .dev = l3_dev, 5303 }; 5304 struct mlxsw_sp_rif *rif; 5305 5306 switch (event) { 5307 case NETDEV_UP: 5308 rif = mlxsw_sp_rif_create(mlxsw_sp, ¶ms); 5309 if (IS_ERR(rif)) 5310 return PTR_ERR(rif); 5311 break; 5312 case NETDEV_DOWN: 5313 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); 5314 mlxsw_sp_rif_destroy(rif); 5315 break; 5316 } 5317 5318 return 0; 5319 } 5320 5321 static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev, 5322 unsigned long event) 5323 { 5324 struct net_device *real_dev = vlan_dev_real_dev(vlan_dev); 5325 u16 vid = vlan_dev_vlan_id(vlan_dev); 5326 5327 if (netif_is_bridge_port(vlan_dev)) 5328 return 0; 5329 5330 if (mlxsw_sp_port_dev_check(real_dev)) 5331 return mlxsw_sp_inetaddr_port_vlan_event(vlan_dev, real_dev, 5332 event, vid); 5333 else if (netif_is_lag_master(real_dev)) 5334 return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event, 5335 vid); 5336 else if (netif_is_bridge_master(real_dev) && br_vlan_enabled(real_dev)) 5337 return mlxsw_sp_inetaddr_bridge_event(vlan_dev, event); 5338 5339 return 0; 5340 } 5341 5342 static int __mlxsw_sp_inetaddr_event(struct net_device *dev, 5343 unsigned long event) 5344 { 5345 if (mlxsw_sp_port_dev_check(dev)) 5346 return mlxsw_sp_inetaddr_port_event(dev, event); 5347 else if (netif_is_lag_master(dev)) 5348 return mlxsw_sp_inetaddr_lag_event(dev, event); 5349 else if (netif_is_bridge_master(dev)) 5350 return mlxsw_sp_inetaddr_bridge_event(dev, event); 5351 else if (is_vlan_dev(dev)) 5352 return mlxsw_sp_inetaddr_vlan_event(dev, event); 5353 else 5354 return 0; 5355 } 5356 5357 int mlxsw_sp_inetaddr_event(struct notifier_block *unused, 5358 unsigned long event, void *ptr) 5359 { 5360 struct in_ifaddr *ifa = (struct in_ifaddr *) ptr; 5361 struct net_device *dev = ifa->ifa_dev->dev; 5362 struct mlxsw_sp *mlxsw_sp; 5363 struct mlxsw_sp_rif *rif; 5364 int err = 0; 5365 5366 mlxsw_sp = mlxsw_sp_lower_get(dev); 5367 if (!mlxsw_sp) 5368 goto out; 5369 5370 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); 5371 if (!mlxsw_sp_rif_should_config(rif, dev, event)) 5372 goto out; 5373 5374 err = __mlxsw_sp_inetaddr_event(dev, event); 5375 out: 5376 return notifier_from_errno(err); 5377 } 5378 5379 struct mlxsw_sp_inet6addr_event_work { 5380 struct work_struct work; 5381 struct net_device *dev; 5382 unsigned long event; 5383 }; 5384 5385 static void mlxsw_sp_inet6addr_event_work(struct work_struct *work) 5386 { 5387 struct mlxsw_sp_inet6addr_event_work *inet6addr_work = 5388 container_of(work, struct mlxsw_sp_inet6addr_event_work, work); 5389 struct net_device *dev = inet6addr_work->dev; 5390 unsigned long event = inet6addr_work->event; 5391 struct mlxsw_sp *mlxsw_sp; 5392 struct mlxsw_sp_rif *rif; 5393 5394 rtnl_lock(); 5395 mlxsw_sp = mlxsw_sp_lower_get(dev); 5396 if (!mlxsw_sp) 5397 goto out; 5398 5399 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); 5400 if (!mlxsw_sp_rif_should_config(rif, dev, event)) 5401 goto out; 5402 5403 __mlxsw_sp_inetaddr_event(dev, event); 5404 out: 5405 rtnl_unlock(); 5406 dev_put(dev); 5407 kfree(inet6addr_work); 5408 } 5409 5410 /* Called with rcu_read_lock() */ 5411 int mlxsw_sp_inet6addr_event(struct notifier_block *unused, 5412 unsigned long event, void *ptr) 5413 { 5414 struct inet6_ifaddr *if6 = (struct inet6_ifaddr *) ptr; 5415 struct mlxsw_sp_inet6addr_event_work *inet6addr_work; 5416 struct net_device *dev = if6->idev->dev; 5417 5418 if (!mlxsw_sp_port_dev_lower_find_rcu(dev)) 5419 return NOTIFY_DONE; 5420 5421 inet6addr_work = kzalloc(sizeof(*inet6addr_work), GFP_ATOMIC); 5422 if (!inet6addr_work) 5423 return NOTIFY_BAD; 5424 5425 INIT_WORK(&inet6addr_work->work, mlxsw_sp_inet6addr_event_work); 5426 inet6addr_work->dev = dev; 5427 inet6addr_work->event = event; 5428 dev_hold(dev); 5429 mlxsw_core_schedule_work(&inet6addr_work->work); 5430 5431 return NOTIFY_DONE; 5432 } 5433 5434 static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index, 5435 const char *mac, int mtu) 5436 { 5437 char ritr_pl[MLXSW_REG_RITR_LEN]; 5438 int err; 5439 5440 mlxsw_reg_ritr_rif_pack(ritr_pl, rif_index); 5441 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 5442 if (err) 5443 return err; 5444 5445 mlxsw_reg_ritr_mtu_set(ritr_pl, mtu); 5446 mlxsw_reg_ritr_if_mac_memcpy_to(ritr_pl, mac); 5447 mlxsw_reg_ritr_op_set(ritr_pl, MLXSW_REG_RITR_RIF_CREATE); 5448 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 5449 } 5450 5451 int mlxsw_sp_netdevice_router_port_event(struct net_device *dev) 5452 { 5453 struct mlxsw_sp *mlxsw_sp; 5454 struct mlxsw_sp_rif *rif; 5455 u16 fid_index; 5456 int err; 5457 5458 mlxsw_sp = mlxsw_sp_lower_get(dev); 5459 if (!mlxsw_sp) 5460 return 0; 5461 5462 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); 5463 if (!rif) 5464 return 0; 5465 fid_index = mlxsw_sp_fid_index(rif->fid); 5466 5467 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, rif->addr, fid_index, false); 5468 if (err) 5469 return err; 5470 5471 err = mlxsw_sp_rif_edit(mlxsw_sp, rif->rif_index, dev->dev_addr, 5472 dev->mtu); 5473 if (err) 5474 goto err_rif_edit; 5475 5476 err = mlxsw_sp_rif_fdb_op(mlxsw_sp, dev->dev_addr, fid_index, true); 5477 if (err) 5478 goto err_rif_fdb_op; 5479 5480 ether_addr_copy(rif->addr, dev->dev_addr); 5481 rif->mtu = dev->mtu; 5482 5483 netdev_dbg(dev, "Updated RIF=%d\n", rif->rif_index); 5484 5485 return 0; 5486 5487 err_rif_fdb_op: 5488 mlxsw_sp_rif_edit(mlxsw_sp, rif->rif_index, rif->addr, rif->mtu); 5489 err_rif_edit: 5490 mlxsw_sp_rif_fdb_op(mlxsw_sp, rif->addr, fid_index, true); 5491 return err; 5492 } 5493 5494 static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp, 5495 struct net_device *l3_dev) 5496 { 5497 struct mlxsw_sp_rif *rif; 5498 5499 /* If netdev is already associated with a RIF, then we need to 5500 * destroy it and create a new one with the new virtual router ID. 5501 */ 5502 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); 5503 if (rif) 5504 __mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN); 5505 5506 return __mlxsw_sp_inetaddr_event(l3_dev, NETDEV_UP); 5507 } 5508 5509 static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp, 5510 struct net_device *l3_dev) 5511 { 5512 struct mlxsw_sp_rif *rif; 5513 5514 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); 5515 if (!rif) 5516 return; 5517 __mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN); 5518 } 5519 5520 int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event, 5521 struct netdev_notifier_changeupper_info *info) 5522 { 5523 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev); 5524 int err = 0; 5525 5526 if (!mlxsw_sp) 5527 return 0; 5528 5529 switch (event) { 5530 case NETDEV_PRECHANGEUPPER: 5531 return 0; 5532 case NETDEV_CHANGEUPPER: 5533 if (info->linking) 5534 err = mlxsw_sp_port_vrf_join(mlxsw_sp, l3_dev); 5535 else 5536 mlxsw_sp_port_vrf_leave(mlxsw_sp, l3_dev); 5537 break; 5538 } 5539 5540 return err; 5541 } 5542 5543 static struct mlxsw_sp_rif_subport * 5544 mlxsw_sp_rif_subport_rif(const struct mlxsw_sp_rif *rif) 5545 { 5546 return container_of(rif, struct mlxsw_sp_rif_subport, common); 5547 } 5548 5549 static void mlxsw_sp_rif_subport_setup(struct mlxsw_sp_rif *rif, 5550 const struct mlxsw_sp_rif_params *params) 5551 { 5552 struct mlxsw_sp_rif_subport *rif_subport; 5553 5554 rif_subport = mlxsw_sp_rif_subport_rif(rif); 5555 rif_subport->vid = params->vid; 5556 rif_subport->lag = params->lag; 5557 if (params->lag) 5558 rif_subport->lag_id = params->lag_id; 5559 else 5560 rif_subport->system_port = params->system_port; 5561 } 5562 5563 static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable) 5564 { 5565 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5566 struct mlxsw_sp_rif_subport *rif_subport; 5567 char ritr_pl[MLXSW_REG_RITR_LEN]; 5568 5569 rif_subport = mlxsw_sp_rif_subport_rif(rif); 5570 mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_SP_IF, 5571 rif->rif_index, rif->vr_id, rif->dev->mtu); 5572 mlxsw_reg_ritr_mac_pack(ritr_pl, rif->dev->dev_addr); 5573 mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag, 5574 rif_subport->lag ? rif_subport->lag_id : 5575 rif_subport->system_port, 5576 rif_subport->vid); 5577 5578 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 5579 } 5580 5581 static int mlxsw_sp_rif_subport_configure(struct mlxsw_sp_rif *rif) 5582 { 5583 int err; 5584 5585 err = mlxsw_sp_rif_subport_op(rif, true); 5586 if (err) 5587 return err; 5588 5589 err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5590 mlxsw_sp_fid_index(rif->fid), true); 5591 if (err) 5592 goto err_rif_fdb_op; 5593 5594 mlxsw_sp_fid_rif_set(rif->fid, rif); 5595 return 0; 5596 5597 err_rif_fdb_op: 5598 mlxsw_sp_rif_subport_op(rif, false); 5599 return err; 5600 } 5601 5602 static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif) 5603 { 5604 struct mlxsw_sp_fid *fid = rif->fid; 5605 5606 mlxsw_sp_fid_rif_set(fid, NULL); 5607 mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5608 mlxsw_sp_fid_index(fid), false); 5609 mlxsw_sp_rif_subport_op(rif, false); 5610 } 5611 5612 static struct mlxsw_sp_fid * 5613 mlxsw_sp_rif_subport_fid_get(struct mlxsw_sp_rif *rif) 5614 { 5615 return mlxsw_sp_fid_rfid_get(rif->mlxsw_sp, rif->rif_index); 5616 } 5617 5618 static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_subport_ops = { 5619 .type = MLXSW_SP_RIF_TYPE_SUBPORT, 5620 .rif_size = sizeof(struct mlxsw_sp_rif_subport), 5621 .setup = mlxsw_sp_rif_subport_setup, 5622 .configure = mlxsw_sp_rif_subport_configure, 5623 .deconfigure = mlxsw_sp_rif_subport_deconfigure, 5624 .fid_get = mlxsw_sp_rif_subport_fid_get, 5625 }; 5626 5627 static int mlxsw_sp_rif_vlan_fid_op(struct mlxsw_sp_rif *rif, 5628 enum mlxsw_reg_ritr_if_type type, 5629 u16 vid_fid, bool enable) 5630 { 5631 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5632 char ritr_pl[MLXSW_REG_RITR_LEN]; 5633 5634 mlxsw_reg_ritr_pack(ritr_pl, enable, type, rif->rif_index, rif->vr_id, 5635 rif->dev->mtu); 5636 mlxsw_reg_ritr_mac_pack(ritr_pl, rif->dev->dev_addr); 5637 mlxsw_reg_ritr_fid_set(ritr_pl, type, vid_fid); 5638 5639 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 5640 } 5641 5642 static u8 mlxsw_sp_router_port(const struct mlxsw_sp *mlxsw_sp) 5643 { 5644 return mlxsw_core_max_ports(mlxsw_sp->core) + 1; 5645 } 5646 5647 static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif) 5648 { 5649 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5650 u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); 5651 int err; 5652 5653 err = mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, true); 5654 if (err) 5655 return err; 5656 5657 err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5658 mlxsw_sp_router_port(mlxsw_sp), true); 5659 if (err) 5660 goto err_fid_mc_flood_set; 5661 5662 err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5663 mlxsw_sp_router_port(mlxsw_sp), true); 5664 if (err) 5665 goto err_fid_bc_flood_set; 5666 5667 err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5668 mlxsw_sp_fid_index(rif->fid), true); 5669 if (err) 5670 goto err_rif_fdb_op; 5671 5672 mlxsw_sp_fid_rif_set(rif->fid, rif); 5673 return 0; 5674 5675 err_rif_fdb_op: 5676 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5677 mlxsw_sp_router_port(mlxsw_sp), false); 5678 err_fid_bc_flood_set: 5679 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5680 mlxsw_sp_router_port(mlxsw_sp), false); 5681 err_fid_mc_flood_set: 5682 mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, false); 5683 return err; 5684 } 5685 5686 static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif) 5687 { 5688 u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); 5689 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5690 struct mlxsw_sp_fid *fid = rif->fid; 5691 5692 mlxsw_sp_fid_rif_set(fid, NULL); 5693 mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5694 mlxsw_sp_fid_index(fid), false); 5695 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5696 mlxsw_sp_router_port(mlxsw_sp), false); 5697 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5698 mlxsw_sp_router_port(mlxsw_sp), false); 5699 mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_VLAN_IF, vid, false); 5700 } 5701 5702 static struct mlxsw_sp_fid * 5703 mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif) 5704 { 5705 u16 vid = is_vlan_dev(rif->dev) ? vlan_dev_vlan_id(rif->dev) : 1; 5706 5707 return mlxsw_sp_fid_8021q_get(rif->mlxsw_sp, vid); 5708 } 5709 5710 static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_ops = { 5711 .type = MLXSW_SP_RIF_TYPE_VLAN, 5712 .rif_size = sizeof(struct mlxsw_sp_rif), 5713 .configure = mlxsw_sp_rif_vlan_configure, 5714 .deconfigure = mlxsw_sp_rif_vlan_deconfigure, 5715 .fid_get = mlxsw_sp_rif_vlan_fid_get, 5716 }; 5717 5718 static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif) 5719 { 5720 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5721 u16 fid_index = mlxsw_sp_fid_index(rif->fid); 5722 int err; 5723 5724 err = mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, 5725 true); 5726 if (err) 5727 return err; 5728 5729 err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5730 mlxsw_sp_router_port(mlxsw_sp), true); 5731 if (err) 5732 goto err_fid_mc_flood_set; 5733 5734 err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5735 mlxsw_sp_router_port(mlxsw_sp), true); 5736 if (err) 5737 goto err_fid_bc_flood_set; 5738 5739 err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5740 mlxsw_sp_fid_index(rif->fid), true); 5741 if (err) 5742 goto err_rif_fdb_op; 5743 5744 mlxsw_sp_fid_rif_set(rif->fid, rif); 5745 return 0; 5746 5747 err_rif_fdb_op: 5748 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5749 mlxsw_sp_router_port(mlxsw_sp), false); 5750 err_fid_bc_flood_set: 5751 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5752 mlxsw_sp_router_port(mlxsw_sp), false); 5753 err_fid_mc_flood_set: 5754 mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false); 5755 return err; 5756 } 5757 5758 static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif) 5759 { 5760 u16 fid_index = mlxsw_sp_fid_index(rif->fid); 5761 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5762 struct mlxsw_sp_fid *fid = rif->fid; 5763 5764 mlxsw_sp_fid_rif_set(fid, NULL); 5765 mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, 5766 mlxsw_sp_fid_index(fid), false); 5767 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, 5768 mlxsw_sp_router_port(mlxsw_sp), false); 5769 mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, 5770 mlxsw_sp_router_port(mlxsw_sp), false); 5771 mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false); 5772 } 5773 5774 static struct mlxsw_sp_fid * 5775 mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif) 5776 { 5777 return mlxsw_sp_fid_8021d_get(rif->mlxsw_sp, rif->dev->ifindex); 5778 } 5779 5780 static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = { 5781 .type = MLXSW_SP_RIF_TYPE_FID, 5782 .rif_size = sizeof(struct mlxsw_sp_rif), 5783 .configure = mlxsw_sp_rif_fid_configure, 5784 .deconfigure = mlxsw_sp_rif_fid_deconfigure, 5785 .fid_get = mlxsw_sp_rif_fid_fid_get, 5786 }; 5787 5788 static struct mlxsw_sp_rif_ipip_lb * 5789 mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif) 5790 { 5791 return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common); 5792 } 5793 5794 static void 5795 mlxsw_sp_rif_ipip_lb_setup(struct mlxsw_sp_rif *rif, 5796 const struct mlxsw_sp_rif_params *params) 5797 { 5798 struct mlxsw_sp_rif_params_ipip_lb *params_lb; 5799 struct mlxsw_sp_rif_ipip_lb *rif_lb; 5800 5801 params_lb = container_of(params, struct mlxsw_sp_rif_params_ipip_lb, 5802 common); 5803 rif_lb = mlxsw_sp_rif_ipip_lb_rif(rif); 5804 rif_lb->lb_config = params_lb->lb_config; 5805 } 5806 5807 static int 5808 mlxsw_sp_rif_ipip_lb_op(struct mlxsw_sp_rif_ipip_lb *lb_rif, 5809 struct mlxsw_sp_vr *ul_vr, bool enable) 5810 { 5811 struct mlxsw_sp_rif_ipip_lb_config lb_cf = lb_rif->lb_config; 5812 struct mlxsw_sp_rif *rif = &lb_rif->common; 5813 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5814 char ritr_pl[MLXSW_REG_RITR_LEN]; 5815 u32 saddr4; 5816 5817 switch (lb_cf.ul_protocol) { 5818 case MLXSW_SP_L3_PROTO_IPV4: 5819 saddr4 = be32_to_cpu(lb_cf.saddr.addr4); 5820 mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_LOOPBACK_IF, 5821 rif->rif_index, rif->vr_id, rif->dev->mtu); 5822 mlxsw_reg_ritr_loopback_ipip4_pack(ritr_pl, lb_cf.lb_ipipt, 5823 MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET, 5824 ul_vr->id, saddr4, lb_cf.okey); 5825 break; 5826 5827 case MLXSW_SP_L3_PROTO_IPV6: 5828 return -EAFNOSUPPORT; 5829 } 5830 5831 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); 5832 } 5833 5834 static int 5835 mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif) 5836 { 5837 struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif); 5838 u32 ul_tb_id = mlxsw_sp_ipip_dev_ul_tb_id(rif->dev); 5839 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5840 struct mlxsw_sp_vr *ul_vr; 5841 int err; 5842 5843 ul_vr = mlxsw_sp_vr_get(mlxsw_sp, ul_tb_id); 5844 if (IS_ERR(ul_vr)) 5845 return PTR_ERR(ul_vr); 5846 5847 err = mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, true); 5848 if (err) 5849 goto err_loopback_op; 5850 5851 lb_rif->ul_vr_id = ul_vr->id; 5852 ++ul_vr->rif_count; 5853 return 0; 5854 5855 err_loopback_op: 5856 mlxsw_sp_vr_put(ul_vr); 5857 return err; 5858 } 5859 5860 static void mlxsw_sp_rif_ipip_lb_deconfigure(struct mlxsw_sp_rif *rif) 5861 { 5862 struct mlxsw_sp_rif_ipip_lb *lb_rif = mlxsw_sp_rif_ipip_lb_rif(rif); 5863 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; 5864 struct mlxsw_sp_vr *ul_vr; 5865 5866 ul_vr = &mlxsw_sp->router->vrs[lb_rif->ul_vr_id]; 5867 mlxsw_sp_rif_ipip_lb_op(lb_rif, ul_vr, false); 5868 5869 --ul_vr->rif_count; 5870 mlxsw_sp_vr_put(ul_vr); 5871 } 5872 5873 static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_ipip_lb_ops = { 5874 .type = MLXSW_SP_RIF_TYPE_IPIP_LB, 5875 .rif_size = sizeof(struct mlxsw_sp_rif_ipip_lb), 5876 .setup = mlxsw_sp_rif_ipip_lb_setup, 5877 .configure = mlxsw_sp_rif_ipip_lb_configure, 5878 .deconfigure = mlxsw_sp_rif_ipip_lb_deconfigure, 5879 }; 5880 5881 static const struct mlxsw_sp_rif_ops *mlxsw_sp_rif_ops_arr[] = { 5882 [MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops, 5883 [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_ops, 5884 [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, 5885 [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp_rif_ipip_lb_ops, 5886 }; 5887 5888 static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp) 5889 { 5890 u64 max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); 5891 5892 mlxsw_sp->router->rifs = kcalloc(max_rifs, 5893 sizeof(struct mlxsw_sp_rif *), 5894 GFP_KERNEL); 5895 if (!mlxsw_sp->router->rifs) 5896 return -ENOMEM; 5897 5898 mlxsw_sp->router->rif_ops_arr = mlxsw_sp_rif_ops_arr; 5899 5900 return 0; 5901 } 5902 5903 static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp) 5904 { 5905 int i; 5906 5907 for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) 5908 WARN_ON_ONCE(mlxsw_sp->router->rifs[i]); 5909 5910 kfree(mlxsw_sp->router->rifs); 5911 } 5912 5913 static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp) 5914 { 5915 mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr; 5916 INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list); 5917 return 0; 5918 } 5919 5920 static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp) 5921 { 5922 WARN_ON(!list_empty(&mlxsw_sp->router->ipip_list)); 5923 } 5924 5925 static void mlxsw_sp_router_fib_dump_flush(struct notifier_block *nb) 5926 { 5927 struct mlxsw_sp_router *router; 5928 5929 /* Flush pending FIB notifications and then flush the device's 5930 * table before requesting another dump. The FIB notification 5931 * block is unregistered, so no need to take RTNL. 5932 */ 5933 mlxsw_core_flush_owq(); 5934 router = container_of(nb, struct mlxsw_sp_router, fib_nb); 5935 mlxsw_sp_router_fib_flush(router->mlxsw_sp); 5936 } 5937 5938 static int __mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) 5939 { 5940 char rgcr_pl[MLXSW_REG_RGCR_LEN]; 5941 u64 max_rifs; 5942 int err; 5943 5944 if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_RIFS)) 5945 return -EIO; 5946 max_rifs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); 5947 5948 mlxsw_reg_rgcr_pack(rgcr_pl, true, true); 5949 mlxsw_reg_rgcr_max_router_interfaces_set(rgcr_pl, max_rifs); 5950 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); 5951 if (err) 5952 return err; 5953 return 0; 5954 } 5955 5956 static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) 5957 { 5958 char rgcr_pl[MLXSW_REG_RGCR_LEN]; 5959 5960 mlxsw_reg_rgcr_pack(rgcr_pl, false, false); 5961 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl); 5962 } 5963 5964 int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) 5965 { 5966 struct mlxsw_sp_router *router; 5967 int err; 5968 5969 router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL); 5970 if (!router) 5971 return -ENOMEM; 5972 mlxsw_sp->router = router; 5973 router->mlxsw_sp = mlxsw_sp; 5974 5975 INIT_LIST_HEAD(&mlxsw_sp->router->nexthop_neighs_list); 5976 err = __mlxsw_sp_router_init(mlxsw_sp); 5977 if (err) 5978 goto err_router_init; 5979 5980 err = mlxsw_sp_rifs_init(mlxsw_sp); 5981 if (err) 5982 goto err_rifs_init; 5983 5984 err = mlxsw_sp_ipips_init(mlxsw_sp); 5985 if (err) 5986 goto err_ipips_init; 5987 5988 err = rhashtable_init(&mlxsw_sp->router->nexthop_ht, 5989 &mlxsw_sp_nexthop_ht_params); 5990 if (err) 5991 goto err_nexthop_ht_init; 5992 5993 err = rhashtable_init(&mlxsw_sp->router->nexthop_group_ht, 5994 &mlxsw_sp_nexthop_group_ht_params); 5995 if (err) 5996 goto err_nexthop_group_ht_init; 5997 5998 err = mlxsw_sp_lpm_init(mlxsw_sp); 5999 if (err) 6000 goto err_lpm_init; 6001 6002 err = mlxsw_sp_vrs_init(mlxsw_sp); 6003 if (err) 6004 goto err_vrs_init; 6005 6006 err = mlxsw_sp_neigh_init(mlxsw_sp); 6007 if (err) 6008 goto err_neigh_init; 6009 6010 mlxsw_sp->router->fib_nb.notifier_call = mlxsw_sp_router_fib_event; 6011 err = register_fib_notifier(&mlxsw_sp->router->fib_nb, 6012 mlxsw_sp_router_fib_dump_flush); 6013 if (err) 6014 goto err_register_fib_notifier; 6015 6016 return 0; 6017 6018 err_register_fib_notifier: 6019 mlxsw_sp_neigh_fini(mlxsw_sp); 6020 err_neigh_init: 6021 mlxsw_sp_vrs_fini(mlxsw_sp); 6022 err_vrs_init: 6023 mlxsw_sp_lpm_fini(mlxsw_sp); 6024 err_lpm_init: 6025 rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht); 6026 err_nexthop_group_ht_init: 6027 rhashtable_destroy(&mlxsw_sp->router->nexthop_ht); 6028 err_nexthop_ht_init: 6029 mlxsw_sp_ipips_fini(mlxsw_sp); 6030 err_ipips_init: 6031 mlxsw_sp_rifs_fini(mlxsw_sp); 6032 err_rifs_init: 6033 __mlxsw_sp_router_fini(mlxsw_sp); 6034 err_router_init: 6035 kfree(mlxsw_sp->router); 6036 return err; 6037 } 6038 6039 void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) 6040 { 6041 unregister_fib_notifier(&mlxsw_sp->router->fib_nb); 6042 mlxsw_sp_neigh_fini(mlxsw_sp); 6043 mlxsw_sp_vrs_fini(mlxsw_sp); 6044 mlxsw_sp_lpm_fini(mlxsw_sp); 6045 rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht); 6046 rhashtable_destroy(&mlxsw_sp->router->nexthop_ht); 6047 mlxsw_sp_ipips_fini(mlxsw_sp); 6048 mlxsw_sp_rifs_fini(mlxsw_sp); 6049 __mlxsw_sp_router_fini(mlxsw_sp); 6050 kfree(mlxsw_sp->router); 6051 } 6052