Commit 2dce6987 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-ecn-marking'



Ido Schimmel says:

====================
mlxsw: spectrum: Fix ECN marking in tunnel decapsulation

Patch #1 fixes a discrepancy between the software and hardware data
paths with regards to ECN marking after decapsulation. See the changelog
for a detailed description.

Patch #2 extends the ECN decap test to cover all possible combinations
of inner and outer ECN markings. The test passes over both data paths.

v2:
* Only set ECT(1) if inner is ECT(0)
* Introduce a new helper to determine inner ECN. Share it between NVE
  and IP-in-IP tunnels
* Extend the selftest
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1b479fb8 4bfd0de5
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <net/red.h>
#include <net/vxlan.h>
#include <net/flow_offload.h>
#include <net/inet_ecn.h>

#include "port.h"
#include "core.h"
@@ -347,6 +348,20 @@ struct mlxsw_sp_port_type_speed_ops {
	u32 (*ptys_proto_cap_masked_get)(u32 eth_proto_cap);
};

static inline u8 mlxsw_sp_tunnel_ecn_decap(u8 outer_ecn, u8 inner_ecn,
					   bool *trap_en)
{
	bool set_ce = false;

	*trap_en = !!__INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce);
	if (set_ce)
		return INET_ECN_CE;
	else if (outer_ecn == INET_ECN_ECT_1 && inner_ecn == INET_ECN_ECT_0)
		return INET_ECN_ECT_1;
	else
		return inner_ecn;
}

static inline struct net_device *
mlxsw_sp_bridge_vxlan_dev_find(struct net_device *br_dev)
{
+3 −4
Original line number Diff line number Diff line
@@ -335,12 +335,11 @@ static int mlxsw_sp_ipip_ecn_decap_init_one(struct mlxsw_sp *mlxsw_sp,
					    u8 inner_ecn, u8 outer_ecn)
{
	char tidem_pl[MLXSW_REG_TIDEM_LEN];
	bool trap_en, set_ce = false;
	u8 new_inner_ecn;
	bool trap_en;

	trap_en = __INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce);
	new_inner_ecn = set_ce ? INET_ECN_CE : inner_ecn;

	new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn,
						  &trap_en);
	mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn,
			     trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0);
	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl);
+3 −4
Original line number Diff line number Diff line
@@ -909,12 +909,11 @@ static int __mlxsw_sp_nve_ecn_decap_init(struct mlxsw_sp *mlxsw_sp,
					 u8 inner_ecn, u8 outer_ecn)
{
	char tndem_pl[MLXSW_REG_TNDEM_LEN];
	bool trap_en, set_ce = false;
	u8 new_inner_ecn;
	bool trap_en;

	trap_en = !!__INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce);
	new_inner_ecn = set_ce ? INET_ECN_CE : inner_ecn;

	new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn,
						  &trap_en);
	mlxsw_reg_tndem_pack(tndem_pl, outer_ecn, inner_ecn, new_inner_ecn,
			     trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0);
	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tndem), tndem_pl);
+12 −1
Original line number Diff line number Diff line
@@ -657,10 +657,21 @@ test_ecn_decap()
{
	# In accordance with INET_ECN_decapsulate()
	__test_ecn_decap 00 00 0x00
	__test_ecn_decap 00 01 0x00
	__test_ecn_decap 00 02 0x00
	# 00 03 is tested in test_ecn_decap_error()
	__test_ecn_decap 01 00 0x01
	__test_ecn_decap 01 01 0x01
	__test_ecn_decap 02 01 0x01
	__test_ecn_decap 01 02 0x01
	__test_ecn_decap 01 03 0x03
	__test_ecn_decap 02 00 0x02
	__test_ecn_decap 02 01 0x01
	__test_ecn_decap 02 02 0x02
	__test_ecn_decap 02 03 0x03
	__test_ecn_decap 03 00 0x03
	__test_ecn_decap 03 01 0x03
	__test_ecn_decap 03 02 0x03
	__test_ecn_decap 03 03 0x03
	test_ecn_decap_error
}