Skip to content
This repository has been archived by the owner on Nov 21, 2022. It is now read-only.

Commit

Permalink
Merge branch 'mlxsw-add-802-1x-and-mab-offload-support'
Browse files Browse the repository at this point in the history
Petr Machata says:

====================
mlxsw: Add 802.1X and MAB offload support

This patchset adds 802.1X [1] and MAB [2] offload support in mlxsw.

Patches #1-#3 add the required switchdev interfaces.

Patches #4-#5 add the required packet traps for 802.1X.

Patches #6-#10 are small preparations in mlxsw.

Patch #11 adds locked bridge port support in mlxsw.

Patches #12-#15 add mlxsw selftests. The patchset was also tested with
the generic forwarding selftest ('bridge_locked_port.sh').

[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=a21d9a670d81103db7f788de1a4a4a6e4b891a0b
[2] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=a35ec8e38cdd1766f29924ca391a01de20163931
====================

Link: https://lore.kernel.org/r/cover.1667902754.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
kuba-moo committed Nov 10, 2022
2 parents bf9b855 + cdbde7e commit 0cb9ed5
Show file tree
Hide file tree
Showing 18 changed files with 366 additions and 25 deletions.
13 changes: 13 additions & 0 deletions Documentation/networking/devlink/devlink-trap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,16 @@ be added to the following table:
- Traps incoming packets that the device decided to drop because
the destination MAC is not configured in the MAC table and
the interface is not in promiscuous mode
* - ``eapol``
- ``control``
- Traps "Extensible Authentication Protocol over LAN" (EAPOL) packets
specified in IEEE 802.1X
* - ``locked_port``
- ``drop``
- Traps packets that the device decided to drop because they failed the
locked bridge port check. That is, packets that were received via a
locked port and whose {SMAC, VID} does not correspond to an FDB entry
pointing to the port

Driver-specific Packet Traps
============================
Expand Down Expand Up @@ -589,6 +599,9 @@ narrow. The description of these groups must be added to the following table:
* - ``parser_error_drops``
- Contains packet traps for packets that were marked by the device during
parsing as erroneous
* - ``eapol``
- Contains packet traps for "Extensible Authentication Protocol over LAN"
(EAPOL) packets specified in IEEE 802.1X

Packet Trap Policers
====================
Expand Down
35 changes: 35 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,39 @@ static inline void mlxsw_reg_spvmlr_pack(char *payload, u16 local_port,
}
}

/* SPFSR - Switch Port FDB Security Register
* -----------------------------------------
* Configures the security mode per port.
*/
#define MLXSW_REG_SPFSR_ID 0x2023
#define MLXSW_REG_SPFSR_LEN 0x08

MLXSW_REG_DEFINE(spfsr, MLXSW_REG_SPFSR_ID, MLXSW_REG_SPFSR_LEN);

/* reg_spfsr_local_port
* Local port.
* Access: Index
*
* Note: not supported for CPU port.
*/
MLXSW_ITEM32_LP(reg, spfsr, 0x00, 16, 0x00, 12);

/* reg_spfsr_security
* Security checks.
* 0: disabled (default)
* 1: enabled
* Access: RW
*/
MLXSW_ITEM32(reg, spfsr, security, 0x04, 31, 1);

static inline void mlxsw_reg_spfsr_pack(char *payload, u16 local_port,
bool security)
{
MLXSW_REG_ZERO(spfsr, payload);
mlxsw_reg_spfsr_local_port_set(payload, local_port);
mlxsw_reg_spfsr_security_set(payload, security);
}

/* SPVC - Switch Port VLAN Classification Register
* -----------------------------------------------
* Configures the port to identify packets as untagged / single tagged /
Expand Down Expand Up @@ -6316,6 +6349,7 @@ enum mlxsw_reg_htgt_trap_group {
MLXSW_REG_HTGT_TRAP_GROUP_SP_TUNNEL_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_ACL_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_BUFFER_DISCARDS,
MLXSW_REG_HTGT_TRAP_GROUP_SP_EAPOL,

__MLXSW_REG_HTGT_TRAP_GROUP_MAX,
MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1
Expand Down Expand Up @@ -12761,6 +12795,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(svpe),
MLXSW_REG(sfmr),
MLXSW_REG(spvmlr),
MLXSW_REG(spfsr),
MLXSW_REG(spvc),
MLXSW_REG(spevet),
MLXSW_REG(smpe),
Expand Down
22 changes: 22 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,24 @@ int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
return err;
}

int mlxsw_sp_port_security_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
char spfsr_pl[MLXSW_REG_SPFSR_LEN];
int err;

if (mlxsw_sp_port->security == enable)
return 0;

mlxsw_reg_spfsr_pack(spfsr_pl, mlxsw_sp_port->local_port, enable);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spfsr), spfsr_pl);
if (err)
return err;

mlxsw_sp_port->security = enable;
return 0;
}

int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type)
{
switch (ethtype) {
Expand Down Expand Up @@ -4742,6 +4760,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are only supported with 802.1q VLAN protocol");
return -EOPNOTSUPP;
}
if (is_vlan_dev(upper_dev) && mlxsw_sp_port->security) {
NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are not supported on a locked port");
return -EOPNOTSUPP;
}
break;
case NETDEV_CHANGEUPPER:
upper_dev = info->upper_dev;
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ struct mlxsw_sp_port {
struct mlxsw_sp *mlxsw_sp;
u16 local_port;
u8 lagged:1,
split:1;
split:1,
security:1;
u16 pvid;
u16 lag_id;
struct {
Expand Down Expand Up @@ -687,6 +688,8 @@ int mlxsw_sp_port_vid_stp_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
int mlxsw_sp_port_vp_mode_set(struct mlxsw_sp_port *mlxsw_sp_port, bool enable);
int mlxsw_sp_port_vid_learning_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid,
bool learn_enable);
int mlxsw_sp_port_security_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool enable);
int mlxsw_sp_ethtype_to_sver_type(u16 ethtype, u8 *p_sver_type);
int mlxsw_sp_port_egress_ethtype_set(struct mlxsw_sp_port *mlxsw_sp_port,
u16 ethtype);
Expand Down
64 changes: 53 additions & 11 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,10 +782,25 @@ mlxsw_sp_bridge_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,

static int
mlxsw_sp_port_attr_br_pre_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct switchdev_brport_flags flags)
const struct net_device *orig_dev,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD))
if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
BR_PORT_LOCKED | BR_PORT_MAB)) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported bridge port flag");
return -EINVAL;
}

if ((flags.mask & BR_PORT_LOCKED) && is_vlan_dev(orig_dev)) {
NL_SET_ERR_MSG_MOD(extack, "Locked flag cannot be set on a VLAN upper");
return -EINVAL;
}

if ((flags.mask & BR_PORT_LOCKED) && vlan_uses_dev(orig_dev)) {
NL_SET_ERR_MSG_MOD(extack, "Locked flag cannot be set on a bridge port that has VLAN uppers");
return -EINVAL;
}

return 0;
}
Expand Down Expand Up @@ -819,6 +834,13 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
return err;
}

if (flags.mask & BR_PORT_LOCKED) {
err = mlxsw_sp_port_security_set(mlxsw_sp_port,
flags.val & BR_PORT_LOCKED);
if (err)
return err;
}

if (bridge_port->bridge_device->multicast_enabled)
goto out;

Expand Down Expand Up @@ -1186,7 +1208,9 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev, const void *ctx,
break;
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
err = mlxsw_sp_port_attr_br_pre_flags_set(mlxsw_sp_port,
attr->u.brport_flags);
attr->orig_dev,
attr->u.brport_flags,
extack);
break;
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port,
Expand Down Expand Up @@ -2783,6 +2807,7 @@ void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,

bridge_device->ops->port_leave(bridge_device, bridge_port,
mlxsw_sp_port);
mlxsw_sp_port_security_set(mlxsw_sp_port, false);
mlxsw_sp_bridge_port_put(mlxsw_sp->bridge, bridge_port);
}

Expand Down Expand Up @@ -2888,13 +2913,14 @@ static void mlxsw_sp_fdb_nve_call_notifiers(struct net_device *dev,
static void
mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
const char *mac, u16 vid,
struct net_device *dev, bool offloaded)
struct net_device *dev, bool offloaded, bool locked)
{
struct switchdev_notifier_fdb_info info = {};

info.addr = mac;
info.vid = vid;
info.offloaded = offloaded;
info.locked = locked;
call_switchdev_notifiers(type, dev, &info.info, NULL);
}

Expand Down Expand Up @@ -2941,6 +2967,12 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0;
evid = mlxsw_sp_port_vlan->vid;

if (adding && mlxsw_sp_port->security) {
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, mac,
vid, bridge_port->dev, false, true);
return;
}

do_fdb_op:
err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, evid,
adding, true);
Expand All @@ -2952,7 +2984,8 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
if (!do_notification)
return;
type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE;
mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding);
mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding,
false);

return;

Expand Down Expand Up @@ -3004,6 +3037,12 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0;
lag_vid = mlxsw_sp_port_vlan->vid;

if (adding && mlxsw_sp_port->security) {
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, mac,
vid, bridge_port->dev, false, true);
return;
}

do_fdb_op:
err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
adding, true);
Expand All @@ -3015,7 +3054,8 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
if (!do_notification)
return;
type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE;
mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding);
mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding,
false);

return;

Expand Down Expand Up @@ -3122,7 +3162,7 @@ static void mlxsw_sp_fdb_notify_mac_uc_tunnel_process(struct mlxsw_sp *mlxsw_sp,

type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE :
SWITCHDEV_FDB_DEL_TO_BRIDGE;
mlxsw_sp_fdb_call_notifiers(type, mac, vid, nve_dev, adding);
mlxsw_sp_fdb_call_notifiers(type, mac, vid, nve_dev, adding, false);

mlxsw_sp_fid_put(fid);

Expand Down Expand Up @@ -3264,7 +3304,7 @@ mlxsw_sp_switchdev_bridge_vxlan_fdb_event(struct mlxsw_sp *mlxsw_sp,
&vxlan_fdb_info.info, NULL);
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
vxlan_fdb_info.eth_addr,
fdb_info->vid, dev, true);
fdb_info->vid, dev, true, false);
break;
case SWITCHDEV_FDB_DEL_TO_DEVICE:
err = mlxsw_sp_port_fdb_tunnel_uc_op(mlxsw_sp,
Expand Down Expand Up @@ -3359,7 +3399,7 @@ static void mlxsw_sp_switchdev_bridge_fdb_event_work(struct work_struct *work)
break;
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
fdb_info->addr,
fdb_info->vid, dev, true);
fdb_info->vid, dev, true, false);
break;
case SWITCHDEV_FDB_DEL_TO_DEVICE:
fdb_info = &switchdev_work->fdb_info;
Expand Down Expand Up @@ -3443,7 +3483,8 @@ mlxsw_sp_switchdev_vxlan_fdb_add(struct mlxsw_sp *mlxsw_sp,
call_switchdev_notifiers(SWITCHDEV_VXLAN_FDB_OFFLOADED, dev,
&vxlan_fdb_info->info, NULL);
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
vxlan_fdb_info->eth_addr, vid, dev, true);
vxlan_fdb_info->eth_addr, vid, dev, true,
false);

mlxsw_sp_fid_put(fid);

Expand Down Expand Up @@ -3493,7 +3534,8 @@ mlxsw_sp_switchdev_vxlan_fdb_del(struct mlxsw_sp *mlxsw_sp,
false, false);
vid = bridge_device->ops->fid_vid(bridge_device, fid);
mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
vxlan_fdb_info->eth_addr, vid, dev, false);
vxlan_fdb_info->eth_addr, vid, dev, false,
false);

mlxsw_sp_fid_put(fid);
}
Expand Down
25 changes: 25 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ mlxsw_sp_trap_policer_items_arr[] = {
{
.policer = MLXSW_SP_TRAP_POLICER(20, 10240, 4096),
},
{
.policer = MLXSW_SP_TRAP_POLICER(21, 128, 128),
},
};

static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
Expand Down Expand Up @@ -628,6 +631,11 @@ static const struct mlxsw_sp_trap_group_item mlxsw_sp_trap_group_items_arr[] = {
.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_FLOW_LOGGING,
.priority = 4,
},
{
.group = DEVLINK_TRAP_GROUP_GENERIC(EAPOL, 21),
.hw_group_id = MLXSW_REG_HTGT_TRAP_GROUP_SP_EAPOL,
.priority = 5,
},
};

static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
Expand Down Expand Up @@ -1160,6 +1168,23 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
MLXSW_SP_RXL_DISCARD(ROUTER3, L3_DISCARDS),
},
},
{
.trap = MLXSW_SP_TRAP_CONTROL(EAPOL, EAPOL, TRAP),
.listeners_arr = {
MLXSW_SP_RXL_NO_MARK(EAPOL, EAPOL, TRAP_TO_CPU, true),
},
},
{
.trap = MLXSW_SP_TRAP_DROP(LOCKED_PORT, L2_DROPS),
.listeners_arr = {
MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISS,
TRAP_EXCEPTION_TO_CPU, false,
SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS),
MLXSW_RXL_DIS(mlxsw_sp_rx_drop_listener, FDB_MISMATCH,
TRAP_EXCEPTION_TO_CPU, false,
SP_L2_DISCARDS, DISCARD, SP_L2_DISCARDS),
},
},
};

static struct mlxsw_sp_trap_policer_item *
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/trap.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ enum {
MLXSW_TRAP_ID_IGMP_V2_LEAVE = 0x33,
MLXSW_TRAP_ID_IGMP_V3_REPORT = 0x34,
MLXSW_TRAP_ID_PKT_SAMPLE = 0x38,
MLXSW_TRAP_ID_FDB_MISS = 0x3A,
MLXSW_TRAP_ID_FDB_MISMATCH = 0x3B,
MLXSW_TRAP_ID_FID_MISS = 0x3D,
MLXSW_TRAP_ID_DECAP_ECN0 = 0x40,
MLXSW_TRAP_ID_MTUERROR = 0x52,
Expand Down
9 changes: 9 additions & 0 deletions include/net/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,8 @@ enum devlink_trap_generic_id {
DEVLINK_TRAP_GENERIC_ID_ESP_PARSING,
DEVLINK_TRAP_GENERIC_ID_BLACKHOLE_NEXTHOP,
DEVLINK_TRAP_GENERIC_ID_DMAC_FILTER,
DEVLINK_TRAP_GENERIC_ID_EAPOL,
DEVLINK_TRAP_GENERIC_ID_LOCKED_PORT,

/* Add new generic trap IDs above */
__DEVLINK_TRAP_GENERIC_ID_MAX,
Expand Down Expand Up @@ -930,6 +932,7 @@ enum devlink_trap_group_generic_id {
DEVLINK_TRAP_GROUP_GENERIC_ID_ACL_SAMPLE,
DEVLINK_TRAP_GROUP_GENERIC_ID_ACL_TRAP,
DEVLINK_TRAP_GROUP_GENERIC_ID_PARSER_ERROR_DROPS,
DEVLINK_TRAP_GROUP_GENERIC_ID_EAPOL,

/* Add new generic trap group IDs above */
__DEVLINK_TRAP_GROUP_GENERIC_ID_MAX,
Expand Down Expand Up @@ -1121,6 +1124,10 @@ enum devlink_trap_group_generic_id {
"blackhole_nexthop"
#define DEVLINK_TRAP_GENERIC_NAME_DMAC_FILTER \
"dmac_filter"
#define DEVLINK_TRAP_GENERIC_NAME_EAPOL \
"eapol"
#define DEVLINK_TRAP_GENERIC_NAME_LOCKED_PORT \
"locked_port"

#define DEVLINK_TRAP_GROUP_GENERIC_NAME_L2_DROPS \
"l2_drops"
Expand Down Expand Up @@ -1174,6 +1181,8 @@ enum devlink_trap_group_generic_id {
"acl_trap"
#define DEVLINK_TRAP_GROUP_GENERIC_NAME_PARSER_ERROR_DROPS \
"parser_error_drops"
#define DEVLINK_TRAP_GROUP_GENERIC_NAME_EAPOL \
"eapol"

#define DEVLINK_TRAP_GENERIC(_type, _init_action, _id, _group_id, \
_metadata_cap) \
Expand Down
Loading

0 comments on commit 0cb9ed5

Please sign in to comment.