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: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
2dce6987a6
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user