diff options
author | David S. Miller <davem@davemloft.net> | 2017-10-02 14:18:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-02 14:18:57 -0400 |
commit | 4ee4553e861a2a7c4f5b045d9453729d837d4a7d (patch) | |
tree | 5a35ef01e5f5b751ad9a37d2a8334936670c0228 | |
parent | 81359617f1b783a01e6e22b46cbb046e9513b9c6 (diff) | |
parent | de0f43c01a4b5d408a5c087c8a92ac1739938f8b (diff) |
Merge branch 'mlxsw-gre-fixes'
Jiri Pirko says:
====================
mlxsw: Fixes in GRE offloading
Petr says:
This patchset fixes a couple unrelated problems in offloading IP-in-IP tunnels
in mlxsw driver.
- The first patch fixes a potential reference-counting problem that might lead
to a kernel crash.
- The second patch associates IPIP next hops with their loopback RIFs. Besides
being the right thing to do, it also fixes a problem where offloaded IPv6
routes that forward to IP-in-IP netdevices were not flagged as such.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 2cfb3f5d092d..032089efc1a0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
@@ -2723,6 +2723,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp, | |||
2723 | mlxsw_sp_nexthop_rif_fini(nh); | 2723 | mlxsw_sp_nexthop_rif_fini(nh); |
2724 | break; | 2724 | break; |
2725 | case MLXSW_SP_NEXTHOP_TYPE_IPIP: | 2725 | case MLXSW_SP_NEXTHOP_TYPE_IPIP: |
2726 | mlxsw_sp_nexthop_rif_fini(nh); | ||
2726 | mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh); | 2727 | mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh); |
2727 | break; | 2728 | break; |
2728 | } | 2729 | } |
@@ -2742,7 +2743,11 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp, | |||
2742 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, | 2743 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, |
2743 | MLXSW_SP_L3_PROTO_IPV4)) { | 2744 | MLXSW_SP_L3_PROTO_IPV4)) { |
2744 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; | 2745 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; |
2745 | return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | 2746 | err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); |
2747 | if (err) | ||
2748 | return err; | ||
2749 | mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); | ||
2750 | return 0; | ||
2746 | } | 2751 | } |
2747 | 2752 | ||
2748 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; | 2753 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; |
@@ -4009,7 +4014,11 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp, | |||
4009 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, | 4014 | router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev, |
4010 | MLXSW_SP_L3_PROTO_IPV6)) { | 4015 | MLXSW_SP_L3_PROTO_IPV6)) { |
4011 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; | 4016 | nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP; |
4012 | return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); | 4017 | err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev); |
4018 | if (err) | ||
4019 | return err; | ||
4020 | mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common); | ||
4021 | return 0; | ||
4013 | } | 4022 | } |
4014 | 4023 | ||
4015 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; | 4024 | nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH; |
@@ -5068,6 +5077,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, | |||
5068 | vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN); | 5077 | vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN); |
5069 | if (IS_ERR(vr)) | 5078 | if (IS_ERR(vr)) |
5070 | return ERR_CAST(vr); | 5079 | return ERR_CAST(vr); |
5080 | vr->rif_count++; | ||
5071 | 5081 | ||
5072 | err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); | 5082 | err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index); |
5073 | if (err) | 5083 | if (err) |
@@ -5099,7 +5109,6 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, | |||
5099 | 5109 | ||
5100 | mlxsw_sp_rif_counters_alloc(rif); | 5110 | mlxsw_sp_rif_counters_alloc(rif); |
5101 | mlxsw_sp->router->rifs[rif_index] = rif; | 5111 | mlxsw_sp->router->rifs[rif_index] = rif; |
5102 | vr->rif_count++; | ||
5103 | 5112 | ||
5104 | return rif; | 5113 | return rif; |
5105 | 5114 | ||
@@ -5110,6 +5119,7 @@ err_fid_get: | |||
5110 | kfree(rif); | 5119 | kfree(rif); |
5111 | err_rif_alloc: | 5120 | err_rif_alloc: |
5112 | err_rif_index_alloc: | 5121 | err_rif_index_alloc: |
5122 | vr->rif_count--; | ||
5113 | mlxsw_sp_vr_put(vr); | 5123 | mlxsw_sp_vr_put(vr); |
5114 | return ERR_PTR(err); | 5124 | return ERR_PTR(err); |
5115 | } | 5125 | } |
@@ -5124,7 +5134,6 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) | |||
5124 | mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif); | 5134 | mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif); |
5125 | vr = &mlxsw_sp->router->vrs[rif->vr_id]; | 5135 | vr = &mlxsw_sp->router->vrs[rif->vr_id]; |
5126 | 5136 | ||
5127 | vr->rif_count--; | ||
5128 | mlxsw_sp->router->rifs[rif->rif_index] = NULL; | 5137 | mlxsw_sp->router->rifs[rif->rif_index] = NULL; |
5129 | mlxsw_sp_rif_counters_free(rif); | 5138 | mlxsw_sp_rif_counters_free(rif); |
5130 | ops->deconfigure(rif); | 5139 | ops->deconfigure(rif); |
@@ -5132,6 +5141,7 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) | |||
5132 | /* Loopback RIFs are not associated with a FID. */ | 5141 | /* Loopback RIFs are not associated with a FID. */ |
5133 | mlxsw_sp_fid_put(fid); | 5142 | mlxsw_sp_fid_put(fid); |
5134 | kfree(rif); | 5143 | kfree(rif); |
5144 | vr->rif_count--; | ||
5135 | mlxsw_sp_vr_put(vr); | 5145 | mlxsw_sp_vr_put(vr); |
5136 | } | 5146 | } |
5137 | 5147 | ||