瀏覽代碼

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>
David S. Miller 8 年之前
父節點
當前提交
4ee4553e86
共有 1 個文件被更改,包括 14 次插入4 次删除
  1. 14 4
      drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

+ 14 - 4
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

@@ -2723,6 +2723,7 @@ static void mlxsw_sp_nexthop_type_fini(struct mlxsw_sp *mlxsw_sp,
 		mlxsw_sp_nexthop_rif_fini(nh);
 		mlxsw_sp_nexthop_rif_fini(nh);
 		break;
 		break;
 	case MLXSW_SP_NEXTHOP_TYPE_IPIP:
 	case MLXSW_SP_NEXTHOP_TYPE_IPIP:
+		mlxsw_sp_nexthop_rif_fini(nh);
 		mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);
 		mlxsw_sp_nexthop_ipip_fini(mlxsw_sp, nh);
 		break;
 		break;
 	}
 	}
@@ -2742,7 +2743,11 @@ static int mlxsw_sp_nexthop4_type_init(struct mlxsw_sp *mlxsw_sp,
 	    router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
 	    router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
 						     MLXSW_SP_L3_PROTO_IPV4)) {
 						     MLXSW_SP_L3_PROTO_IPV4)) {
 		nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
 		nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
-		return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+		err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+		if (err)
+			return err;
+		mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common);
+		return 0;
 	}
 	}
 
 
 	nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
 	nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
@@ -4009,7 +4014,11 @@ static int mlxsw_sp_nexthop6_type_init(struct mlxsw_sp *mlxsw_sp,
 	    router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
 	    router->ipip_ops_arr[ipipt]->can_offload(mlxsw_sp, dev,
 						     MLXSW_SP_L3_PROTO_IPV6)) {
 						     MLXSW_SP_L3_PROTO_IPV6)) {
 		nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
 		nh->type = MLXSW_SP_NEXTHOP_TYPE_IPIP;
-		return mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+		err = mlxsw_sp_nexthop_ipip_init(mlxsw_sp, ipipt, nh, dev);
+		if (err)
+			return err;
+		mlxsw_sp_nexthop_rif_init(nh, &nh->ipip_entry->ol_lb->common);
+		return 0;
 	}
 	}
 
 
 	nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
 	nh->type = MLXSW_SP_NEXTHOP_TYPE_ETH;
@@ -5068,6 +5077,7 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
 	vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN);
 	vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN);
 	if (IS_ERR(vr))
 	if (IS_ERR(vr))
 		return ERR_CAST(vr);
 		return ERR_CAST(vr);
+	vr->rif_count++;
 
 
 	err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
 	err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
 	if (err)
 	if (err)
@@ -5099,7 +5109,6 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
 
 
 	mlxsw_sp_rif_counters_alloc(rif);
 	mlxsw_sp_rif_counters_alloc(rif);
 	mlxsw_sp->router->rifs[rif_index] = rif;
 	mlxsw_sp->router->rifs[rif_index] = rif;
-	vr->rif_count++;
 
 
 	return rif;
 	return rif;
 
 
@@ -5110,6 +5119,7 @@ err_fid_get:
 	kfree(rif);
 	kfree(rif);
 err_rif_alloc:
 err_rif_alloc:
 err_rif_index_alloc:
 err_rif_index_alloc:
+	vr->rif_count--;
 	mlxsw_sp_vr_put(vr);
 	mlxsw_sp_vr_put(vr);
 	return ERR_PTR(err);
 	return ERR_PTR(err);
 }
 }
@@ -5124,7 +5134,6 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
 	mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
 	mlxsw_sp_router_rif_gone_sync(mlxsw_sp, rif);
 	vr = &mlxsw_sp->router->vrs[rif->vr_id];
 	vr = &mlxsw_sp->router->vrs[rif->vr_id];
 
 
-	vr->rif_count--;
 	mlxsw_sp->router->rifs[rif->rif_index] = NULL;
 	mlxsw_sp->router->rifs[rif->rif_index] = NULL;
 	mlxsw_sp_rif_counters_free(rif);
 	mlxsw_sp_rif_counters_free(rif);
 	ops->deconfigure(rif);
 	ops->deconfigure(rif);
@@ -5132,6 +5141,7 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif)
 		/* Loopback RIFs are not associated with a FID. */
 		/* Loopback RIFs are not associated with a FID. */
 		mlxsw_sp_fid_put(fid);
 		mlxsw_sp_fid_put(fid);
 	kfree(rif);
 	kfree(rif);
+	vr->rif_count--;
 	mlxsw_sp_vr_put(vr);
 	mlxsw_sp_vr_put(vr);
 }
 }