Commit 4ee9e6e0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-Add-tunnel-devlink-trap-support'



Ido Schimmel says:

====================
mlxsw: Add tunnel devlink-trap support

This patch set from Amit adds support in mlxsw for tunnel traps and a
few additional layer 3 traps that can report drops and exceptions via
devlink-trap.

These traps allow the user to more quickly diagnose problems relating to
tunnel decapsulation errors, such as packet being too short to
decapsulate or a packet containing wrong GRE key in its GRE header.

Patch set overview:

Patches #1-#4 add three additional layer 3 traps. Two of which are
mlxsw-specific as they relate to hardware-specific errors. The patches
include documentation of each trap and selftests.

Patches #5-#8 are preparations. They ensure that the correct ECN bits
are set in the outer header during IPinIP encapsulation and that packets
with an invalid ECN combination in underlay and overlay are trapped to
the kernel and not decapsulated in hardware.

Patches #9-#15 add support for two tunnel related traps. Each trap is
documented and selftested using both VXLAN and IPinIP tunnels, if
applicable.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 95ae2d1d b3073dfb
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -223,6 +223,21 @@ be added to the following table:
   * - ``ipv6_lpm_miss``
     - ``exception``
     - Traps unicast IPv6 packets that did not match any route
   * - ``non_routable_packet``
     - ``drop``
     - Traps packets that the device decided to drop because they are not
       supposed to be routed. For example, IGMP queries can be flooded by the
       device in layer 2 and reach the router. Such packets should not be
       routed and instead dropped
   * - ``decap_error``
     - ``exception``
     - Traps NVE and IPinIP packets that the device decided to drop because of
       failure during decapsulation (e.g., packet being too short, reserved
       bits set in VXLAN header)
   * - ``overlay_smac_is_mc``
     - ``drop``
     - Traps NVE packets that the device decided to drop because their overlay
       source MAC is multicast

Driver-specific Packet Traps
============================
@@ -234,6 +249,7 @@ links to the description of driver-specific traps registered by various device
drivers:

  * :doc:`netdevsim`
  * :doc:`mlxsw`

Generic Packet Trap Groups
==========================
@@ -258,6 +274,9 @@ narrow. The description of these groups must be added to the following table:
   * - ``buffer_drops``
     - Contains packet traps for packets that were dropped by the device due to
       an enqueue decision
   * - ``tunnel_drops``
     - Contains packet traps for packets that were dropped by the device during
       tunnel encapsulation / decapsulation

Testing
=======
+22 −0
Original line number Diff line number Diff line
@@ -57,3 +57,25 @@ The ``mlxsw`` driver reports the following versions
   * - ``fw.version``
     - running
     - Three digit firmware version

Driver-specific Traps
=====================

.. list-table:: List of Driver-specific Traps Registered by ``mlxsw``
   :widths: 5 5 90

   * - Name
     - Type
     - Description
   * - ``irif_disabled``
     - ``drop``
     - Traps packets that the device decided to drop because they need to be
       routed from a disabled router interface (RIF). This can happen during
       RIF dismantle, when the RIF is first disabled before being removed
       completely
   * - ``erif_disabled``
     - ``drop``
     - Traps packets that the device decided to drop because they need to be
       routed through a disabled router interface (RIF). This can happen during
       RIF dismantle, when the RIF is first disabled before being removed
       completely
+89 −0
Original line number Diff line number Diff line
@@ -5513,6 +5513,7 @@ enum mlxsw_reg_htgt_discard_trap_group {
	MLXSW_REG_HTGT_DISCARD_TRAP_GROUP_BASE = MLXSW_REG_HTGT_TRAP_GROUP_MAX,
	MLXSW_REG_HTGT_TRAP_GROUP_SP_L2_DISCARDS,
	MLXSW_REG_HTGT_TRAP_GROUP_SP_L3_DISCARDS,
	MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
};

/* reg_htgt_trap_group
@@ -10140,6 +10141,92 @@ static inline void mlxsw_reg_tigcr_pack(char *payload, bool ttlc, u8 ttl_uc)
	mlxsw_reg_tigcr_ttl_uc_set(payload, ttl_uc);
}

/* TIEEM - Tunneling IPinIP Encapsulation ECN Mapping Register
 * -----------------------------------------------------------
 * The TIEEM register maps ECN of the IP header at the ingress to the
 * encapsulation to the ECN of the underlay network.
 */
#define MLXSW_REG_TIEEM_ID 0xA812
#define MLXSW_REG_TIEEM_LEN 0x0C

MLXSW_REG_DEFINE(tieem, MLXSW_REG_TIEEM_ID, MLXSW_REG_TIEEM_LEN);

/* reg_tieem_overlay_ecn
 * ECN of the IP header in the overlay network.
 * Access: Index
 */
MLXSW_ITEM32(reg, tieem, overlay_ecn, 0x04, 24, 2);

/* reg_tineem_underlay_ecn
 * ECN of the IP header in the underlay network.
 * Access: RW
 */
MLXSW_ITEM32(reg, tieem, underlay_ecn, 0x04, 16, 2);

static inline void mlxsw_reg_tieem_pack(char *payload, u8 overlay_ecn,
					u8 underlay_ecn)
{
	MLXSW_REG_ZERO(tieem, payload);
	mlxsw_reg_tieem_overlay_ecn_set(payload, overlay_ecn);
	mlxsw_reg_tieem_underlay_ecn_set(payload, underlay_ecn);
}

/* TIDEM - Tunneling IPinIP Decapsulation ECN Mapping Register
 * -----------------------------------------------------------
 * The TIDEM register configures the actions that are done in the
 * decapsulation.
 */
#define MLXSW_REG_TIDEM_ID 0xA813
#define MLXSW_REG_TIDEM_LEN 0x0C

MLXSW_REG_DEFINE(tidem, MLXSW_REG_TIDEM_ID, MLXSW_REG_TIDEM_LEN);

/* reg_tidem_underlay_ecn
 * ECN field of the IP header in the underlay network.
 * Access: Index
 */
MLXSW_ITEM32(reg, tidem, underlay_ecn, 0x04, 24, 2);

/* reg_tidem_overlay_ecn
 * ECN field of the IP header in the overlay network.
 * Access: Index
 */
MLXSW_ITEM32(reg, tidem, overlay_ecn, 0x04, 16, 2);

/* reg_tidem_eip_ecn
 * Egress IP ECN. ECN field of the IP header of the packet which goes out
 * from the decapsulation.
 * Access: RW
 */
MLXSW_ITEM32(reg, tidem, eip_ecn, 0x04, 8, 2);

/* reg_tidem_trap_en
 * Trap enable:
 * 0 - No trap due to decap ECN
 * 1 - Trap enable with trap_id
 * Access: RW
 */
MLXSW_ITEM32(reg, tidem, trap_en, 0x08, 28, 4);

/* reg_tidem_trap_id
 * Trap ID. Either DECAP_ECN0 or DECAP_ECN1.
 * Reserved when trap_en is '0'.
 * Access: RW
 */
MLXSW_ITEM32(reg, tidem, trap_id, 0x08, 0, 9);

static inline void mlxsw_reg_tidem_pack(char *payload, u8 underlay_ecn,
					u8 overlay_ecn, u8 eip_ecn,
					bool trap_en, u16 trap_id)
{
	MLXSW_REG_ZERO(tidem, payload);
	mlxsw_reg_tidem_underlay_ecn_set(payload, underlay_ecn);
	mlxsw_reg_tidem_overlay_ecn_set(payload, overlay_ecn);
	mlxsw_reg_tidem_eip_ecn_set(payload, eip_ecn);
	mlxsw_reg_tidem_trap_en_set(payload, trap_en);
	mlxsw_reg_tidem_trap_id_set(payload, trap_id);
}

/* SBPR - Shared Buffer Pools Register
 * -----------------------------------
 * The SBPR configures and retrieves the shared buffer pools and configuration.
@@ -10684,6 +10771,8 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
	MLXSW_REG(tndem),
	MLXSW_REG(tnpc),
	MLXSW_REG(tigcr),
	MLXSW_REG(tieem),
	MLXSW_REG(tidem),
	MLXSW_REG(sbpr),
	MLXSW_REG(sbcm),
	MLXSW_REG(sbpm),
+0 −2
Original line number Diff line number Diff line
@@ -4538,8 +4538,6 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {
			  false),
	MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV4, TRAP_TO_CPU, ROUTER_EXP, false),
	MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false),
	MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false),
	MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false),
	MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, VRRP, false),
	MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, VRRP, false),
	MLXSW_SP_RXL_NO_MARK(DISCARD_ING_ROUTER_SIP_CLASS_E, FORWARD,
+60 −0
Original line number Diff line number Diff line
@@ -3,8 +3,10 @@

#include <net/ip_tunnels.h>
#include <net/ip6_tunnel.h>
#include <net/inet_ecn.h>

#include "spectrum_ipip.h"
#include "reg.h"

struct ip_tunnel_parm
mlxsw_sp_ipip_netdev_parms4(const struct net_device *ol_dev)
@@ -338,3 +340,61 @@ static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = {
const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = {
	[MLXSW_SP_IPIP_TYPE_GRE4] = &mlxsw_sp_ipip_gre4_ops,
};

static int mlxsw_sp_ipip_ecn_encap_init_one(struct mlxsw_sp *mlxsw_sp,
					    u8 inner_ecn, u8 outer_ecn)
{
	char tieem_pl[MLXSW_REG_TIEEM_LEN];

	mlxsw_reg_tieem_pack(tieem_pl, inner_ecn, outer_ecn);
	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tieem), tieem_pl);
}

int mlxsw_sp_ipip_ecn_encap_init(struct mlxsw_sp *mlxsw_sp)
{
	int i;

	/* Iterate over inner ECN values */
	for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) {
		u8 outer_ecn = INET_ECN_encapsulate(0, i);
		int err;

		err = mlxsw_sp_ipip_ecn_encap_init_one(mlxsw_sp, i, outer_ecn);
		if (err)
			return err;
	}

	return 0;
}

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;

	trap_en = __INET_ECN_decapsulate(outer_ecn, inner_ecn, &set_ce);
	new_inner_ecn = set_ce ? INET_ECN_CE : 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);
	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tidem), tidem_pl);
}

int mlxsw_sp_ipip_ecn_decap_init(struct mlxsw_sp *mlxsw_sp)
{
	int i, j, err;

	/* Iterate over inner ECN values */
	for (i = INET_ECN_NOT_ECT; i <= INET_ECN_CE; i++) {
		/* Iterate over outer ECN values */
		for (j = INET_ECN_NOT_ECT; j <= INET_ECN_CE; j++) {
			err = mlxsw_sp_ipip_ecn_decap_init_one(mlxsw_sp, i, j);
			if (err)
				return err;
		}
	}

	return 0;
}
Loading