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

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
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <net/red.h> #include <net/red.h>
#include <net/vxlan.h> #include <net/vxlan.h>
#include <net/flow_offload.h> #include <net/flow_offload.h>
#include <net/inet_ecn.h>
#include "port.h" #include "port.h"
#include "core.h" #include "core.h"
...@@ -347,6 +348,20 @@ struct mlxsw_sp_port_type_speed_ops { ...@@ -347,6 +348,20 @@ struct mlxsw_sp_port_type_speed_ops {
u32 (*ptys_proto_cap_masked_get)(u32 eth_proto_cap); 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 * static inline struct net_device *
mlxsw_sp_bridge_vxlan_dev_find(struct net_device *br_dev) 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, ...@@ -335,12 +335,11 @@ static int mlxsw_sp_ipip_ecn_decap_init_one(struct mlxsw_sp *mlxsw_sp,
u8 inner_ecn, u8 outer_ecn) u8 inner_ecn, u8 outer_ecn)
{ {
char tidem_pl[MLXSW_REG_TIDEM_LEN]; char tidem_pl[MLXSW_REG_TIDEM_LEN];
bool trap_en, set_ce = false;
u8 new_inner_ecn; u8 new_inner_ecn;
bool trap_en;
trap_en = __INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce); new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn,
new_inner_ecn = set_ce ? INET_ECN_CE : inner_ecn; &trap_en);
mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn, mlxsw_reg_tidem_pack(tidem_pl, outer_ecn, inner_ecn, new_inner_ecn,
trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0); trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl); 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, ...@@ -909,12 +909,11 @@ static int __mlxsw_sp_nve_ecn_decap_init(struct mlxsw_sp *mlxsw_sp,
u8 inner_ecn, u8 outer_ecn) u8 inner_ecn, u8 outer_ecn)
{ {
char tndem_pl[MLXSW_REG_TNDEM_LEN]; char tndem_pl[MLXSW_REG_TNDEM_LEN];
bool trap_en, set_ce = false;
u8 new_inner_ecn; u8 new_inner_ecn;
bool trap_en;
trap_en = !!__INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce); new_inner_ecn = mlxsw_sp_tunnel_ecn_decap(outer_ecn, inner_ecn,
new_inner_ecn = set_ce ? INET_ECN_CE : inner_ecn; &trap_en);
mlxsw_reg_tndem_pack(tndem_pl, outer_ecn, inner_ecn, new_inner_ecn, mlxsw_reg_tndem_pack(tndem_pl, outer_ecn, inner_ecn, new_inner_ecn,
trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0); trap_en, trap_en ? MLXSW_TRAP_ID_DECAP_ECN0 : 0);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tndem), tndem_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tndem), tndem_pl);
......
...@@ -657,10 +657,21 @@ test_ecn_decap() ...@@ -657,10 +657,21 @@ test_ecn_decap()
{ {
# In accordance with INET_ECN_decapsulate() # In accordance with INET_ECN_decapsulate()
__test_ecn_decap 00 00 0x00 __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 01 01 0x01
__test_ecn_decap 02 01 0x01 __test_ecn_decap 01 02 0x01
__test_ecn_decap 01 03 0x03 __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 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 test_ecn_decap_error
} }
......
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