1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #include <linux/rhashtable.h> 5 #include <net/ipv6.h> 6 7 #include "spectrum_mr.h" 8 #include "spectrum_router.h" 9 10 struct mlxsw_sp_mr { 11 const struct mlxsw_sp_mr_ops *mr_ops; 12 void *catchall_route_priv; 13 struct delayed_work stats_update_dw; 14 struct list_head table_list; 15 #define MLXSW_SP_MR_ROUTES_COUNTER_UPDATE_INTERVAL 5000 /* ms */ 16 unsigned long priv[0]; 17 /* priv has to be always the last item */ 18 }; 19 20 struct mlxsw_sp_mr_vif; 21 struct mlxsw_sp_mr_vif_ops { 22 bool (*is_regular)(const struct mlxsw_sp_mr_vif *vif); 23 }; 24 25 struct mlxsw_sp_mr_vif { 26 struct net_device *dev; 27 const struct mlxsw_sp_rif *rif; 28 unsigned long vif_flags; 29 30 /* A list of route_vif_entry structs that point to routes that the VIF 31 * instance is used as one of the egress VIFs 32 */ 33 struct list_head route_evif_list; 34 35 /* A list of route_vif_entry structs that point to routes that the VIF 36 * instance is used as an ingress VIF 37 */ 38 struct list_head route_ivif_list; 39 40 /* Protocol specific operations for a VIF */ 41 const struct mlxsw_sp_mr_vif_ops *ops; 42 }; 43 44 struct mlxsw_sp_mr_route_vif_entry { 45 struct list_head vif_node; 46 struct list_head route_node; 47 struct mlxsw_sp_mr_vif *mr_vif; 48 struct mlxsw_sp_mr_route *mr_route; 49 }; 50 51 struct mlxsw_sp_mr_table; 52 struct mlxsw_sp_mr_table_ops { 53 bool (*is_route_valid)(const struct mlxsw_sp_mr_table *mr_table, 54 const struct mr_mfc *mfc); 55 void (*key_create)(struct mlxsw_sp_mr_table *mr_table, 56 struct mlxsw_sp_mr_route_key *key, 57 struct mr_mfc *mfc); 58 bool (*is_route_starg)(const struct mlxsw_sp_mr_table *mr_table, 59 const struct mlxsw_sp_mr_route *mr_route); 60 }; 61 62 struct mlxsw_sp_mr_table { 63 struct list_head node; 64 enum mlxsw_sp_l3proto proto; 65 struct mlxsw_sp *mlxsw_sp; 66 u32 vr_id; 67 struct mlxsw_sp_mr_vif vifs[MAXVIFS]; 68 struct list_head route_list; 69 struct rhashtable route_ht; 70 const struct mlxsw_sp_mr_table_ops *ops; 71 char catchall_route_priv[0]; 72 /* catchall_route_priv has to be always the last item */ 73 }; 74 75 struct mlxsw_sp_mr_route { 76 struct list_head node; 77 struct rhash_head ht_node; 78 struct mlxsw_sp_mr_route_key key; 79 enum mlxsw_sp_mr_route_action route_action; 80 u16 min_mtu; 81 struct mr_mfc *mfc; 82 void *route_priv; 83 const struct mlxsw_sp_mr_table *mr_table; 84 /* A list of route_vif_entry structs that point to the egress VIFs */ 85 struct list_head evif_list; 86 /* A route_vif_entry struct that point to the ingress VIF */ 87 struct mlxsw_sp_mr_route_vif_entry ivif; 88 }; 89 90 static const struct rhashtable_params mlxsw_sp_mr_route_ht_params = { 91 .key_len = sizeof(struct mlxsw_sp_mr_route_key), 92 .key_offset = offsetof(struct mlxsw_sp_mr_route, key), 93 .head_offset = offsetof(struct mlxsw_sp_mr_route, ht_node), 94 .automatic_shrinking = true, 95 }; 96 97 static bool mlxsw_sp_mr_vif_valid(const struct mlxsw_sp_mr_vif *vif) 98 { 99 return vif->ops->is_regular(vif) && vif->dev && vif->rif; 100 } 101 102 static bool mlxsw_sp_mr_vif_exists(const struct mlxsw_sp_mr_vif *vif) 103 { 104 return vif->dev; 105 } 106 107 static bool 108 mlxsw_sp_mr_route_ivif_in_evifs(const struct mlxsw_sp_mr_route *mr_route) 109 { 110 vifi_t ivif = mr_route->mfc->mfc_parent; 111 112 return mr_route->mfc->mfc_un.res.ttls[ivif] != 255; 113 } 114 115 static int 116 mlxsw_sp_mr_route_valid_evifs_num(const struct mlxsw_sp_mr_route *mr_route) 117 { 118 struct mlxsw_sp_mr_route_vif_entry *rve; 119 int valid_evifs; 120 121 valid_evifs = 0; 122 list_for_each_entry(rve, &mr_route->evif_list, route_node) 123 if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) 124 valid_evifs++; 125 return valid_evifs; 126 } 127 128 static enum mlxsw_sp_mr_route_action 129 mlxsw_sp_mr_route_action(const struct mlxsw_sp_mr_route *mr_route) 130 { 131 struct mlxsw_sp_mr_route_vif_entry *rve; 132 133 /* If the ingress port is not regular and resolved, trap the route */ 134 if (!mlxsw_sp_mr_vif_valid(mr_route->ivif.mr_vif)) 135 return MLXSW_SP_MR_ROUTE_ACTION_TRAP; 136 137 /* The kernel does not match a (*,G) route that the ingress interface is 138 * not one of the egress interfaces, so trap these kind of routes. 139 */ 140 if (mr_route->mr_table->ops->is_route_starg(mr_route->mr_table, 141 mr_route) && 142 !mlxsw_sp_mr_route_ivif_in_evifs(mr_route)) 143 return MLXSW_SP_MR_ROUTE_ACTION_TRAP; 144 145 /* If the route has no valid eVIFs, trap it. */ 146 if (!mlxsw_sp_mr_route_valid_evifs_num(mr_route)) 147 return MLXSW_SP_MR_ROUTE_ACTION_TRAP; 148 149 /* If one of the eVIFs has no RIF, trap-and-forward the route as there 150 * is some more routing to do in software too. 151 */ 152 list_for_each_entry(rve, &mr_route->evif_list, route_node) 153 if (mlxsw_sp_mr_vif_exists(rve->mr_vif) && !rve->mr_vif->rif) 154 return MLXSW_SP_MR_ROUTE_ACTION_TRAP_AND_FORWARD; 155 156 return MLXSW_SP_MR_ROUTE_ACTION_FORWARD; 157 } 158 159 static enum mlxsw_sp_mr_route_prio 160 mlxsw_sp_mr_route_prio(const struct mlxsw_sp_mr_route *mr_route) 161 { 162 return mr_route->mr_table->ops->is_route_starg(mr_route->mr_table, 163 mr_route) ? 164 MLXSW_SP_MR_ROUTE_PRIO_STARG : MLXSW_SP_MR_ROUTE_PRIO_SG; 165 } 166 167 static int mlxsw_sp_mr_route_evif_link(struct mlxsw_sp_mr_route *mr_route, 168 struct mlxsw_sp_mr_vif *mr_vif) 169 { 170 struct mlxsw_sp_mr_route_vif_entry *rve; 171 172 rve = kzalloc(sizeof(*rve), GFP_KERNEL); 173 if (!rve) 174 return -ENOMEM; 175 rve->mr_route = mr_route; 176 rve->mr_vif = mr_vif; 177 list_add_tail(&rve->route_node, &mr_route->evif_list); 178 list_add_tail(&rve->vif_node, &mr_vif->route_evif_list); 179 return 0; 180 } 181 182 static void 183 mlxsw_sp_mr_route_evif_unlink(struct mlxsw_sp_mr_route_vif_entry *rve) 184 { 185 list_del(&rve->route_node); 186 list_del(&rve->vif_node); 187 kfree(rve); 188 } 189 190 static void mlxsw_sp_mr_route_ivif_link(struct mlxsw_sp_mr_route *mr_route, 191 struct mlxsw_sp_mr_vif *mr_vif) 192 { 193 mr_route->ivif.mr_route = mr_route; 194 mr_route->ivif.mr_vif = mr_vif; 195 list_add_tail(&mr_route->ivif.vif_node, &mr_vif->route_ivif_list); 196 } 197 198 static void mlxsw_sp_mr_route_ivif_unlink(struct mlxsw_sp_mr_route *mr_route) 199 { 200 list_del(&mr_route->ivif.vif_node); 201 } 202 203 static int 204 mlxsw_sp_mr_route_info_create(struct mlxsw_sp_mr_table *mr_table, 205 struct mlxsw_sp_mr_route *mr_route, 206 struct mlxsw_sp_mr_route_info *route_info) 207 { 208 struct mlxsw_sp_mr_route_vif_entry *rve; 209 u16 *erif_indices; 210 u16 irif_index; 211 u16 erif = 0; 212 213 erif_indices = kmalloc_array(MAXVIFS, sizeof(*erif_indices), 214 GFP_KERNEL); 215 if (!erif_indices) 216 return -ENOMEM; 217 218 list_for_each_entry(rve, &mr_route->evif_list, route_node) { 219 if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { 220 u16 rifi = mlxsw_sp_rif_index(rve->mr_vif->rif); 221 222 erif_indices[erif++] = rifi; 223 } 224 } 225 226 if (mlxsw_sp_mr_vif_valid(mr_route->ivif.mr_vif)) 227 irif_index = mlxsw_sp_rif_index(mr_route->ivif.mr_vif->rif); 228 else 229 irif_index = 0; 230 231 route_info->irif_index = irif_index; 232 route_info->erif_indices = erif_indices; 233 route_info->min_mtu = mr_route->min_mtu; 234 route_info->route_action = mr_route->route_action; 235 route_info->erif_num = erif; 236 return 0; 237 } 238 239 static void 240 mlxsw_sp_mr_route_info_destroy(struct mlxsw_sp_mr_route_info *route_info) 241 { 242 kfree(route_info->erif_indices); 243 } 244 245 static int mlxsw_sp_mr_route_write(struct mlxsw_sp_mr_table *mr_table, 246 struct mlxsw_sp_mr_route *mr_route, 247 bool replace) 248 { 249 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 250 struct mlxsw_sp_mr_route_info route_info; 251 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 252 int err; 253 254 err = mlxsw_sp_mr_route_info_create(mr_table, mr_route, &route_info); 255 if (err) 256 return err; 257 258 if (!replace) { 259 struct mlxsw_sp_mr_route_params route_params; 260 261 mr_route->route_priv = kzalloc(mr->mr_ops->route_priv_size, 262 GFP_KERNEL); 263 if (!mr_route->route_priv) { 264 err = -ENOMEM; 265 goto out; 266 } 267 268 route_params.key = mr_route->key; 269 route_params.value = route_info; 270 route_params.prio = mlxsw_sp_mr_route_prio(mr_route); 271 err = mr->mr_ops->route_create(mlxsw_sp, mr->priv, 272 mr_route->route_priv, 273 &route_params); 274 if (err) 275 kfree(mr_route->route_priv); 276 } else { 277 err = mr->mr_ops->route_update(mlxsw_sp, mr_route->route_priv, 278 &route_info); 279 } 280 out: 281 mlxsw_sp_mr_route_info_destroy(&route_info); 282 return err; 283 } 284 285 static void mlxsw_sp_mr_route_erase(struct mlxsw_sp_mr_table *mr_table, 286 struct mlxsw_sp_mr_route *mr_route) 287 { 288 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 289 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 290 291 mr->mr_ops->route_destroy(mlxsw_sp, mr->priv, mr_route->route_priv); 292 kfree(mr_route->route_priv); 293 } 294 295 static struct mlxsw_sp_mr_route * 296 mlxsw_sp_mr_route_create(struct mlxsw_sp_mr_table *mr_table, 297 struct mr_mfc *mfc) 298 { 299 struct mlxsw_sp_mr_route_vif_entry *rve, *tmp; 300 struct mlxsw_sp_mr_route *mr_route; 301 int err = 0; 302 int i; 303 304 /* Allocate and init a new route and fill it with parameters */ 305 mr_route = kzalloc(sizeof(*mr_route), GFP_KERNEL); 306 if (!mr_route) 307 return ERR_PTR(-ENOMEM); 308 INIT_LIST_HEAD(&mr_route->evif_list); 309 310 /* Find min_mtu and link iVIF and eVIFs */ 311 mr_route->min_mtu = ETH_MAX_MTU; 312 mr_cache_hold(mfc); 313 mr_route->mfc = mfc; 314 mr_table->ops->key_create(mr_table, &mr_route->key, mr_route->mfc); 315 316 mr_route->mr_table = mr_table; 317 for (i = 0; i < MAXVIFS; i++) { 318 if (mfc->mfc_un.res.ttls[i] != 255) { 319 err = mlxsw_sp_mr_route_evif_link(mr_route, 320 &mr_table->vifs[i]); 321 if (err) 322 goto err; 323 if (mr_table->vifs[i].dev && 324 mr_table->vifs[i].dev->mtu < mr_route->min_mtu) 325 mr_route->min_mtu = mr_table->vifs[i].dev->mtu; 326 } 327 } 328 mlxsw_sp_mr_route_ivif_link(mr_route, 329 &mr_table->vifs[mfc->mfc_parent]); 330 331 mr_route->route_action = mlxsw_sp_mr_route_action(mr_route); 332 return mr_route; 333 err: 334 mr_cache_put(mfc); 335 list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node) 336 mlxsw_sp_mr_route_evif_unlink(rve); 337 kfree(mr_route); 338 return ERR_PTR(err); 339 } 340 341 static void mlxsw_sp_mr_route_destroy(struct mlxsw_sp_mr_table *mr_table, 342 struct mlxsw_sp_mr_route *mr_route) 343 { 344 struct mlxsw_sp_mr_route_vif_entry *rve, *tmp; 345 346 mlxsw_sp_mr_route_ivif_unlink(mr_route); 347 mr_cache_put(mr_route->mfc); 348 list_for_each_entry_safe(rve, tmp, &mr_route->evif_list, route_node) 349 mlxsw_sp_mr_route_evif_unlink(rve); 350 kfree(mr_route); 351 } 352 353 static void mlxsw_sp_mr_mfc_offload_set(struct mlxsw_sp_mr_route *mr_route, 354 bool offload) 355 { 356 if (offload) 357 mr_route->mfc->mfc_flags |= MFC_OFFLOAD; 358 else 359 mr_route->mfc->mfc_flags &= ~MFC_OFFLOAD; 360 } 361 362 static void mlxsw_sp_mr_mfc_offload_update(struct mlxsw_sp_mr_route *mr_route) 363 { 364 bool offload; 365 366 offload = mr_route->route_action != MLXSW_SP_MR_ROUTE_ACTION_TRAP; 367 mlxsw_sp_mr_mfc_offload_set(mr_route, offload); 368 } 369 370 static void __mlxsw_sp_mr_route_del(struct mlxsw_sp_mr_table *mr_table, 371 struct mlxsw_sp_mr_route *mr_route) 372 { 373 mlxsw_sp_mr_mfc_offload_set(mr_route, false); 374 mlxsw_sp_mr_route_erase(mr_table, mr_route); 375 rhashtable_remove_fast(&mr_table->route_ht, &mr_route->ht_node, 376 mlxsw_sp_mr_route_ht_params); 377 list_del(&mr_route->node); 378 mlxsw_sp_mr_route_destroy(mr_table, mr_route); 379 } 380 381 int mlxsw_sp_mr_route_add(struct mlxsw_sp_mr_table *mr_table, 382 struct mr_mfc *mfc, bool replace) 383 { 384 struct mlxsw_sp_mr_route *mr_orig_route = NULL; 385 struct mlxsw_sp_mr_route *mr_route; 386 int err; 387 388 if (!mr_table->ops->is_route_valid(mr_table, mfc)) 389 return -EINVAL; 390 391 /* Create a new route */ 392 mr_route = mlxsw_sp_mr_route_create(mr_table, mfc); 393 if (IS_ERR(mr_route)) 394 return PTR_ERR(mr_route); 395 396 /* Find any route with a matching key */ 397 mr_orig_route = rhashtable_lookup_fast(&mr_table->route_ht, 398 &mr_route->key, 399 mlxsw_sp_mr_route_ht_params); 400 if (replace) { 401 /* On replace case, make the route point to the new route_priv. 402 */ 403 if (WARN_ON(!mr_orig_route)) { 404 err = -ENOENT; 405 goto err_no_orig_route; 406 } 407 mr_route->route_priv = mr_orig_route->route_priv; 408 } else if (mr_orig_route) { 409 /* On non replace case, if another route with the same key was 410 * found, abort, as duplicate routes are used for proxy routes. 411 */ 412 dev_warn(mr_table->mlxsw_sp->bus_info->dev, 413 "Offloading proxy routes is not supported.\n"); 414 err = -EINVAL; 415 goto err_duplicate_route; 416 } 417 418 /* Put it in the table data-structures */ 419 list_add_tail(&mr_route->node, &mr_table->route_list); 420 err = rhashtable_insert_fast(&mr_table->route_ht, 421 &mr_route->ht_node, 422 mlxsw_sp_mr_route_ht_params); 423 if (err) 424 goto err_rhashtable_insert; 425 426 /* Write the route to the hardware */ 427 err = mlxsw_sp_mr_route_write(mr_table, mr_route, replace); 428 if (err) 429 goto err_mr_route_write; 430 431 /* Destroy the original route */ 432 if (replace) { 433 rhashtable_remove_fast(&mr_table->route_ht, 434 &mr_orig_route->ht_node, 435 mlxsw_sp_mr_route_ht_params); 436 list_del(&mr_orig_route->node); 437 mlxsw_sp_mr_route_destroy(mr_table, mr_orig_route); 438 } 439 440 mlxsw_sp_mr_mfc_offload_update(mr_route); 441 return 0; 442 443 err_mr_route_write: 444 rhashtable_remove_fast(&mr_table->route_ht, &mr_route->ht_node, 445 mlxsw_sp_mr_route_ht_params); 446 err_rhashtable_insert: 447 list_del(&mr_route->node); 448 err_no_orig_route: 449 err_duplicate_route: 450 mlxsw_sp_mr_route_destroy(mr_table, mr_route); 451 return err; 452 } 453 454 void mlxsw_sp_mr_route_del(struct mlxsw_sp_mr_table *mr_table, 455 struct mr_mfc *mfc) 456 { 457 struct mlxsw_sp_mr_route *mr_route; 458 struct mlxsw_sp_mr_route_key key; 459 460 mr_table->ops->key_create(mr_table, &key, mfc); 461 mr_route = rhashtable_lookup_fast(&mr_table->route_ht, &key, 462 mlxsw_sp_mr_route_ht_params); 463 if (mr_route) 464 __mlxsw_sp_mr_route_del(mr_table, mr_route); 465 } 466 467 /* Should be called after the VIF struct is updated */ 468 static int 469 mlxsw_sp_mr_route_ivif_resolve(struct mlxsw_sp_mr_table *mr_table, 470 struct mlxsw_sp_mr_route_vif_entry *rve) 471 { 472 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 473 enum mlxsw_sp_mr_route_action route_action; 474 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 475 u16 irif_index; 476 int err; 477 478 route_action = mlxsw_sp_mr_route_action(rve->mr_route); 479 if (route_action == MLXSW_SP_MR_ROUTE_ACTION_TRAP) 480 return 0; 481 482 /* rve->mr_vif->rif is guaranteed to be valid at this stage */ 483 irif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); 484 err = mr->mr_ops->route_irif_update(mlxsw_sp, rve->mr_route->route_priv, 485 irif_index); 486 if (err) 487 return err; 488 489 err = mr->mr_ops->route_action_update(mlxsw_sp, 490 rve->mr_route->route_priv, 491 route_action); 492 if (err) 493 /* No need to rollback here because the iRIF change only takes 494 * place after the action has been updated. 495 */ 496 return err; 497 498 rve->mr_route->route_action = route_action; 499 mlxsw_sp_mr_mfc_offload_update(rve->mr_route); 500 return 0; 501 } 502 503 static void 504 mlxsw_sp_mr_route_ivif_unresolve(struct mlxsw_sp_mr_table *mr_table, 505 struct mlxsw_sp_mr_route_vif_entry *rve) 506 { 507 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 508 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 509 510 mr->mr_ops->route_action_update(mlxsw_sp, rve->mr_route->route_priv, 511 MLXSW_SP_MR_ROUTE_ACTION_TRAP); 512 rve->mr_route->route_action = MLXSW_SP_MR_ROUTE_ACTION_TRAP; 513 mlxsw_sp_mr_mfc_offload_update(rve->mr_route); 514 } 515 516 /* Should be called after the RIF struct is updated */ 517 static int 518 mlxsw_sp_mr_route_evif_resolve(struct mlxsw_sp_mr_table *mr_table, 519 struct mlxsw_sp_mr_route_vif_entry *rve) 520 { 521 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 522 enum mlxsw_sp_mr_route_action route_action; 523 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 524 u16 erif_index = 0; 525 int err; 526 527 /* Update the route action, as the new eVIF can be a tunnel or a pimreg 528 * device which will require updating the action. 529 */ 530 route_action = mlxsw_sp_mr_route_action(rve->mr_route); 531 if (route_action != rve->mr_route->route_action) { 532 err = mr->mr_ops->route_action_update(mlxsw_sp, 533 rve->mr_route->route_priv, 534 route_action); 535 if (err) 536 return err; 537 } 538 539 /* Add the eRIF */ 540 if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { 541 erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); 542 err = mr->mr_ops->route_erif_add(mlxsw_sp, 543 rve->mr_route->route_priv, 544 erif_index); 545 if (err) 546 goto err_route_erif_add; 547 } 548 549 /* Update the minimum MTU */ 550 if (rve->mr_vif->dev->mtu < rve->mr_route->min_mtu) { 551 rve->mr_route->min_mtu = rve->mr_vif->dev->mtu; 552 err = mr->mr_ops->route_min_mtu_update(mlxsw_sp, 553 rve->mr_route->route_priv, 554 rve->mr_route->min_mtu); 555 if (err) 556 goto err_route_min_mtu_update; 557 } 558 559 rve->mr_route->route_action = route_action; 560 mlxsw_sp_mr_mfc_offload_update(rve->mr_route); 561 return 0; 562 563 err_route_min_mtu_update: 564 if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) 565 mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, 566 erif_index); 567 err_route_erif_add: 568 if (route_action != rve->mr_route->route_action) 569 mr->mr_ops->route_action_update(mlxsw_sp, 570 rve->mr_route->route_priv, 571 rve->mr_route->route_action); 572 return err; 573 } 574 575 /* Should be called before the RIF struct is updated */ 576 static void 577 mlxsw_sp_mr_route_evif_unresolve(struct mlxsw_sp_mr_table *mr_table, 578 struct mlxsw_sp_mr_route_vif_entry *rve) 579 { 580 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 581 enum mlxsw_sp_mr_route_action route_action; 582 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 583 u16 rifi; 584 585 /* If the unresolved RIF was not valid, no need to delete it */ 586 if (!mlxsw_sp_mr_vif_valid(rve->mr_vif)) 587 return; 588 589 /* Update the route action: if there is only one valid eVIF in the 590 * route, set the action to trap as the VIF deletion will lead to zero 591 * valid eVIFs. On any other case, use the mlxsw_sp_mr_route_action to 592 * determine the route action. 593 */ 594 if (mlxsw_sp_mr_route_valid_evifs_num(rve->mr_route) == 1) 595 route_action = MLXSW_SP_MR_ROUTE_ACTION_TRAP; 596 else 597 route_action = mlxsw_sp_mr_route_action(rve->mr_route); 598 if (route_action != rve->mr_route->route_action) 599 mr->mr_ops->route_action_update(mlxsw_sp, 600 rve->mr_route->route_priv, 601 route_action); 602 603 /* Delete the erif from the route */ 604 rifi = mlxsw_sp_rif_index(rve->mr_vif->rif); 605 mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, rifi); 606 rve->mr_route->route_action = route_action; 607 mlxsw_sp_mr_mfc_offload_update(rve->mr_route); 608 } 609 610 static int mlxsw_sp_mr_vif_resolve(struct mlxsw_sp_mr_table *mr_table, 611 struct net_device *dev, 612 struct mlxsw_sp_mr_vif *mr_vif, 613 unsigned long vif_flags, 614 const struct mlxsw_sp_rif *rif) 615 { 616 struct mlxsw_sp_mr_route_vif_entry *irve, *erve; 617 int err; 618 619 /* Update the VIF */ 620 mr_vif->dev = dev; 621 mr_vif->rif = rif; 622 mr_vif->vif_flags = vif_flags; 623 624 /* Update all routes where this VIF is used as an unresolved iRIF */ 625 list_for_each_entry(irve, &mr_vif->route_ivif_list, vif_node) { 626 err = mlxsw_sp_mr_route_ivif_resolve(mr_table, irve); 627 if (err) 628 goto err_irif_unresolve; 629 } 630 631 /* Update all routes where this VIF is used as an unresolved eRIF */ 632 list_for_each_entry(erve, &mr_vif->route_evif_list, vif_node) { 633 err = mlxsw_sp_mr_route_evif_resolve(mr_table, erve); 634 if (err) 635 goto err_erif_unresolve; 636 } 637 return 0; 638 639 err_erif_unresolve: 640 list_for_each_entry_from_reverse(erve, &mr_vif->route_evif_list, 641 vif_node) 642 mlxsw_sp_mr_route_evif_unresolve(mr_table, erve); 643 err_irif_unresolve: 644 list_for_each_entry_from_reverse(irve, &mr_vif->route_ivif_list, 645 vif_node) 646 mlxsw_sp_mr_route_ivif_unresolve(mr_table, irve); 647 mr_vif->rif = NULL; 648 return err; 649 } 650 651 static void mlxsw_sp_mr_vif_unresolve(struct mlxsw_sp_mr_table *mr_table, 652 struct net_device *dev, 653 struct mlxsw_sp_mr_vif *mr_vif) 654 { 655 struct mlxsw_sp_mr_route_vif_entry *rve; 656 657 /* Update all routes where this VIF is used as an unresolved eRIF */ 658 list_for_each_entry(rve, &mr_vif->route_evif_list, vif_node) 659 mlxsw_sp_mr_route_evif_unresolve(mr_table, rve); 660 661 /* Update all routes where this VIF is used as an unresolved iRIF */ 662 list_for_each_entry(rve, &mr_vif->route_ivif_list, vif_node) 663 mlxsw_sp_mr_route_ivif_unresolve(mr_table, rve); 664 665 /* Update the VIF */ 666 mr_vif->dev = dev; 667 mr_vif->rif = NULL; 668 } 669 670 int mlxsw_sp_mr_vif_add(struct mlxsw_sp_mr_table *mr_table, 671 struct net_device *dev, vifi_t vif_index, 672 unsigned long vif_flags, const struct mlxsw_sp_rif *rif) 673 { 674 struct mlxsw_sp_mr_vif *mr_vif = &mr_table->vifs[vif_index]; 675 676 if (WARN_ON(vif_index >= MAXVIFS)) 677 return -EINVAL; 678 if (mr_vif->dev) 679 return -EEXIST; 680 return mlxsw_sp_mr_vif_resolve(mr_table, dev, mr_vif, vif_flags, rif); 681 } 682 683 void mlxsw_sp_mr_vif_del(struct mlxsw_sp_mr_table *mr_table, vifi_t vif_index) 684 { 685 struct mlxsw_sp_mr_vif *mr_vif = &mr_table->vifs[vif_index]; 686 687 if (WARN_ON(vif_index >= MAXVIFS)) 688 return; 689 if (WARN_ON(!mr_vif->dev)) 690 return; 691 mlxsw_sp_mr_vif_unresolve(mr_table, NULL, mr_vif); 692 } 693 694 static struct mlxsw_sp_mr_vif * 695 mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table, 696 const struct net_device *dev) 697 { 698 vifi_t vif_index; 699 700 for (vif_index = 0; vif_index < MAXVIFS; vif_index++) 701 if (mr_table->vifs[vif_index].dev == dev) 702 return &mr_table->vifs[vif_index]; 703 return NULL; 704 } 705 706 int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table, 707 const struct mlxsw_sp_rif *rif) 708 { 709 const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 710 struct mlxsw_sp_mr_vif *mr_vif; 711 712 if (!rif_dev) 713 return 0; 714 715 mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 716 if (!mr_vif) 717 return 0; 718 return mlxsw_sp_mr_vif_resolve(mr_table, mr_vif->dev, mr_vif, 719 mr_vif->vif_flags, rif); 720 } 721 722 void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table, 723 const struct mlxsw_sp_rif *rif) 724 { 725 const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 726 struct mlxsw_sp_mr_vif *mr_vif; 727 728 if (!rif_dev) 729 return; 730 731 mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 732 if (!mr_vif) 733 return; 734 mlxsw_sp_mr_vif_unresolve(mr_table, mr_vif->dev, mr_vif); 735 } 736 737 void mlxsw_sp_mr_rif_mtu_update(struct mlxsw_sp_mr_table *mr_table, 738 const struct mlxsw_sp_rif *rif, int mtu) 739 { 740 const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif); 741 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 742 struct mlxsw_sp_mr_route_vif_entry *rve; 743 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 744 struct mlxsw_sp_mr_vif *mr_vif; 745 746 if (!rif_dev) 747 return; 748 749 /* Search for a VIF that use that RIF */ 750 mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); 751 if (!mr_vif) 752 return; 753 754 /* Update all the routes that uses that VIF as eVIF */ 755 list_for_each_entry(rve, &mr_vif->route_evif_list, vif_node) { 756 if (mtu < rve->mr_route->min_mtu) { 757 rve->mr_route->min_mtu = mtu; 758 mr->mr_ops->route_min_mtu_update(mlxsw_sp, 759 rve->mr_route->route_priv, 760 mtu); 761 } 762 } 763 } 764 765 /* Protocol specific functions */ 766 static bool 767 mlxsw_sp_mr_route4_validate(const struct mlxsw_sp_mr_table *mr_table, 768 const struct mr_mfc *c) 769 { 770 struct mfc_cache *mfc = (struct mfc_cache *) c; 771 772 /* If the route is a (*,*) route, abort, as these kind of routes are 773 * used for proxy routes. 774 */ 775 if (mfc->mfc_origin == htonl(INADDR_ANY) && 776 mfc->mfc_mcastgrp == htonl(INADDR_ANY)) { 777 dev_warn(mr_table->mlxsw_sp->bus_info->dev, 778 "Offloading proxy routes is not supported.\n"); 779 return false; 780 } 781 return true; 782 } 783 784 static void mlxsw_sp_mr_route4_key(struct mlxsw_sp_mr_table *mr_table, 785 struct mlxsw_sp_mr_route_key *key, 786 struct mr_mfc *c) 787 { 788 const struct mfc_cache *mfc = (struct mfc_cache *) c; 789 bool starg; 790 791 starg = (mfc->mfc_origin == htonl(INADDR_ANY)); 792 793 memset(key, 0, sizeof(*key)); 794 key->vrid = mr_table->vr_id; 795 key->proto = MLXSW_SP_L3_PROTO_IPV4; 796 key->group.addr4 = mfc->mfc_mcastgrp; 797 key->group_mask.addr4 = htonl(0xffffffff); 798 key->source.addr4 = mfc->mfc_origin; 799 key->source_mask.addr4 = htonl(starg ? 0 : 0xffffffff); 800 } 801 802 static bool mlxsw_sp_mr_route4_starg(const struct mlxsw_sp_mr_table *mr_table, 803 const struct mlxsw_sp_mr_route *mr_route) 804 { 805 return mr_route->key.source_mask.addr4 == htonl(INADDR_ANY); 806 } 807 808 static bool mlxsw_sp_mr_vif4_is_regular(const struct mlxsw_sp_mr_vif *vif) 809 { 810 return !(vif->vif_flags & (VIFF_TUNNEL | VIFF_REGISTER)); 811 } 812 813 static bool 814 mlxsw_sp_mr_route6_validate(const struct mlxsw_sp_mr_table *mr_table, 815 const struct mr_mfc *c) 816 { 817 struct mfc6_cache *mfc = (struct mfc6_cache *) c; 818 819 /* If the route is a (*,*) route, abort, as these kind of routes are 820 * used for proxy routes. 821 */ 822 if (ipv6_addr_any(&mfc->mf6c_origin) && 823 ipv6_addr_any(&mfc->mf6c_mcastgrp)) { 824 dev_warn(mr_table->mlxsw_sp->bus_info->dev, 825 "Offloading proxy routes is not supported.\n"); 826 return false; 827 } 828 return true; 829 } 830 831 static void mlxsw_sp_mr_route6_key(struct mlxsw_sp_mr_table *mr_table, 832 struct mlxsw_sp_mr_route_key *key, 833 struct mr_mfc *c) 834 { 835 const struct mfc6_cache *mfc = (struct mfc6_cache *) c; 836 837 memset(key, 0, sizeof(*key)); 838 key->vrid = mr_table->vr_id; 839 key->proto = MLXSW_SP_L3_PROTO_IPV6; 840 key->group.addr6 = mfc->mf6c_mcastgrp; 841 memset(&key->group_mask.addr6, 0xff, sizeof(key->group_mask.addr6)); 842 key->source.addr6 = mfc->mf6c_origin; 843 if (!ipv6_addr_any(&mfc->mf6c_origin)) 844 memset(&key->source_mask.addr6, 0xff, 845 sizeof(key->source_mask.addr6)); 846 } 847 848 static bool mlxsw_sp_mr_route6_starg(const struct mlxsw_sp_mr_table *mr_table, 849 const struct mlxsw_sp_mr_route *mr_route) 850 { 851 return ipv6_addr_any(&mr_route->key.source_mask.addr6); 852 } 853 854 static bool mlxsw_sp_mr_vif6_is_regular(const struct mlxsw_sp_mr_vif *vif) 855 { 856 return !(vif->vif_flags & MIFF_REGISTER); 857 } 858 859 static struct 860 mlxsw_sp_mr_vif_ops mlxsw_sp_mr_vif_ops_arr[] = { 861 { 862 .is_regular = mlxsw_sp_mr_vif4_is_regular, 863 }, 864 { 865 .is_regular = mlxsw_sp_mr_vif6_is_regular, 866 }, 867 }; 868 869 static struct 870 mlxsw_sp_mr_table_ops mlxsw_sp_mr_table_ops_arr[] = { 871 { 872 .is_route_valid = mlxsw_sp_mr_route4_validate, 873 .key_create = mlxsw_sp_mr_route4_key, 874 .is_route_starg = mlxsw_sp_mr_route4_starg, 875 }, 876 { 877 .is_route_valid = mlxsw_sp_mr_route6_validate, 878 .key_create = mlxsw_sp_mr_route6_key, 879 .is_route_starg = mlxsw_sp_mr_route6_starg, 880 }, 881 882 }; 883 884 struct mlxsw_sp_mr_table *mlxsw_sp_mr_table_create(struct mlxsw_sp *mlxsw_sp, 885 u32 vr_id, 886 enum mlxsw_sp_l3proto proto) 887 { 888 struct mlxsw_sp_mr_route_params catchall_route_params = { 889 .prio = MLXSW_SP_MR_ROUTE_PRIO_CATCHALL, 890 .key = { 891 .vrid = vr_id, 892 .proto = proto, 893 }, 894 .value = { 895 .route_action = MLXSW_SP_MR_ROUTE_ACTION_TRAP, 896 } 897 }; 898 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 899 struct mlxsw_sp_mr_table *mr_table; 900 int err; 901 int i; 902 903 mr_table = kzalloc(sizeof(*mr_table) + mr->mr_ops->route_priv_size, 904 GFP_KERNEL); 905 if (!mr_table) 906 return ERR_PTR(-ENOMEM); 907 908 mr_table->vr_id = vr_id; 909 mr_table->mlxsw_sp = mlxsw_sp; 910 mr_table->proto = proto; 911 mr_table->ops = &mlxsw_sp_mr_table_ops_arr[proto]; 912 INIT_LIST_HEAD(&mr_table->route_list); 913 914 err = rhashtable_init(&mr_table->route_ht, 915 &mlxsw_sp_mr_route_ht_params); 916 if (err) 917 goto err_route_rhashtable_init; 918 919 for (i = 0; i < MAXVIFS; i++) { 920 INIT_LIST_HEAD(&mr_table->vifs[i].route_evif_list); 921 INIT_LIST_HEAD(&mr_table->vifs[i].route_ivif_list); 922 mr_table->vifs[i].ops = &mlxsw_sp_mr_vif_ops_arr[proto]; 923 } 924 925 err = mr->mr_ops->route_create(mlxsw_sp, mr->priv, 926 mr_table->catchall_route_priv, 927 &catchall_route_params); 928 if (err) 929 goto err_ops_route_create; 930 list_add_tail(&mr_table->node, &mr->table_list); 931 return mr_table; 932 933 err_ops_route_create: 934 rhashtable_destroy(&mr_table->route_ht); 935 err_route_rhashtable_init: 936 kfree(mr_table); 937 return ERR_PTR(err); 938 } 939 940 void mlxsw_sp_mr_table_destroy(struct mlxsw_sp_mr_table *mr_table) 941 { 942 struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; 943 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 944 945 WARN_ON(!mlxsw_sp_mr_table_empty(mr_table)); 946 list_del(&mr_table->node); 947 mr->mr_ops->route_destroy(mlxsw_sp, mr->priv, 948 &mr_table->catchall_route_priv); 949 rhashtable_destroy(&mr_table->route_ht); 950 kfree(mr_table); 951 } 952 953 void mlxsw_sp_mr_table_flush(struct mlxsw_sp_mr_table *mr_table) 954 { 955 struct mlxsw_sp_mr_route *mr_route, *tmp; 956 int i; 957 958 list_for_each_entry_safe(mr_route, tmp, &mr_table->route_list, node) 959 __mlxsw_sp_mr_route_del(mr_table, mr_route); 960 961 for (i = 0; i < MAXVIFS; i++) { 962 mr_table->vifs[i].dev = NULL; 963 mr_table->vifs[i].rif = NULL; 964 } 965 } 966 967 bool mlxsw_sp_mr_table_empty(const struct mlxsw_sp_mr_table *mr_table) 968 { 969 int i; 970 971 for (i = 0; i < MAXVIFS; i++) 972 if (mr_table->vifs[i].dev) 973 return false; 974 return list_empty(&mr_table->route_list); 975 } 976 977 static void mlxsw_sp_mr_route_stats_update(struct mlxsw_sp *mlxsw_sp, 978 struct mlxsw_sp_mr_route *mr_route) 979 { 980 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 981 u64 packets, bytes; 982 983 if (mr_route->route_action == MLXSW_SP_MR_ROUTE_ACTION_TRAP) 984 return; 985 986 mr->mr_ops->route_stats(mlxsw_sp, mr_route->route_priv, &packets, 987 &bytes); 988 989 if (mr_route->mfc->mfc_un.res.pkt != packets) 990 mr_route->mfc->mfc_un.res.lastuse = jiffies; 991 mr_route->mfc->mfc_un.res.pkt = packets; 992 mr_route->mfc->mfc_un.res.bytes = bytes; 993 } 994 995 static void mlxsw_sp_mr_stats_update(struct work_struct *work) 996 { 997 struct mlxsw_sp_mr *mr = container_of(work, struct mlxsw_sp_mr, 998 stats_update_dw.work); 999 struct mlxsw_sp_mr_table *mr_table; 1000 struct mlxsw_sp_mr_route *mr_route; 1001 unsigned long interval; 1002 1003 rtnl_lock(); 1004 list_for_each_entry(mr_table, &mr->table_list, node) 1005 list_for_each_entry(mr_route, &mr_table->route_list, node) 1006 mlxsw_sp_mr_route_stats_update(mr_table->mlxsw_sp, 1007 mr_route); 1008 rtnl_unlock(); 1009 1010 interval = msecs_to_jiffies(MLXSW_SP_MR_ROUTES_COUNTER_UPDATE_INTERVAL); 1011 mlxsw_core_schedule_dw(&mr->stats_update_dw, interval); 1012 } 1013 1014 int mlxsw_sp_mr_init(struct mlxsw_sp *mlxsw_sp, 1015 const struct mlxsw_sp_mr_ops *mr_ops) 1016 { 1017 struct mlxsw_sp_mr *mr; 1018 unsigned long interval; 1019 int err; 1020 1021 mr = kzalloc(sizeof(*mr) + mr_ops->priv_size, GFP_KERNEL); 1022 if (!mr) 1023 return -ENOMEM; 1024 mr->mr_ops = mr_ops; 1025 mlxsw_sp->mr = mr; 1026 INIT_LIST_HEAD(&mr->table_list); 1027 1028 err = mr_ops->init(mlxsw_sp, mr->priv); 1029 if (err) 1030 goto err; 1031 1032 /* Create the delayed work for counter updates */ 1033 INIT_DELAYED_WORK(&mr->stats_update_dw, mlxsw_sp_mr_stats_update); 1034 interval = msecs_to_jiffies(MLXSW_SP_MR_ROUTES_COUNTER_UPDATE_INTERVAL); 1035 mlxsw_core_schedule_dw(&mr->stats_update_dw, interval); 1036 return 0; 1037 err: 1038 kfree(mr); 1039 return err; 1040 } 1041 1042 void mlxsw_sp_mr_fini(struct mlxsw_sp *mlxsw_sp) 1043 { 1044 struct mlxsw_sp_mr *mr = mlxsw_sp->mr; 1045 1046 cancel_delayed_work_sync(&mr->stats_update_dw); 1047 mr->mr_ops->fini(mlxsw_sp, mr->priv); 1048 kfree(mr); 1049 } 1050