Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mlxsw-preparations-for-nexthop-objects-support-part-2-2'

Ido Schimmel says:

====================
mlxsw: Preparations for nexthop objects support - part 2/2

This patch set contains the second round of preparations towards nexthop
objects support in mlxsw. Follow up patches can be found here [1].

The patches are mostly small and trivial and contain non-functional
changes aimed at making it easier to integrate nexthop objects with
mlxsw.

Patch #1 is a fix for an issue introduced in previous submission. Found
by Coverity.

[1] https://github.com/idosch/linux/tree/submit/nexthop_objects
====================

Link: https://lore.kernel.org/r/20201117174704.291990-1-idosch@idosch.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+67 -36
+67 -36
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
··· 1353 1353 1354 1354 /* Given decap parameters, find the corresponding IPIP entry. */ 1355 1355 static struct mlxsw_sp_ipip_entry * 1356 - mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp, 1357 - const struct net_device *ul_dev, 1356 + mlxsw_sp_ipip_entry_find_by_decap(struct mlxsw_sp *mlxsw_sp, int ul_dev_ifindex, 1358 1357 enum mlxsw_sp_l3proto ul_proto, 1359 1358 union mlxsw_sp_l3addr ul_dip) 1360 1359 { 1361 - struct mlxsw_sp_ipip_entry *ipip_entry; 1360 + struct mlxsw_sp_ipip_entry *ipip_entry = NULL; 1361 + struct net_device *ul_dev; 1362 + 1363 + rcu_read_lock(); 1364 + 1365 + ul_dev = dev_get_by_index_rcu(mlxsw_sp_net(mlxsw_sp), ul_dev_ifindex); 1366 + if (!ul_dev) 1367 + goto out_unlock; 1362 1368 1363 1369 list_for_each_entry(ipip_entry, &mlxsw_sp->router->ipip_list, 1364 1370 ipip_list_node) 1365 1371 if (mlxsw_sp_ipip_entry_matches_decap(mlxsw_sp, ul_dev, 1366 1372 ul_proto, ul_dip, 1367 1373 ipip_entry)) 1368 - return ipip_entry; 1374 + goto out_unlock; 1375 + 1376 + rcu_read_unlock(); 1369 1377 1370 1378 return NULL; 1379 + 1380 + out_unlock: 1381 + rcu_read_unlock(); 1382 + return ipip_entry; 1371 1383 } 1372 1384 1373 1385 static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp, ··· 2897 2885 }; 2898 2886 struct mlxsw_sp_nexthop_group_info *nhgi; 2899 2887 enum mlxsw_sp_nexthop_group_type type; 2888 + bool can_destroy; 2900 2889 }; 2901 2890 2902 2891 void mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp, ··· 3552 3539 } 3553 3540 } 3554 3541 3555 - static void 3542 + static int 3556 3543 mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp, 3557 3544 struct mlxsw_sp_nexthop_group *nh_grp) 3558 3545 { ··· 3562 3549 bool offload_change = false; 3563 3550 u32 adj_index; 3564 3551 bool old_adj_index_valid; 3552 + int i, err2, err = 0; 3565 3553 u32 old_adj_index; 3566 - int i; 3567 - int err; 3568 3554 3569 3555 if (!nhgi->gateway) { 3570 3556 mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 3571 - return; 3557 + return 0; 3572 3558 } 3573 3559 3574 3560 for (i = 0; i < nhgi->count; i++) { ··· 3588 3576 dev_warn(mlxsw_sp->bus_info->dev, "Failed to update neigh MAC in adjacency table.\n"); 3589 3577 goto set_trap; 3590 3578 } 3591 - return; 3579 + return 0; 3592 3580 } 3593 3581 mlxsw_sp_nexthop_group_normalize(nhgi); 3594 3582 if (!nhgi->sum_norm_weight) ··· 3636 3624 dev_warn(mlxsw_sp->bus_info->dev, "Failed to add adjacency index to fib entries.\n"); 3637 3625 goto set_trap; 3638 3626 } 3639 - return; 3627 + return 0; 3640 3628 } 3641 3629 3642 3630 err = mlxsw_sp_adj_index_mass_update(mlxsw_sp, nh_grp, ··· 3648 3636 goto set_trap; 3649 3637 } 3650 3638 3651 - return; 3639 + return 0; 3652 3640 3653 3641 set_trap: 3654 3642 old_adj_index_valid = nhgi->adj_index_valid; ··· 3657 3645 nh = &nhgi->nexthops[i]; 3658 3646 nh->offloaded = 0; 3659 3647 } 3660 - err = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 3661 - if (err) 3648 + err2 = mlxsw_sp_nexthop_fib_entries_update(mlxsw_sp, nh_grp); 3649 + if (err2) 3662 3650 dev_warn(mlxsw_sp->bus_info->dev, "Failed to set traps for fib entries.\n"); 3663 3651 mlxsw_sp_nexthop_group_offload_refresh(mlxsw_sp, nh_grp); 3664 3652 if (old_adj_index_valid) 3665 3653 mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 3666 3654 nhgi->ecmp_size, nhgi->adj_index); 3655 + return err; 3667 3656 } 3668 3657 3669 3658 static void __mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp_nexthop *nh, ··· 3984 3971 3985 3972 if (!dev) 3986 3973 return 0; 3974 + nh->ifindex = dev->ifindex; 3987 3975 3988 3976 rcu_read_lock(); 3989 3977 in_dev = __in_dev_get_rcu(dev); ··· 4122 4108 if (err) 4123 4109 goto err_nexthop4_init; 4124 4110 } 4125 - mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 4111 + err = mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 4112 + if (err) 4113 + goto err_group_refresh; 4126 4114 4127 4115 return 0; 4128 4116 4117 + err_group_refresh: 4118 + i = nhgi->count; 4129 4119 err_nexthop4_init: 4130 4120 for (i--; i >= 0; i--) { 4131 4121 nh = &nhgi->nexthops[i]; ··· 4178 4160 if (err) 4179 4161 goto err_nexthop_group_insert; 4180 4162 4163 + nh_grp->can_destroy = true; 4164 + 4181 4165 return nh_grp; 4182 4166 4183 4167 err_nexthop_group_insert: ··· 4194 4174 mlxsw_sp_nexthop4_group_destroy(struct mlxsw_sp *mlxsw_sp, 4195 4175 struct mlxsw_sp_nexthop_group *nh_grp) 4196 4176 { 4177 + if (!nh_grp->can_destroy) 4178 + return; 4197 4179 mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp); 4198 4180 mlxsw_sp_nexthop4_group_info_fini(mlxsw_sp, nh_grp); 4199 4181 fib_info_put(nh_grp->ipv4.fi); ··· 4787 4765 const struct fib_entry_notifier_info *fen_info, 4788 4766 struct mlxsw_sp_fib_entry *fib_entry) 4789 4767 { 4790 - struct net_device *dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev; 4768 + struct mlxsw_sp_nexthop_group_info *nhgi = fib_entry->nh_group->nhgi; 4791 4769 union mlxsw_sp_l3addr dip = { .addr4 = htonl(fen_info->dst) }; 4792 4770 struct mlxsw_sp_router *router = mlxsw_sp->router; 4793 4771 u32 tb_id = mlxsw_sp_fix_tb_id(fen_info->tb_id); 4772 + int ifindex = nhgi->nexthops[0].ifindex; 4794 4773 struct mlxsw_sp_ipip_entry *ipip_entry; 4795 - struct fib_info *fi = fen_info->fi; 4796 4774 4797 4775 switch (fen_info->type) { 4798 4776 case RTN_LOCAL: 4799 - ipip_entry = mlxsw_sp_ipip_entry_find_by_decap(mlxsw_sp, dev, 4800 - MLXSW_SP_L3_PROTO_IPV4, dip); 4777 + ipip_entry = mlxsw_sp_ipip_entry_find_by_decap(mlxsw_sp, ifindex, 4778 + MLXSW_SP_L3_PROTO_IPV4, dip); 4801 4779 if (ipip_entry && ipip_entry->ol_dev->flags & IFF_UP) { 4802 4780 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP; 4803 4781 return mlxsw_sp_fib_entry_decap_init(mlxsw_sp, ··· 4830 4808 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE; 4831 4809 return 0; 4832 4810 case RTN_UNICAST: 4833 - if (mlxsw_sp_fi_is_gateway(mlxsw_sp, fi)) 4811 + if (nhgi->gateway) 4834 4812 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE; 4835 4813 else 4836 4814 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; ··· 4873 4851 goto err_fib_entry_priv_create; 4874 4852 } 4875 4853 4876 - err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry); 4877 - if (err) 4878 - goto err_fib4_entry_type_set; 4879 - 4880 4854 err = mlxsw_sp_nexthop4_group_get(mlxsw_sp, fib_entry, fen_info->fi); 4881 4855 if (err) 4882 4856 goto err_nexthop4_group_get; 4857 + 4858 + err = mlxsw_sp_fib4_entry_type_set(mlxsw_sp, fen_info, fib_entry); 4859 + if (err) 4860 + goto err_fib4_entry_type_set; 4883 4861 4884 4862 fib4_entry->fi = fen_info->fi; 4885 4863 fib_info_hold(fib4_entry->fi); ··· 4891 4869 4892 4870 return fib4_entry; 4893 4871 4894 - err_nexthop4_group_get: 4895 - mlxsw_sp_fib4_entry_type_unset(mlxsw_sp, fib_entry); 4896 4872 err_fib4_entry_type_set: 4873 + mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common); 4874 + err_nexthop4_group_get: 4897 4875 mlxsw_sp_fib_entry_priv_put(fib_entry->priv); 4898 4876 err_fib_entry_priv_create: 4899 4877 kfree(fib4_entry); ··· 4904 4882 struct mlxsw_sp_fib4_entry *fib4_entry) 4905 4883 { 4906 4884 fib_info_put(fib4_entry->fi); 4907 - mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common); 4908 4885 mlxsw_sp_fib4_entry_type_unset(mlxsw_sp, &fib4_entry->common); 4886 + mlxsw_sp_nexthop4_group_put(mlxsw_sp, &fib4_entry->common); 4909 4887 mlxsw_sp_fib_entry_priv_put(fib4_entry->common.priv); 4910 4888 kfree(fib4_entry); 4911 4889 } ··· 5333 5311 { 5334 5312 struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh; 5335 5313 5336 - fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; 5314 + if (!mlxsw_sp_rt6->rt->nh) 5315 + fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; 5337 5316 mlxsw_sp_rt6_release(mlxsw_sp_rt6->rt); 5338 5317 kfree(mlxsw_sp_rt6); 5339 5318 } ··· 5437 5414 mlxsw_sp_rt6 = list_next_entry(mlxsw_sp_rt6, list); 5438 5415 } 5439 5416 nh_grp->nhgi = nhgi; 5440 - mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 5417 + err = mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); 5418 + if (err) 5419 + goto err_group_refresh; 5441 5420 5442 5421 return 0; 5443 5422 5423 + err_group_refresh: 5424 + i = nhgi->count; 5444 5425 err_nexthop6_init: 5445 5426 for (i--; i >= 0; i--) { 5446 5427 nh = &nhgi->nexthops[i]; 5447 5428 mlxsw_sp_nexthop6_fini(mlxsw_sp, nh); 5448 5429 } 5449 - kfree(nh_grp); 5430 + kfree(nhgi); 5450 5431 return err; 5451 5432 } 5452 5433 ··· 5492 5465 if (err) 5493 5466 goto err_nexthop_group_insert; 5494 5467 5468 + nh_grp->can_destroy = true; 5469 + 5495 5470 return nh_grp; 5496 5471 5497 5472 err_nexthop_group_insert: ··· 5507 5478 mlxsw_sp_nexthop6_group_destroy(struct mlxsw_sp *mlxsw_sp, 5508 5479 struct mlxsw_sp_nexthop_group *nh_grp) 5509 5480 { 5481 + if (!nh_grp->can_destroy) 5482 + return; 5510 5483 mlxsw_sp_nexthop_group_remove(mlxsw_sp, nh_grp); 5511 5484 mlxsw_sp_nexthop6_group_info_fini(mlxsw_sp, nh_grp); 5512 5485 kfree(nh_grp); ··· 5526 5495 return PTR_ERR(nh_grp); 5527 5496 } 5528 5497 5529 - list_add_tail(&fib6_entry->common.nexthop_group_node, 5530 - &nh_grp->fib_list); 5531 - fib6_entry->common.nh_group = nh_grp; 5532 - 5533 5498 /* The route and the nexthop are described by the same struct, so we 5534 5499 * need to the update the nexthop offload indication for the new route. 5535 5500 */ 5536 5501 __mlxsw_sp_nexthop6_group_offload_refresh(nh_grp, fib6_entry); 5502 + 5503 + list_add_tail(&fib6_entry->common.nexthop_group_node, 5504 + &nh_grp->fib_list); 5505 + fib6_entry->common.nh_group = nh_grp; 5537 5506 5538 5507 return 0; 5539 5508 } ··· 5658 5627 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_BLACKHOLE; 5659 5628 else if (rt->fib6_flags & RTF_REJECT) 5660 5629 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_UNREACHABLE; 5661 - else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt)) 5630 + else if (fib_entry->nh_group->nhgi->gateway) 5662 5631 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE; 5663 5632 else 5664 5633 fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; ··· 5710 5679 fib6_entry->nrt6++; 5711 5680 } 5712 5681 5713 - mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, rt_arr[0]); 5714 - 5715 5682 err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry); 5716 5683 if (err) 5717 5684 goto err_nexthop6_group_get; 5685 + 5686 + mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, rt_arr[0]); 5718 5687 5719 5688 fib_entry->fib_node = fib_node; 5720 5689