Skip to content

Commit 431c7ec

Browse files
committed
Merge branch 'mlxsw-Offloading-encapsulated-SPAN'
Jiri Pirko says: ==================== mlxsw: Offloading encapsulated SPAN Petr says: This patch series introduces support for mirroring with GRE encapsulation. It offloads tc action mirred mirror from a mlxsw port to either a gretap or an ip6gretap netdevice. Spectrum hardware needs to know all the details of the requested encapsulation: source and destination MAC and IP addresses, details of VLAN tagging, etc. The only variables are the encapsulated packet itself, and TOS field, which may be inherited. To that end, mlxsw driver resolves the route that encapsulated packets would take, queries the corresponding neighbor, and with that configuration in hand, configures the mirroring in the hardware. The driver also hooks into event handlers for netdevice changes, FIB and neighbor events, and reconsiders the configuration on each such change. When the new configuration differs from the currently-offloaded one, the existing offload is removed and replaced with a new one. It is possible to mirror to {ip6,}gretap from a matchall rule as well as from a flower match. ** Note that with this patch set, mlxsw build depends on NET_IPGRE and IPV6_GRE. Current limitations: - There has to be a route that directs packets to an mlxsw port. We intend to extend the logic to support other netdevice types in the future, but the eventual egress netdevice will have to be an mlxsw port in any case. - Offload reconfiguration due to changes in netdevice configuration creates a window of time where packets are not mirrored. Under some circumstances this can be prevented by configuring an unused port analyzer and migrating mirrors over to that. However that's currently not implemented. - Remote address of a tunnel device needs to be set, there may not be a GRE key, checksumming or sequence numbers, and TTL needs to be fixed (non-inherit). These are hard requirements imposed by the underlying hardware. - TOS of a tunnel device needs to be "inherit". The hardware supports a fixed TOS, but that's currently not implemented. The series start with two patches, #1 and #2, that publish one function and add support for querying IPv6 tunnel parameters. In patches #3 and #4, we introduce helpers to GRE and tunneling code that we will use later in the patchset from the SPAN code. Patches #5 and #6 introduce support for encapsulated SPAN in reg.h. The following seven patches, #7-#13, then prepare the SPAN codebase for introduction of mirroring to netdevices that don't correspond to front panel ports. Then #14 and #15 pull all this together to implement mirroring to {ip6,}gretap netdevices. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 63d6380 + 8f08a52 commit 431c7ec

18 files changed

+808
-157
lines changed

drivers/net/ethernet/mellanox/mlxsw/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ config MLXSW_SPECTRUM
7878
depends on IPV6 || IPV6=n
7979
select PARMAN
8080
select MLXFW
81+
depends on NET_IPGRE
82+
depends on !(MLXSW_CORE=y && NET_IPGRE=m)
83+
depends on IPV6_GRE
84+
depends on !(MLXSW_CORE=y && IPV6_GRE=m)
8185
default m
8286
---help---
8387
This driver supports Mellanox Technologies Spectrum Ethernet

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
3-
* Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3+
* Copyright (c) 2017, 2018 Mellanox Technologies. All rights reserved.
44
* Copyright (c) 2017 Jiri Pirko <[email protected]>
55
*
66
* Redistribution and use in source and binary forms, with or without
@@ -838,7 +838,6 @@ struct mlxsw_afa_mirror {
838838
struct mlxsw_afa_resource resource;
839839
int span_id;
840840
u8 local_in_port;
841-
u8 local_out_port;
842841
bool ingress;
843842
};
844843

@@ -848,7 +847,7 @@ mlxsw_afa_mirror_destroy(struct mlxsw_afa_block *block,
848847
{
849848
block->afa->ops->mirror_del(block->afa->ops_priv,
850849
mirror->local_in_port,
851-
mirror->local_out_port,
850+
mirror->span_id,
852851
mirror->ingress);
853852
kfree(mirror);
854853
}
@@ -864,9 +863,8 @@ mlxsw_afa_mirror_destructor(struct mlxsw_afa_block *block,
864863
}
865864

866865
static struct mlxsw_afa_mirror *
867-
mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
868-
u8 local_in_port, u8 local_out_port,
869-
bool ingress)
866+
mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, u8 local_in_port,
867+
const struct net_device *out_dev, bool ingress)
870868
{
871869
struct mlxsw_afa_mirror *mirror;
872870
int err;
@@ -876,13 +874,12 @@ mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
876874
return ERR_PTR(-ENOMEM);
877875

878876
err = block->afa->ops->mirror_add(block->afa->ops_priv,
879-
local_in_port, local_out_port,
877+
local_in_port, out_dev,
880878
ingress, &mirror->span_id);
881879
if (err)
882880
goto err_mirror_add;
883881

884882
mirror->ingress = ingress;
885-
mirror->local_out_port = local_out_port;
886883
mirror->local_in_port = local_in_port;
887884
mirror->resource.destructor = mlxsw_afa_mirror_destructor;
888885
mlxsw_afa_resource_add(block, &mirror->resource);
@@ -909,13 +906,13 @@ mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
909906
}
910907

911908
int
912-
mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
913-
u8 local_in_port, u8 local_out_port, bool ingress)
909+
mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, u8 local_in_port,
910+
const struct net_device *out_dev, bool ingress)
914911
{
915912
struct mlxsw_afa_mirror *mirror;
916913
int err;
917914

918-
mirror = mlxsw_afa_mirror_create(block, local_in_port, local_out_port,
915+
mirror = mlxsw_afa_mirror_create(block, local_in_port, out_dev,
919916
ingress);
920917
if (IS_ERR(mirror))
921918
return PTR_ERR(mirror);

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#define _MLXSW_CORE_ACL_FLEX_ACTIONS_H
3737

3838
#include <linux/types.h>
39+
#include <linux/netdevice.h>
3940

4041
struct mlxsw_afa;
4142
struct mlxsw_afa_block;
@@ -48,9 +49,10 @@ struct mlxsw_afa_ops {
4849
void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index);
4950
int (*counter_index_get)(void *priv, unsigned int *p_counter_index);
5051
void (*counter_index_put)(void *priv, unsigned int counter_index);
51-
int (*mirror_add)(void *priv, u8 locol_in_port, u8 local_out_port,
52+
int (*mirror_add)(void *priv, u8 local_in_port,
53+
const struct net_device *out_dev,
5254
bool ingress, int *p_span_id);
53-
void (*mirror_del)(void *priv, u8 locol_in_port, u8 local_out_port,
55+
void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
5456
bool ingress);
5557
};
5658

@@ -70,7 +72,8 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
7072
int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
7173
u16 trap_id);
7274
int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
73-
u8 local_in_port, u8 local_out_port,
75+
u8 local_in_port,
76+
const struct net_device *out_dev,
7477
bool ingress);
7578
int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
7679
u8 local_port, bool in_port);

drivers/net/ethernet/mellanox/mlxsw/reg.h

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
22
* drivers/net/ethernet/mellanox/mlxsw/reg.h
3-
* Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved.
3+
* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved.
44
* Copyright (c) 2015-2016 Ido Schimmel <[email protected]>
55
* Copyright (c) 2015 Elad Raz <[email protected]>
66
* Copyright (c) 2015-2017 Jiri Pirko <[email protected]>
77
* Copyright (c) 2016 Yotam Gigi <[email protected]>
8-
* Copyright (c) 2017 Petr Machata <[email protected]>
8+
* Copyright (c) 2017-2018 Petr Machata <[email protected]>
99
*
1010
* Redistribution and use in source and binary forms, with or without
1111
* modification, are permitted provided that the following conditions are met:
@@ -6772,15 +6772,154 @@ MLXSW_ITEM32(reg, mpat, qos, 0x04, 26, 1);
67726772
*/
67736773
MLXSW_ITEM32(reg, mpat, be, 0x04, 25, 1);
67746774

6775+
enum mlxsw_reg_mpat_span_type {
6776+
/* Local SPAN Ethernet.
6777+
* The original packet is not encapsulated.
6778+
*/
6779+
MLXSW_REG_MPAT_SPAN_TYPE_LOCAL_ETH = 0x0,
6780+
6781+
/* Encapsulated Remote SPAN Ethernet L3 GRE.
6782+
* The packet is encapsulated with GRE header.
6783+
*/
6784+
MLXSW_REG_MPAT_SPAN_TYPE_REMOTE_ETH_L3 = 0x3,
6785+
};
6786+
6787+
/* reg_mpat_span_type
6788+
* SPAN type.
6789+
* Access: RW
6790+
*/
6791+
MLXSW_ITEM32(reg, mpat, span_type, 0x04, 0, 4);
6792+
6793+
/* Remote SPAN - Ethernet VLAN
6794+
* - - - - - - - - - - - - - -
6795+
*/
6796+
6797+
/* reg_mpat_eth_rspan_vid
6798+
* Encapsulation header VLAN ID.
6799+
* Access: RW
6800+
*/
6801+
MLXSW_ITEM32(reg, mpat, eth_rspan_vid, 0x18, 0, 12);
6802+
6803+
/* Encapsulated Remote SPAN - Ethernet L2
6804+
* - - - - - - - - - - - - - - - - - - -
6805+
*/
6806+
6807+
enum mlxsw_reg_mpat_eth_rspan_version {
6808+
MLXSW_REG_MPAT_ETH_RSPAN_VERSION_NO_HEADER = 15,
6809+
};
6810+
6811+
/* reg_mpat_eth_rspan_version
6812+
* RSPAN mirror header version.
6813+
* Access: RW
6814+
*/
6815+
MLXSW_ITEM32(reg, mpat, eth_rspan_version, 0x10, 18, 4);
6816+
6817+
/* reg_mpat_eth_rspan_mac
6818+
* Destination MAC address.
6819+
* Access: RW
6820+
*/
6821+
MLXSW_ITEM_BUF(reg, mpat, eth_rspan_mac, 0x12, 6);
6822+
6823+
/* reg_mpat_eth_rspan_tp
6824+
* Tag Packet. Indicates whether the mirroring header should be VLAN tagged.
6825+
* Access: RW
6826+
*/
6827+
MLXSW_ITEM32(reg, mpat, eth_rspan_tp, 0x18, 16, 1);
6828+
6829+
/* Encapsulated Remote SPAN - Ethernet L3
6830+
* - - - - - - - - - - - - - - - - - - -
6831+
*/
6832+
6833+
enum mlxsw_reg_mpat_eth_rspan_protocol {
6834+
MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV4,
6835+
MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV6,
6836+
};
6837+
6838+
/* reg_mpat_eth_rspan_protocol
6839+
* SPAN encapsulation protocol.
6840+
* Access: RW
6841+
*/
6842+
MLXSW_ITEM32(reg, mpat, eth_rspan_protocol, 0x18, 24, 4);
6843+
6844+
/* reg_mpat_eth_rspan_ttl
6845+
* Encapsulation header Time-to-Live/HopLimit.
6846+
* Access: RW
6847+
*/
6848+
MLXSW_ITEM32(reg, mpat, eth_rspan_ttl, 0x1C, 4, 8);
6849+
6850+
/* reg_mpat_eth_rspan_smac
6851+
* Source MAC address
6852+
* Access: RW
6853+
*/
6854+
MLXSW_ITEM_BUF(reg, mpat, eth_rspan_smac, 0x22, 6);
6855+
6856+
/* reg_mpat_eth_rspan_dip*
6857+
* Destination IP address. The IP version is configured by protocol.
6858+
* Access: RW
6859+
*/
6860+
MLXSW_ITEM32(reg, mpat, eth_rspan_dip4, 0x4C, 0, 32);
6861+
MLXSW_ITEM_BUF(reg, mpat, eth_rspan_dip6, 0x40, 16);
6862+
6863+
/* reg_mpat_eth_rspan_sip*
6864+
* Source IP address. The IP version is configured by protocol.
6865+
* Access: RW
6866+
*/
6867+
MLXSW_ITEM32(reg, mpat, eth_rspan_sip4, 0x5C, 0, 32);
6868+
MLXSW_ITEM_BUF(reg, mpat, eth_rspan_sip6, 0x50, 16);
6869+
67756870
static inline void mlxsw_reg_mpat_pack(char *payload, u8 pa_id,
6776-
u16 system_port, bool e)
6871+
u16 system_port, bool e,
6872+
enum mlxsw_reg_mpat_span_type span_type)
67776873
{
67786874
MLXSW_REG_ZERO(mpat, payload);
67796875
mlxsw_reg_mpat_pa_id_set(payload, pa_id);
67806876
mlxsw_reg_mpat_system_port_set(payload, system_port);
67816877
mlxsw_reg_mpat_e_set(payload, e);
67826878
mlxsw_reg_mpat_qos_set(payload, 1);
67836879
mlxsw_reg_mpat_be_set(payload, 1);
6880+
mlxsw_reg_mpat_span_type_set(payload, span_type);
6881+
}
6882+
6883+
static inline void mlxsw_reg_mpat_eth_rspan_pack(char *payload, u16 vid)
6884+
{
6885+
mlxsw_reg_mpat_eth_rspan_vid_set(payload, vid);
6886+
}
6887+
6888+
static inline void
6889+
mlxsw_reg_mpat_eth_rspan_l2_pack(char *payload,
6890+
enum mlxsw_reg_mpat_eth_rspan_version version,
6891+
const char *mac,
6892+
bool tp)
6893+
{
6894+
mlxsw_reg_mpat_eth_rspan_version_set(payload, version);
6895+
mlxsw_reg_mpat_eth_rspan_mac_memcpy_to(payload, mac);
6896+
mlxsw_reg_mpat_eth_rspan_tp_set(payload, tp);
6897+
}
6898+
6899+
static inline void
6900+
mlxsw_reg_mpat_eth_rspan_l3_ipv4_pack(char *payload, u8 ttl,
6901+
const char *smac,
6902+
u32 sip, u32 dip)
6903+
{
6904+
mlxsw_reg_mpat_eth_rspan_ttl_set(payload, ttl);
6905+
mlxsw_reg_mpat_eth_rspan_smac_memcpy_to(payload, smac);
6906+
mlxsw_reg_mpat_eth_rspan_protocol_set(payload,
6907+
MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV4);
6908+
mlxsw_reg_mpat_eth_rspan_sip4_set(payload, sip);
6909+
mlxsw_reg_mpat_eth_rspan_dip4_set(payload, dip);
6910+
}
6911+
6912+
static inline void
6913+
mlxsw_reg_mpat_eth_rspan_l3_ipv6_pack(char *payload, u8 ttl,
6914+
const char *smac,
6915+
struct in6_addr sip, struct in6_addr dip)
6916+
{
6917+
mlxsw_reg_mpat_eth_rspan_ttl_set(payload, ttl);
6918+
mlxsw_reg_mpat_eth_rspan_smac_memcpy_to(payload, smac);
6919+
mlxsw_reg_mpat_eth_rspan_protocol_set(payload,
6920+
MLXSW_REG_MPAT_ETH_RSPAN_PROTOCOL_IPV6);
6921+
mlxsw_reg_mpat_eth_rspan_sip6_memcpy_to(payload, (void *)&sip);
6922+
mlxsw_reg_mpat_eth_rspan_dip6_memcpy_to(payload, (void *)&dip);
67846923
}
67856924

67866925
/* MPAR - Monitoring Port Analyzer Register

0 commit comments

Comments
 (0)