mlxsw: Offloading GRE tunnels
Subsystems (3)
v2 cover mlxsw: Offloading GRE tunnels
From: Jiri Pirko <[email protected]>
Petr says:
This patch series introduces to mlxsw driver support for offloading IP-in-IP tunnels in general, and for (subset of) GRE in particular.
This patchset supports two ways of configuring GRE:
- So called "hierarchical configuration", where the GRE device has a bound dummy device, which is in a different VRF. The VRF with host traffic is called "overlay", the one with encapsulated traffic is called "underlay".
- So called "flat configuration", where the GRE device doesn't have a bound device, and overlay and underlay are both in the same VRF (possibly the default one).
Two routes are then interesting: a route that directs traffic to a GRE device (which would typically be in overlay VRF, but could be in another one), and a local route for the tunnel's local address (in underlay). Handling of these two route types is then introduced as patches to support, respectively, IPv4 and IPv6 encapsulation and IPv4 decapsulation.
The encap and decap routes then reference a loopback device, a new type of RIF introduced by this patchset for the specific use of offloading tunnels.
The encap and decap code is abstract with respect to the particulars of individual L3 tunnel types. This patchset introduces support for GRE tunnels in particular.
Limitations:
- Each tunnel needs to have a different local address (within a given VRF). When two tunnels are used that are in conflict, FIB abort is triggered and the driver ceases offloading FIBs. Full handling of such configurations needs special setup in the hardware, such that the tunnels that share an address are dispatched correctly according to their key (or lack thereof). That's currently not implemented, and to keep things deterministic, the driver triggers FIB abort.
- A next hop that uses an incompletely-specified tunnel (e.g. such that are used for LWT) is not offloaded, but doesn't trigger FIB abort like the above. If such routes end up being in a de facto conflict with other tunnels, then if there already is an offload for that address, the traffic for the conflicting tunnel will end up mismatching the configuration of the offloaded tunnel, and thus gets to slow path through an error trap.
- GRE checksumming and sequence numbers are not supported and TTL and TOS need to be set to inherit. Tunnels with a different configuration are not offloaded and their traffic is trapping to slow path.
Note in particular that TOS of inherit is not the default configuration and needs to be explicitly specified when the tunnel is created.
- The only feature that is not graciously handled is that if a change is made to the tunnel, e.g. through "ip tunnel change", such changes are not reflected in the driver. There is currently no notification mechanism for these changes. Introduction of this mechanism and its leverage in the driver will be subject of follow-up work. For now this limitation can be worked around by removing and re-adding the encap route.
---v1->v2:
-fix order of patch 5
Petr Machata (21):
mlxsw: reg: Update RITR to support loopback device
mlxsw: reg: Update RATR to support IP-in-IP tunnels
mlxsw: reg: Move enum mlxsw_reg_ratr_trap_id
mlxsw: reg: Add mlxsw_reg_ralue_act_ip2me_tun_pack()
mlxsw: reg: Add Routing Tunnel Decap Properties Register
mlxsw: reg: Extract mlxsw_reg_ritr_mac_pack()
mlxsw: reg: Give mlxsw_reg_ratr_pack a type parameter
mlxsw: spectrum_router: Publish mlxsw_sp_l3proto
mlxsw: spectrum_router: Add mlxsw_sp_ipip_ops
mlxsw: spectrum_router: Support FID-less RIFs
mlxsw: spectrum_router: Introduce loopback RIFs
mlxsw: spectrum_router: Extract mlxsw_sp_fi_is_gateway()
mlxsw: spectrum_router: Extract mlxsw_sp_rt6_is_gateway()
mlxsw: spectrum_router: Make nexthops typed
mlxsw: spectrum_router: Support IPv4 overlay encap
mlxsw: spectrum_router: Support IPv6 overlay encap
mlxsw: spectrum_router: Support IPv4 underlay decap
mlxsw: spectrum_router: Use existing decap route
mlxsw: spectrum: Register for IPIP_DECAP_ERROR trap
mlxsw: spectrum_router: Add loopback accessors
mlxsw: spectrum_router: Support GRE tunnels
drivers/net/ethernet/mellanox/mlxsw/Makefile | 4 +- drivers/net/ethernet/mellanox/mlxsw/reg.h | 311 ++++++- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 + drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_ipip.c | 214 +++++ .../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 79 ++ .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 947 +++++++++++++++++++-- .../net/ethernet/mellanox/mlxsw/spectrum_router.h | 28 + drivers/net/ethernet/mellanox/mlxsw/trap.h | 1 + 9 files changed, 1485 insertions(+), 101 deletions(-) create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
Signature · 1 line
2.9.3
PATCH v2 1/21 mlxsw: reg: Update RITR to support loopback device
From: Petr Machata <[email protected]>
Update the register so that loopback RIFs can be created and loopback properties specified.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/reg.h +88 -0
@@ -3998,6 +3998,8 @@ enum mlxsw_reg_ritr_if_type {MLXSW_REG_RITR_FID_IF ,/* Sub-port interface. */ MLXSW_REG_RITR_SP_IF , +/* Loopback Interface. */ + MLXSW_REG_RITR_LOOPBACK_IF, };/* reg_ritr_type
@@ -4129,6 +4131,67 @@ MLXSW_ITEM32(reg, ritr, sp_if_system_port, 0x08, 0, 16);*/ MLXSW_ITEM32 (reg, ritr, sp_if_vid,0x18 ,0 ,12 ); +/* Loopback Interface */ + +enum mlxsw_reg_ritr_loopback_protocol { +/* IPinIP IPv4 underlay Unicast */ +MLXSW_REG_RITR_LOOPBACK_PROTOCOL_IPIP_IPV4 , +/* IPinIP IPv6 underlay Unicast */ +MLXSW_REG_RITR_LOOPBACK_PROTOCOL_IPIP_IPV6 , +}; + +/* reg_ritr_loopback_protocol +* Access: RW +*/ +MLXSW_ITEM32 (reg, ritr, loopback_protocol,0x08 ,28 ,4 ); + +enum mlxsw_reg_ritr_loopback_ipip_type { +/* Tunnel is IPinIP. */ +MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_IP , +/* Tunnel is GRE, no key. */ +MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP , +/* Tunnel is GRE, with a key. */ +MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP , +}; + +/* reg_ritr_loopback_ipip_type +* Encapsulation type. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ritr, loopback_ipip_type,0x10 ,24 ,4 ); + +enum mlxsw_reg_ritr_loopback_ipip_options { +/* The key is defined by gre_key. */ +MLXSW_REG_RITR_LOOPBACK_IPIP_OPTIONS_GRE_KEY_PRESET , +}; + +/* reg_ritr_loopback_ipip_options +* Access: RW +*/ +MLXSW_ITEM32 (reg, ritr, loopback_ipip_options,0x10 ,20 ,4 ); + +/* reg_ritr_loopback_ipip_uvr +* Underlay Virtual Router ID. +* Range is 0..cap_max_virtual_routers-1. +* Reserved for Spectrum-2. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ritr, loopback_ipip_uvr,0x10 ,0 ,16 ); + +/* reg_ritr_loopback_ipip_usip* +* Encapsulation Underlay source IP. +* Access: RW +*/ +MLXSW_ITEM_BUF (reg, ritr, loopback_ipip_usip6,0x18 ,16 ); +MLXSW_ITEM32 (reg, ritr, loopback_ipip_usip4,0x24 ,0 ,32 ); + +/* reg_ritr_loopback_ipip_gre_key +* GRE Key. +* Reserved when ipip_type is not IP_IN_GRE_KEY_IN_IP. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ritr, loopback_ipip_gre_key,0x28 ,0 ,32 ); +/* Shared between ingress/egress */ enum mlxsw_reg_ritr_counter_set_type {/* No Count. */
@@ -4219,6 +4282,31 @@ static inline void mlxsw_reg_ritr_pack(char *payload, bool enable,mlxsw_reg_ritr_if_mac_memcpy_to (payload, mac); } +static inline void +mlxsw_reg_ritr_loopback_ipip_common_pack (char *payload, +enum mlxsw_reg_ritr_loopback_ipip_type ipip_type, +enum mlxsw_reg_ritr_loopback_ipip_options options, +u16 uvr_id,u32 gre_key) +{ +mlxsw_reg_ritr_loopback_ipip_type_set (payload, ipip_type); +mlxsw_reg_ritr_loopback_ipip_options_set (payload, options); +mlxsw_reg_ritr_loopback_ipip_uvr_set (payload, uvr_id); +mlxsw_reg_ritr_loopback_ipip_gre_key_set (payload, gre_key); +} + +static inline void +mlxsw_reg_ritr_loopback_ipip4_pack (char *payload, +enum mlxsw_reg_ritr_loopback_ipip_type ipip_type, +enum mlxsw_reg_ritr_loopback_ipip_options options, +u16 uvr_id,u32 usip,u32 gre_key) +{ +mlxsw_reg_ritr_loopback_protocol_set (payload, +MLXSW_REG_RITR_LOOPBACK_PROTOCOL_IPIP_IPV4 ); +mlxsw_reg_ritr_loopback_ipip_common_pack (payload, ipip_type, options, + uvr_id, gre_key); +mlxsw_reg_ritr_loopback_ipip_usip4_set (payload, usip); +} +/* RATR - Router Adjacency Table Register * -------------------------------------- * The RATR register is used to configure the Router Adjacency (next-hop)
Signature · 1 line
2.9.3
PATCH v2 2/21 mlxsw: reg: Update RATR to support IP-in-IP tunnels
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
So far, adjacencies have always been of type Ethernet (with value of 0), and thus there was no need to explicitly support RATR type. However to support IP-in-IP adjacencies, this type and a suite of IP-in-IP-specific attributes need to be added.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/reg.h +66 -0
@@ -4362,6 +4362,38 @@ MLXSW_ITEM32(reg, ratr, v, 0x00, 24, 1);*/ MLXSW_ITEM32 (reg, ratr, a,0x00 ,16 ,1 ); +enum mlxsw_reg_ratr_type { +/* Ethernet */ +MLXSW_REG_RATR_TYPE_ETHERNET , +/* IPoIB Unicast without GRH. +* Reserved for Spectrum. +*/ +MLXSW_REG_RATR_TYPE_IPOIB_UC , +/* IPoIB Unicast with GRH. Supported only in table 0 (Ethernet unicast +* adjacency). +* Reserved for Spectrum. +*/ +MLXSW_REG_RATR_TYPE_IPOIB_UC_W_GRH , +/* IPoIB Multicast. +* Reserved for Spectrum. +*/ +MLXSW_REG_RATR_TYPE_IPOIB_MC , +/* MPLS. +* Reserved for SwitchX/-2. +*/ +MLXSW_REG_RATR_TYPE_MPLS , +/* IPinIP Encap. +* Reserved for SwitchX/-2. +*/ +MLXSW_REG_RATR_TYPE_IPIP , +}; + +/* reg_ratr_type +* Adjacency entry type. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ratr, type,0x04 ,28 ,4 ); +/* reg_ratr_adjacency_index_low * Bits 15:0 of index into the adjacency table. * For SwitchX and SwitchX-2, the adjacency table is linear and
@@ -4416,6 +4448,34 @@ MLXSW_ITEM32(reg, ratr, trap_id, 0x0C, 0, 8);*/ MLXSW_ITEM_BUF (reg, ratr, eth_destination_mac,0x12 ,6 ); +enum mlxsw_reg_ratr_ipip_type { +/* IPv4, address set by mlxsw_reg_ratr_ipip_ipv4_udip. */ +MLXSW_REG_RATR_IPIP_TYPE_IPV4 , +/* IPv6, address set by mlxsw_reg_ratr_ipip_ipv6_ptr. */ +MLXSW_REG_RATR_IPIP_TYPE_IPV6 , +}; + +/* reg_ratr_ipip_type +* Underlay destination ip type. +* Note: the type field must match the protocol of the router interface. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ratr, ipip_type,0x10 ,16 ,4 ); + +/* reg_ratr_ipip_ipv4_udip +* Underlay ipv4 dip. +* Reserved when ipip_type is IPv6. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ratr, ipip_ipv4_udip,0x18 ,0 ,32 ); + +/* reg_ratr_ipip_ipv6_ptr +* Pointer to IPv6 underlay destination ip address. +* For Spectrum: Pointer to KVD linear space. +* Access: RW +*/ +MLXSW_ITEM32 (reg, ratr, ipip_ipv6_ptr,0x1C ,0 ,24 ); + static inline void mlxsw_reg_ratr_pack(char *payload, enum mlxsw_reg_ratr_op op, bool valid,
@@ -4435,6 +4495,12 @@ static inline void mlxsw_reg_ratr_eth_entry_pack(char *payload,mlxsw_reg_ratr_eth_destination_mac_memcpy_to (payload, dest_mac); } +static inline void mlxsw_reg_ratr_ipip4_entry_pack (char *payload,u32 ipv4_udip) +{ +mlxsw_reg_ratr_ipip_type_set (payload,MLXSW_REG_RATR_IPIP_TYPE_IPV4 ); +mlxsw_reg_ratr_ipip_ipv4_udip_set (payload, ipv4_udip); +} +/* RICNT - Router Interface Counter Register * ----------------------------------------- * The RICNT register retrieves per port performance counters
Signature · 1 line
2.9.3
PATCH v2 3/21 mlxsw: reg: Move enum mlxsw_reg_ratr_trap_id
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
This enum is used with reg_ratr_trap_id, so move it next to the register definition.
While at it, drop the enumerator initializers.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/reg.h +5 -5
@@ -4423,17 +4423,17 @@ enum mlxsw_reg_ratr_trap_action {*/ MLXSW_ITEM32 (reg, ratr, trap_action,0x0C ,28 ,4 ); -enum mlxsw_reg_ratr_trap_id { -MLXSW_REG_RATR_TRAP_ID_RTR_EGRESS0 =0 , -MLXSW_REG_RATR_TRAP_ID_RTR_EGRESS1 =1 , -}; -/* reg_ratr_adjacency_index_high * Bits 23:16 of the adjacency_index. * Access: Index */ MLXSW_ITEM32 (reg, ratr, adjacency_index_high,0x0C ,16 ,8 ); +enum mlxsw_reg_ratr_trap_id { +MLXSW_REG_RATR_TRAP_ID_RTR_EGRESS0 , +MLXSW_REG_RATR_TRAP_ID_RTR_EGRESS1 , +}; +/* reg_ratr_trap_id * Trap ID to be reported to CPU. * Trap-ID is RTR_EGRESS0 or RTR_EGRESS1.
Signature · 1 line
2.9.3
PATCH v2 4/21 mlxsw: reg: Add mlxsw_reg_ralue_act_ip2me_tun_pack()
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
To implement IP-in-IP decapsulation, Spectrum uses LPM entries of type IP2ME with tunnel validity bit and tunnel pointer set. The necessary register fields are already available, so add a function to pack the RALUE as appropriate.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/reg.h +9 -0
@@ -5054,6 +5054,15 @@ mlxsw_reg_ralue_act_ip2me_pack(char *payload) MLXSW_REG_RALUE_ACTION_TYPE_IP2ME); } +static inline void +mlxsw_reg_ralue_act_ip2me_tun_pack (char *payload,u32 tunnel_ptr) +{ +mlxsw_reg_ralue_action_type_set (payload, +MLXSW_REG_RALUE_ACTION_TYPE_IP2ME ); +mlxsw_reg_ralue_ip2me_v_set (payload,1 ); +mlxsw_reg_ralue_ip2me_tunnel_ptr_set (payload, tunnel_ptr); +} +/* RAUHT - Router Algorithmic LPM Unicast Host Table Register * ---------------------------------------------------------- * The RAUHT register is used to configure and query the Unicast Host table in
Signature · 1 line
2.9.3
PATCH v2 5/21 mlxsw: reg: Add Routing Tunnel Decap Properties Register
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
The RTDP register is used for configuring the tunnel decap properties of NVE and IPinIP.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 129 ++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/reg.h +129 -0
@@ -5,6 +5,7 @@* Copyright (c) 2015 Elad Raz <[email protected]> * Copyright (c) 2015-2017 Jiri Pirko <[email protected]> * Copyright (c) 2016 Yotam Gigi <[email protected]> +* Copyright (c) 2017 Petr Machata <[email protected]> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met:
@@ -5463,6 +5464,133 @@ static inline void mlxsw_reg_rauhtd_ent_ipv6_unpack(char *payload,mlxsw_reg_rauhtd_ipv6_ent_dip_memcpy_from (payload, rec_index, p_dip); } +/* RTDP - Routing Tunnel Decap Properties Register +* ----------------------------------------------- +* The RTDP register is used for configuring the tunnel decap properties of NVE +* and IPinIP. +*/ +#define MLXSW_REG_RTDP_ID 0x8020 +#define MLXSW_REG_RTDP_LEN 0x44 + +MLXSW_REG_DEFINE (rtdp,MLXSW_REG_RTDP_ID ,MLXSW_REG_RTDP_LEN ); + +enum mlxsw_reg_rtdp_type { +MLXSW_REG_RTDP_TYPE_NVE , +MLXSW_REG_RTDP_TYPE_IPIP , +}; + +/* reg_rtdp_type +* Type of the RTDP entry as per enum mlxsw_reg_rtdp_type. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, type,0x00 ,28 ,4 ); + +/* reg_rtdp_tunnel_index +* Index to the Decap entry. +* For Spectrum, Index to KVD Linear. +* Access: Index +*/ +MLXSW_ITEM32 (reg, rtdp, tunnel_index,0x00 ,0 ,24 ); + +/* IPinIP */ + +/* reg_rtdp_ipip_irif +* Ingress Router Interface for the overlay router +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_irif,0x04 ,16 ,16 ); + +enum mlxsw_reg_rtdp_ipip_sip_check { +/* No sip checks. */ +MLXSW_REG_RTDP_IPIP_SIP_CHECK_NO , +/* Filter packet if underlay is not IPv4 or if underlay SIP does not +* equal ipv4_usip. +*/ +MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV4 , +/* Filter packet if underlay is not IPv6 or if underlay SIP does not +* equal ipv6_usip. +*/ +MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV6 =3 , +}; + +/* reg_rtdp_ipip_sip_check +* SIP check to perform. If decapsulation failed due to these configurations +* then trap_id is IPIP_DECAP_ERROR. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_sip_check,0x04 ,0 ,3 ); + +/* If set, allow decapsulation of IPinIP (without GRE). */ +#define MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_IPIP BIT(0) +/* If set, allow decapsulation of IPinGREinIP without a key. */ +#define MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE BIT(1) +/* If set, allow decapsulation of IPinGREinIP with a key. */ +#define MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY BIT(2) + +/* reg_rtdp_ipip_type_check +* Flags as per MLXSW_REG_RTDP_IPIP_TYPE_CHECK_*. If decapsulation failed due to +* these configurations then trap_id is IPIP_DECAP_ERROR. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_type_check,0x08 ,24 ,3 ); + +/* reg_rtdp_ipip_gre_key_check +* Whether GRE key should be checked. When check is enabled: +* - A packet received as IPinIP (without GRE) will always pass. +* - A packet received as IPinGREinIP without a key will not pass the check. +* - A packet received as IPinGREinIP with a key will pass the check only if the +* key in the packet is equal to expected_gre_key. +* If decapsulation failed due to GRE key then trap_id is IPIP_DECAP_ERROR. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_gre_key_check,0x08 ,23 ,1 ); + +/* reg_rtdp_ipip_ipv4_usip +* Underlay IPv4 address for ipv4 source address check. +* Reserved when sip_check is not '1'. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_ipv4_usip,0x0C ,0 ,32 ); + +/* reg_rtdp_ipip_ipv6_usip_ptr +* This field is valid when sip_check is "sipv6 check explicitly". This is a +* pointer to the IPv6 DIP which is configured by RIPS. For Spectrum, the index +* is to the KVD linear. +* Reserved when sip_check is not MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV6. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_ipv6_usip_ptr,0x10 ,0 ,24 ); + +/* reg_rtdp_ipip_expected_gre_key +* GRE key for checking. +* Reserved when gre_key_check is '0'. +* Access: RW +*/ +MLXSW_ITEM32 (reg, rtdp, ipip_expected_gre_key,0x14 ,0 ,32 ); + +static inline void mlxsw_reg_rtdp_pack (char *payload, +enum mlxsw_reg_rtdp_type type, +u32 tunnel_index) +{ +MLXSW_REG_ZERO (rtdp, payload); +mlxsw_reg_rtdp_type_set (payload, type); +mlxsw_reg_rtdp_tunnel_index_set (payload, tunnel_index); +} + +static inline void +mlxsw_reg_rtdp_ipip4_pack (char *payload,u16 irif, +enum mlxsw_reg_rtdp_ipip_sip_check sip_check, +unsigned int type_check,bool gre_key_check, +u32 ipv4_usip,u32 expected_gre_key) +{ +mlxsw_reg_rtdp_ipip_irif_set (payload, irif); +mlxsw_reg_rtdp_ipip_sip_check_set (payload, sip_check); +mlxsw_reg_rtdp_ipip_type_check_set (payload, type_check); +mlxsw_reg_rtdp_ipip_gre_key_check_set (payload, gre_key_check); +mlxsw_reg_rtdp_ipip_ipv4_usip_set (payload, ipv4_usip); +mlxsw_reg_rtdp_ipip_expected_gre_key_set (payload, expected_gre_key); +} +/* MFCR - Management Fan Control Register * -------------------------------------- * This register controls the settings of the Fan Speed PWM mechanism.
@@ -6724,6 +6852,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {MLXSW_REG (rgcr),MLXSW_REG (ritr),MLXSW_REG (ratr), +MLXSW_REG (rtdp),MLXSW_REG (ricnt),MLXSW_REG (ralta), MLXSW_REG(ralst),
Signature · 1 line
2.9.3
PATCH v2 6/21 mlxsw: reg: Extract mlxsw_reg_ritr_mac_pack()
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
Unlike other interface types, loopback RIFs do not have MAC address. So drop the corresponding argument from mlxsw_reg_ritr_pack() and move it to a new function. Call that from callers of mlxsw_reg_ritr_pack.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 7 +++++-- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/reg.h +5 -2
@@ -4263,8 +4263,7 @@ static inline void mlxsw_reg_ritr_sp_if_pack(char *payload, bool lag,static inline void mlxsw_reg_ritr_pack (char *payload,bool enable,enum mlxsw_reg_ritr_if_type type, -u16 rif,u16 vr_id,u16 mtu, -const char *mac) +u16 rif,u16 vr_id,u16 mtu) {bool op = enable ?MLXSW_REG_RITR_RIF_CREATE :MLXSW_REG_RITR_RIF_DEL ;
@@ -4280,6 +4279,10 @@ static inline void mlxsw_reg_ritr_pack(char *payload, bool enable,mlxsw_reg_ritr_lb_en_set (payload,1 );mlxsw_reg_ritr_virtual_router_set (payload, vr_id);mlxsw_reg_ritr_mtu_set (payload, mtu); +} + +static inline void mlxsw_reg_ritr_mac_pack (char *payload,const char *mac) +{mlxsw_reg_ritr_if_mac_memcpy_to (payload, mac); }
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +4 -3
@@ -4955,8 +4955,8 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable) rif_subport =mlxsw_sp_rif_subport_rif (rif);mlxsw_reg_ritr_pack (ritr_pl, enable,MLXSW_REG_RITR_SP_IF , - rif->rif_index, rif->vr_id, rif->dev->mtu, - rif->dev->dev_addr); + rif->rif_index, rif->vr_id, rif->dev->mtu); +mlxsw_reg_ritr_mac_pack (ritr_pl, rif->dev->dev_addr); mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag, rif_subport->lag ? rif_subport->lag_id : rif_subport->system_port,
@@ -4998,7 +4998,8 @@ static int mlxsw_sp_rif_vlan_fid_op(struct mlxsw_sp_rif *rif,char ritr_pl[MLXSW_REG_RITR_LEN ];mlxsw_reg_ritr_pack (ritr_pl, enable, type, rif->rif_index, rif->vr_id, - rif->dev->mtu, rif->dev->dev_addr); + rif->dev->mtu); +mlxsw_reg_ritr_mac_pack (ritr_pl, rif->dev->dev_addr);mlxsw_reg_ritr_fid_set (ritr_pl, type, vid_fid);return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (ritr), ritr_pl);
Signature · 1 line
2.9.3
PATCH v2 7/21 mlxsw: reg: Give mlxsw_reg_ratr_pack a type parameter
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
To support IPIP, the driver needs to be able to construct an IPIP adjacency. Change mlxsw_reg_ratr_pack to take an adjacency type as an argument. Adjust the one existing caller.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 2 ++ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/reg.h +2 -0
@@ -4483,11 +4483,13 @@ MLXSW_ITEM32(reg, ratr, ipip_ipv6_ptr, 0x1C, 0, 24);static inline void mlxsw_reg_ratr_pack (char *payload,enum mlxsw_reg_ratr_op op,bool valid, +enum mlxsw_reg_ratr_type type,u32 adjacency_index,u16 egress_rif) {MLXSW_REG_ZERO (ratr, payload);mlxsw_reg_ratr_op_set (payload, op);mlxsw_reg_ratr_v_set (payload, valid); +mlxsw_reg_ratr_type_set (payload, type);mlxsw_reg_ratr_adjacency_index_low_set (payload, adjacency_index);mlxsw_reg_ratr_adjacency_index_high_set (payload, adjacency_index >>16 );mlxsw_reg_ratr_egress_router_interface_set (payload, egress_rif);
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +2 -1
@@ -1928,7 +1928,8 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index,char ratr_pl[MLXSW_REG_RATR_LEN ];mlxsw_reg_ratr_pack (ratr_pl,MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY , - true, adj_index, neigh_entry->rif); + true,MLXSW_REG_RATR_TYPE_ETHERNET , + adj_index, neigh_entry->rif);mlxsw_reg_ratr_eth_entry_pack (ratr_pl, neigh_entry->ha);return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (ratr), ratr_pl); }
Signature · 1 line
2.9.3
PATCH v2 8/21 mlxsw: spectrum_router: Publish mlxsw_sp_l3proto
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
The spectrum_ipip module that will be introduced in the follow-up patches needs to know the data type.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 5 ----- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +0 -5
@@ -405,11 +405,6 @@ struct mlxsw_sp_rt6 {struct rt6_info *rt; }; -enum mlxsw_sp_l3proto { -MLXSW_SP_L3_PROTO_IPV4 , -MLXSW_SP_L3_PROTO_IPV6 , -}; -struct mlxsw_sp_lpm_tree {u8 id;/* tree ID */ unsigned int ref_count;
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +5 -0
@@ -37,6 +37,11 @@#include "spectrum.h" +enum mlxsw_sp_l3proto { +MLXSW_SP_L3_PROTO_IPV4 , +MLXSW_SP_L3_PROTO_IPV6 , +}; +enum mlxsw_sp_rif_counter_dir {MLXSW_SP_RIF_COUNTER_INGRESS ,MLXSW_SP_RIF_COUNTER_EGRESS ,
Signature · 1 line
2.9.3
PATCH v2 9/21 mlxsw: spectrum_router: Add mlxsw_sp_ipip_ops
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
Details of individual tunnel types are kept in an array of mlxsw_sp_ipip_ops objects. Follow-up patches will use the list to determine whether a constructed RIF should be a loopback, and to decide whether a next hop references a tunnel.
The list is currently empty, follow-up patches will add support for GRE.
--- drivers/net/ethernet/mellanox/mlxsw/Makefile | 4 +- .../net/ethernet/mellanox/mlxsw/spectrum_ipip.c | 38 ++++++++++++++++ .../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 51 ++++++++++++++++++++++ .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 19 ++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h
drivers/net/ethernet/mellanox/mlxsw/Makefile +2 -2
@@ -16,8 +16,8 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \ spectrum_switchdev.o spectrum_router.o \ spectrum_kvdl.o spectrum_acl_tcam.o \ spectrum_acl.o spectrum_flower.o \ - spectrum_cnt.o \ - spectrum_fid.o + spectrum_cnt.o spectrum_fid.o \ + spectrum_ipip.o mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c new file +38 -0
@@ -0,0 +1,38 @@ +/* +* drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c +* Copyright (c) 2017 Mellanox Technologies. All rights reserved. +* Copyright (c) 2017 Petr Machata <[email protected]> +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the names of the copyright holders nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* Alternatively, this software may be distributed under the terms of the +* GNU General Public License ("GPL") version 2 as published by the Free +* Software Foundation. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "spectrum_ipip.h" + +const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = { +};
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h new file +51 -0
51 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +19 -0
@@ -62,6 +62,7 @@#include "reg.h" #include "spectrum_cnt.h" #include "spectrum_dpipe.h" +#include "spectrum_ipip.h" #include "spectrum_router.h" struct mlxsw_sp_vr ;
@@ -89,6 +90,7 @@ struct mlxsw_sp_router {bool aborted;struct notifier_block fib_nb;const struct mlxsw_sp_rif_ops **rif_ops_arr; +const struct mlxsw_sp_ipip_ops **ipip_ops_arr; };struct mlxsw_sp_rif {
@@ -5152,6 +5154,16 @@ static void mlxsw_sp_rifs_fini(struct mlxsw_sp *mlxsw_sp)kfree (mlxsw_sp->router->rifs); } +static int mlxsw_sp_ipips_init (struct mlxsw_sp *mlxsw_sp) +{ + mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr; +return 0 ; +} + +static void mlxsw_sp_ipips_fini (struct mlxsw_sp *mlxsw_sp) +{ +} +static void mlxsw_sp_router_fib_dump_flush (struct notifier_block *nb) {struct mlxsw_sp_router *router;
@@ -5211,6 +5223,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp)if (err) goto err_rifs_init; + err =mlxsw_sp_ipips_init (mlxsw_sp); +if (err) + goto err_ipips_init; + err =rhashtable_init (&mlxsw_sp->router->nexthop_ht, &mlxsw_sp_nexthop_ht_params);if (err)
@@ -5252,6 +5268,8 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp) err_nexthop_group_ht_init:rhashtable_destroy (&mlxsw_sp->router->nexthop_ht); err_nexthop_ht_init: +mlxsw_sp_ipips_fini (mlxsw_sp); +err_ipips_init:mlxsw_sp_rifs_fini (mlxsw_sp); err_rifs_init:__mlxsw_sp_router_fini (mlxsw_sp);
@@ -5268,6 +5286,7 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)mlxsw_sp_lpm_fini (mlxsw_sp);rhashtable_destroy (&mlxsw_sp->router->nexthop_group_ht);rhashtable_destroy (&mlxsw_sp->router->nexthop_ht); +mlxsw_sp_ipips_fini (mlxsw_sp);mlxsw_sp_rifs_fini (mlxsw_sp);__mlxsw_sp_router_fini (mlxsw_sp);kfree (mlxsw_sp->router);
Signature · 1 line
2.9.3
PATCH v2 10/21 mlxsw: spectrum_router: Support FID-less RIFs
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
Loopback RIFs, which will be introduced in a follow-up patch, differ from other RIFs in that they do not have a FID associated with them.
To support this, demote FID allocation from mlxsw_sp_rif_create to configure op of the existing RIF types, and likewise the FID release from mlxsw_sp_rif_destroy to deconfigure op.
--- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 85 ++++++++++++++++------ 1 file changed, 63 insertions(+), 22 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +63 -22
@@ -4444,9 +4444,9 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, {u32 tb_id =l3mdev_fib_table (params->dev);const struct mlxsw_sp_rif_ops *ops; +struct mlxsw_sp_fid *fid =NULL ;enum mlxsw_sp_rif_type type;struct mlxsw_sp_rif *rif; -struct mlxsw_sp_fid *fid;struct mlxsw_sp_vr *vr;u16 rif_index;int err;
@@ -4470,12 +4470,14 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, rif->mlxsw_sp = mlxsw_sp; rif->ops = ops; - fid = ops->fid_get (rif); -if (IS_ERR (fid)) { - err =PTR_ERR (fid); - goto err_fid_get; +if (ops->fid_get) { + fid = ops->fid_get (rif); +if (IS_ERR (fid)) { + err =PTR_ERR (fid); + goto err_fid_get; + } + rif->fid = fid; } - rif->fid = fid;if (ops->setup) ops->setup (rif, params);
@@ -4484,22 +4486,15 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,if (err) goto err_configure; - err =mlxsw_sp_rif_fdb_op (mlxsw_sp, params->dev->dev_addr, -mlxsw_sp_fid_index (fid), true); -if (err) - goto err_rif_fdb_op; -mlxsw_sp_rif_counters_alloc (rif); -mlxsw_sp_fid_rif_set (fid, rif); mlxsw_sp->router->rifs[rif_index] = rif; vr->rif_count++;return rif; -err_rif_fdb_op: - ops->deconfigure (rif); err_configure: -mlxsw_sp_fid_put (fid); +if (fid) +mlxsw_sp_fid_put (fid); err_fid_get:kfree (rif); err_rif_alloc:
@@ -4520,12 +4515,11 @@ void mlxsw_sp_rif_destroy(struct mlxsw_sp_rif *rif) vr->rif_count--; mlxsw_sp->router->rifs[rif->rif_index] =NULL ; -mlxsw_sp_fid_rif_set (fid,NULL );mlxsw_sp_rif_counters_free (rif); -mlxsw_sp_rif_fdb_op (mlxsw_sp, rif->dev->dev_addr, -mlxsw_sp_fid_index (fid), false); ops->deconfigure (rif); -mlxsw_sp_fid_put (fid); +if (fid) +/* Loopback RIFs are not associated with a FID. */ +mlxsw_sp_fid_put (fid);kfree (rif);mlxsw_sp_vr_put (vr); }
@@ -4965,11 +4959,32 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable)static int mlxsw_sp_rif_subport_configure (struct mlxsw_sp_rif *rif) { -return mlxsw_sp_rif_subport_op (rif, true); +int err; + + err =mlxsw_sp_rif_subport_op (rif, true); +if (err) +return err; + + err =mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (rif->fid), true); +if (err) + goto err_rif_fdb_op; + +mlxsw_sp_fid_rif_set (rif->fid, rif); +return 0 ; + +err_rif_fdb_op: +mlxsw_sp_rif_subport_op (rif, false); +return err; }static void mlxsw_sp_rif_subport_deconfigure (struct mlxsw_sp_rif *rif) { +struct mlxsw_sp_fid *fid = rif->fid; + +mlxsw_sp_fid_rif_set (fid,NULL ); +mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (fid), false);mlxsw_sp_rif_subport_op (rif, false); }
@@ -5028,8 +5043,17 @@ static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif)if (err) goto err_fid_bc_flood_set; + err =mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (rif->fid), true); +if (err) + goto err_rif_fdb_op; + +mlxsw_sp_fid_rif_set (rif->fid, rif);return 0 ; +err_rif_fdb_op: +mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_BC , +mlxsw_sp_router_port (mlxsw_sp), false); err_fid_bc_flood_set:mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_MC ,mlxsw_sp_router_port (mlxsw_sp), false);
@@ -5040,9 +5064,13 @@ static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif)static void mlxsw_sp_rif_vlan_deconfigure (struct mlxsw_sp_rif *rif) { -struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;u16 vid =mlxsw_sp_fid_8021q_vid (rif->fid); +struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; +struct mlxsw_sp_fid *fid = rif->fid; +mlxsw_sp_fid_rif_set (fid,NULL ); +mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (fid), false);mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_BC ,mlxsw_sp_router_port (mlxsw_sp), false); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
@@ -5087,8 +5115,17 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)if (err) goto err_fid_bc_flood_set; + err =mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (rif->fid), true); +if (err) + goto err_rif_fdb_op; + +mlxsw_sp_fid_rif_set (rif->fid, rif);return 0 ; +err_rif_fdb_op: +mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_BC , +mlxsw_sp_router_port (mlxsw_sp), false); err_fid_bc_flood_set:mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_MC ,mlxsw_sp_router_port (mlxsw_sp), false);
@@ -5099,9 +5136,13 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif)static void mlxsw_sp_rif_fid_deconfigure (struct mlxsw_sp_rif *rif) { -struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;u16 fid_index =mlxsw_sp_fid_index (rif->fid); +struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; +struct mlxsw_sp_fid *fid = rif->fid; +mlxsw_sp_fid_rif_set (fid,NULL ); +mlxsw_sp_rif_fdb_op (rif->mlxsw_sp, rif->dev->dev_addr, +mlxsw_sp_fid_index (fid), false);mlxsw_sp_fid_flood_set (rif->fid,MLXSW_SP_FLOOD_TYPE_BC ,mlxsw_sp_router_port (mlxsw_sp), false); mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
Signature · 1 line
2.9.3
PATCH v2 11/21 mlxsw: spectrum_router: Introduce loopback RIFs
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
When offloading L3 tunnels, an adjacency entry is created that loops the packet back into the underlay router. Loopback interfaces then hold the corresponding information and are created for IP-in-IP netdevices.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 152 ++++++++++++++++++++- .../net/ethernet/mellanox/mlxsw/spectrum_router.h | 13 ++ 3 files changed, 164 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +1 -0
@@ -77,6 +77,7 @@ enum mlxsw_sp_rif_type {MLXSW_SP_RIF_TYPE_SUBPORT ,MLXSW_SP_RIF_TYPE_VLAN ,MLXSW_SP_RIF_TYPE_FID , +MLXSW_SP_RIF_TYPE_IPIP_LB ,/* IP-in-IP loopback. */ MLXSW_SP_RIF_TYPE_MAX, };
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +150 -2
200 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +13 -0
@@ -36,12 +36,25 @@#define _MLXSW_ROUTER_H_#include "spectrum.h" +#include "reg.h" enum mlxsw_sp_l3proto {MLXSW_SP_L3_PROTO_IPV4 ,MLXSW_SP_L3_PROTO_IPV6 , }; +union mlxsw_sp_l3addr { +__be32 addr4; +struct in6_addr addr6; +}; + +struct mlxsw_sp_rif_ipip_lb_config { +enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; +u32 okey; +enum mlxsw_sp_l3proto ul_protocol;/* Underlay. */ +union mlxsw_sp_l3addr saddr; +}; +enum mlxsw_sp_rif_counter_dir {MLXSW_SP_RIF_COUNTER_INGRESS ,MLXSW_SP_RIF_COUNTER_EGRESS ,
Signature · 1 line
2.9.3
PATCH v2 12/21 mlxsw: spectrum_router: Extract mlxsw_sp_fi_is_gateway()
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
For IPv4 IP-in-IP offload, routes that direct traffic to IP-in-IP devices need to be considered gateway routes as well. That involves a bit more logic, so extract the current test to a separate function, where the logic can be later added.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +10 -4
@@ -2382,6 +2382,12 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, } } +static bool mlxsw_sp_fi_is_gateway (const struct mlxsw_sp *mlxsw_sp, +const struct fib_info *fi) +{ +return fi->fib_nh->nh_scope ==RT_SCOPE_LINK ; +} +static struct mlxsw_sp_nexthop_group *mlxsw_sp_nexthop4_group_create (struct mlxsw_sp *mlxsw_sp,struct fib_info *fi) {
@@ -2401,7 +2407,7 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)INIT_LIST_HEAD (&nh_grp->fib_list); nh_grp->neigh_tbl = &arp_tbl; - nh_grp->gateway = fi->fib_nh->nh_scope ==RT_SCOPE_LINK ; + nh_grp->gateway =mlxsw_sp_fi_is_gateway (mlxsw_sp, fi); nh_grp->count = fi->fib_nhs;fib_info_hold (fi);for (i =0 ; i < nh_grp->count; i++) {
@@ -2801,10 +2807,10 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp, fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ;return 0 ;case RTN_UNICAST : -if (fi->fib_nh->nh_scope !=RT_SCOPE_LINK ) - fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ; -else +if (mlxsw_sp_fi_is_gateway (mlxsw_sp, fi)) fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_REMOTE ; +else + fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_LOCAL ;return 0 ;default :return -EINVAL ;
Signature · 1 line
2.9.3
PATCH v2 13/21 mlxsw: spectrum_router: Extract mlxsw_sp_rt6_is_gateway()
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
IPv6 counterpart of the previous patch: introduce a function to determine whether a given route is a gateway route.
The new function takes a mlxsw_sp argument which follow-up patches will use. Thus mlxsw_sp_fib6_entry_type_set() got that argument as well.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +11 -4
@@ -3526,6 +3526,12 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,mlxsw_sp_nexthop_rif_fini (nh); } +static bool mlxsw_sp_rt6_is_gateway (const struct mlxsw_sp *mlxsw_sp, +const struct rt6_info *rt) +{ +return rt->rt6i_flags &RTF_GATEWAY ; +} +static struct mlxsw_sp_nexthop_group *mlxsw_sp_nexthop6_group_create (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_fib6_entry *fib6_entry)
@@ -3548,7 +3554,7 @@ mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp,#endif mlxsw_sp_rt6 =list_first_entry (&fib6_entry->rt6_list, struct mlxsw_sp_rt6, list); - nh_grp->gateway = !!(mlxsw_sp_rt6->rt->rt6i_flags &RTF_GATEWAY ); + nh_grp->gateway =mlxsw_sp_rt6_is_gateway (mlxsw_sp, mlxsw_sp_rt6->rt); nh_grp->count = fib6_entry->nrt6;for (i =0 ; i < nh_grp->count; i++) {struct rt6_info *rt = mlxsw_sp_rt6->rt;
@@ -3705,7 +3711,8 @@ mlxsw_sp_fib6_entry_nexthop_del(struct mlxsw_sp *mlxsw_sp,mlxsw_sp_rt6_destroy (mlxsw_sp_rt6); } -static void mlxsw_sp_fib6_entry_type_set (struct mlxsw_sp_fib_entry *fib_entry, +static void mlxsw_sp_fib6_entry_type_set (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_fib_entry *fib_entry,const struct rt6_info *rt) {/* Packets hitting RTF_REJECT routes need to be discarded by the
@@ -3718,7 +3725,7 @@ static void mlxsw_sp_fib6_entry_type_set(struct mlxsw_sp_fib_entry *fib_entry, fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_TRAP ; else if (rt->rt6i_flags & RTF_REJECT) fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL; - else if (rt->rt6i_flags & RTF_GATEWAY) + else if (mlxsw_sp_rt6_is_gateway(mlxsw_sp, rt)) fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE; else fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
@@ -3758,7 +3765,7 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp, goto err_rt6_create; } -mlxsw_sp_fib6_entry_type_set (fib_entry, mlxsw_sp_rt6->rt); +mlxsw_sp_fib6_entry_type_set (mlxsw_sp, fib_entry, mlxsw_sp_rt6->rt);INIT_LIST_HEAD (&fib6_entry->rt6_list);list_add_tail (&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
Signature · 1 line
2.9.3
PATCH v2 14/21 mlxsw: spectrum_router: Make nexthops typed
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
In the router, some next hops may reference an encapsulating netdevice, such as GRE or IPIP. To properly offload these next hops, mlxsw needs to keep track of whether a given next hop is a regular Ethernet entry, or an IP-in-IP tunneling entry.
To facilitate this book-keeping, add a type field to struct mlxsw_sp_nexthop. There is, as of this patch, only one next hop type:MLXSW_SP_NEXTHOP_TYPE_ETH. Follow-up patches will introduce the IP-in-IP variant.
There are several places where next hops are initialized in the IPv4 path. Instead of replicating the logic at every one of them, factor it out to a function mlxsw_sp_nexthop4_type_init(). The corresponding fini is actually protocol-neutral, so put it to mlxsw_sp_nexthop_type_fini(), but create a corresponding protocoled _fini function that dispatches to the protocol-neutral one.
The IPv6 path is simpler, but for symmetry with IPv4, create the same suite of functions with corresponding logic.
--- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 138 ++++++++++++++------- 1 file changed, 95 insertions(+), 43 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +95 -43
@@ -1652,6 +1652,10 @@ static void mlxsw_sp_neigh_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, } } +enum mlxsw_sp_nexthop_type { +MLXSW_SP_NEXTHOP_TYPE_ETH , +}; +struct mlxsw_sp_nexthop_key {struct fib_nh *fib_nh; };
@@ -1676,7 +1680,10 @@ struct mlxsw_sp_nexthop { update:1 ;/* set indicates that MAC of this neigh should be * updated in HW */ -struct mlxsw_sp_neigh_entry *neigh_entry; +enum mlxsw_sp_nexthop_type type; +union { +struct mlxsw_sp_neigh_entry *neigh_entry; + }; };struct mlxsw_sp_nexthop_group {
@@ -1964,9 +1971,9 @@ static int mlxsw_sp_nexthop_mac_update(struct mlxsw_sp *mlxsw_sp, u32 adj_index, }static int -mlxsw_sp_nexthop_group_mac_update (struct mlxsw_sp *mlxsw_sp, -struct mlxsw_sp_nexthop_group *nh_grp, -bool reallocate) +mlxsw_sp_nexthop_group_update (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop_group *nh_grp, +bool reallocate) {u32 adj_index = nh_grp->adj_index;/* base */ struct mlxsw_sp_nexthop *nh;
@@ -1982,8 +1989,12 @@ mlxsw_sp_nexthop_group_mac_update(struct mlxsw_sp *mlxsw_sp, }if (nh->update || reallocate) { - err =mlxsw_sp_nexthop_mac_update (mlxsw_sp, - adj_index, nh); +switch (nh->type) { +case MLXSW_SP_NEXTHOP_TYPE_ETH : + err =mlxsw_sp_nexthop_mac_update + (mlxsw_sp, adj_index, nh); +break ; + }if (err)return err; nh->update =0 ;
@@ -2071,8 +2082,7 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp,/* Nothing was added or removed, so no need to reallocate. Just * update MAC on existing adjacency indexes. */ - err =mlxsw_sp_nexthop_group_mac_update (mlxsw_sp, nh_grp, - false); + err =mlxsw_sp_nexthop_group_update (mlxsw_sp, nh_grp, false);if (err) {dev_warn (mlxsw_sp->bus_info->dev,"Failed to update neigh MAC in adjacency table.\n" ); goto set_trap;
@@ -2099,7 +2109,7 @@ mlxsw_sp_nexthop_group_refresh(struct mlxsw_sp *mlxsw_sp, nh_grp->adj_index_valid =1 ; nh_grp->adj_index = adj_index; nh_grp->ecmp_size = ecmp_size; - err =mlxsw_sp_nexthop_group_mac_update (mlxsw_sp, nh_grp, true); + err =mlxsw_sp_nexthop_group_update (mlxsw_sp, nh_grp, true);if (err) {dev_warn (mlxsw_sp->bus_info->dev,"Failed to update neigh MAC in adjacency table.\n" ); goto set_trap;
@@ -2287,6 +2297,48 @@ static bool mlxsw_sp_netdev_ipip_type(const struct mlxsw_sp *mlxsw_sp,return false; } +static void mlxsw_sp_nexthop_type_fini (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop *nh) +{ +switch (nh->type) { +case MLXSW_SP_NEXTHOP_TYPE_ETH : +mlxsw_sp_nexthop_neigh_fini (mlxsw_sp, nh); +mlxsw_sp_nexthop_rif_fini (nh); +break ; + } +} + +static int mlxsw_sp_nexthop4_type_init (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop *nh, +struct fib_nh *fib_nh) +{ +struct net_device *dev = fib_nh->nh_dev; +struct mlxsw_sp_rif *rif; +int err; + + nh->type =MLXSW_SP_NEXTHOP_TYPE_ETH ; + rif =mlxsw_sp_rif_find_by_dev (mlxsw_sp, dev); +if (!rif) +return 0 ; + +mlxsw_sp_nexthop_rif_init (nh, rif); + err =mlxsw_sp_nexthop_neigh_init (mlxsw_sp, nh); +if (err) + goto err_neigh_init; + +return 0 ; + +err_neigh_init: +mlxsw_sp_nexthop_rif_fini (nh); +return err; +} + +static void mlxsw_sp_nexthop4_type_fini (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop *nh) +{ +mlxsw_sp_nexthop_type_fini (mlxsw_sp, nh); +} + static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop_group *nh_grp, struct mlxsw_sp_nexthop *nh,
@@ -2294,7 +2346,6 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp, {struct net_device *dev = fib_nh->nh_dev;struct in_device *in_dev; -struct mlxsw_sp_rif *rif;int err; nh->nh_grp = nh_grp;
@@ -2312,19 +2363,13 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp, fib_nh->nh_flags & RTNH_F_LINKDOWN)return 0 ; - rif =mlxsw_sp_rif_find_by_dev (mlxsw_sp, dev); -if (!rif) -return 0 ; -mlxsw_sp_nexthop_rif_init (nh, rif); - - err =mlxsw_sp_nexthop_neigh_init (mlxsw_sp, nh); + err =mlxsw_sp_nexthop4_type_init (mlxsw_sp, nh, fib_nh);if (err) goto err_nexthop_neigh_init;return 0 ; err_nexthop_neigh_init: -mlxsw_sp_nexthop_rif_fini (nh);mlxsw_sp_nexthop_remove (mlxsw_sp, nh);return err; }
@@ -2332,8 +2377,7 @@ static int mlxsw_sp_nexthop4_init(struct mlxsw_sp *mlxsw_sp,static void mlxsw_sp_nexthop4_fini (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_nexthop *nh) { -mlxsw_sp_nexthop_neigh_fini (mlxsw_sp, nh); -mlxsw_sp_nexthop_rif_fini (nh); +mlxsw_sp_nexthop4_type_fini (mlxsw_sp, nh);mlxsw_sp_nexthop_remove (mlxsw_sp, nh); }
@@ -2342,7 +2386,6 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp, {struct mlxsw_sp_nexthop_key key;struct mlxsw_sp_nexthop *nh; -struct mlxsw_sp_rif *rif;if (mlxsw_sp->router->aborted)return ;
@@ -2352,18 +2395,12 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp,if (WARN_ON_ONCE (!nh))return ; - rif =mlxsw_sp_rif_find_by_dev (mlxsw_sp, fib_nh->nh_dev); -if (!rif) -return ; -switch (event) {case FIB_EVENT_NH_ADD : -mlxsw_sp_nexthop_rif_init (nh, rif); -mlxsw_sp_nexthop_neigh_init (mlxsw_sp, nh); +mlxsw_sp_nexthop4_type_init (mlxsw_sp, nh, fib_nh);break ;case FIB_EVENT_NH_DEL : -mlxsw_sp_nexthop_neigh_fini (mlxsw_sp, nh); -mlxsw_sp_nexthop_rif_fini (nh); +mlxsw_sp_nexthop4_type_fini (mlxsw_sp, nh);break ; }
@@ -2376,8 +2413,7 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_nexthop *nh, *tmp;list_for_each_entry_safe (nh, tmp, &rif->nexthop_list, rif_list_node) { -mlxsw_sp_nexthop_neigh_fini (mlxsw_sp, nh); -mlxsw_sp_nexthop_rif_fini (nh); +mlxsw_sp_nexthop_type_fini (mlxsw_sp, nh);mlxsw_sp_nexthop_group_refresh (mlxsw_sp, nh->nh_grp); } }
@@ -3487,22 +3523,16 @@ mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,return NULL ; } -static int mlxsw_sp_nexthop6_init (struct mlxsw_sp *mlxsw_sp, -struct mlxsw_sp_nexthop_group *nh_grp, -struct mlxsw_sp_nexthop *nh, -const struct rt6_info *rt) +static int mlxsw_sp_nexthop6_type_init (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop_group *nh_grp, +struct mlxsw_sp_nexthop *nh, +const struct rt6_info *rt) {struct net_device *dev = rt->dst.dev;struct mlxsw_sp_rif *rif;int err; - nh->nh_grp = nh_grp; -memcpy (&nh->gw_addr, &rt->rt6i_gateway,sizeof (nh->gw_addr)); - -if (!dev) -return 0 ; - nh->ifindex = dev->ifindex; - + nh->type =MLXSW_SP_NEXTHOP_TYPE_ETH ; rif =mlxsw_sp_rif_find_by_dev (mlxsw_sp, dev);if (!rif)return 0 ;
@@ -3519,11 +3549,33 @@ static int mlxsw_sp_nexthop6_init(struct mlxsw_sp *mlxsw_sp,return err; } +static void mlxsw_sp_nexthop6_type_fini (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop *nh) +{ +mlxsw_sp_nexthop_type_fini (mlxsw_sp, nh); +} + +static int mlxsw_sp_nexthop6_init (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_nexthop_group *nh_grp, +struct mlxsw_sp_nexthop *nh, +const struct rt6_info *rt) +{ +struct net_device *dev = rt->dst.dev; + + nh->nh_grp = nh_grp; +memcpy (&nh->gw_addr, &rt->rt6i_gateway,sizeof (nh->gw_addr)); + +if (!dev) +return 0 ; + nh->ifindex = dev->ifindex; + +return mlxsw_sp_nexthop6_type_init (mlxsw_sp, nh_grp, nh, rt); +} +static void mlxsw_sp_nexthop6_fini (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_nexthop *nh) { -mlxsw_sp_nexthop_neigh_fini (mlxsw_sp, nh); -mlxsw_sp_nexthop_rif_fini (nh); +mlxsw_sp_nexthop6_type_fini (mlxsw_sp, nh); } static bool mlxsw_sp_rt6_is_gateway(const struct mlxsw_sp *mlxsw_sp,
Signature · 1 line
2.9.3
PATCH v2 15/21 mlxsw: spectrum_router: Support IPv4 overlay encap
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
This introduces some common code for tracking of offloaded IP-in-IP tunnels, and support for offloading IPv4 overlay encapsulating routes in particular. A follow-up patch will introduce IPv6 overlay as well.
Offloaded tunnels are kept in a linked list of mlxsw_sp_ipip_entry objects hooked up in mlxsw_sp_router. A network device that represents the tunnel is used as a key to look up the corresponding IPIP entry. Note that in the future, more general keying mechanism will be needed, because parts of the tunnel information can be provided by the route.
IPIP entries are reference counted, because several next hops may end up using the same tunnel, and we only want to offload it once.
Encapsulation path hooks into next hop handling. Routes that forward to a tunnel are now considered gateway routes, thus giving them the same treatment that other remote routes get. An IPIP next hop type is introduced.
Details of individual tunnel types are kept in an array of mlxsw_sp_ipip_ops objects. If a tunnel type doesn't match any of the known tunnel types, the next-hop is not considered an IPIP next hop.
The list of IPIP tunnel types is currently empty, follow-up patches will add support for GRE. Traffic to IPIP tunnel types that are not explicitly recognized by the driver traps and is handled in slow path.
--- .../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 20 ++ .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 238 ++++++++++++++++++++- 2 files changed, 257 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h +20 -0
@@ -41,9 +41,29 @@ enum mlxsw_sp_ipip_type { MLXSW_SP_IPIP_TYPE_MAX, }; +struct mlxsw_sp_ipip_entry { +enum mlxsw_sp_ipip_type ipipt; +struct net_device *ol_dev;/* Overlay. */ +struct mlxsw_sp_rif_ipip_lb *ol_lb; +unsigned int ref_count;/* Number of next hops using the tunnel. */ +struct list_head ipip_list_node; +}; +struct mlxsw_sp_ipip_ops {int dev_type;enum mlxsw_sp_l3proto ul_proto;/* Underlay. */ + +int (*nexthop_update)(struct mlxsw_sp *mlxsw_sp,u32 adj_index, +struct mlxsw_sp_ipip_entry *ipip_entry); + +bool (*can_offload)(const struct mlxsw_sp *mlxsw_sp, +const struct net_device *ol_dev, +enum mlxsw_sp_l3proto ol_proto); + +/* Return a configuration for creating an overlay loopback RIF. */ +struct mlxsw_sp_rif_ipip_lb_config + (*ol_loopback_config)(struct mlxsw_sp *mlxsw_sp, +const struct net_device *ol_dev); };extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +237 -1
313 lines not on this page · raw message
Signature · 1 line
2.9.3
PATCH v2 16/21 mlxsw: spectrum_router: Support IPv6 overlay encap
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
Add the missing bits to recognize IPv6 next hops as IPIP ones to enable offloading of IPv6 overlay encapsulation.
--- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +19 -1
@@ -3757,15 +3757,32 @@ mlxsw_sp_fib6_entry_rt_find(const struct mlxsw_sp_fib6_entry *fib6_entry,return NULL ; } +static bool mlxsw_sp_nexthop6_ipip_type (const struct mlxsw_sp *mlxsw_sp, +const struct rt6_info *rt, +enum mlxsw_sp_ipip_type *ret) +{ +return rt->dst.dev && +mlxsw_sp_netdev_ipip_type (mlxsw_sp, rt->dst.dev, ret); +} +static int mlxsw_sp_nexthop6_type_init (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_nexthop_group *nh_grp,struct mlxsw_sp_nexthop *nh,const struct rt6_info *rt) { +struct mlxsw_sp_router *router = mlxsw_sp->router;struct net_device *dev = rt->dst.dev; +enum mlxsw_sp_ipip_type ipipt;struct mlxsw_sp_rif *rif;int err; +if (mlxsw_sp_nexthop6_ipip_type (mlxsw_sp, rt, &ipipt) && + router->ipip_ops_arr[ipipt]->can_offload (mlxsw_sp, dev, +MLXSW_SP_L3_PROTO_IPV6 )) { + nh->type =MLXSW_SP_NEXTHOP_TYPE_IPIP ; +return mlxsw_sp_nexthop_ipip_init (mlxsw_sp, ipipt, nh, dev); + } + nh->type =MLXSW_SP_NEXTHOP_TYPE_ETH ; rif =mlxsw_sp_rif_find_by_dev (mlxsw_sp, dev);if (!rif)
@@ -3815,7 +3832,8 @@ static void mlxsw_sp_nexthop6_fini(struct mlxsw_sp *mlxsw_sp,static bool mlxsw_sp_rt6_is_gateway (const struct mlxsw_sp *mlxsw_sp,const struct rt6_info *rt) { -return rt->rt6i_flags &RTF_GATEWAY ; +return rt->rt6i_flags &RTF_GATEWAY || +mlxsw_sp_nexthop6_ipip_type (mlxsw_sp, rt,NULL ); } static struct mlxsw_sp_nexthop_group *
Signature · 1 line
2.9.3
PATCH v2 17/21 mlxsw: spectrum_router: Support IPv4 underlay decap
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
Unlike encapsulation, which is represented by a next hop forwarding to an IPIP tunnel, decapsulation is a type of local route. It is created for local routes whose prefix corresponds to the local address of one of offloaded IPIP tunnels. When the tunnel is removed (i.e. all the encap next hops are removed), the decap offload is migrated back to a trap for resolution in slow path.
This patch assumes that decap route is already present when encap route is added. A follow-up patch will fix this issue.
Note that this patch only supports IPv4 underlay. Support for IPv6 underlay will be subject to follow-up work apart from this patchset.
--- .../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 7 + .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 141 ++++++++++++++++++++- .../net/ethernet/mellanox/mlxsw/spectrum_router.h | 3 + 3 files changed, 146 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h +7 -0
@@ -36,6 +36,7 @@#define _MLXSW_IPIP_H_#include "spectrum_router.h" +#include <net/ip_fib.h> enum mlxsw_sp_ipip_type {MLXSW_SP_IPIP_TYPE_MAX ,
@@ -46,6 +47,7 @@ struct mlxsw_sp_ipip_entry {struct net_device *ol_dev;/* Overlay. */ struct mlxsw_sp_rif_ipip_lb *ol_lb;unsigned int ref_count;/* Number of next hops using the tunnel. */ +struct mlxsw_sp_fib_entry *decap_fib_entry;struct list_head ipip_list_node; };
@@ -64,6 +66,11 @@ struct mlxsw_sp_ipip_ops {struct mlxsw_sp_rif_ipip_lb_config (*ol_loopback_config)(struct mlxsw_sp *mlxsw_sp,const struct net_device *ol_dev); + +int (*fib_entry_op)(struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_ipip_entry *ipip_entry, +enum mlxsw_reg_ralue_op op, +u32 tunnel_index); };extern const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[];
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +136 -5
221 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +3 -0
@@ -97,5 +97,8 @@ mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_neigh_entry *neigh_entry, bool adding);bool mlxsw_sp_neigh_ipv6_ignore (struct mlxsw_sp_neigh_entry *neigh_entry); +union mlxsw_sp_l3addr +mlxsw_sp_ipip_netdev_saddr (enum mlxsw_sp_l3proto proto, +const struct net_device *ol_dev);#endif /* _MLXSW_ROUTER_H_*/
Signature · 1 line
2.9.3
PATCH v2 18/21 mlxsw: spectrum_router: Use existing decap route
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
The local route that points at IPIP's underlay device (decap route) can be present long before the GRE device. Thus when an encap route is added, it's necessary to look inside the underlay FIB if the decap route is already present. If so, the current trap offload needs to be withdrawn and replaced with a decap offload.
--- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 80 ++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +76 -4
@@ -1072,6 +1072,9 @@ static void mlxsw_sp_fib_entry_decap_fini(struct mlxsw_sp *mlxsw_sp,mlxsw_sp_kvdl_free (mlxsw_sp, fib_entry->decap.tunnel_index); } +static struct mlxsw_sp_fib_node * +mlxsw_sp_fib_node_lookup (struct mlxsw_sp_fib *fib,const void *addr, +size_t addr_len,unsigned char prefix_len);static int mlxsw_sp_fib_entry_update (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_fib_entry *fib_entry);
@@ -1087,6 +1090,73 @@ mlxsw_sp_ipip_entry_demote_decap(struct mlxsw_sp *mlxsw_sp,mlxsw_sp_fib_entry_update (mlxsw_sp, fib_entry); } +static void +mlxsw_sp_ipip_entry_promote_decap (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_ipip_entry *ipip_entry, +struct mlxsw_sp_fib_entry *decap_fib_entry) +{ +if (mlxsw_sp_fib_entry_decap_init (mlxsw_sp, decap_fib_entry, + ipip_entry)) +return ; + decap_fib_entry->type =MLXSW_SP_FIB_ENTRY_TYPE_IPIP_DECAP ; + +if (mlxsw_sp_fib_entry_update (mlxsw_sp, decap_fib_entry)) +mlxsw_sp_ipip_entry_demote_decap (mlxsw_sp, ipip_entry); +} + +/* Given an IPIP entry, find the corresponding decap route. */ +static struct mlxsw_sp_fib_entry * +mlxsw_sp_ipip_entry_find_decap (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_ipip_entry *ipip_entry) +{ +static struct mlxsw_sp_fib_node *fib_node; +const struct mlxsw_sp_ipip_ops *ipip_ops; +struct mlxsw_sp_fib_entry *fib_entry; +unsigned char saddr_prefix_len; +union mlxsw_sp_l3addr saddr; +struct mlxsw_sp_fib *ul_fib; +struct mlxsw_sp_vr *ul_vr; +const void *saddrp; +size_t saddr_len; +u32 ul_tb_id; +u32 saddr4; + + ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipip_entry->ipipt]; + + ul_tb_id =mlxsw_sp_ipip_dev_ul_tb_id (ipip_entry->ol_dev); + ul_vr =mlxsw_sp_vr_find (mlxsw_sp, ul_tb_id); +if (!ul_vr) +return NULL ; + + ul_fib =mlxsw_sp_vr_fib (ul_vr, ipip_ops->ul_proto); + saddr =mlxsw_sp_ipip_netdev_saddr (ipip_ops->ul_proto, + ipip_entry->ol_dev); + +switch (ipip_ops->ul_proto) { +case MLXSW_SP_L3_PROTO_IPV4 : + saddr4 =be32_to_cpu (saddr.addr4); + saddrp = &saddr4; + saddr_len =4 ; + saddr_prefix_len =32 ; +break ; +case MLXSW_SP_L3_PROTO_IPV6 : +WARN_ON (1 ); +return NULL ; + } + + fib_node =mlxsw_sp_fib_node_lookup (ul_fib, saddrp, saddr_len, + saddr_prefix_len); +if (!fib_node ||list_empty (&fib_node->entry_list)) +return NULL ; + + fib_entry =list_first_entry (&fib_node->entry_list, + struct mlxsw_sp_fib_entry, list); +if (fib_entry->type !=MLXSW_SP_FIB_ENTRY_TYPE_TRAP ) +return NULL ; + +return fib_entry; +} +static struct mlxsw_sp_ipip_entry * mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp, enum mlxsw_sp_ipip_type ipipt,
@@ -1094,6 +1164,7 @@ mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp, {u32 ul_tb_id =mlxsw_sp_ipip_dev_ul_tb_id (ol_dev);struct mlxsw_sp_router *router = mlxsw_sp->router; +struct mlxsw_sp_fib_entry *decap_fib_entry;struct mlxsw_sp_ipip_entry *ipip_entry;enum mlxsw_sp_l3proto ul_proto;union mlxsw_sp_l3addr saddr;
@@ -1118,6 +1189,11 @@ mlxsw_sp_ipip_entry_get(struct mlxsw_sp *mlxsw_sp,if (IS_ERR (ipip_entry))return ipip_entry; + decap_fib_entry =mlxsw_sp_ipip_entry_find_decap (mlxsw_sp, ipip_entry); +if (decap_fib_entry) +mlxsw_sp_ipip_entry_promote_decap (mlxsw_sp, ipip_entry, + decap_fib_entry); +list_add_tail (&ipip_entry->ipip_list_node, &mlxsw_sp->router->ipip_list);
@@ -3259,10 +3335,6 @@ static void mlxsw_sp_fib4_entry_destroy(struct mlxsw_sp *mlxsw_sp,kfree (fib4_entry); } -static struct mlxsw_sp_fib_node * -mlxsw_sp_fib_node_lookup (struct mlxsw_sp_fib *fib,const void *addr, -size_t addr_len,unsigned char prefix_len); -static struct mlxsw_sp_fib4_entry *mlxsw_sp_fib4_entry_lookup (struct mlxsw_sp *mlxsw_sp,const struct fib_entry_notifier_info *fen_info)
Signature · 1 line
2.9.3
PATCH v2 19/21 mlxsw: spectrum: Register for IPIP_DECAP_ERROR trap
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
These traps are generated for packets that fail checks for source IP, encapsulation type, or GRE key. Trap these packets to CPU for follow-up handling by the kernel, which will send ICMP destination unreachable responses.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 + drivers/net/ethernet/mellanox/mlxsw/trap.h | 1 + 2 files changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +1 -0
@@ -3400,6 +3400,7 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = {MLXSW_SP_RXL_MARK (HOST_MISS_IPV6 ,TRAP_TO_CPU ,HOST_MISS , 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),/* PKT Sample trap */ MLXSW_RXL (mlxsw_sp_rx_listener_sample_func,PKT_SAMPLE ,MIRROR_TO_CPU , false, SP_IP2ME, DISCARD),
drivers/net/ethernet/mellanox/mlxsw/trap.h +1 -0
@@ -85,6 +85,7 @@ enum {MLXSW_TRAP_ID_HOST_MISS_IPV4 =0x90 ,MLXSW_TRAP_ID_IPV6_MC_LINK_LOCAL_DEST =0x91 ,MLXSW_TRAP_ID_HOST_MISS_IPV6 =0x92 , +MLXSW_TRAP_ID_IPIP_DECAP_ERROR =0xB1 ,MLXSW_TRAP_ID_ROUTER_ALERT_IPV4 =0xD6 ,MLXSW_TRAP_ID_ROUTER_ALERT_IPV6 =0xD7 , MLXSW_TRAP_ID_ACL0 = 0x1C0,
Signature · 1 line
2.9.3
PATCH v2 20/21 mlxsw: spectrum_router: Add loopback accessors
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
struct mlxsw_sp_rif is a router-private structure, and therefore everything related to it is as well: parameters, and derived RIF types including loopbacks. IPIP module needs access to some details of loopback interfaces, but exporting all the RIF shebang would create too large an interface.
So instead export just the bare minimum necessary: accessors for RIF index and underlay VRF ID.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 ++++++++++ drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h | 3 +++ 2 files changed, 13 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +10 -0
@@ -5007,6 +5007,16 @@ u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif)return rif->rif_index; } +u16 mlxsw_sp_ipip_lb_rif_index (const struct mlxsw_sp_rif_ipip_lb *lb_rif) +{ +return lb_rif->common.rif_index; +} + +u16 mlxsw_sp_ipip_lb_ul_vr_id (const struct mlxsw_sp_rif_ipip_lb *lb_rif) +{ +return lb_rif->ul_vr_id; +} +int mlxsw_sp_rif_dev_ifindex (const struct mlxsw_sp_rif *rif) {return rif->dev->ifindex;
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +3 -0
@@ -48,6 +48,7 @@ union mlxsw_sp_l3addr {struct in6_addr addr6; }; +struct mlxsw_sp_rif_ipip_lb ;struct mlxsw_sp_rif_ipip_lb_config {enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt;u32 okey;
@@ -65,6 +66,8 @@ struct mlxsw_sp_neigh_entry;struct mlxsw_sp_rif *mlxsw_sp_rif_by_index (const struct mlxsw_sp *mlxsw_sp,u16 rif_index);u16 mlxsw_sp_rif_index (const struct mlxsw_sp_rif *rif); +u16 mlxsw_sp_ipip_lb_rif_index (const struct mlxsw_sp_rif_ipip_lb *rif); +u16 mlxsw_sp_ipip_lb_ul_vr_id (const struct mlxsw_sp_rif_ipip_lb *rif);int mlxsw_sp_rif_dev_ifindex (const struct mlxsw_sp_rif *rif); int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_rif *rif,
Signature · 1 line
2.9.3
PATCH v2 21/21 mlxsw: spectrum_router: Support GRE tunnels
In reply to Jiri PirkoFrom: Petr Machata <[email protected]>
This patch introduces callbacks and tunnel type to offload GRE tunnels.
--- .../net/ethernet/mellanox/mlxsw/spectrum_ipip.c | 176 +++++++++++++++++++++ .../net/ethernet/mellanox/mlxsw/spectrum_ipip.h | 1 + .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 26 +++ .../net/ethernet/mellanox/mlxsw/spectrum_router.h | 4 + 4 files changed, 207 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c +176 -0
@@ -32,7 +32,183 @@* POSSIBILITY OF SUCH DAMAGE. */ +#include <net/ip_tunnels.h> +#include "spectrum_ipip.h" +static bool +mlxsw_sp_ipip_netdev_has_ikey (const struct net_device *ol_dev) +{ +struct ip_tunnel *tun =netdev_priv (ol_dev); + +return !!(tun->parms.i_flags &TUNNEL_KEY ); +} + +static bool +mlxsw_sp_ipip_netdev_has_okey (const struct net_device *ol_dev) +{ +struct ip_tunnel *tun =netdev_priv (ol_dev); + +return !!(tun->parms.o_flags &TUNNEL_KEY ); +} + +static u32 mlxsw_sp_ipip_netdev_ikey (const struct net_device *ol_dev) +{ +struct ip_tunnel *tun =netdev_priv (ol_dev); + +return mlxsw_sp_ipip_netdev_has_ikey (ol_dev) ? +be32_to_cpu (tun->parms.i_key) :0 ; +} + +static u32 mlxsw_sp_ipip_netdev_okey (const struct net_device *ol_dev) +{ +struct ip_tunnel *tun =netdev_priv (ol_dev); + +return mlxsw_sp_ipip_netdev_has_okey (ol_dev) ? +be32_to_cpu (tun->parms.o_key) :0 ; +} + +static int +mlxsw_sp_ipip_nexthop_update_gre4 (struct mlxsw_sp *mlxsw_sp,u32 adj_index, +struct mlxsw_sp_ipip_entry *ipip_entry) +{ +u16 rif_index =mlxsw_sp_ipip_lb_rif_index (ipip_entry->ol_lb); +__be32 daddr4 =mlxsw_sp_ipip_netdev_daddr4 (ipip_entry->ol_dev); +char ratr_pl[MLXSW_REG_RATR_LEN ]; + +mlxsw_reg_ratr_pack (ratr_pl,MLXSW_REG_RATR_OP_WRITE_WRITE_ENTRY , + true,MLXSW_REG_RATR_TYPE_IPIP , + adj_index, rif_index); +mlxsw_reg_ratr_ipip4_entry_pack (ratr_pl,be32_to_cpu (daddr4)); + +return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (ratr), ratr_pl); +} + +static int +mlxsw_sp_ipip_fib_entry_op_gre4_rtdp (struct mlxsw_sp *mlxsw_sp, +u32 tunnel_index, +struct mlxsw_sp_ipip_entry *ipip_entry) +{ +bool has_ikey =mlxsw_sp_ipip_netdev_has_ikey (ipip_entry->ol_dev); +u16 rif_index =mlxsw_sp_ipip_lb_rif_index (ipip_entry->ol_lb); +u32 ikey =mlxsw_sp_ipip_netdev_ikey (ipip_entry->ol_dev); +char rtdp_pl[MLXSW_REG_RTDP_LEN ]; +unsigned int type_check; +u32 daddr4; + +mlxsw_reg_rtdp_pack (rtdp_pl,MLXSW_REG_RTDP_TYPE_IPIP , tunnel_index); + + type_check = has_ikey ? +MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE_KEY : +MLXSW_REG_RTDP_IPIP_TYPE_CHECK_ALLOW_GRE ; + +/* Linux demuxes tunnels based on packet SIP (which must match tunnel +* remote IP). Thus configure decap so that it filters out packets that +* are not IPv4 or have the wrong SIP. IPIP_DECAP_ERROR trap is +* generated for packets that fail this criterion. Linux then handles +* such packets in slow path and generates ICMP destination unreachable. +*/ + daddr4 =be32_to_cpu (mlxsw_sp_ipip_netdev_daddr4 (ipip_entry->ol_dev)); +mlxsw_reg_rtdp_ipip4_pack (rtdp_pl, rif_index, +MLXSW_REG_RTDP_IPIP_SIP_CHECK_FILTER_IPV4 , + type_check, has_ikey, daddr4, ikey); + +return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (rtdp), rtdp_pl); +} + +static int +mlxsw_sp_ipip_fib_entry_op_gre4_ralue (struct mlxsw_sp *mlxsw_sp, +u32 dip,u8 prefix_len,u16 ul_vr_id, +enum mlxsw_reg_ralue_op op, +u32 tunnel_index) +{ +char ralue_pl[MLXSW_REG_RALUE_LEN ]; + +mlxsw_reg_ralue_pack4 (ralue_pl,MLXSW_REG_RALXX_PROTOCOL_IPV4 , op, + ul_vr_id, prefix_len, dip); +mlxsw_reg_ralue_act_ip2me_tun_pack (ralue_pl, tunnel_index); +return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (ralue), ralue_pl); +} + +static int mlxsw_sp_ipip_fib_entry_op_gre4 (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_ipip_entry *ipip_entry, +enum mlxsw_reg_ralue_op op, +u32 tunnel_index) +{ +u16 ul_vr_id =mlxsw_sp_ipip_lb_ul_vr_id (ipip_entry->ol_lb); +__be32 dip; +int err; + + err =mlxsw_sp_ipip_fib_entry_op_gre4_rtdp (mlxsw_sp, tunnel_index, + ipip_entry); +if (err) +return err; + + dip =mlxsw_sp_ipip_netdev_saddr (MLXSW_SP_L3_PROTO_IPV4 , + ipip_entry->ol_dev).addr4; +return mlxsw_sp_ipip_fib_entry_op_gre4_ralue (mlxsw_sp,be32_to_cpu (dip), +32 , ul_vr_id, op, + tunnel_index); +} + +static bool mlxsw_sp_ipip_tunnel_complete (enum mlxsw_sp_l3proto proto, +const struct net_device *ol_dev) +{ +union mlxsw_sp_l3addr saddr =mlxsw_sp_ipip_netdev_saddr (proto, ol_dev); +union mlxsw_sp_l3addr daddr =mlxsw_sp_ipip_netdev_daddr (proto, ol_dev); +union mlxsw_sp_l3addr naddr = {0 }; + +/* Tunnels with unset local or remote address are valid in Linux and +* used for lightweight tunnels (LWT) and Non-Broadcast Multi-Access +* (NBMA) tunnels. In principle these can be offloaded, but the driver +* currently doesn't support this. So punt. +*/ +return memcmp (&saddr, &naddr,sizeof (naddr)) && +memcmp (&daddr, &naddr,sizeof (naddr)); +} + +static bool mlxsw_sp_ipip_can_offload_gre4 (const struct mlxsw_sp *mlxsw_sp, +const struct net_device *ol_dev, +enum mlxsw_sp_l3proto ol_proto) +{ +struct ip_tunnel *tunnel =netdev_priv (ol_dev); +__be16 okflags =TUNNEL_KEY ;/* We can't offload any other features. */ +bool inherit_ttl = tunnel->parms.iph.ttl ==0 ; +bool inherit_tos = tunnel->parms.iph.tos &0x1 ; + +return (tunnel->parms.i_flags & ~okflags) ==0 && + (tunnel->parms.o_flags & ~okflags) ==0 && + inherit_ttl && inherit_tos && +mlxsw_sp_ipip_tunnel_complete (MLXSW_SP_L3_PROTO_IPV4 , ol_dev); +} + +static struct mlxsw_sp_rif_ipip_lb_config +mlxsw_sp_ipip_ol_loopback_config_gre4 (struct mlxsw_sp *mlxsw_sp, +const struct net_device *ol_dev) +{ +enum mlxsw_reg_ritr_loopback_ipip_type lb_ipipt; + + lb_ipipt =mlxsw_sp_ipip_netdev_has_okey (ol_dev) ? +MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_KEY_IN_IP : +MLXSW_REG_RITR_LOOPBACK_IPIP_TYPE_IP_IN_GRE_IN_IP ; +return (struct mlxsw_sp_rif_ipip_lb_config ){ + .lb_ipipt = lb_ipipt, + .okey =mlxsw_sp_ipip_netdev_okey (ol_dev), + .ul_protocol =MLXSW_SP_L3_PROTO_IPV4 , + .saddr =mlxsw_sp_ipip_netdev_saddr (MLXSW_SP_L3_PROTO_IPV4 , + ol_dev), + }; +} + +static const struct mlxsw_sp_ipip_ops mlxsw_sp_ipip_gre4_ops = { + .dev_type =ARPHRD_IPGRE , + .ul_proto =MLXSW_SP_L3_PROTO_IPV4 , + .nexthop_update = mlxsw_sp_ipip_nexthop_update_gre4, + .fib_entry_op = mlxsw_sp_ipip_fib_entry_op_gre4, + .can_offload = mlxsw_sp_ipip_can_offload_gre4, + .ol_loopback_config = mlxsw_sp_ipip_ol_loopback_config_gre4, +}; +const struct mlxsw_sp_ipip_ops *mlxsw_sp_ipip_ops_arr[] = { + [MLXSW_SP_IPIP_TYPE_GRE4 ] = &mlxsw_sp_ipip_gre4_ops, };
drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.h +1 -0
@@ -39,6 +39,7 @@#include <net/ip_fib.h> enum mlxsw_sp_ipip_type { +MLXSW_SP_IPIP_TYPE_GRE4 ,MLXSW_SP_IPIP_TYPE_MAX , };
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +26 -0
@@ -1020,6 +1020,32 @@ mlxsw_sp_ipip_netdev_saddr(enum mlxsw_sp_l3proto proto, }; } +__be32 mlxsw_sp_ipip_netdev_daddr4 (const struct net_device *ol_dev) +{ +struct ip_tunnel *tun =netdev_priv (ol_dev); + +return tun->parms.iph.daddr; +} + +union mlxsw_sp_l3addr +mlxsw_sp_ipip_netdev_daddr (enum mlxsw_sp_l3proto proto, +const struct net_device *ol_dev) +{ +switch (proto) { +case MLXSW_SP_L3_PROTO_IPV4 : +return (union mlxsw_sp_l3addr ) { + .addr4 =mlxsw_sp_ipip_netdev_daddr4 (ol_dev), + }; +case MLXSW_SP_L3_PROTO_IPV6 : +break ; + }; + +WARN_ON (1 ); +return (union mlxsw_sp_l3addr ) { + .addr4 =0 , + }; +} +static bool mlxsw_sp_l3addr_eq (const union mlxsw_sp_l3addr *addr1,const union mlxsw_sp_l3addr *addr2) {
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +4 -0
@@ -103,5 +103,9 @@ bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);union mlxsw_sp_l3addr mlxsw_sp_ipip_netdev_saddr (enum mlxsw_sp_l3proto proto,const struct net_device *ol_dev); +union mlxsw_sp_l3addr +mlxsw_sp_ipip_netdev_daddr (enum mlxsw_sp_l3proto proto, +const struct net_device *ol_dev); +__be32 mlxsw_sp_ipip_netdev_daddr4 (const struct net_device *ol_dev);#endif /* _MLXSW_ROUTER_H_*/
Signature · 1 line
2.9.3
David Miller
maintainerFrom: Jiri Pirko <[email protected]>
Date: Sat, 2 Sep 2017 23:49:08 +0200
Quoted 6 lines
From: Jiri Pirko <[email protected]>
Petr says:
This patch series introduces to mlxsw driver support for offloading IP-in-IP tunnels in general, and for (subset of) GRE in particular.
...
Series applied, thanks!