History

Merge branch 'mlxsw-maintain-candidate-rifs'

Petr Machata says: ==================== mlxsw: Maintain candidate RIFs The mlxsw driver currently makes the assumption that the user applies configuration in a bottom-up manner. Thus netdevices need to be added to the bridge before IP addresses are configured on that bridge or SVI added on top of it. Enslaving a netdevice to another netdevice that already has uppers is in fact forbidden by mlxsw for this reason. Despite this safety, it is rather easy to get into situations where the offloaded configuration is just plain wrong. As an example, take a front panel port, configure an IP address: it gets a RIF. Now enslave the port to the bridge, and the RIF is gone. Remove the port from the bridge again, but the RIF never comes back. There is a number of similar situations, where changing the configuration there and back utterly breaks the offload. The situation is going to be made better by implementing a range of replays and post-hoc offloads. This patch set lays the ground for replay of next hops. The particular issue that it deals with is that currently, driver-specific bookkeeping for next hops is hooked off RIF objects, which come and go across the lifetime of a netdevice. We would rather keep these objects at an entity that mirrors the lifetime of the netdevice itself. That way they are at hand and can be offloaded when a RIF is eventually created. To that end, with this patchset, mlxsw keeps a hash table of CRIFs: candidate RIFs, persistent handles for netdevices that mlxsw deems potentially interesting. The lifetime of a CRIF matches that of the underlying netdevice, and thus a RIF can always assume a CRIF exists. A CRIF is where next hops are kept, and when RIF is created, these next hops can be easily offloaded. (Previously only the next hops created after the RIF was created were offloaded.) - Patches #1 and #2 are minor adjustments. - In patches #3 and #4, add CRIF bookkeeping. - In patch #5, link CRIFs to RIFs such that given a netdevice-backed RIF, the corresponding CRIF is easy to look up. - Patch #6 is a clean-up allowed by the previous patches - Patches #7 and #8 move next hop tracking to CRIFs No observable effects are intended as of yet. This will be useful once there is support for RIF creation for netdevices that become mlxsw uppers, which will come in following patch sets. ====================

Jakub Kicinski committed 3 years ago

Commit d1d29a42 parents faaa5fd 9464a3d2 files · +326 −79Browse files

Unified · Split

2 files
  1. drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +324 −78
  2. drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +2 −1
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c+324−78
@@ -51,10 +51,27 @@ struct mlxsw_sp_vr; · 50 unmodified lines
51struct mlxsw_sp_lpm_tree;51struct mlxsw_sp_lpm_tree;
52struct mlxsw_sp_rif_ops;52struct mlxsw_sp_rif_ops;
53 53
54struct mlxsw_sp_rif {54struct mlxsw_sp_crif_key {
55 struct net_device *dev;
56};
57
58struct mlxsw_sp_crif {
59 struct mlxsw_sp_crif_key key;
60 struct rhash_head ht_node;
61 bool can_destroy;
55 struct list_head nexthop_list;62 struct list_head nexthop_list;
63 struct mlxsw_sp_rif *rif;
64};
65
66static const struct rhashtable_params mlxsw_sp_crif_ht_params = {
67 .key_offset = offsetof(struct mlxsw_sp_crif, key),
68 .key_len = sizeof_field(struct mlxsw_sp_crif, key),
69 .head_offset = offsetof(struct mlxsw_sp_crif, ht_node),
70};
71
72struct mlxsw_sp_rif {
73 struct mlxsw_sp_crif *crif; /* NULL for underlay RIF */
56 struct list_head neigh_list;74 struct list_head neigh_list;
57 struct net_device *dev; /* NULL for underlay RIF */
58 struct mlxsw_sp_fid *fid;75 struct mlxsw_sp_fid *fid;
59 unsigned char addr[ETH_ALEN];76 unsigned char addr[ETH_ALEN];
60 int mtu;77 int mtu;
@@ -73,7 +90,9 @@ struct mlxsw_sp_rif { · 12 unmodified lines
73 90
74static struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)91static struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
75{92{
76 return rif->dev;93 if (!rif->crif)
94 return NULL;
95 return rif->crif->key.dev;
77}96}
78 97
79struct mlxsw_sp_rif_params {98struct mlxsw_sp_rif_params {
@@ -1060,6 +1079,61 @@ u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev) · 980 unmodified lines
1060 return tb_id;1079 return tb_id;
1061}1080}
1062 1081
1082static void
1083mlxsw_sp_crif_init(struct mlxsw_sp_crif *crif, struct net_device *dev)
1084{
1085 crif->key.dev = dev;
1086 INIT_LIST_HEAD(&crif->nexthop_list);
1087}
1088
1089static struct mlxsw_sp_crif *
1090mlxsw_sp_crif_alloc(struct net_device *dev)
1091{
1092 struct mlxsw_sp_crif *crif;
1093
1094 crif = kzalloc(sizeof(*crif), GFP_KERNEL);
1095 if (!crif)
1096 return NULL;
1097
1098 mlxsw_sp_crif_init(crif, dev);
1099 return crif;
1100}
1101
1102static void mlxsw_sp_crif_free(struct mlxsw_sp_crif *crif)
1103{
1104 if (WARN_ON(crif->rif))
1105 return;
1106
1107 WARN_ON(!list_empty(&crif->nexthop_list));
1108 kfree(crif);
1109}
1110
1111static int mlxsw_sp_crif_insert(struct mlxsw_sp_router *router,
1112 struct mlxsw_sp_crif *crif)
1113{
1114 return rhashtable_insert_fast(&router->crif_ht, &crif->ht_node,
1115 mlxsw_sp_crif_ht_params);
1116}
1117
1118static void mlxsw_sp_crif_remove(struct mlxsw_sp_router *router,
1119 struct mlxsw_sp_crif *crif)
1120{
1121 rhashtable_remove_fast(&router->crif_ht, &crif->ht_node,
1122 mlxsw_sp_crif_ht_params);
1123}
1124
1125static struct mlxsw_sp_crif *
1126mlxsw_sp_crif_lookup(struct mlxsw_sp_router *router,
1127 const struct net_device *dev)
1128{
1129 struct mlxsw_sp_crif_key key = {
1130 .dev = (struct net_device *)dev,
1131 };
1132
1133 return rhashtable_lookup_fast(&router->crif_ht, &key,
1134 mlxsw_sp_crif_ht_params);
1135}
1136
1063static struct mlxsw_sp_rif *1137static struct mlxsw_sp_rif *
1064mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,1138mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
1065 const struct mlxsw_sp_rif_params *params,1139 const struct mlxsw_sp_rif_params *params,
@@ -1648,17 +1722,26 @@ static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp, · 582 unmodified lines
1648 mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);1722 mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);
1649}1723}
1650 1724
1651static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,1725static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
1652 struct mlxsw_sp_rif *old_rif,1726 struct mlxsw_sp_rif *rif);
1653 struct mlxsw_sp_rif *new_rif);1727
1654static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp,1728static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp,
1655 struct mlxsw_sp_rif *old_rif,1729 struct mlxsw_sp_rif *old_rif,
1656 struct mlxsw_sp_rif *new_rif,1730 struct mlxsw_sp_rif *new_rif,
1657 bool migrate_nhs)1731 bool migrate_nhs)
1658{1732{
1733 struct mlxsw_sp_crif *crif = old_rif->crif;
1734 struct mlxsw_sp_crif mock_crif = {};
1735
1659 if (migrate_nhs)1736 if (migrate_nhs)
1660 mlxsw_sp_nexthop_rif_migrate(mlxsw_sp, old_rif, new_rif);1737 mlxsw_sp_nexthop_rif_update(mlxsw_sp, new_rif);
1661 1738
1739 /* Plant a mock CRIF so that destroying the old RIF doesn't unoffload
1740 * our nexthops and IPIP tunnels, and doesn't sever the crif->rif link.
1741 */
1742 mlxsw_sp_crif_init(&mock_crif, crif->key.dev);
1743 old_rif->crif = &mock_crif;
1744 mock_crif.rif = old_rif;
1662 mlxsw_sp_rif_destroy(old_rif);1745 mlxsw_sp_rif_destroy(old_rif);
1663}1746}
1664 1747
@@ -1684,9 +1767,6 @@ mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, · 19 unmodified lines
1684 return 0;1767 return 0;
1685}1768}
1686 1769
1687static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
1688 struct mlxsw_sp_rif *rif);
1689
1690/**1770/**
1691 * __mlxsw_sp_ipip_entry_update_tunnel - Update offload related to IPIP entry.1771 * __mlxsw_sp_ipip_entry_update_tunnel - Update offload related to IPIP entry.
1692 * @mlxsw_sp: mlxsw_sp.1772 * @mlxsw_sp: mlxsw_sp.
@@ -2915,7 +2995,7 @@ struct mlxsw_sp_nexthop_key { · 1222 unmodified lines
2915 2995
2916struct mlxsw_sp_nexthop {2996struct mlxsw_sp_nexthop {
2917 struct list_head neigh_list_node; /* member of neigh entry list */2997 struct list_head neigh_list_node; /* member of neigh entry list */
2918 struct list_head rif_list_node;2998 struct list_head crif_list_node;
2919 struct list_head router_list_node;2999 struct list_head router_list_node;
2920 struct mlxsw_sp_nexthop_group_info *nhgi; /* pointer back to the group3000 struct mlxsw_sp_nexthop_group_info *nhgi; /* pointer back to the group
2921 * this nexthop belongs to3001 * this nexthop belongs to
@@ -2928,7 +3008,7 @@ struct mlxsw_sp_nexthop { · 6 unmodified lines
2928 int nh_weight;3008 int nh_weight;
2929 int norm_nh_weight;3009 int norm_nh_weight;
2930 int num_adj_entries;3010 int num_adj_entries;
2931 struct mlxsw_sp_rif *rif;3011 struct mlxsw_sp_crif *crif;
2932 u8 should_offload:1, /* set indicates this nexthop should be written3012 u8 should_offload:1, /* set indicates this nexthop should be written
2933 * to the adjacency table.3013 * to the adjacency table.
2934 */3014 */
@@ -2951,9 +3031,9 @@ struct mlxsw_sp_nexthop { · 16 unmodified lines
2951static struct net_device *3031static struct net_device *
2952mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh)3032mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh)
2953{3033{
2954 if (nh->rif)3034 if (!nh->crif)
2955 return mlxsw_sp_rif_dev(nh->rif);3035 return NULL;
2956 return NULL;3036 return nh->crif->key.dev;
2957}3037}
2958 3038
2959enum mlxsw_sp_nexthop_group_type {3039enum mlxsw_sp_nexthop_group_type {
@@ -2978,7 +3058,11 @@ struct mlxsw_sp_nexthop_group_info { · 18 unmodified lines
2978static struct mlxsw_sp_rif *3058static struct mlxsw_sp_rif *
2979mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi)3059mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi)
2980{3060{
2981 return nhgi->nexthops[0].rif;3061 struct mlxsw_sp_crif *crif = nhgi->nexthops[0].crif;
3062
3063 if (!crif)
3064 return NULL;
3065 return crif->rif;
2982}3066}
2983 3067
2984struct mlxsw_sp_nexthop_group_vr_key {3068struct mlxsw_sp_nexthop_group_vr_key {
@@ -3102,7 +3186,9 @@ int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index, · 117 unmodified lines
3102 3186
3103struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh)3187struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh)
3104{3188{
3105 return nh->rif;3189 if (WARN_ON(!nh->crif))
3190 return NULL;
3191 return nh->crif->rif;
3106}3192}
3107 3193
3108bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)3194bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)
@@ -3487,11 +3573,12 @@ static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, · 378 unmodified lines
3487 bool force, char *ratr_pl)3573 bool force, char *ratr_pl)
3488{3574{
3489 struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;3575 struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
3576 struct mlxsw_sp_rif *rif = mlxsw_sp_nexthop_rif(nh);
3490 enum mlxsw_reg_ratr_op op;3577 enum mlxsw_reg_ratr_op op;
3491 u16 rif_index;3578 u16 rif_index;
3492 3579
3493 rif_index = nh->rif ? nh->rif->rif_index :3580 rif_index = rif ? rif->rif_index :
3494 mlxsw_sp->router->lb_rif_index;3581 mlxsw_sp->router->lb_crif->rif->rif_index;
3495 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :3582 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
3496 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;3583 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
3497 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_ETHERNET,3584 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_ETHERNET,
@@ -4109,23 +4196,23 @@ mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, · 611 unmodified lines
4109 }4196 }
4110}4197}
4111 4198
4112static void mlxsw_sp_nexthop_rif_init(struct mlxsw_sp_nexthop *nh,4199static void mlxsw_sp_nexthop_crif_init(struct mlxsw_sp_nexthop *nh,
4113 struct mlxsw_sp_rif *rif)4200 struct mlxsw_sp_crif *crif)
4114{4201{
4115 if (nh->rif)4202 if (nh->crif)
4116 return;4203 return;
4117 4204
4118 nh->rif = rif;4205 nh->crif = crif;
4119 list_add(&nh->rif_list_node, &rif->nexthop_list);4206 list_add(&nh->crif_list_node, &crif->nexthop_list);
4120}4207}
4121 4208
4122static void mlxsw_sp_nexthop_rif_fini(struct mlxsw_sp_nexthop *nh)4209static void mlxsw_sp_nexthop_crif_fini(struct mlxsw_sp_nexthop *nh)
4123{4210{
4124 if (!nh->rif)4211 if (!nh->crif)
4125 return;4212 return;
4126 4213
4127 list_del(&nh->rif_list_node);4214 list_del(&nh->crif_list_node);
4128 nh->rif = NULL;4215 nh->crif = NULL;
4129}4216}
4130 4217
4131static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,4218static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
@@ -4137,6 +4224,9 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, · 5 unmodified lines
4137 u8 nud_state, dead;4224 u8 nud_state, dead;
4138 int err;4225 int err;
4139 4226
4227 if (WARN_ON(!nh->crif->rif))
4228 return 0;
4229
4140 if (!nh->nhgi->gateway || nh->neigh_entry)4230 if (!nh->nhgi->gateway || nh->neigh_entry)
4141 return 0;4231 return 0;
4142 dev = mlxsw_sp_nexthop_dev(nh);4232 dev = mlxsw_sp_nexthop_dev(nh);
@@ -4227,15 +4317,20 @@ static void mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp, · 84 unmodified lines
4227 struct mlxsw_sp_nexthop *nh,4317 struct mlxsw_sp_nexthop *nh,
4228 struct mlxsw_sp_ipip_entry *ipip_entry)4318 struct mlxsw_sp_ipip_entry *ipip_entry)
4229{4319{
4320 struct mlxsw_sp_crif *crif;
4230 bool removing;4321 bool removing;
4231 4322
4232 if (!nh->nhgi->gateway || nh->ipip_entry)4323 if (!nh->nhgi->gateway || nh->ipip_entry)
4233 return;4324 return;
4234 4325
4326 crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, ipip_entry->ol_dev);
4327 if (WARN_ON(!crif))
4328 return;
4329
4235 nh->ipip_entry = ipip_entry;4330 nh->ipip_entry = ipip_entry;
4236 removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev);4331 removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev);
4237 __mlxsw_sp_nexthop_neigh_update(nh, removing);4332 __mlxsw_sp_nexthop_neigh_update(nh, removing);
4238 mlxsw_sp_nexthop_rif_init(nh, &ipip_entry->ol_lb->common);4333 mlxsw_sp_nexthop_crif_init(nh, crif);
4239}4334}
4240 4335
4241static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,4336static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,
@@ -4267,7 +4362,7 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 25 unmodified lines
4267{4362{
4268 const struct mlxsw_sp_ipip_ops *ipip_ops;4363 const struct mlxsw_sp_ipip_ops *ipip_ops;
4269 struct mlxsw_sp_ipip_entry *ipip_entry;4364 struct mlxsw_sp_ipip_entry *ipip_entry;
4270 struct mlxsw_sp_rif *rif;4365 struct mlxsw_sp_crif *crif;
4271 int err;4366 int err;
4272 4367
4273 ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, dev);4368 ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, dev);
@@ -4281,11 +4376,15 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 7 unmodified lines
4281 }4376 }
4282 4377
4283 nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;4378 nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
4284 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);4379 crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, dev);
4285 if (!rif)4380 if (!crif)
4381 return 0;
4382
4383 mlxsw_sp_nexthop_crif_init(nh, crif);
4384
4385 if (!crif->rif)
4286 return 0;4386 return 0;
4287 4387
4288 mlxsw_sp_nexthop_rif_init(nh, rif);
4289 err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);4388 err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
4290 if (err)4389 if (err)
4291 goto err_neigh_init;4390 goto err_neigh_init;
@@ -4293,25 +4392,30 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 1 unmodified line
4293 return 0;4392 return 0;
4294 4393
4295err_neigh_init:4394err_neigh_init:
4296 mlxsw_sp_nexthop_rif_fini(nh);4395 mlxsw_sp_nexthop_crif_fini(nh);
4297 return err;4396 return err;
4298}4397}
4299 4398
4300static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,4399static void mlxsw_sp_nexthop_type_rif_gone(struct mlxsw_sp *mlxsw_sp,
4301 struct mlxsw_sp_nexthop *nh)4400 struct mlxsw_sp_nexthop *nh)
4302{4401{
4303 switch (nh->type) {4402 switch (nh->type) {
4304 case MLXSW_SP_NEXTHOP_TYPE_ETH:4403 case MLXSW_SP_NEXTHOP_TYPE_ETH:
4305 mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);4404 mlxsw_sp_nexthop_neigh_fini(mlxsw_sp, nh);
4306 mlxsw_sp_nexthop_rif_fini(nh);
4307 break;4405 break;
4308 case MLXSW_SP_NEXTHOP_TYPE_IPIP:4406 case MLXSW_SP_NEXTHOP_TYPE_IPIP:
4309 mlxsw_sp_nexthop_rif_fini(nh);
4310 mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);4407 mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);
4311 break;4408 break;
4312 }4409 }
4313}4410}
4314 4411
4412static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
4413 struct mlxsw_sp_nexthop *nh)
4414{
4415 mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh);
4416 mlxsw_sp_nexthop_crif_fini(nh);
4417}
4418
4315static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,4419static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
4316 struct mlxsw_sp_nexthop_group *nh_grp,4420 struct mlxsw_sp_nexthop_group *nh_grp,
4317 struct mlxsw_sp_nexthop *nh,4421 struct mlxsw_sp_nexthop *nh,
@@ -4402,7 +4506,7 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, · 84 unmodified lines
4402 struct mlxsw_sp_nexthop *nh;4506 struct mlxsw_sp_nexthop *nh;
4403 bool removing;4507 bool removing;
4404 4508
4405 list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) {4509 list_for_each_entry(nh, &rif->crif->nexthop_list, crif_list_node) {
4406 switch (nh->type) {4510 switch (nh->type) {
4407 case MLXSW_SP_NEXTHOP_TYPE_ETH:4511 case MLXSW_SP_NEXTHOP_TYPE_ETH:
4408 removing = false;4512 removing = false;
@@ -4420,25 +4524,14 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, · 11 unmodified lines
4420 }4524 }
4421}4525}
4422 4526
4423static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,
4424 struct mlxsw_sp_rif *old_rif,
4425 struct mlxsw_sp_rif *new_rif)
4426{
4427 struct mlxsw_sp_nexthop *nh;
4428
4429 list_splice_init(&old_rif->nexthop_list, &new_rif->nexthop_list);
4430 list_for_each_entry(nh, &new_rif->nexthop_list, rif_list_node)
4431 nh->rif = new_rif;
4432 mlxsw_sp_nexthop_rif_update(mlxsw_sp, new_rif);
4433}
4434
4435static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,4527static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
4436 struct mlxsw_sp_rif *rif)4528 struct mlxsw_sp_rif *rif)
4437{4529{
4438 struct mlxsw_sp_nexthop *nh, *tmp;4530 struct mlxsw_sp_nexthop *nh, *tmp;
4439 4531
4440 list_for_each_entry_safe(nh, tmp, &rif->nexthop_list, rif_list_node) {4532 list_for_each_entry_safe(nh, tmp, &rif->crif->nexthop_list,
4441 mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);4533 crif_list_node) {
4534 mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh);
4442 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);4535 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
4443 }4536 }
4444}4537}
@@ -4458,7 +4551,7 @@ static int mlxsw_sp_adj_trap_entry_init(struct mlxsw_sp *mlxsw_sp) · 13 unmodified lines
4458 mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,4551 mlxsw_reg_ratr_pack(ratr_pl, MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY, true,
4459 MLXSW_REG_RATR_TYPE_ETHERNET,4552 MLXSW_REG_RATR_TYPE_ETHERNET,
4460 mlxsw_sp->router->adj_trap_index,4553 mlxsw_sp->router->adj_trap_index,
4461 mlxsw_sp->router->lb_rif_index);4554 mlxsw_sp->router->lb_crif->rif->rif_index);
4462 mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);4555 mlxsw_reg_ratr_trap_action_set(ratr_pl, trap_action);
4463 mlxsw_reg_ratr_trap_id_set(ratr_pl, MLXSW_TRAP_ID_RTR_EGRESS0);4556 mlxsw_reg_ratr_trap_id_set(ratr_pl, MLXSW_TRAP_ID_RTR_EGRESS0);
4464 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);4557 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ratr), ratr_pl);
@@ -4774,21 +4867,19 @@ static bool mlxsw_sp_nexthop_obj_is_gateway(struct mlxsw_sp *mlxsw_sp, · 309 unmodified lines
4774static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp,4867static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp,
4775 struct mlxsw_sp_nexthop *nh)4868 struct mlxsw_sp_nexthop *nh)
4776{4869{
4777 u16 lb_rif_index = mlxsw_sp->router->lb_rif_index;
4778
4779 nh->action = MLXSW_SP_NEXTHOP_ACTION_DISCARD;4870 nh->action = MLXSW_SP_NEXTHOP_ACTION_DISCARD;
4780 nh->should_offload = 1;4871 nh->should_offload = 1;
4781 /* While nexthops that discard packets do not forward packets4872 /* While nexthops that discard packets do not forward packets
4782 * via an egress RIF, they still need to be programmed using a4873 * via an egress RIF, they still need to be programmed using a
4783 * valid RIF, so use the loopback RIF created during init.4874 * valid RIF, so use the loopback RIF created during init.
4784 */4875 */
4785 nh->rif = mlxsw_sp->router->rifs[lb_rif_index];4876 nh->crif = mlxsw_sp->router->lb_crif;
4786}4877}
4787 4878
4788static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp,4879static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp,
4789 struct mlxsw_sp_nexthop *nh)4880 struct mlxsw_sp_nexthop *nh)
4790{4881{
4791 nh->rif = NULL;4882 nh->crif = NULL;
4792 nh->should_offload = 0;4883 nh->should_offload = 0;
4793}4884}
4794 4885
@@ -7796,6 +7887,9 @@ static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif) · 3001 unmodified lines
7796static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,7887static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
7797 struct mlxsw_sp_rif *rif)7888 struct mlxsw_sp_rif *rif)
7798{7889{
7890 /* Signal to nexthop cleanup that the RIF is going away. */
7891 rif->crif->rif = NULL;
7892
7799 mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index);7893 mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index);
7800 mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif);7894 mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif);
7801 mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);7895 mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);
@@ -7905,23 +7999,26 @@ static void mlxsw_sp_rif_index_free(struct mlxsw_sp *mlxsw_sp, u16 rif_index, · 103 unmodified lines
7905 7999
7906static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index,8000static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index,
7907 u16 vr_id,8001 u16 vr_id,
7908 struct net_device *l3_dev)8002 struct mlxsw_sp_crif *crif)
7909{8003{
8004 struct net_device *l3_dev = crif ? crif->key.dev : NULL;
7910 struct mlxsw_sp_rif *rif;8005 struct mlxsw_sp_rif *rif;
7911 8006
7912 rif = kzalloc(rif_size, GFP_KERNEL);8007 rif = kzalloc(rif_size, GFP_KERNEL);
7913 if (!rif)8008 if (!rif)
7914 return NULL;8009 return NULL;
7915 8010
7916 INIT_LIST_HEAD(&rif->nexthop_list);
7917 INIT_LIST_HEAD(&rif->neigh_list);8011 INIT_LIST_HEAD(&rif->neigh_list);
7918 if (l3_dev) {8012 if (l3_dev) {
7919 ether_addr_copy(rif->addr, l3_dev->dev_addr);8013 ether_addr_copy(rif->addr, l3_dev->dev_addr);
7920 rif->mtu = l3_dev->mtu;8014 rif->mtu = l3_dev->mtu;
7921 rif->dev = l3_dev;
7922 }8015 }
7923 rif->vr_id = vr_id;8016 rif->vr_id = vr_id;
7924 rif->rif_index = rif_index;8017 rif->rif_index = rif_index;
8018 if (crif) {
8019 rif->crif = crif;
8020 crif->rif = rif;
8021 }
7925 8022
7926 return rif;8023 return rif;
7927}8024}
@@ -7929,7 +8026,9 @@ static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index, · 1 unmodified line
7929static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif)8026static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif)
7930{8027{
7931 WARN_ON(!list_empty(&rif->neigh_list));8028 WARN_ON(!list_empty(&rif->neigh_list));
7932 WARN_ON(!list_empty(&rif->nexthop_list));8029
8030 if (rif->crif)
8031 rif->crif->rif = NULL;
7933 kfree(rif);8032 kfree(rif);
7934}8033}
7935 8034
@@ -8163,6 +8262,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, · 227 unmodified lines
8163 const struct mlxsw_sp_rif_ops *ops;8262 const struct mlxsw_sp_rif_ops *ops;
8164 struct mlxsw_sp_fid *fid = NULL;8263 struct mlxsw_sp_fid *fid = NULL;
8165 enum mlxsw_sp_rif_type type;8264 enum mlxsw_sp_rif_type type;
8265 struct mlxsw_sp_crif *crif;
8166 struct mlxsw_sp_rif *rif;8266 struct mlxsw_sp_rif *rif;
8167 struct mlxsw_sp_vr *vr;8267 struct mlxsw_sp_vr *vr;
8168 u16 rif_index;8268 u16 rif_index;
@@ -8182,7 +8282,13 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, · 13 unmodified lines
8182 goto err_rif_index_alloc;8282 goto err_rif_index_alloc;
8183 }8283 }
8184 8284
8185 rif = mlxsw_sp_rif_alloc(ops->rif_size, rif_index, vr->id, params->dev);8285 crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, params->dev);
8286 if (WARN_ON(!crif)) {
8287 err = -ENOENT;
8288 goto err_crif_lookup;
8289 }
8290
8291 rif = mlxsw_sp_rif_alloc(ops->rif_size, rif_index, vr->id, crif);
8186 if (!rif) {8292 if (!rif) {
8187 err = -ENOMEM;8293 err = -ENOMEM;
8188 goto err_rif_alloc;8294 goto err_rif_alloc;
@@ -8241,6 +8347,7 @@ err_fid_get: · 52 unmodified lines
8241 dev_put(params->dev);8347 dev_put(params->dev);
8242 mlxsw_sp_rif_free(rif);8348 mlxsw_sp_rif_free(rif);
8243err_rif_alloc:8349err_rif_alloc:
8350err_crif_lookup:
8244 mlxsw_sp_rif_index_free(mlxsw_sp, rif_index, rif_entries);8351 mlxsw_sp_rif_index_free(mlxsw_sp, rif_index, rif_entries);
8245err_rif_index_alloc:8352err_rif_index_alloc:
8246 vr->rif_count--;8353 vr->rif_count--;
@@ -8253,6 +8360,7 @@ static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) · 6 unmodified lines
8253 struct net_device *dev = mlxsw_sp_rif_dev(rif);8360 struct net_device *dev = mlxsw_sp_rif_dev(rif);
8254 const struct mlxsw_sp_rif_ops *ops = rif->ops;8361 const struct mlxsw_sp_rif_ops *ops = rif->ops;
8255 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;8362 struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
8363 struct mlxsw_sp_crif *crif = rif->crif;
8256 struct mlxsw_sp_fid *fid = rif->fid;8364 struct mlxsw_sp_fid *fid = rif->fid;
8257 u8 rif_entries = rif->rif_entries;8365 u8 rif_entries = rif->rif_entries;
8258 u16 rif_index = rif->rif_index;8366 u16 rif_index = rif->rif_index;
@@ -8283,6 +8391,9 @@ static void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) · 24 unmodified lines
8283 mlxsw_sp_rif_index_free(mlxsw_sp, rif_index, rif_entries);8391 mlxsw_sp_rif_index_free(mlxsw_sp, rif_index, rif_entries);
8284 vr->rif_count--;8392 vr->rif_count--;
8285 mlxsw_sp_vr_put(mlxsw_sp, vr);8393 mlxsw_sp_vr_put(mlxsw_sp, vr);
8394
8395 if (crif->can_destroy)
8396 mlxsw_sp_crif_free(crif);
8286}8397}
8287 8398
8288void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,8399void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
@@ -9148,6 +9259,104 @@ static int mlxsw_sp_router_port_pre_changeaddr_event(struct mlxsw_sp_rif *rif, · 859 unmodified lines
9148 return -ENOBUFS;9259 return -ENOBUFS;
9149}9260}
9150 9261
9262static bool mlxsw_sp_router_netdevice_interesting(struct mlxsw_sp *mlxsw_sp,
9263 struct net_device *dev)
9264{
9265 struct vlan_dev_priv *vlan;
9266
9267 if (netif_is_lag_master(dev) ||
9268 netif_is_bridge_master(dev) ||
9269 mlxsw_sp_port_dev_check(dev) ||
9270 mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev) ||
9271 netif_is_l3_master(dev))
9272 return true;
9273
9274 if (!is_vlan_dev(dev))
9275 return false;
9276
9277 vlan = vlan_dev_priv(dev);
9278 return netif_is_lag_master(vlan->real_dev) ||
9279 netif_is_bridge_master(vlan->real_dev) ||
9280 mlxsw_sp_port_dev_check(vlan->real_dev);
9281}
9282
9283static struct mlxsw_sp_crif *
9284mlxsw_sp_crif_register(struct mlxsw_sp_router *router, struct net_device *dev)
9285{
9286 struct mlxsw_sp_crif *crif;
9287 int err;
9288
9289 if (WARN_ON(mlxsw_sp_crif_lookup(router, dev)))
9290 return NULL;
9291
9292 crif = mlxsw_sp_crif_alloc(dev);
9293 if (!crif)
9294 return ERR_PTR(-ENOMEM);
9295
9296 err = mlxsw_sp_crif_insert(router, crif);
9297 if (err)
9298 goto err_netdev_insert;
9299
9300 return crif;
9301
9302err_netdev_insert:
9303 mlxsw_sp_crif_free(crif);
9304 return ERR_PTR(err);
9305}
9306
9307static void mlxsw_sp_crif_unregister(struct mlxsw_sp_router *router,
9308 struct mlxsw_sp_crif *crif)
9309{
9310 struct mlxsw_sp_nexthop *nh, *tmp;
9311
9312 mlxsw_sp_crif_remove(router, crif);
9313
9314 list_for_each_entry_safe(nh, tmp, &crif->nexthop_list, crif_list_node)
9315 mlxsw_sp_nexthop_type_fini(router->mlxsw_sp, nh);
9316
9317 if (crif->rif)
9318 crif->can_destroy = true;
9319 else
9320 mlxsw_sp_crif_free(crif);
9321}
9322
9323static int mlxsw_sp_netdevice_register(struct mlxsw_sp_router *router,
9324 struct net_device *dev)
9325{
9326 struct mlxsw_sp_crif *crif;
9327
9328 if (!mlxsw_sp_router_netdevice_interesting(router->mlxsw_sp, dev))
9329 return 0;
9330
9331 crif = mlxsw_sp_crif_register(router, dev);
9332 return PTR_ERR_OR_ZERO(crif);
9333}
9334
9335static void mlxsw_sp_netdevice_unregister(struct mlxsw_sp_router *router,
9336 struct net_device *dev)
9337{
9338 struct mlxsw_sp_crif *crif;
9339
9340 if (!mlxsw_sp_router_netdevice_interesting(router->mlxsw_sp, dev))
9341 return;
9342
9343 /* netdev_run_todo(), by way of netdev_wait_allrefs_any(), rebroadcasts
9344 * the NETDEV_UNREGISTER message, so we can get here twice. If that's
9345 * what happened, the netdevice state is NETREG_UNREGISTERED. In that
9346 * case, we expect to have collected the CRIF already, and warn if it
9347 * still exists. Otherwise we expect the CRIF to exist.
9348 */
9349 crif = mlxsw_sp_crif_lookup(router, dev);
9350 if (dev->reg_state == NETREG_UNREGISTERED) {
9351 if (!WARN_ON(crif))
9352 return;
9353 }
9354 if (WARN_ON(!crif))
9355 return;
9356
9357 mlxsw_sp_crif_unregister(router, crif);
9358}
9359
9151static bool mlxsw_sp_is_offload_xstats_event(unsigned long event)9360static bool mlxsw_sp_is_offload_xstats_event(unsigned long event)
9152{9361{
9153 switch (event) {9362 switch (event) {
@@ -9367,6 +9576,15 @@ static int mlxsw_sp_router_netdevice_event(struct notifier_block *nb, · 213 unmodified lines
9367 9576
9368 mutex_lock(&mlxsw_sp->router->lock);9577 mutex_lock(&mlxsw_sp->router->lock);
9369 9578
9579 if (event == NETDEV_REGISTER) {
9580 err = mlxsw_sp_netdevice_register(router, dev);
9581 if (err)
9582 /* No need to roll this back, UNREGISTER will collect it
9583 * anyhow.
9584 */
9585 goto out;
9586 }
9587
9370 if (mlxsw_sp_is_offload_xstats_event(event))9588 if (mlxsw_sp_is_offload_xstats_event(event))
9371 err = mlxsw_sp_netdevice_offload_xstats_cmd(mlxsw_sp, dev,9589 err = mlxsw_sp_netdevice_offload_xstats_cmd(mlxsw_sp, dev,
9372 event, ptr);9590 event, ptr);
@@ -9381,6 +9599,10 @@ static int mlxsw_sp_router_netdevice_event(struct notifier_block *nb, · 8 unmodified lines
9381 else if (mlxsw_sp_is_vrf_event(event, ptr))9599 else if (mlxsw_sp_is_vrf_event(event, ptr))
9382 err = mlxsw_sp_netdevice_vrf_event(dev, event, ptr);9600 err = mlxsw_sp_netdevice_vrf_event(dev, event, ptr);
9383 9601
9602 if (event == NETDEV_UNREGISTER)
9603 mlxsw_sp_netdevice_unregister(router, dev);
9604
9605out:
9384 mutex_unlock(&mlxsw_sp->router->lock);9606 mutex_unlock(&mlxsw_sp->router->lock);
9385 9607
9386 return notifier_from_errno(err);9608 return notifier_from_errno(err);
@@ -9901,6 +10123,7 @@ mlxsw_sp_rif_ipip_lb_ul_rif_op(struct mlxsw_sp_rif *ul_rif, bool enable) · 514 unmodified lines
9901 10123
9902static struct mlxsw_sp_rif *10124static struct mlxsw_sp_rif *
9903mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,10125mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr,
10126 struct mlxsw_sp_crif *ul_crif,
9904 struct netlink_ext_ack *extack)10127 struct netlink_ext_ack *extack)
9905{10128{
9906 struct mlxsw_sp_rif *ul_rif;10129 struct mlxsw_sp_rif *ul_rif;
@@ -9914,7 +10137,8 @@ mlxsw_sp_ul_rif_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_vr *vr, · 7 unmodified lines
9914 return ERR_PTR(err);10137 return ERR_PTR(err);
9915 }10138 }
9916 10139
9917 ul_rif = mlxsw_sp_rif_alloc(sizeof(*ul_rif), rif_index, vr->id, NULL);10140 ul_rif = mlxsw_sp_rif_alloc(sizeof(*ul_rif), rif_index, vr->id,
10141 ul_crif);
9918 if (!ul_rif) {10142 if (!ul_rif) {
9919 err = -ENOMEM;10143 err = -ENOMEM;
9920 goto err_rif_alloc;10144 goto err_rif_alloc;
@@ -9953,6 +10177,7 @@ static void mlxsw_sp_ul_rif_destroy(struct mlxsw_sp_rif *ul_rif) · 32 unmodified lines
9953 10177
9954static struct mlxsw_sp_rif *10178static struct mlxsw_sp_rif *
9955mlxsw_sp_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,10179mlxsw_sp_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
10180 struct mlxsw_sp_crif *ul_crif,
9956 struct netlink_ext_ack *extack)10181 struct netlink_ext_ack *extack)
9957{10182{
9958 struct mlxsw_sp_vr *vr;10183 struct mlxsw_sp_vr *vr;
@@ -9965,7 +10190,7 @@ mlxsw_sp_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id, · 6 unmodified lines
9965 if (refcount_inc_not_zero(&vr->ul_rif_refcnt))10190 if (refcount_inc_not_zero(&vr->ul_rif_refcnt))
9966 return vr->ul_rif;10191 return vr->ul_rif;
9967 10192
9968 vr->ul_rif = mlxsw_sp_ul_rif_create(mlxsw_sp, vr, extack);10193 vr->ul_rif = mlxsw_sp_ul_rif_create(mlxsw_sp, vr, ul_crif, extack);
9969 if (IS_ERR(vr->ul_rif)) {10194 if (IS_ERR(vr->ul_rif)) {
9970 err = PTR_ERR(vr->ul_rif);10195 err = PTR_ERR(vr->ul_rif);
9971 goto err_ul_rif_create;10196 goto err_ul_rif_create;
@@ -10003,7 +10228,7 @@ int mlxsw_sp_router_ul_rif_get(struct mlxsw_sp *mlxsw_sp, u32 ul_tb_id, · 31 unmodified lines
10003 int err = 0;10228 int err = 0;
10004 10229
10005 mutex_lock(&mlxsw_sp->router->lock);10230 mutex_lock(&mlxsw_sp->router->lock);
10006 ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL);10231 ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL, NULL);
10007 if (IS_ERR(ul_rif)) {10232 if (IS_ERR(ul_rif)) {
10008 err = PTR_ERR(ul_rif);10233 err = PTR_ERR(ul_rif);
10009 goto out;10234 goto out;
@@ -10039,7 +10264,7 @@ mlxsw_sp2_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif, · 29 unmodified lines
10039 struct mlxsw_sp_rif *ul_rif;10264 struct mlxsw_sp_rif *ul_rif;
10040 int err;10265 int err;
10041 10266
10042 ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, extack);10267 ul_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, ul_tb_id, NULL, extack);
10043 if (IS_ERR(ul_rif))10268 if (IS_ERR(ul_rif))
10044 return PTR_ERR(ul_rif);10269 return PTR_ERR(ul_rif);
10045 10270
@@ -10561,28 +10786,41 @@ static void __mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) · 515 unmodified lines
10561 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);10786 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rgcr), rgcr_pl);
10562}10787}
10563 10788
10564static int mlxsw_sp_lb_rif_init(struct mlxsw_sp *mlxsw_sp)10789static int mlxsw_sp_lb_rif_init(struct mlxsw_sp *mlxsw_sp,
10790 struct netlink_ext_ack *extack)
10565{10791{
10566 u16 lb_rif_index;10792 struct mlxsw_sp_router *router = mlxsw_sp->router;
10793 struct mlxsw_sp_rif *lb_rif;
10567 int err;10794 int err;
10568 10795
10796 router->lb_crif = mlxsw_sp_crif_alloc(NULL);
10797 if (IS_ERR(router->lb_crif))
10798 return PTR_ERR(router->lb_crif);
10799
10569 /* Create a generic loopback RIF associated with the main table10800 /* Create a generic loopback RIF associated with the main table
10570 * (default VRF). Any table can be used, but the main table exists10801 * (default VRF). Any table can be used, but the main table exists
10571 * anyway, so we do not waste resources.10802 * anyway, so we do not waste resources. Loopback RIFs are usually
10803 * created with a NULL CRIF, but this RIF is used as a fallback RIF
10804 * for blackhole nexthops, and nexthops expect to have a valid CRIF.
10572 */10805 */
10573 err = mlxsw_sp_router_ul_rif_get(mlxsw_sp, RT_TABLE_MAIN,10806 lb_rif = mlxsw_sp_ul_rif_get(mlxsw_sp, RT_TABLE_MAIN, router->lb_crif,
10574 &lb_rif_index);10807 extack);
10575 if (err)10808 if (IS_ERR(lb_rif)) {
10576 return err;10809 err = PTR_ERR(lb_rif);
10577 10810 goto err_ul_rif_get;
10578 mlxsw_sp->router->lb_rif_index = lb_rif_index;10811 }
10579 10812
10580 return 0;10813 return 0;
10814
10815err_ul_rif_get:
10816 mlxsw_sp_crif_free(router->lb_crif);
10817 return err;
10581}10818}
10582 10819
10583static void mlxsw_sp_lb_rif_fini(struct mlxsw_sp *mlxsw_sp)10820static void mlxsw_sp_lb_rif_fini(struct mlxsw_sp *mlxsw_sp)
10584{10821{
10585 mlxsw_sp_router_ul_rif_put(mlxsw_sp, mlxsw_sp->router->lb_rif_index);10822 mlxsw_sp_ul_rif_put(mlxsw_sp->router->lb_crif->rif);
10823 mlxsw_sp_crif_free(mlxsw_sp->router->lb_crif);
10586}10824}
10587 10825
10588static int mlxsw_sp1_router_init(struct mlxsw_sp *mlxsw_sp)10826static int mlxsw_sp1_router_init(struct mlxsw_sp *mlxsw_sp)
@@ -10647,6 +10885,11 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, · 58 unmodified lines
10647 if (err)10885 if (err)
10648 goto err_ipips_init;10886 goto err_ipips_init;
10649 10887
10888 err = rhashtable_init(&mlxsw_sp->router->crif_ht,
10889 &mlxsw_sp_crif_ht_params);
10890 if (err)
10891 goto err_crif_ht_init;
10892
10650 err = mlxsw_sp_rifs_init(mlxsw_sp);10893 err = mlxsw_sp_rifs_init(mlxsw_sp);
10651 if (err)10894 if (err)
10652 goto err_rifs_init;10895 goto err_rifs_init;
@@ -10674,7 +10917,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, · 21 unmodified lines
10674 if (err)10917 if (err)
10675 goto err_vrs_init;10918 goto err_vrs_init;
10676 10919
10677 err = mlxsw_sp_lb_rif_init(mlxsw_sp);10920 err = mlxsw_sp_lb_rif_init(mlxsw_sp, extack);
10678 if (err)10921 if (err)
10679 goto err_lb_rif_init;10922 goto err_lb_rif_init;
10680 10923
@@ -10778,6 +11021,8 @@ err_nexthop_group_ht_init: · 97 unmodified lines
10778err_nexthop_ht_init:11021err_nexthop_ht_init:
10779 mlxsw_sp_rifs_fini(mlxsw_sp);11022 mlxsw_sp_rifs_fini(mlxsw_sp);
10780err_rifs_init:11023err_rifs_init:
11024 rhashtable_destroy(&mlxsw_sp->router->crif_ht);
11025err_crif_ht_init:
10781 mlxsw_sp_ipips_fini(mlxsw_sp);11026 mlxsw_sp_ipips_fini(mlxsw_sp);
10782err_ipips_init:11027err_ipips_init:
10783 __mlxsw_sp_router_fini(mlxsw_sp);11028 __mlxsw_sp_router_fini(mlxsw_sp);
@@ -10813,6 +11058,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) · 29 unmodified lines
10813 rhashtable_destroy(&router->nexthop_group_ht);11058 rhashtable_destroy(&router->nexthop_group_ht);
10814 rhashtable_destroy(&router->nexthop_ht);11059 rhashtable_destroy(&router->nexthop_ht);
10815 mlxsw_sp_rifs_fini(mlxsw_sp);11060 mlxsw_sp_rifs_fini(mlxsw_sp);
11061 rhashtable_destroy(&mlxsw_sp->router->crif_ht);
10816 mlxsw_sp_ipips_fini(mlxsw_sp);11062 mlxsw_sp_ipips_fini(mlxsw_sp);
10817 __mlxsw_sp_router_fini(mlxsw_sp);11063 __mlxsw_sp_router_fini(mlxsw_sp);
10818 cancel_delayed_work_sync(&router->nh_grp_activity_dw);11064 cancel_delayed_work_sync(&router->nh_grp_activity_dw);
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h+2−1
@@ -20,6 +20,7 @@ struct mlxsw_sp_router_nve_decap { · 19 unmodified lines
20 20
21struct mlxsw_sp_router {21struct mlxsw_sp_router {
22 struct mlxsw_sp *mlxsw_sp;22 struct mlxsw_sp *mlxsw_sp;
23 struct rhashtable crif_ht;
23 struct gen_pool *rifs_table;24 struct gen_pool *rifs_table;
24 struct mlxsw_sp_rif **rifs;25 struct mlxsw_sp_rif **rifs;
25 struct idr rif_mac_profiles_idr;26 struct idr rif_mac_profiles_idr;
@@ -59,7 +60,7 @@ struct mlxsw_sp_router { · 33 unmodified lines
59 struct mlxsw_sp_router_nve_decap nve_decap_config;60 struct mlxsw_sp_router_nve_decap nve_decap_config;
60 struct mutex lock; /* Protects shared router resources */61 struct mutex lock; /* Protects shared router resources */
61 struct mlxsw_sp_fib_entry_op_ctx *ll_op_ctx;62 struct mlxsw_sp_fib_entry_op_ctx *ll_op_ctx;
62 u16 lb_rif_index;63 struct mlxsw_sp_crif *lb_crif;
63 const struct mlxsw_sp_adj_grp_size_range *adj_grp_size_ranges;64 const struct mlxsw_sp_adj_grp_size_range *adj_grp_size_ranges;
64 size_t adj_grp_size_ranges_count;65 size_t adj_grp_size_ranges_count;
65 struct delayed_work nh_grp_activity_dw;66 struct delayed_work nh_grp_activity_dw;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t