History

mlxsw: spectrum_router: Track next hops at CRIFs

Move the list of next hops from struct mlxsw_sp_rif to mlxsw_sp_crif. The reason is that eventually, next hops for mlxsw uppers should be offloaded and unoffloaded on demand as a netdevice becomes an upper, or stops being one. Currently, next hops are tracked at RIFs, but RIFs do not exist when a netdevice is not an mlxsw uppers. CRIFs are kept track of throughout the netdevice lifetime. Correspondingly, track at each next hop not its RIF, but its CRIF (from which a RIF can always be deduced). Note that now that next hops are tracked at a CRIF, it is not necessary to move each over to a new RIF when it is necessary to edit a RIF. Therefore drop mlxsw_sp_nexthop_rif_migrate() and have mlxsw_sp_rif_migrate_destroy() call mlxsw_sp_nexthop_rif_update() directly.

Petr Machata committed 3 years ago

Commit 9464a3d1 parent a285d661 file · +75 −52Browse files

Unified · Split

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c+75−52
@@ -59,6 +59,7 @@ struct mlxsw_sp_crif { · 58 unmodified lines
5959 struct mlxsw_sp_crif_key key;
6060 struct rhash_head ht_node;
6161 bool can_destroy;
62+ struct list_head nexthop_list;
6263 struct mlxsw_sp_rif *rif;
6364 };
6465
@@ -70,7 +71,6 @@ static const struct rhashtable_params mlxsw_sp_crif_ht_params = { · 5 unmodified lines
7071
7172 struct mlxsw_sp_rif {
7273 struct mlxsw_sp_crif *crif; /* NULL for underlay RIF */
73− struct list_head nexthop_list;
7474 struct list_head neigh_list;
7575 struct mlxsw_sp_fid *fid;
7676 unsigned char addr[ETH_ALEN];
@@ -1083,6 +1083,7 @@ static void · 1006 unmodified lines
10831083 mlxsw_sp_crif_init(struct mlxsw_sp_crif *crif, struct net_device *dev)
10841084 {
10851085 crif->key.dev = dev;
1086+ INIT_LIST_HEAD(&crif->nexthop_list);
10861087 }
10871088
10881089 static struct mlxsw_sp_crif *
@@ -1103,6 +1104,7 @@ static void mlxsw_sp_crif_free(struct mlxsw_sp_crif *crif) · 14 unmodified lines
11031104 if (WARN_ON(crif->rif))
11041105 return;
11051106
1107+ WARN_ON(!list_empty(&crif->nexthop_list));
11061108 kfree(crif);
11071109 }
11081110
@@ -1720,17 +1722,26 @@ static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp, · 611 unmodified lines
17201722 mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry);
17211723 }
17221724
1723−static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,
1724− struct mlxsw_sp_rif *old_rif,
1725− struct mlxsw_sp_rif *new_rif);
1725+static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
1726+ struct mlxsw_sp_rif *rif);
1727+
17261728 static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp,
17271729 struct mlxsw_sp_rif *old_rif,
17281730 struct mlxsw_sp_rif *new_rif,
17291731 bool migrate_nhs)
17301732 {
1733+ struct mlxsw_sp_crif *crif = old_rif->crif;
1734+ struct mlxsw_sp_crif mock_crif = {};
1735+
17311736 if (migrate_nhs)
1732− mlxsw_sp_nexthop_rif_migrate(mlxsw_sp, old_rif, new_rif);
1737+ mlxsw_sp_nexthop_rif_update(mlxsw_sp, new_rif);
17331738
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;
17341745 mlxsw_sp_rif_destroy(old_rif);
17351746 }
17361747
@@ -1756,9 +1767,6 @@ mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, · 19 unmodified lines
17561767 return 0;
17571768 }
17581769
1759−static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
1760− struct mlxsw_sp_rif *rif);
1761−
17621770 /**
17631771 * __mlxsw_sp_ipip_entry_update_tunnel - Update offload related to IPIP entry.
17641772 * @mlxsw_sp: mlxsw_sp.
@@ -2987,7 +2995,7 @@ struct mlxsw_sp_nexthop_key { · 1222 unmodified lines
29872995
29882996 struct mlxsw_sp_nexthop {
29892997 struct list_head neigh_list_node; /* member of neigh entry list */
2990− struct list_head rif_list_node;
2998+ struct list_head crif_list_node;
29912999 struct list_head router_list_node;
29923000 struct mlxsw_sp_nexthop_group_info *nhgi; /* pointer back to the group
29933001 * this nexthop belongs to
@@ -3000,7 +3008,7 @@ struct mlxsw_sp_nexthop { · 6 unmodified lines
30003008 int nh_weight;
30013009 int norm_nh_weight;
30023010 int num_adj_entries;
3003− struct mlxsw_sp_rif *rif;
3011+ struct mlxsw_sp_crif *crif;
30043012 u8 should_offload:1, /* set indicates this nexthop should be written
30053013 * to the adjacency table.
30063014 */
@@ -3023,9 +3031,9 @@ struct mlxsw_sp_nexthop { · 16 unmodified lines
30233031 static struct net_device *
30243032 mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh)
30253033 {
3026− if (nh->rif)
3027− return mlxsw_sp_rif_dev(nh->rif);
3028− return NULL;
3034+ if (!nh->crif)
3035+ return NULL;
3036+ return nh->crif->key.dev;
30293037 }
30303038
30313039 enum mlxsw_sp_nexthop_group_type {
@@ -3050,7 +3058,11 @@ struct mlxsw_sp_nexthop_group_info { · 18 unmodified lines
30503058 static struct mlxsw_sp_rif *
30513059 mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi)
30523060 {
3053− 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;
30543066 }
30553067
30563068 struct mlxsw_sp_nexthop_group_vr_key {
@@ -3174,7 +3186,9 @@ int mlxsw_sp_nexthop_indexes(struct mlxsw_sp_nexthop *nh, u32 *p_adj_index, · 117 unmodified lines
31743186
31753187 struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh)
31763188 {
3177− return nh->rif;
3189+ if (WARN_ON(!nh->crif))
3190+ return NULL;
3191+ return nh->crif->rif;
31783192 }
31793193
31803194 bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh)
@@ -3559,11 +3573,12 @@ static int __mlxsw_sp_nexthop_eth_update(struct mlxsw_sp *mlxsw_sp, · 378 unmodified lines
35593573 bool force, char *ratr_pl)
35603574 {
35613575 struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
3576+ struct mlxsw_sp_rif *rif = mlxsw_sp_nexthop_rif(nh);
35623577 enum mlxsw_reg_ratr_op op;
35633578 u16 rif_index;
35643579
3565− rif_index = nh->rif ? nh->rif->rif_index :
3566− mlxsw_sp->router->lb_crif->rif->rif_index;
3580+ rif_index = rif ? rif->rif_index :
3581+ mlxsw_sp->router->lb_crif->rif->rif_index;
35673582 op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY :
35683583 MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY;
35693584 mlxsw_reg_ratr_pack(ratr_pl, op, true, MLXSW_REG_RATR_TYPE_ETHERNET,
@@ -4181,23 +4196,23 @@ mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, · 611 unmodified lines
41814196 }
41824197 }
41834198
4184−static void mlxsw_sp_nexthop_rif_init(struct mlxsw_sp_nexthop *nh,
4185− struct mlxsw_sp_rif *rif)
4199+static void mlxsw_sp_nexthop_crif_init(struct mlxsw_sp_nexthop *nh,
4200+ struct mlxsw_sp_crif *crif)
41864201 {
4187− if (nh->rif)
4202+ if (nh->crif)
41884203 return;
41894204
4190− nh->rif = rif;
4191− list_add(&nh->rif_list_node, &rif->nexthop_list);
4205+ nh->crif = crif;
4206+ list_add(&nh->crif_list_node, &crif->nexthop_list);
41924207 }
41934208
4194−static void mlxsw_sp_nexthop_rif_fini(struct mlxsw_sp_nexthop *nh)
4209+static void mlxsw_sp_nexthop_crif_fini(struct mlxsw_sp_nexthop *nh)
41954210 {
4196− if (!nh->rif)
4211+ if (!nh->crif)
41974212 return;
41984213
4199− list_del(&nh->rif_list_node);
4200− nh->rif = NULL;
4214+ list_del(&nh->crif_list_node);
4215+ nh->crif = NULL;
42014216 }
42024217
42034218 static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
@@ -4209,6 +4224,9 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, · 5 unmodified lines
42094224 u8 nud_state, dead;
42104225 int err;
42114226
4227+ if (WARN_ON(!nh->crif->rif))
4228+ return 0;
4229+
42124230 if (!nh->nhgi->gateway || nh->neigh_entry)
42134231 return 0;
42144232 dev = mlxsw_sp_nexthop_dev(nh);
@@ -4299,15 +4317,20 @@ static void mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp, · 84 unmodified lines
42994317 struct mlxsw_sp_nexthop *nh,
43004318 struct mlxsw_sp_ipip_entry *ipip_entry)
43014319 {
4320+ struct mlxsw_sp_crif *crif;
43024321 bool removing;
43034322
43044323 if (!nh->nhgi->gateway || nh->ipip_entry)
43054324 return;
43064325
4326+ crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, ipip_entry->ol_dev);
4327+ if (WARN_ON(!crif))
4328+ return;
4329+
43074330 nh->ipip_entry = ipip_entry;
43084331 removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev);
43094332 __mlxsw_sp_nexthop_neigh_update(nh, removing);
4310− mlxsw_sp_nexthop_rif_init(nh, &ipip_entry->ol_lb->common);
4333+ mlxsw_sp_nexthop_crif_init(nh, crif);
43114334 }
43124335
43134336 static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp,
@@ -4339,7 +4362,7 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 25 unmodified lines
43394362 {
43404363 const struct mlxsw_sp_ipip_ops *ipip_ops;
43414364 struct mlxsw_sp_ipip_entry *ipip_entry;
4342− struct mlxsw_sp_rif *rif;
4365+ struct mlxsw_sp_crif *crif;
43434366 int err;
43444367
43454368 ipip_entry = mlxsw_sp_ipip_entry_find_by_ol_dev(mlxsw_sp, dev);
@@ -4353,11 +4376,15 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 7 unmodified lines
43534376 }
43544377
43554378 nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
4356− rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
4357− if (!rif)
4379+ crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, dev);
4380+ if (!crif)
4381+ return 0;
4382+
4383+ mlxsw_sp_nexthop_crif_init(nh, crif);
4384+
4385+ if (!crif->rif)
43584386 return 0;
43594387
4360− mlxsw_sp_nexthop_rif_init(nh, rif);
43614388 err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh);
43624389 if (err)
43634390 goto err_neigh_init;
@@ -4365,7 +4392,7 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 1 unmodified line
43654392 return 0;
43664393
43674394 err_neigh_init:
4368− mlxsw_sp_nexthop_rif_fini(nh);
4395+ mlxsw_sp_nexthop_crif_fini(nh);
43694396 return err;
43704397 }
43714398
@@ -4386,7 +4413,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, · 14 unmodified lines
43864413 struct mlxsw_sp_nexthop *nh)
43874414 {
43884415 mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh);
4389− mlxsw_sp_nexthop_rif_fini(nh);
4416+ mlxsw_sp_nexthop_crif_fini(nh);
43904417 }
43914418
43924419 static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,
@@ -4479,7 +4506,7 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, · 86 unmodified lines
44794506 struct mlxsw_sp_nexthop *nh;
44804507 bool removing;
44814508
4482− list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) {
4509+ list_for_each_entry(nh, &rif->crif->nexthop_list, crif_list_node) {
44834510 switch (nh->type) {
44844511 case MLXSW_SP_NEXTHOP_TYPE_ETH:
44854512 removing = false;
@@ -4497,25 +4524,14 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, · 11 unmodified lines
44974524 }
44984525 }
44994526
4500−static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp,
4501− struct mlxsw_sp_rif *old_rif,
4502− struct mlxsw_sp_rif *new_rif)
4503−{
4504− struct mlxsw_sp_nexthop *nh;
4505−
4506− list_splice_init(&old_rif->nexthop_list, &new_rif->nexthop_list);
4507− list_for_each_entry(nh, &new_rif->nexthop_list, rif_list_node)
4508− nh->rif = new_rif;
4509− mlxsw_sp_nexthop_rif_update(mlxsw_sp, new_rif);
4510−}
4511−
45124527 static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
45134528 struct mlxsw_sp_rif *rif)
45144529 {
45154530 struct mlxsw_sp_nexthop *nh, *tmp;
45164531
4517− list_for_each_entry_safe(nh, tmp, &rif->nexthop_list, rif_list_node) {
4518− mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh);
4532+ list_for_each_entry_safe(nh, tmp, &rif->crif->nexthop_list,
4533+ crif_list_node) {
4534+ mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh);
45194535 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp);
45204536 }
45214537 }
@@ -4857,13 +4873,13 @@ static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp, · 335 unmodified lines
48574873 * via an egress RIF, they still need to be programmed using a
48584874 * valid RIF, so use the loopback RIF created during init.
48594875 */
4860− nh->rif = mlxsw_sp->router->lb_crif->rif;
4876+ nh->crif = mlxsw_sp->router->lb_crif;
48614877 }
48624878
48634879 static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp,
48644880 struct mlxsw_sp_nexthop *nh)
48654881 {
4866− nh->rif = NULL;
4882+ nh->crif = NULL;
48674883 nh->should_offload = 0;
48684884 }
48694885
@@ -7871,6 +7887,9 @@ static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif) · 3001 unmodified lines
78717887 static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
78727888 struct mlxsw_sp_rif *rif)
78737889 {
7890+ /* Signal to nexthop cleanup that the RIF is going away. */
7891+ rif->crif->rif = NULL;
7892+
78747893 mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index);
78757894 mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif);
78767895 mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif);
@@ -7989,7 +8008,6 @@ static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index, · 112 unmodified lines
79898008 if (!rif)
79908009 return NULL;
79918010
7992− INIT_LIST_HEAD(&rif->nexthop_list);
79938011 INIT_LIST_HEAD(&rif->neigh_list);
79948012 if (l3_dev) {
79958013 ether_addr_copy(rif->addr, l3_dev->dev_addr);
@@ -8008,7 +8026,6 @@ static struct mlxsw_sp_rif *mlxsw_sp_rif_alloc(size_t rif_size, u16 rif_index, · 12 unmodified lines
80088026 static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif)
80098027 {
80108028 WARN_ON(!list_empty(&rif->neigh_list));
8011− WARN_ON(!list_empty(&rif->nexthop_list));
80128029
80138030 if (rif->crif)
80148031 rif->crif->rif = NULL;
@@ -9290,7 +9307,13 @@ err_netdev_insert: · 1275 unmodified lines
92909307 static void mlxsw_sp_crif_unregister(struct mlxsw_sp_router *router,
92919308 struct mlxsw_sp_crif *crif)
92929309 {
9310+ struct mlxsw_sp_nexthop *nh, *tmp;
9311+
92939312 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+
92949317 if (crif->rif)
92959318 crif->can_destroy = true;
92969319 else

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