aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-10-02 14:18:57 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-02 14:18:57 -0400
commit4ee4553e861a2a7c4f5b045d9453729d837d4a7d (patch)
tree5a35ef01e5f5b751ad9a37d2a8334936670c0228
parent81359617f1b783a01e6e22b46cbb046e9513b9c6 (diff)
parentde0f43c01a4b5d408a5c087c8a92ac1739938f8b (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.c18
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);
5111err_rif_alloc: 5120err_rif_alloc:
5112err_rif_index_alloc: 5121err_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