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.
Unified · Split
| @@ -59,6 +59,7 @@ struct mlxsw_sp_crif { · 58 unmodified lines | |||
| 59 | struct mlxsw_sp_crif_key key; | 59 | struct mlxsw_sp_crif_key key; |
| 60 | struct rhash_head ht_node; | 60 | struct rhash_head ht_node; |
| 61 | bool can_destroy; | 61 | bool can_destroy; |
| 62 | struct list_head nexthop_list; | ||
| 62 | struct mlxsw_sp_rif *rif; | 63 | struct mlxsw_sp_rif *rif; |
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| @@ -70,7 +71,6 @@ static const struct rhashtable_params mlxsw_sp_crif_ht_params = { · 5 unmodified lines | |||
| 70 | 71 | ||
| 71 | struct mlxsw_sp_rif { | 72 | struct mlxsw_sp_rif { |
| 72 | struct mlxsw_sp_crif *crif; /* NULL for underlay RIF */ | 73 | struct mlxsw_sp_crif *crif; /* NULL for underlay RIF */ |
| 73 | struct list_head nexthop_list; | ||
| 74 | struct list_head neigh_list; | 74 | struct list_head neigh_list; |
| 75 | struct mlxsw_sp_fid *fid; | 75 | struct mlxsw_sp_fid *fid; |
| 76 | unsigned char addr[ETH_ALEN]; | 76 | unsigned char addr[ETH_ALEN]; |
| @@ -1083,6 +1083,7 @@ static void · 1006 unmodified lines | |||
| 1083 | mlxsw_sp_crif_init(struct mlxsw_sp_crif *crif, struct net_device *dev) | 1083 | mlxsw_sp_crif_init(struct mlxsw_sp_crif *crif, struct net_device *dev) |
| 1084 | { | 1084 | { |
| 1085 | crif->key.dev = dev; | 1085 | crif->key.dev = dev; |
| 1086 | INIT_LIST_HEAD(&crif->nexthop_list); | ||
| 1086 | } | 1087 | } |
| 1087 | 1088 | ||
| 1088 | static struct mlxsw_sp_crif * | 1089 | static struct mlxsw_sp_crif * |
| @@ -1103,6 +1104,7 @@ static void mlxsw_sp_crif_free(struct mlxsw_sp_crif *crif) · 14 unmodified lines | |||
| 1103 | if (WARN_ON(crif->rif)) | 1104 | if (WARN_ON(crif->rif)) |
| 1104 | return; | 1105 | return; |
| 1105 | 1106 | ||
| 1107 | WARN_ON(!list_empty(&crif->nexthop_list)); | ||
| 1106 | kfree(crif); | 1108 | kfree(crif); |
| 1107 | } | 1109 | } |
| 1108 | 1110 | ||
| @@ -1720,17 +1722,26 @@ static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp, · 611 unmodified lines | |||
| 1720 | mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry); | 1722 | mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry); |
| 1721 | } | 1723 | } |
| 1722 | 1724 | ||
| 1723 | static void mlxsw_sp_nexthop_rif_migrate(struct mlxsw_sp *mlxsw_sp, | 1725 | static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, |
| 1724 | struct mlxsw_sp_rif *old_rif, | 1726 | struct mlxsw_sp_rif *rif); |
| 1725 | struct mlxsw_sp_rif *new_rif); | 1727 | |
| 1726 | static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp, | 1728 | static void mlxsw_sp_rif_migrate_destroy(struct mlxsw_sp *mlxsw_sp, |
| 1727 | struct mlxsw_sp_rif *old_rif, | 1729 | struct mlxsw_sp_rif *old_rif, |
| 1728 | struct mlxsw_sp_rif *new_rif, | 1730 | struct mlxsw_sp_rif *new_rif, |
| 1729 | bool migrate_nhs) | 1731 | bool migrate_nhs) |
| 1730 | { | 1732 | { |
| 1733 | struct mlxsw_sp_crif *crif = old_rif->crif; | ||
| 1734 | struct mlxsw_sp_crif mock_crif = {}; | ||
| 1735 | |||
| 1731 | if (migrate_nhs) | 1736 | 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); |
| 1733 | 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; | ||
| 1734 | mlxsw_sp_rif_destroy(old_rif); | 1745 | mlxsw_sp_rif_destroy(old_rif); |
| 1735 | } | 1746 | } |
| 1736 | 1747 | ||
| @@ -1756,9 +1767,6 @@ mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, · 19 unmodified lines | |||
| 1756 | return 0; | 1767 | return 0; |
| 1757 | } | 1768 | } |
| 1758 | 1769 | ||
| 1759 | static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, | ||
| 1760 | struct mlxsw_sp_rif *rif); | ||
| 1761 | |||
| 1762 | /** | 1770 | /** |
| 1763 | * __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. |
| 1764 | * @mlxsw_sp: mlxsw_sp. | 1772 | * @mlxsw_sp: mlxsw_sp. |
| @@ -2987,7 +2995,7 @@ struct mlxsw_sp_nexthop_key { · 1222 unmodified lines | |||
| 2987 | 2995 | ||
| 2988 | struct mlxsw_sp_nexthop { | 2996 | struct mlxsw_sp_nexthop { |
| 2989 | struct list_head neigh_list_node; /* member of neigh entry list */ | 2997 | 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; |
| 2991 | struct list_head router_list_node; | 2999 | struct list_head router_list_node; |
| 2992 | struct mlxsw_sp_nexthop_group_info *nhgi; /* pointer back to the group | 3000 | struct mlxsw_sp_nexthop_group_info *nhgi; /* pointer back to the group |
| 2993 | * this nexthop belongs to | 3001 | * this nexthop belongs to |
| @@ -3000,7 +3008,7 @@ struct mlxsw_sp_nexthop { · 6 unmodified lines | |||
| 3000 | int nh_weight; | 3008 | int nh_weight; |
| 3001 | int norm_nh_weight; | 3009 | int norm_nh_weight; |
| 3002 | int num_adj_entries; | 3010 | int num_adj_entries; |
| 3003 | struct mlxsw_sp_rif *rif; | 3011 | struct mlxsw_sp_crif *crif; |
| 3004 | u8 should_offload:1, /* set indicates this nexthop should be written | 3012 | u8 should_offload:1, /* set indicates this nexthop should be written |
| 3005 | * to the adjacency table. | 3013 | * to the adjacency table. |
| 3006 | */ | 3014 | */ |
| @@ -3023,9 +3031,9 @@ struct mlxsw_sp_nexthop { · 16 unmodified lines | |||
| 3023 | static struct net_device * | 3031 | static struct net_device * |
| 3024 | mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh) | 3032 | mlxsw_sp_nexthop_dev(const struct mlxsw_sp_nexthop *nh) |
| 3025 | { | 3033 | { |
| 3026 | if (nh->rif) | 3034 | if (!nh->crif) |
| 3027 | return mlxsw_sp_rif_dev(nh->rif); | 3035 | return NULL; |
| 3028 | return NULL; | 3036 | return nh->crif->key.dev; |
| 3029 | } | 3037 | } |
| 3030 | 3038 | ||
| 3031 | enum mlxsw_sp_nexthop_group_type { | 3039 | enum mlxsw_sp_nexthop_group_type { |
| @@ -3050,7 +3058,11 @@ struct mlxsw_sp_nexthop_group_info { · 18 unmodified lines | |||
| 3050 | static struct mlxsw_sp_rif * | 3058 | static struct mlxsw_sp_rif * |
| 3051 | mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi) | 3059 | mlxsw_sp_nhgi_rif(const struct mlxsw_sp_nexthop_group_info *nhgi) |
| 3052 | { | 3060 | { |
| 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; | ||
| 3054 | } | 3066 | } |
| 3055 | 3067 | ||
| 3056 | struct mlxsw_sp_nexthop_group_vr_key { | 3068 | 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 | |||
| 3174 | 3186 | ||
| 3175 | struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh) | 3187 | struct mlxsw_sp_rif *mlxsw_sp_nexthop_rif(struct mlxsw_sp_nexthop *nh) |
| 3176 | { | 3188 | { |
| 3177 | return nh->rif; | 3189 | if (WARN_ON(!nh->crif)) |
| 3190 | return NULL; | ||
| 3191 | return nh->crif->rif; | ||
| 3178 | } | 3192 | } |
| 3179 | 3193 | ||
| 3180 | bool mlxsw_sp_nexthop_group_has_ipip(struct mlxsw_sp_nexthop *nh) | 3194 | 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 | |||
| 3559 | bool force, char *ratr_pl) | 3573 | bool force, char *ratr_pl) |
| 3560 | { | 3574 | { |
| 3561 | 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); | ||
| 3562 | enum mlxsw_reg_ratr_op op; | 3577 | enum mlxsw_reg_ratr_op op; |
| 3563 | u16 rif_index; | 3578 | u16 rif_index; |
| 3564 | 3579 | ||
| 3565 | rif_index = nh->rif ? nh->rif->rif_index : | 3580 | rif_index = rif ? rif->rif_index : |
| 3566 | mlxsw_sp->router->lb_crif->rif->rif_index; | 3581 | mlxsw_sp->router->lb_crif->rif->rif_index; |
| 3567 | op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY : | 3582 | op = force ? MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY : |
| 3568 | MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY; | 3583 | MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY_ON_ACTIVITY; |
| 3569 | 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, |
| @@ -4181,23 +4196,23 @@ mlxsw_sp_nexthop_neigh_update(struct mlxsw_sp *mlxsw_sp, · 611 unmodified lines | |||
| 4181 | } | 4196 | } |
| 4182 | } | 4197 | } |
| 4183 | 4198 | ||
| 4184 | static void mlxsw_sp_nexthop_rif_init(struct mlxsw_sp_nexthop *nh, | 4199 | static void mlxsw_sp_nexthop_crif_init(struct mlxsw_sp_nexthop *nh, |
| 4185 | struct mlxsw_sp_rif *rif) | 4200 | struct mlxsw_sp_crif *crif) |
| 4186 | { | 4201 | { |
| 4187 | if (nh->rif) | 4202 | if (nh->crif) |
| 4188 | return; | 4203 | return; |
| 4189 | 4204 | ||
| 4190 | nh->rif = rif; | 4205 | nh->crif = crif; |
| 4191 | list_add(&nh->rif_list_node, &rif->nexthop_list); | 4206 | list_add(&nh->crif_list_node, &crif->nexthop_list); |
| 4192 | } | 4207 | } |
| 4193 | 4208 | ||
| 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) |
| 4195 | { | 4210 | { |
| 4196 | if (!nh->rif) | 4211 | if (!nh->crif) |
| 4197 | return; | 4212 | return; |
| 4198 | 4213 | ||
| 4199 | list_del(&nh->rif_list_node); | 4214 | list_del(&nh->crif_list_node); |
| 4200 | nh->rif = NULL; | 4215 | nh->crif = NULL; |
| 4201 | } | 4216 | } |
| 4202 | 4217 | ||
| 4203 | static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp, | 4218 | 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 | |||
| 4209 | u8 nud_state, dead; | 4224 | u8 nud_state, dead; |
| 4210 | int err; | 4225 | int err; |
| 4211 | 4226 | ||
| 4227 | if (WARN_ON(!nh->crif->rif)) | ||
| 4228 | return 0; | ||
| 4229 | |||
| 4212 | if (!nh->nhgi->gateway || nh->neigh_entry) | 4230 | if (!nh->nhgi->gateway || nh->neigh_entry) |
| 4213 | return 0; | 4231 | return 0; |
| 4214 | dev = mlxsw_sp_nexthop_dev(nh); | 4232 | 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 | |||
| 4299 | struct mlxsw_sp_nexthop *nh, | 4317 | struct mlxsw_sp_nexthop *nh, |
| 4300 | struct mlxsw_sp_ipip_entry *ipip_entry) | 4318 | struct mlxsw_sp_ipip_entry *ipip_entry) |
| 4301 | { | 4319 | { |
| 4320 | struct mlxsw_sp_crif *crif; | ||
| 4302 | bool removing; | 4321 | bool removing; |
| 4303 | 4322 | ||
| 4304 | if (!nh->nhgi->gateway || nh->ipip_entry) | 4323 | if (!nh->nhgi->gateway || nh->ipip_entry) |
| 4305 | return; | 4324 | return; |
| 4306 | 4325 | ||
| 4326 | crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, ipip_entry->ol_dev); | ||
| 4327 | if (WARN_ON(!crif)) | ||
| 4328 | return; | ||
| 4329 | |||
| 4307 | nh->ipip_entry = ipip_entry; | 4330 | nh->ipip_entry = ipip_entry; |
| 4308 | removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev); | 4331 | removing = !mlxsw_sp_ipip_netdev_ul_up(ipip_entry->ol_dev); |
| 4309 | __mlxsw_sp_nexthop_neigh_update(nh, removing); | 4332 | __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); |
| 4311 | } | 4334 | } |
| 4312 | 4335 | ||
| 4313 | static void mlxsw_sp_nexthop_ipip_fini(struct mlxsw_sp *mlxsw_sp, | 4336 | 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 | |||
| 4339 | { | 4362 | { |
| 4340 | const struct mlxsw_sp_ipip_ops *ipip_ops; | 4363 | const struct mlxsw_sp_ipip_ops *ipip_ops; |
| 4341 | struct mlxsw_sp_ipip_entry *ipip_entry; | 4364 | struct mlxsw_sp_ipip_entry *ipip_entry; |
| 4342 | struct mlxsw_sp_rif *rif; | 4365 | struct mlxsw_sp_crif *crif; |
| 4343 | int err; | 4366 | int err; |
| 4344 | 4367 | ||
| 4345 | 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); |
| @@ -4353,11 +4376,15 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 7 unmodified lines | |||
| 4353 | } | 4376 | } |
| 4354 | 4377 | ||
| 4355 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; | 4378 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; |
| 4356 | rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev); | 4379 | crif = mlxsw_sp_crif_lookup(mlxsw_sp->router, dev); |
| 4357 | if (!rif) | 4380 | if (!crif) |
| 4381 | return 0; | ||
| 4382 | |||
| 4383 | mlxsw_sp_nexthop_crif_init(nh, crif); | ||
| 4384 | |||
| 4385 | if (!crif->rif) | ||
| 4358 | return 0; | 4386 | return 0; |
| 4359 | 4387 | ||
| 4360 | mlxsw_sp_nexthop_rif_init(nh, rif); | ||
| 4361 | err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh); | 4388 | err = mlxsw_sp_nexthop_neigh_init(mlxsw_sp, nh); |
| 4362 | if (err) | 4389 | if (err) |
| 4363 | goto err_neigh_init; | 4390 | goto err_neigh_init; |
| @@ -4365,7 +4392,7 @@ static int mlxsw_sp_nexthop_type_init(struct mlxsw_sp *mlxsw_sp, · 1 unmodified line | |||
| 4365 | return 0; | 4392 | return 0; |
| 4366 | 4393 | ||
| 4367 | err_neigh_init: | 4394 | err_neigh_init: |
| 4368 | mlxsw_sp_nexthop_rif_fini(nh); | 4395 | mlxsw_sp_nexthop_crif_fini(nh); |
| 4369 | return err; | 4396 | return err; |
| 4370 | } | 4397 | } |
| 4371 | 4398 | ||
| @@ -4386,7 +4413,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, · 14 unmodified lines | |||
| 4386 | struct mlxsw_sp_nexthop *nh) | 4413 | struct mlxsw_sp_nexthop *nh) |
| 4387 | { | 4414 | { |
| 4388 | mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh); | 4415 | mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh); |
| 4389 | mlxsw_sp_nexthop_rif_fini(nh); | 4416 | mlxsw_sp_nexthop_crif_fini(nh); |
| 4390 | } | 4417 | } |
| 4391 | 4418 | ||
| 4392 | static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp, | 4419 | 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 | |||
| 4479 | struct mlxsw_sp_nexthop *nh; | 4506 | struct mlxsw_sp_nexthop *nh; |
| 4480 | bool removing; | 4507 | bool removing; |
| 4481 | 4508 | ||
| 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) { |
| 4483 | switch (nh->type) { | 4510 | switch (nh->type) { |
| 4484 | case MLXSW_SP_NEXTHOP_TYPE_ETH: | 4511 | case MLXSW_SP_NEXTHOP_TYPE_ETH: |
| 4485 | removing = false; | 4512 | removing = false; |
| @@ -4497,25 +4524,14 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, · 11 unmodified lines | |||
| 4497 | } | 4524 | } |
| 4498 | } | 4525 | } |
| 4499 | 4526 | ||
| 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 | |||
| 4512 | static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, | 4527 | static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, |
| 4513 | struct mlxsw_sp_rif *rif) | 4528 | struct mlxsw_sp_rif *rif) |
| 4514 | { | 4529 | { |
| 4515 | struct mlxsw_sp_nexthop *nh, *tmp; | 4530 | struct mlxsw_sp_nexthop *nh, *tmp; |
| 4516 | 4531 | ||
| 4517 | 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, |
| 4518 | mlxsw_sp_nexthop_type_fini(mlxsw_sp, nh); | 4533 | crif_list_node) { |
| 4534 | mlxsw_sp_nexthop_type_rif_gone(mlxsw_sp, nh); | ||
| 4519 | mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp); | 4535 | mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nhgi->nh_grp); |
| 4520 | } | 4536 | } |
| 4521 | } | 4537 | } |
| @@ -4857,13 +4873,13 @@ static void mlxsw_sp_nexthop_obj_blackhole_init(struct mlxsw_sp *mlxsw_sp, · 335 unmodified lines | |||
| 4857 | * via an egress RIF, they still need to be programmed using a | 4873 | * via an egress RIF, they still need to be programmed using a |
| 4858 | * valid RIF, so use the loopback RIF created during init. | 4874 | * valid RIF, so use the loopback RIF created during init. |
| 4859 | */ | 4875 | */ |
| 4860 | nh->rif = mlxsw_sp->router->lb_crif->rif; | 4876 | nh->crif = mlxsw_sp->router->lb_crif; |
| 4861 | } | 4877 | } |
| 4862 | 4878 | ||
| 4863 | static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp, | 4879 | static void mlxsw_sp_nexthop_obj_blackhole_fini(struct mlxsw_sp *mlxsw_sp, |
| 4864 | struct mlxsw_sp_nexthop *nh) | 4880 | struct mlxsw_sp_nexthop *nh) |
| 4865 | { | 4881 | { |
| 4866 | nh->rif = NULL; | 4882 | nh->crif = NULL; |
| 4867 | nh->should_offload = 0; | 4883 | nh->should_offload = 0; |
| 4868 | } | 4884 | } |
| 4869 | 4885 | ||
| @@ -7871,6 +7887,9 @@ static int mlxsw_sp_router_rif_disable(struct mlxsw_sp *mlxsw_sp, u16 rif) · 3001 unmodified lines | |||
| 7871 | static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, | 7887 | static void mlxsw_sp_router_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, |
| 7872 | struct mlxsw_sp_rif *rif) | 7888 | struct mlxsw_sp_rif *rif) |
| 7873 | { | 7889 | { |
| 7890 | /* Signal to nexthop cleanup that the RIF is going away. */ | ||
| 7891 | rif->crif->rif = NULL; | ||
| 7892 | |||
| 7874 | mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index); | 7893 | mlxsw_sp_router_rif_disable(mlxsw_sp, rif->rif_index); |
| 7875 | mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif); | 7894 | mlxsw_sp_nexthop_rif_gone_sync(mlxsw_sp, rif); |
| 7876 | mlxsw_sp_neigh_rif_gone_sync(mlxsw_sp, rif); | 7895 | 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 | |||
| 7989 | if (!rif) | 8008 | if (!rif) |
| 7990 | return NULL; | 8009 | return NULL; |
| 7991 | 8010 | ||
| 7992 | INIT_LIST_HEAD(&rif->nexthop_list); | ||
| 7993 | INIT_LIST_HEAD(&rif->neigh_list); | 8011 | INIT_LIST_HEAD(&rif->neigh_list); |
| 7994 | if (l3_dev) { | 8012 | if (l3_dev) { |
| 7995 | ether_addr_copy(rif->addr, l3_dev->dev_addr); | 8013 | 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 | |||
| 8008 | static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif) | 8026 | static void mlxsw_sp_rif_free(struct mlxsw_sp_rif *rif) |
| 8009 | { | 8027 | { |
| 8010 | WARN_ON(!list_empty(&rif->neigh_list)); | 8028 | WARN_ON(!list_empty(&rif->neigh_list)); |
| 8011 | WARN_ON(!list_empty(&rif->nexthop_list)); | ||
| 8012 | 8029 | ||
| 8013 | if (rif->crif) | 8030 | if (rif->crif) |
| 8014 | rif->crif->rif = NULL; | 8031 | rif->crif->rif = NULL; |
| @@ -9290,7 +9307,13 @@ err_netdev_insert: · 1275 unmodified lines | |||
| 9290 | static void mlxsw_sp_crif_unregister(struct mlxsw_sp_router *router, | 9307 | static void mlxsw_sp_crif_unregister(struct mlxsw_sp_router *router, |
| 9291 | struct mlxsw_sp_crif *crif) | 9308 | struct mlxsw_sp_crif *crif) |
| 9292 | { | 9309 | { |
| 9310 | struct mlxsw_sp_nexthop *nh, *tmp; | ||
| 9311 | |||
| 9293 | mlxsw_sp_crif_remove(router, crif); | 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 | |||
| 9294 | if (crif->rif) | 9317 | if (crif->rif) |
| 9295 | crif->can_destroy = true; | 9318 | crif->can_destroy = true; |
| 9296 | else | 9319 | else |