Commit 8d4f1046 authored by Amit Cohen's avatar Amit Cohen Committed by David S. Miller

mlxsw: spectrum_router: Increase parsing depth for IPv6 decapsulation

The Spectrum ASIC has a configurable limit on how deep into the packet
it parses. By default, the limit is 96 bytes.

For IP-in-IP packets, with IPv6 outer and inner headers, the default
parsing depth is not enough and without increasing it such packets cannot
be properly decapsulated.

Use the existing API to set parsing depth, call it once for each
decapsulation entry when it is created/destroyed.
There is no need to protect the code with new mutex because 'router->lock'
is already taken in these code paths.
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 53eedd61
...@@ -316,6 +316,7 @@ mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp, ...@@ -316,6 +316,7 @@ mlxsw_sp_ipip_ol_netdev_change_gre4(struct mlxsw_sp *mlxsw_sp,
static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = { static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = {
.dev_type = ARPHRD_IPGRE, .dev_type = ARPHRD_IPGRE,
.ul_proto = MLXSW_SP_L3_PROTO_IPV4, .ul_proto = MLXSW_SP_L3_PROTO_IPV4,
.inc_parsing_depth = false,
.parms_init = mlxsw_sp_ipip_netdev_parms_init_gre4, .parms_init = mlxsw_sp_ipip_netdev_parms_init_gre4,
.nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4, .nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4,
.decap_config = mlxsw_sp_ipip_decap_config_gre4, .decap_config = mlxsw_sp_ipip_decap_config_gre4,
...@@ -379,6 +380,7 @@ mlxsw_sp1_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp, ...@@ -379,6 +380,7 @@ mlxsw_sp1_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
static const struct mlxsw_sp_ipip_ops mlxsw_sp1_ipip_gre6_ops = { static const struct mlxsw_sp_ipip_ops mlxsw_sp1_ipip_gre6_ops = {
.dev_type = ARPHRD_IP6GRE, .dev_type = ARPHRD_IP6GRE,
.ul_proto = MLXSW_SP_L3_PROTO_IPV6, .ul_proto = MLXSW_SP_L3_PROTO_IPV6,
.inc_parsing_depth = true,
.parms_init = mlxsw_sp1_ipip_netdev_parms_init_gre6, .parms_init = mlxsw_sp1_ipip_netdev_parms_init_gre6,
.nexthop_update = mlxsw_sp1_ipip_nexthop_update_gre6, .nexthop_update = mlxsw_sp1_ipip_nexthop_update_gre6,
.decap_config = mlxsw_sp1_ipip_decap_config_gre6, .decap_config = mlxsw_sp1_ipip_decap_config_gre6,
......
...@@ -46,6 +46,7 @@ struct mlxsw_sp_ipip_entry { ...@@ -46,6 +46,7 @@ struct mlxsw_sp_ipip_entry {
struct mlxsw_sp_ipip_ops { struct mlxsw_sp_ipip_ops {
int dev_type; int dev_type;
enum mlxsw_sp_l3proto ul_proto; /* Underlay. */ enum mlxsw_sp_l3proto ul_proto; /* Underlay. */
bool inc_parsing_depth;
struct mlxsw_sp_ipip_parms struct mlxsw_sp_ipip_parms
(*parms_init)(const struct net_device *ol_dev); (*parms_init)(const struct net_device *ol_dev);
......
...@@ -1157,6 +1157,32 @@ mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp, ...@@ -1157,6 +1157,32 @@ mlxsw_sp_ipip_entry_saddr_matches(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_l3addr_eq(&tun_saddr, &saddr); mlxsw_sp_l3addr_eq(&tun_saddr, &saddr);
} }
static int mlxsw_sp_ipip_decap_parsing_depth_inc(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt)
{
const struct mlxsw_sp_ipip_ops *ipip_ops;
ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt];
/* Not all tunnels require to increase the default pasing depth
* (96 bytes).
*/
if (ipip_ops->inc_parsing_depth)
return mlxsw_sp_parsing_depth_inc(mlxsw_sp);
return 0;
}
static void mlxsw_sp_ipip_decap_parsing_depth_dec(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_ipip_type ipipt)
{
const struct mlxsw_sp_ipip_ops *ipip_ops =
mlxsw_sp->router->ipip_ops_arr[ipipt];
if (ipip_ops->inc_parsing_depth)
mlxsw_sp_parsing_depth_dec(mlxsw_sp);
}
static int static int
mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry, struct mlxsw_sp_fib_entry *fib_entry,
...@@ -1170,18 +1196,32 @@ mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp, ...@@ -1170,18 +1196,32 @@ mlxsw_sp_fib_entry_decap_init(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
return err; return err;
err = mlxsw_sp_ipip_decap_parsing_depth_inc(mlxsw_sp,
ipip_entry->ipipt);
if (err)
goto err_parsing_depth_inc;
ipip_entry->decap_fib_entry = fib_entry; ipip_entry->decap_fib_entry = fib_entry;
fib_entry->decap.ipip_entry = ipip_entry; fib_entry->decap.ipip_entry = ipip_entry;
fib_entry->decap.tunnel_index = tunnel_index; fib_entry->decap.tunnel_index = tunnel_index;
return 0; return 0;
err_parsing_depth_inc:
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, 1,
fib_entry->decap.tunnel_index);
return err;
} }
static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_fib_entry *fib_entry) struct mlxsw_sp_fib_entry *fib_entry)
{ {
enum mlxsw_sp_ipip_type ipipt = fib_entry->decap.ipip_entry->ipipt;
/* Unlink this node from the IPIP entry that it's the decap entry of. */ /* Unlink this node from the IPIP entry that it's the decap entry of. */
fib_entry->decap.ipip_entry->decap_fib_entry = NULL; fib_entry->decap.ipip_entry->decap_fib_entry = NULL;
fib_entry->decap.ipip_entry = NULL; fib_entry->decap.ipip_entry = NULL;
mlxsw_sp_ipip_decap_parsing_depth_dec(mlxsw_sp, ipipt);
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ, mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ADJ,
1, fib_entry->decap.tunnel_index); 1, fib_entry->decap.tunnel_index);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment