Merge branch 'mlx5-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux
Leon Romanovsky says: ==================== mlx5 MACsec RoCEv2 support From Patrisious: This series extends previously added MACsec offload support to cover RoCE traffic either. In order to achieve that, we need configure MACsec with offload between the two endpoints, like below: REMOTE_MAC=10:70:fd:43:71:c0 * ip addr add 1.1.1.1/16 dev eth2 * ip link set dev eth2 up * ip link add link eth2 macsec0 type macsec encrypt on * ip macsec offload macsec0 mac * ip macsec add macsec0 tx sa 0 pn 1 on key 00 dffafc8d7b9a43d5b9a3dfbbf6a30c16 * ip macsec add macsec0 rx port 1 address $REMOTE_MAC * ip macsec add macsec0 rx port 1 address $REMOTE_MAC sa 0 pn 1 on key 01 ead3664f508eb06c40ac7104cdae4ce5 * ip addr add 10.1.0.1/16 dev macsec0 * ip link set dev macsec0 up And in a similar manner on the other machine, while noting the keys order would be reversed and the MAC address of the other machine. RDMA traffic is separated through relevant GID entries and in case of IP ambiguity issue - meaning we have a physical GIDs and a MACsec GIDs with the same IP/GID, we disable our physical GID in order to force the user to only use the MACsec GID. v0: https://lore.kernel.org/netdev/20230813064703.574082-1-leon@kernel.org/ * 'mlx5-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux: RDMA/mlx5: Handles RoCE MACsec steering rules addition and deletion net/mlx5: Add RoCE MACsec steering infrastructure in core net/mlx5: Configure MACsec steering for ingress RoCEv2 traffic net/mlx5: Configure MACsec steering for egress RoCEv2 traffic IB/core: Reorder GID delete code for RoCE net/mlx5: Add MACsec priorities in RDMA namespaces RDMA/mlx5: Implement MACsec gid addition and deletion net/mlx5: Maintain fs_id xarray per MACsec device inside macsec steering net/mlx5: Remove netdevice from MACsec steering net/mlx5e: Move MACsec flow steering and statistics database from ethernet to core net/mlx5e: Rename MACsec flow steering functions/parameters to suit core naming style net/mlx5: Remove dependency of macsec flow steering on ethernet net/mlx5e: Move MACsec flow steering operations to be used as core library macsec: add functions to get macsec real netdevice and check offload ==================== Link: https://lore.kernel.org/r/20230821073833.59042-1-leon@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
3c5066c6b0
@ -400,6 +400,9 @@ static void del_gid(struct ib_device *ib_dev, u32 port,
|
||||
table->data_vec[ix] = NULL;
|
||||
write_unlock_irq(&table->rwlock);
|
||||
|
||||
if (rdma_cap_roce_gid_table(ib_dev, port))
|
||||
ib_dev->ops.del_gid(&entry->attr, &entry->context);
|
||||
|
||||
ndev_storage = entry->ndev_storage;
|
||||
if (ndev_storage) {
|
||||
entry->ndev_storage = NULL;
|
||||
@ -407,9 +410,6 @@ static void del_gid(struct ib_device *ib_dev, u32 port,
|
||||
call_rcu(&ndev_storage->rcu_head, put_gid_ndev);
|
||||
}
|
||||
|
||||
if (rdma_cap_roce_gid_table(ib_dev, port))
|
||||
ib_dev->ops.del_gid(&entry->attr, &entry->context);
|
||||
|
||||
put_gid_entry_locked(entry);
|
||||
}
|
||||
|
||||
|
@ -28,3 +28,4 @@ mlx5_ib-$(CONFIG_INFINIBAND_USER_ACCESS) += devx.o \
|
||||
fs.o \
|
||||
qos.o \
|
||||
std_types.o
|
||||
mlx5_ib-$(CONFIG_MLX5_MACSEC) += macsec.o
|
||||
|
364
drivers/infiniband/hw/mlx5/macsec.c
Normal file
364
drivers/infiniband/hw/mlx5/macsec.c
Normal file
@ -0,0 +1,364 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
|
||||
|
||||
#include "macsec.h"
|
||||
#include <linux/mlx5/macsec.h>
|
||||
|
||||
struct mlx5_reserved_gids {
|
||||
int macsec_index;
|
||||
const struct ib_gid_attr *physical_gid;
|
||||
};
|
||||
|
||||
struct mlx5_roce_gids {
|
||||
struct list_head roce_gid_list_entry;
|
||||
u16 gid_idx;
|
||||
union {
|
||||
struct sockaddr_in sockaddr_in;
|
||||
struct sockaddr_in6 sockaddr_in6;
|
||||
} addr;
|
||||
};
|
||||
|
||||
struct mlx5_macsec_device {
|
||||
struct list_head macsec_devices_list_entry;
|
||||
void *macdev;
|
||||
struct list_head macsec_roce_gids;
|
||||
struct list_head tx_rules_list;
|
||||
struct list_head rx_rules_list;
|
||||
};
|
||||
|
||||
static void cleanup_macsec_device(struct mlx5_macsec_device *macsec_device)
|
||||
{
|
||||
if (!list_empty(&macsec_device->tx_rules_list) ||
|
||||
!list_empty(&macsec_device->rx_rules_list) ||
|
||||
!list_empty(&macsec_device->macsec_roce_gids))
|
||||
return;
|
||||
|
||||
list_del(&macsec_device->macsec_devices_list_entry);
|
||||
kfree(macsec_device);
|
||||
}
|
||||
|
||||
static struct mlx5_macsec_device *get_macsec_device(void *macdev,
|
||||
struct list_head *macsec_devices_list)
|
||||
{
|
||||
struct mlx5_macsec_device *iter, *macsec_device = NULL;
|
||||
|
||||
list_for_each_entry(iter, macsec_devices_list, macsec_devices_list_entry) {
|
||||
if (iter->macdev == macdev) {
|
||||
macsec_device = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (macsec_device)
|
||||
return macsec_device;
|
||||
|
||||
macsec_device = kzalloc(sizeof(*macsec_device), GFP_KERNEL);
|
||||
if (!macsec_device)
|
||||
return NULL;
|
||||
|
||||
macsec_device->macdev = macdev;
|
||||
INIT_LIST_HEAD(&macsec_device->tx_rules_list);
|
||||
INIT_LIST_HEAD(&macsec_device->rx_rules_list);
|
||||
INIT_LIST_HEAD(&macsec_device->macsec_roce_gids);
|
||||
list_add(&macsec_device->macsec_devices_list_entry, macsec_devices_list);
|
||||
|
||||
return macsec_device;
|
||||
}
|
||||
|
||||
static void mlx5_macsec_del_roce_gid(struct mlx5_macsec_device *macsec_device, u16 gid_idx)
|
||||
{
|
||||
struct mlx5_roce_gids *current_gid, *next_gid;
|
||||
|
||||
list_for_each_entry_safe(current_gid, next_gid, &macsec_device->macsec_roce_gids,
|
||||
roce_gid_list_entry)
|
||||
if (current_gid->gid_idx == gid_idx) {
|
||||
list_del(¤t_gid->roce_gid_list_entry);
|
||||
kfree(current_gid);
|
||||
}
|
||||
}
|
||||
|
||||
static void mlx5_macsec_save_roce_gid(struct mlx5_macsec_device *macsec_device,
|
||||
const struct sockaddr *addr, u16 gid_idx)
|
||||
{
|
||||
struct mlx5_roce_gids *roce_gids;
|
||||
|
||||
roce_gids = kzalloc(sizeof(*roce_gids), GFP_KERNEL);
|
||||
if (!roce_gids)
|
||||
return;
|
||||
|
||||
roce_gids->gid_idx = gid_idx;
|
||||
if (addr->sa_family == AF_INET)
|
||||
memcpy(&roce_gids->addr.sockaddr_in, addr, sizeof(roce_gids->addr.sockaddr_in));
|
||||
else
|
||||
memcpy(&roce_gids->addr.sockaddr_in6, addr, sizeof(roce_gids->addr.sockaddr_in6));
|
||||
|
||||
list_add_tail(&roce_gids->roce_gid_list_entry, &macsec_device->macsec_roce_gids);
|
||||
}
|
||||
|
||||
static void handle_macsec_gids(struct list_head *macsec_devices_list,
|
||||
struct mlx5_macsec_event_data *data)
|
||||
{
|
||||
struct mlx5_macsec_device *macsec_device;
|
||||
struct mlx5_roce_gids *gid;
|
||||
|
||||
macsec_device = get_macsec_device(data->macdev, macsec_devices_list);
|
||||
if (!macsec_device)
|
||||
return;
|
||||
|
||||
list_for_each_entry(gid, &macsec_device->macsec_roce_gids, roce_gid_list_entry) {
|
||||
mlx5_macsec_add_roce_sa_rules(data->fs_id, (struct sockaddr *)&gid->addr,
|
||||
gid->gid_idx, &macsec_device->tx_rules_list,
|
||||
&macsec_device->rx_rules_list, data->macsec_fs,
|
||||
data->is_tx);
|
||||
}
|
||||
}
|
||||
|
||||
static void del_sa_roce_rule(struct list_head *macsec_devices_list,
|
||||
struct mlx5_macsec_event_data *data)
|
||||
{
|
||||
struct mlx5_macsec_device *macsec_device;
|
||||
|
||||
macsec_device = get_macsec_device(data->macdev, macsec_devices_list);
|
||||
WARN_ON(!macsec_device);
|
||||
|
||||
mlx5_macsec_del_roce_sa_rules(data->fs_id, data->macsec_fs,
|
||||
&macsec_device->tx_rules_list,
|
||||
&macsec_device->rx_rules_list, data->is_tx);
|
||||
}
|
||||
|
||||
static int macsec_event(struct notifier_block *nb, unsigned long event, void *data)
|
||||
{
|
||||
struct mlx5_macsec *macsec = container_of(nb, struct mlx5_macsec, blocking_events_nb);
|
||||
|
||||
mutex_lock(&macsec->lock);
|
||||
switch (event) {
|
||||
case MLX5_DRIVER_EVENT_MACSEC_SA_ADDED:
|
||||
handle_macsec_gids(&macsec->macsec_devices_list, data);
|
||||
break;
|
||||
case MLX5_DRIVER_EVENT_MACSEC_SA_DELETED:
|
||||
del_sa_roce_rule(&macsec->macsec_devices_list, data);
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&macsec->lock);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
mutex_unlock(&macsec->lock);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
void mlx5r_macsec_event_register(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dev->macsec.blocking_events_nb.notifier_call = macsec_event;
|
||||
blocking_notifier_chain_register(&dev->mdev->macsec_nh,
|
||||
&dev->macsec.blocking_events_nb);
|
||||
}
|
||||
|
||||
void mlx5r_macsec_event_unregister(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
return;
|
||||
}
|
||||
|
||||
blocking_notifier_chain_unregister(&dev->mdev->macsec_nh,
|
||||
&dev->macsec.blocking_events_nb);
|
||||
}
|
||||
|
||||
int mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
int i, j, max_gids;
|
||||
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
|
||||
for (i = 0; i < dev->num_ports; i++) {
|
||||
dev->port[i].reserved_gids = kcalloc(max_gids,
|
||||
sizeof(*dev->port[i].reserved_gids),
|
||||
GFP_KERNEL);
|
||||
if (!dev->port[i].reserved_gids)
|
||||
goto err;
|
||||
|
||||
for (j = 0; j < max_gids; j++)
|
||||
dev->port[i].reserved_gids[j].macsec_index = -1;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&dev->macsec.macsec_devices_list);
|
||||
mutex_init(&dev->macsec.lock);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
while (i >= 0) {
|
||||
kfree(dev->port[i].reserved_gids);
|
||||
i--;
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev))
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
|
||||
for (i = 0; i < dev->num_ports; i++)
|
||||
kfree(dev->port[i].reserved_gids);
|
||||
|
||||
mutex_destroy(&dev->macsec.lock);
|
||||
}
|
||||
|
||||
int mlx5r_add_gid_macsec_operations(const struct ib_gid_attr *attr)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(attr->device);
|
||||
struct mlx5_macsec_device *macsec_device;
|
||||
const struct ib_gid_attr *physical_gid;
|
||||
struct mlx5_reserved_gids *mgids;
|
||||
struct net_device *ndev;
|
||||
int ret = 0;
|
||||
union {
|
||||
struct sockaddr_in sockaddr_in;
|
||||
struct sockaddr_in6 sockaddr_in6;
|
||||
} addr;
|
||||
|
||||
if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
|
||||
return 0;
|
||||
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
ndev = rcu_dereference(attr->ndev);
|
||||
if (!ndev) {
|
||||
rcu_read_unlock();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
|
||||
rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
dev_hold(ndev);
|
||||
rcu_read_unlock();
|
||||
|
||||
mutex_lock(&dev->macsec.lock);
|
||||
macsec_device = get_macsec_device(ndev, &dev->macsec.macsec_devices_list);
|
||||
if (!macsec_device) {
|
||||
ret = -ENOMEM;
|
||||
goto dev_err;
|
||||
}
|
||||
|
||||
physical_gid = rdma_find_gid(attr->device, &attr->gid,
|
||||
attr->gid_type, NULL);
|
||||
if (!IS_ERR(physical_gid)) {
|
||||
ret = set_roce_addr(to_mdev(physical_gid->device),
|
||||
physical_gid->port_num,
|
||||
physical_gid->index, NULL,
|
||||
physical_gid);
|
||||
if (ret)
|
||||
goto gid_err;
|
||||
|
||||
mgids = &dev->port[attr->port_num - 1].reserved_gids[physical_gid->index];
|
||||
mgids->macsec_index = attr->index;
|
||||
mgids->physical_gid = physical_gid;
|
||||
}
|
||||
|
||||
/* Proceed with adding steering rules, regardless if there was gid ambiguity or not.*/
|
||||
rdma_gid2ip((struct sockaddr *)&addr, &attr->gid);
|
||||
ret = mlx5_macsec_add_roce_rule(ndev, (struct sockaddr *)&addr, attr->index,
|
||||
&macsec_device->tx_rules_list,
|
||||
&macsec_device->rx_rules_list, dev->mdev->macsec_fs);
|
||||
if (ret && !IS_ERR(physical_gid))
|
||||
goto rule_err;
|
||||
|
||||
mlx5_macsec_save_roce_gid(macsec_device, (struct sockaddr *)&addr, attr->index);
|
||||
|
||||
dev_put(ndev);
|
||||
mutex_unlock(&dev->macsec.lock);
|
||||
return ret;
|
||||
|
||||
rule_err:
|
||||
set_roce_addr(to_mdev(physical_gid->device), physical_gid->port_num,
|
||||
physical_gid->index, &physical_gid->gid, physical_gid);
|
||||
mgids->macsec_index = -1;
|
||||
gid_err:
|
||||
rdma_put_gid_attr(physical_gid);
|
||||
cleanup_macsec_device(macsec_device);
|
||||
dev_err:
|
||||
dev_put(ndev);
|
||||
mutex_unlock(&dev->macsec.lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mlx5r_del_gid_macsec_operations(const struct ib_gid_attr *attr)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(attr->device);
|
||||
struct mlx5_macsec_device *macsec_device;
|
||||
struct mlx5_reserved_gids *mgids;
|
||||
struct net_device *ndev;
|
||||
int i, max_gids;
|
||||
|
||||
if (attr->gid_type != IB_GID_TYPE_ROCE_UDP_ENCAP)
|
||||
return;
|
||||
|
||||
if (!mlx5_is_macsec_roce_supported(dev->mdev)) {
|
||||
mlx5_ib_dbg(dev, "RoCE MACsec not supported due to capabilities\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mgids = &dev->port[attr->port_num - 1].reserved_gids[attr->index];
|
||||
if (mgids->macsec_index != -1) { /* Checking if physical gid has ambiguous IP */
|
||||
rdma_put_gid_attr(mgids->physical_gid);
|
||||
mgids->macsec_index = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
ndev = rcu_dereference(attr->ndev);
|
||||
if (!ndev) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netif_is_macsec(ndev) || !macsec_netdev_is_offloaded(ndev)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
dev_hold(ndev);
|
||||
rcu_read_unlock();
|
||||
|
||||
mutex_lock(&dev->macsec.lock);
|
||||
max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size);
|
||||
for (i = 0; i < max_gids; i++) { /* Checking if macsec gid has ambiguous IP */
|
||||
mgids = &dev->port[attr->port_num - 1].reserved_gids[i];
|
||||
if (mgids->macsec_index == attr->index) {
|
||||
const struct ib_gid_attr *physical_gid = mgids->physical_gid;
|
||||
|
||||
set_roce_addr(to_mdev(physical_gid->device),
|
||||
physical_gid->port_num,
|
||||
physical_gid->index,
|
||||
&physical_gid->gid, physical_gid);
|
||||
|
||||
rdma_put_gid_attr(physical_gid);
|
||||
mgids->macsec_index = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
macsec_device = get_macsec_device(ndev, &dev->macsec.macsec_devices_list);
|
||||
mlx5_macsec_del_roce_rule(attr->index, dev->mdev->macsec_fs,
|
||||
&macsec_device->tx_rules_list, &macsec_device->rx_rules_list);
|
||||
mlx5_macsec_del_roce_gid(macsec_device, attr->index);
|
||||
cleanup_macsec_device(macsec_device);
|
||||
|
||||
dev_put(ndev);
|
||||
mutex_unlock(&dev->macsec.lock);
|
||||
}
|
29
drivers/infiniband/hw/mlx5/macsec.h
Normal file
29
drivers/infiniband/hw/mlx5/macsec.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
|
||||
|
||||
#ifndef __MLX5_MACSEC_H__
|
||||
#define __MLX5_MACSEC_H__
|
||||
|
||||
#include <net/macsec.h>
|
||||
#include <rdma/ib_cache.h>
|
||||
#include <rdma/ib_addr.h>
|
||||
#include "mlx5_ib.h"
|
||||
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_reserved_gids;
|
||||
|
||||
int mlx5r_add_gid_macsec_operations(const struct ib_gid_attr *attr);
|
||||
void mlx5r_del_gid_macsec_operations(const struct ib_gid_attr *attr);
|
||||
int mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev *dev);
|
||||
void mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev *dev);
|
||||
void mlx5r_macsec_event_register(struct mlx5_ib_dev *dev);
|
||||
void mlx5r_macsec_event_unregister(struct mlx5_ib_dev *dev);
|
||||
#else
|
||||
static inline int mlx5r_add_gid_macsec_operations(const struct ib_gid_attr *attr) { return 0; }
|
||||
static inline void mlx5r_del_gid_macsec_operations(const struct ib_gid_attr *attr) {}
|
||||
static inline int mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev *dev) { return 0; }
|
||||
static inline void mlx5r_macsec_dealloc_gids(struct mlx5_ib_dev *dev) {}
|
||||
static inline void mlx5r_macsec_event_register(struct mlx5_ib_dev *dev) {}
|
||||
static inline void mlx5r_macsec_event_unregister(struct mlx5_ib_dev *dev) {}
|
||||
#endif
|
||||
#endif /* __MLX5_MACSEC_H__ */
|
@ -46,6 +46,7 @@
|
||||
#include <rdma/uverbs_ioctl.h>
|
||||
#include <rdma/mlx5_user_ioctl_verbs.h>
|
||||
#include <rdma/mlx5_user_ioctl_cmds.h>
|
||||
#include "macsec.h"
|
||||
|
||||
#define UVERBS_MODULE_NAME mlx5_ib
|
||||
#include <rdma/uverbs_named_ioctl.h>
|
||||
@ -564,9 +565,9 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int set_roce_addr(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
unsigned int index, const union ib_gid *gid,
|
||||
const struct ib_gid_attr *attr)
|
||||
int set_roce_addr(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
unsigned int index, const union ib_gid *gid,
|
||||
const struct ib_gid_attr *attr)
|
||||
{
|
||||
enum ib_gid_type gid_type;
|
||||
u16 vlan_id = 0xffff;
|
||||
@ -607,6 +608,12 @@ static int set_roce_addr(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
static int mlx5_ib_add_gid(const struct ib_gid_attr *attr,
|
||||
__always_unused void **context)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mlx5r_add_gid_macsec_operations(attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return set_roce_addr(to_mdev(attr->device), attr->port_num,
|
||||
attr->index, &attr->gid, attr);
|
||||
}
|
||||
@ -614,8 +621,15 @@ static int mlx5_ib_add_gid(const struct ib_gid_attr *attr,
|
||||
static int mlx5_ib_del_gid(const struct ib_gid_attr *attr,
|
||||
__always_unused void **context)
|
||||
{
|
||||
return set_roce_addr(to_mdev(attr->device), attr->port_num,
|
||||
attr->index, NULL, attr);
|
||||
int ret;
|
||||
|
||||
ret = set_roce_addr(to_mdev(attr->device), attr->port_num,
|
||||
attr->index, NULL, attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mlx5r_del_gid_macsec_operations(attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__be16 mlx5_get_roce_udp_sport_min(const struct mlx5_ib_dev *dev,
|
||||
@ -3644,13 +3658,13 @@ static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
|
||||
mutex_destroy(&dev->cap_mask_mutex);
|
||||
WARN_ON(!xa_empty(&dev->sig_mrs));
|
||||
WARN_ON(!bitmap_empty(dev->dm.memic_alloc_pages, MLX5_MAX_MEMIC_PAGES));
|
||||
mlx5r_macsec_dealloc_gids(dev);
|
||||
}
|
||||
|
||||
static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = dev->mdev;
|
||||
int err;
|
||||
int i;
|
||||
int err, i;
|
||||
|
||||
dev->ib_dev.node_type = RDMA_NODE_IB_CA;
|
||||
dev->ib_dev.local_dma_lkey = 0 /* not supported for now */;
|
||||
@ -3670,10 +3684,14 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_ib_init_multiport_master(dev);
|
||||
err = mlx5r_macsec_init_gids_and_devlist(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mlx5_ib_init_multiport_master(dev);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
err = set_has_smi_cap(dev);
|
||||
if (err)
|
||||
goto err_mp;
|
||||
@ -3697,7 +3715,8 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
|
||||
spin_lock_init(&dev->dm.lock);
|
||||
dev->dm.dev = mdev;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
mlx5r_macsec_dealloc_gids(dev);
|
||||
err_mp:
|
||||
mlx5_ib_cleanup_multiport_master(dev);
|
||||
return err;
|
||||
@ -4106,11 +4125,15 @@ static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
dev->mdev_events.notifier_call = mlx5_ib_event;
|
||||
mlx5_notifier_register(dev->mdev, &dev->mdev_events);
|
||||
|
||||
mlx5r_macsec_event_register(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev)
|
||||
{
|
||||
mlx5r_macsec_event_unregister(dev);
|
||||
mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "srq.h"
|
||||
#include "qp.h"
|
||||
#include "macsec.h"
|
||||
|
||||
#define mlx5_ib_dbg(_dev, format, arg...) \
|
||||
dev_dbg(&(_dev)->ib_dev.dev, "%s:%d:(pid %d): " format, __func__, \
|
||||
@ -870,6 +871,9 @@ struct mlx5_ib_port {
|
||||
struct mlx5_ib_dbg_cc_params *dbg_cc_params;
|
||||
struct mlx5_roce roce;
|
||||
struct mlx5_eswitch_rep *rep;
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_reserved_gids *reserved_gids;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mlx5_ib_dbg_param {
|
||||
@ -1086,6 +1090,12 @@ struct mlx5_special_mkeys {
|
||||
__be32 terminate_scatter_list_mkey;
|
||||
};
|
||||
|
||||
struct mlx5_macsec {
|
||||
struct mutex lock; /* Protects mlx5_macsec internal contexts */
|
||||
struct list_head macsec_devices_list;
|
||||
struct notifier_block blocking_events_nb;
|
||||
};
|
||||
|
||||
struct mlx5_ib_dev {
|
||||
struct ib_device ib_dev;
|
||||
struct mlx5_core_dev *mdev;
|
||||
@ -1145,6 +1155,10 @@ struct mlx5_ib_dev {
|
||||
u16 pkey_table_len;
|
||||
u8 lag_ports;
|
||||
struct mlx5_special_mkeys mkeys;
|
||||
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_macsec macsec;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct mlx5_ib_cq *to_mibcq(struct mlx5_core_cq *mcq)
|
||||
@ -1648,4 +1662,7 @@ static inline bool mlx5_umem_needs_ats(struct mlx5_ib_dev *dev,
|
||||
return access_flags & IB_ACCESS_RELAXED_ORDERING;
|
||||
}
|
||||
|
||||
int set_roce_addr(struct mlx5_ib_dev *dev, u32 port_num,
|
||||
unsigned int index, const union ib_gid *gid,
|
||||
const struct ib_gid_attr *attr);
|
||||
#endif /* MLX5_IB_H */
|
||||
|
@ -140,7 +140,7 @@ config MLX5_CORE_IPOIB
|
||||
help
|
||||
MLX5 IPoIB offloads & acceleration support.
|
||||
|
||||
config MLX5_EN_MACSEC
|
||||
config MLX5_MACSEC
|
||||
bool "Connect-X support for MACSec offload"
|
||||
depends on MLX5_CORE_EN
|
||||
depends on MACSEC
|
||||
|
@ -98,7 +98,7 @@ mlx5_core-$(CONFIG_MLX5_CORE_IPOIB) += ipoib/ipoib.o ipoib/ethtool.o ipoib/ipoib
|
||||
#
|
||||
mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o
|
||||
|
||||
mlx5_core-$(CONFIG_MLX5_EN_MACSEC) += en_accel/macsec.o en_accel/macsec_fs.o \
|
||||
mlx5_core-$(CONFIG_MLX5_MACSEC) += en_accel/macsec.o lib/macsec_fs.o \
|
||||
en_accel/macsec_stats.o
|
||||
|
||||
mlx5_core-$(CONFIG_MLX5_EN_IPSEC) += en_accel/ipsec.o en_accel/ipsec_rxtx.o \
|
||||
|
@ -917,7 +917,7 @@ struct mlx5e_priv {
|
||||
|
||||
const struct mlx5e_profile *profile;
|
||||
void *ppriv;
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5e_macsec *macsec;
|
||||
#endif
|
||||
#ifdef CONFIG_MLX5_EN_IPSEC
|
||||
|
@ -138,7 +138,7 @@ static inline bool mlx5e_accel_tx_begin(struct net_device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
if (unlikely(mlx5e_macsec_skb_is_offload(skb))) {
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
|
||||
@ -173,7 +173,7 @@ static inline void mlx5e_accel_tx_eseg(struct mlx5e_priv *priv,
|
||||
mlx5e_ipsec_tx_build_eseg(priv, skb, eseg);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
if (unlikely(mlx5e_macsec_skb_is_offload(skb)))
|
||||
mlx5e_macsec_tx_build_eseg(priv->macsec, skb, eseg);
|
||||
#endif
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "lib/aso.h"
|
||||
#include "lib/crypto.h"
|
||||
#include "en_accel/macsec.h"
|
||||
#include "en_accel/macsec_fs.h"
|
||||
|
||||
#define MLX5_MACSEC_EPN_SCOPE_MID 0x80000000L
|
||||
#define MLX5E_MACSEC_ASO_CTX_SZ MLX5_ST_SZ_BYTES(macsec_aso)
|
||||
@ -66,9 +65,7 @@ struct mlx5e_macsec_sa {
|
||||
ssci_t ssci;
|
||||
salt_t salt;
|
||||
|
||||
struct rhash_head hash;
|
||||
u32 fs_id;
|
||||
union mlx5e_macsec_rule *macsec_rule;
|
||||
union mlx5_macsec_rule *macsec_rule;
|
||||
struct rcu_head rcu_head;
|
||||
struct mlx5e_macsec_epn_state epn_state;
|
||||
};
|
||||
@ -106,14 +103,6 @@ struct mlx5e_macsec_aso {
|
||||
u32 pdn;
|
||||
};
|
||||
|
||||
static const struct rhashtable_params rhash_sci = {
|
||||
.key_len = sizeof_field(struct mlx5e_macsec_sa, sci),
|
||||
.key_offset = offsetof(struct mlx5e_macsec_sa, sci),
|
||||
.head_offset = offsetof(struct mlx5e_macsec_sa, hash),
|
||||
.automatic_shrinking = true,
|
||||
.min_size = 1,
|
||||
};
|
||||
|
||||
struct mlx5e_macsec_device {
|
||||
const struct net_device *netdev;
|
||||
struct mlx5e_macsec_sa *tx_sa[MACSEC_NUM_AN];
|
||||
@ -125,20 +114,13 @@ struct mlx5e_macsec_device {
|
||||
struct mlx5e_macsec {
|
||||
struct list_head macsec_device_list_head;
|
||||
int num_of_devices;
|
||||
struct mlx5e_macsec_fs *macsec_fs;
|
||||
struct mutex lock; /* Protects mlx5e_macsec internal contexts */
|
||||
|
||||
/* Tx sci -> fs id mapping handling */
|
||||
struct rhashtable sci_hash; /* sci -> mlx5e_macsec_sa */
|
||||
|
||||
/* Rx fs_id -> rx_sc mapping */
|
||||
struct xarray sc_xarray;
|
||||
|
||||
struct mlx5_core_dev *mdev;
|
||||
|
||||
/* Stats manage */
|
||||
struct mlx5e_macsec_stats stats;
|
||||
|
||||
/* ASO */
|
||||
struct mlx5e_macsec_aso aso;
|
||||
|
||||
@ -330,36 +312,30 @@ static void mlx5e_macsec_destroy_object(struct mlx5_core_dev *mdev, u32 macsec_o
|
||||
|
||||
static void mlx5e_macsec_cleanup_sa(struct mlx5e_macsec *macsec,
|
||||
struct mlx5e_macsec_sa *sa,
|
||||
bool is_tx)
|
||||
bool is_tx, struct net_device *netdev, u32 fs_id)
|
||||
{
|
||||
int action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
|
||||
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
|
||||
|
||||
if ((is_tx) && sa->fs_id) {
|
||||
/* Make sure ongoing datapath readers sees a valid SA */
|
||||
rhashtable_remove_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
|
||||
sa->fs_id = 0;
|
||||
}
|
||||
|
||||
if (!sa->macsec_rule)
|
||||
return;
|
||||
|
||||
mlx5e_macsec_fs_del_rule(macsec->macsec_fs, sa->macsec_rule, action);
|
||||
mlx5_macsec_fs_del_rule(macsec->mdev->macsec_fs, sa->macsec_rule, action, netdev,
|
||||
fs_id);
|
||||
mlx5e_macsec_destroy_object(macsec->mdev, sa->macsec_obj_id);
|
||||
sa->macsec_rule = NULL;
|
||||
}
|
||||
|
||||
static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
|
||||
struct mlx5e_macsec_sa *sa,
|
||||
bool encrypt,
|
||||
bool is_tx)
|
||||
bool encrypt, bool is_tx, u32 *fs_id)
|
||||
{
|
||||
struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev);
|
||||
struct mlx5e_macsec *macsec = priv->macsec;
|
||||
struct mlx5_macsec_rule_attrs rule_attrs;
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
struct mlx5_macsec_obj_attrs obj_attrs;
|
||||
union mlx5e_macsec_rule *macsec_rule;
|
||||
union mlx5_macsec_rule *macsec_rule;
|
||||
int err;
|
||||
|
||||
obj_attrs.next_pn = sa->next_pn;
|
||||
@ -387,7 +363,7 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
|
||||
rule_attrs.action = (is_tx) ? MLX5_ACCEL_MACSEC_ACTION_ENCRYPT :
|
||||
MLX5_ACCEL_MACSEC_ACTION_DECRYPT;
|
||||
|
||||
macsec_rule = mlx5e_macsec_fs_add_rule(macsec->macsec_fs, ctx, &rule_attrs, &sa->fs_id);
|
||||
macsec_rule = mlx5_macsec_fs_add_rule(mdev->macsec_fs, ctx, &rule_attrs, fs_id);
|
||||
if (!macsec_rule) {
|
||||
err = -ENOMEM;
|
||||
goto destroy_macsec_object;
|
||||
@ -395,16 +371,8 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
|
||||
|
||||
sa->macsec_rule = macsec_rule;
|
||||
|
||||
if (is_tx) {
|
||||
err = rhashtable_insert_fast(&macsec->sci_hash, &sa->hash, rhash_sci);
|
||||
if (err)
|
||||
goto destroy_macsec_object_and_rule;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_macsec_object_and_rule:
|
||||
mlx5e_macsec_cleanup_sa(macsec, sa, is_tx);
|
||||
destroy_macsec_object:
|
||||
mlx5e_macsec_destroy_object(mdev, sa->macsec_obj_id);
|
||||
|
||||
@ -426,7 +394,7 @@ mlx5e_macsec_get_rx_sc_from_sc_list(const struct list_head *list, sci_t sci)
|
||||
|
||||
static int macsec_rx_sa_active_update(struct macsec_context *ctx,
|
||||
struct mlx5e_macsec_sa *rx_sa,
|
||||
bool active)
|
||||
bool active, u32 *fs_id)
|
||||
{
|
||||
struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev);
|
||||
struct mlx5e_macsec *macsec = priv->macsec;
|
||||
@ -437,11 +405,11 @@ static int macsec_rx_sa_active_update(struct macsec_context *ctx,
|
||||
|
||||
rx_sa->active = active;
|
||||
if (!active) {
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev, *fs_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false, fs_id);
|
||||
if (err)
|
||||
rx_sa->active = false;
|
||||
|
||||
@ -563,7 +531,7 @@ static int mlx5e_macsec_add_txsa(struct macsec_context *ctx)
|
||||
!tx_sa->active)
|
||||
goto out;
|
||||
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
|
||||
if (err)
|
||||
goto destroy_encryption_key;
|
||||
|
||||
@ -627,7 +595,7 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
|
||||
if (ctx_tx_sa->active) {
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
|
||||
if (err)
|
||||
goto out;
|
||||
} else {
|
||||
@ -636,7 +604,7 @@ static int mlx5e_macsec_upd_txsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&macsec->lock);
|
||||
@ -669,7 +637,7 @@ static int mlx5e_macsec_del_txsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
|
||||
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
|
||||
kfree_rcu_mightsleep(tx_sa);
|
||||
macsec_device->tx_sa[assoc_num] = NULL;
|
||||
@ -680,20 +648,6 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32 mlx5e_macsec_get_sa_from_hashtable(struct rhashtable *sci_hash, sci_t *sci)
|
||||
{
|
||||
struct mlx5e_macsec_sa *macsec_sa;
|
||||
u32 fs_id = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
macsec_sa = rhashtable_lookup(sci_hash, sci, rhash_sci);
|
||||
if (macsec_sa)
|
||||
fs_id = macsec_sa->fs_id;
|
||||
rcu_read_unlock();
|
||||
|
||||
return fs_id;
|
||||
}
|
||||
|
||||
static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
|
||||
{
|
||||
struct mlx5e_macsec_rx_sc_xarray_element *sc_xarray_element;
|
||||
@ -813,7 +767,8 @@ static int mlx5e_macsec_upd_rxsc(struct macsec_context *ctx)
|
||||
if (!rx_sa)
|
||||
continue;
|
||||
|
||||
err = macsec_rx_sa_active_update(ctx, rx_sa, rx_sa->active && ctx_rx_sc->active);
|
||||
err = macsec_rx_sa_active_update(ctx, rx_sa, rx_sa->active && ctx_rx_sc->active,
|
||||
&rx_sc->sc_xarray_element->fs_id);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
@ -824,7 +779,8 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec_rx_sc *rx_sc)
|
||||
static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec_rx_sc *rx_sc,
|
||||
struct net_device *netdev)
|
||||
{
|
||||
struct mlx5e_macsec_sa *rx_sa;
|
||||
int i;
|
||||
@ -834,7 +790,8 @@ static void macsec_del_rxsc_ctx(struct mlx5e_macsec *macsec, struct mlx5e_macsec
|
||||
if (!rx_sa)
|
||||
continue;
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, netdev,
|
||||
rx_sc->sc_xarray_element->fs_id);
|
||||
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
|
||||
|
||||
kfree(rx_sa);
|
||||
@ -882,7 +839,7 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
macsec_del_rxsc_ctx(macsec, rx_sc);
|
||||
macsec_del_rxsc_ctx(macsec, rx_sc, ctx->secy->netdev);
|
||||
out:
|
||||
mutex_unlock(&macsec->lock);
|
||||
|
||||
@ -941,7 +898,6 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
|
||||
rx_sa->next_pn = ctx_rx_sa->next_pn;
|
||||
rx_sa->sci = sci;
|
||||
rx_sa->assoc_num = assoc_num;
|
||||
rx_sa->fs_id = rx_sc->sc_xarray_element->fs_id;
|
||||
|
||||
if (ctx->secy->xpn)
|
||||
update_macsec_epn(rx_sa, &ctx_rx_sa->key, &ctx_rx_sa->next_pn_halves,
|
||||
@ -958,7 +914,7 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
|
||||
//TODO - add support for both authentication and encryption flows
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false, &rx_sc->sc_xarray_element->fs_id);
|
||||
if (err)
|
||||
goto destroy_encryption_key;
|
||||
|
||||
@ -1025,7 +981,8 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = macsec_rx_sa_active_update(ctx, rx_sa, ctx_rx_sa->active);
|
||||
err = macsec_rx_sa_active_update(ctx, rx_sa, ctx_rx_sa->active,
|
||||
&rx_sc->sc_xarray_element->fs_id);
|
||||
out:
|
||||
mutex_unlock(&macsec->lock);
|
||||
|
||||
@ -1073,7 +1030,8 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev,
|
||||
rx_sc->sc_xarray_element->fs_id);
|
||||
mlx5_destroy_encryption_key(macsec->mdev, rx_sa->enc_key_id);
|
||||
kfree(rx_sa);
|
||||
rx_sc->rx_sa[assoc_num] = NULL;
|
||||
@ -1154,7 +1112,8 @@ static int macsec_upd_secy_hw_address(struct macsec_context *ctx,
|
||||
if (!rx_sa || !rx_sa->macsec_rule)
|
||||
continue;
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false);
|
||||
mlx5e_macsec_cleanup_sa(macsec, rx_sa, false, ctx->secy->netdev,
|
||||
rx_sc->sc_xarray_element->fs_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1165,7 +1124,8 @@ static int macsec_upd_secy_hw_address(struct macsec_context *ctx,
|
||||
continue;
|
||||
|
||||
if (rx_sa->active) {
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false);
|
||||
err = mlx5e_macsec_init_sa(ctx, rx_sa, true, false,
|
||||
&rx_sc->sc_xarray_element->fs_id);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
@ -1218,7 +1178,7 @@ static int mlx5e_macsec_upd_secy(struct macsec_context *ctx)
|
||||
if (!tx_sa)
|
||||
continue;
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < MACSEC_NUM_AN; ++i) {
|
||||
@ -1227,7 +1187,7 @@ static int mlx5e_macsec_upd_secy(struct macsec_context *ctx)
|
||||
continue;
|
||||
|
||||
if (tx_sa->assoc_num == tx_sc->encoding_sa && tx_sa->active) {
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true);
|
||||
err = mlx5e_macsec_init_sa(ctx, tx_sa, tx_sc->encrypt, true, NULL);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
@ -1265,7 +1225,7 @@ static int mlx5e_macsec_del_secy(struct macsec_context *ctx)
|
||||
if (!tx_sa)
|
||||
continue;
|
||||
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true);
|
||||
mlx5e_macsec_cleanup_sa(macsec, tx_sa, true, ctx->secy->netdev, 0);
|
||||
mlx5_destroy_encryption_key(macsec->mdev, tx_sa->enc_key_id);
|
||||
kfree(tx_sa);
|
||||
macsec_device->tx_sa[i] = NULL;
|
||||
@ -1273,7 +1233,7 @@ static int mlx5e_macsec_del_secy(struct macsec_context *ctx)
|
||||
|
||||
list = &macsec_device->macsec_rx_sc_list_head;
|
||||
list_for_each_entry_safe(rx_sc, tmp, list, rx_sc_list_element)
|
||||
macsec_del_rxsc_ctx(macsec, rx_sc);
|
||||
macsec_del_rxsc_ctx(macsec, rx_sc, ctx->secy->netdev);
|
||||
|
||||
kfree(macsec_device->dev_addr);
|
||||
macsec_device->dev_addr = NULL;
|
||||
@ -1647,50 +1607,6 @@ static void mlx5e_macsec_aso_cleanup(struct mlx5e_macsec_aso *aso, struct mlx5_c
|
||||
mlx5_core_dealloc_pd(mdev, aso->pdn);
|
||||
}
|
||||
|
||||
bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev)
|
||||
{
|
||||
if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
|
||||
MLX5_GENERAL_OBJ_TYPES_CAP_MACSEC_OFFLOAD))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_GEN(mdev, log_max_dek))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, log_max_macsec_offload))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_RX(mdev, macsec_decrypt) ||
|
||||
!MLX5_CAP_FLOWTABLE_NIC_RX(mdev, reformat_remove_macsec))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, macsec_encrypt) ||
|
||||
!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, reformat_add_macsec))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_encrypt) &&
|
||||
!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_encrypt))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_decrypt) &&
|
||||
!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_decrypt))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void mlx5e_macsec_get_stats_fill(struct mlx5e_macsec *macsec, void *macsec_stats)
|
||||
{
|
||||
mlx5e_macsec_fs_get_stats_fill(macsec->macsec_fs, macsec_stats);
|
||||
}
|
||||
|
||||
struct mlx5e_macsec_stats *mlx5e_macsec_get_stats(struct mlx5e_macsec *macsec)
|
||||
{
|
||||
if (!macsec)
|
||||
return NULL;
|
||||
|
||||
return &macsec->stats;
|
||||
}
|
||||
|
||||
static const struct macsec_ops macsec_offload_ops = {
|
||||
.mdo_add_txsa = mlx5e_macsec_add_txsa,
|
||||
.mdo_upd_txsa = mlx5e_macsec_upd_txsa,
|
||||
@ -1711,7 +1627,8 @@ bool mlx5e_macsec_handle_tx_skb(struct mlx5e_macsec *macsec, struct sk_buff *skb
|
||||
struct metadata_dst *md_dst = skb_metadata_dst(skb);
|
||||
u32 fs_id;
|
||||
|
||||
fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
|
||||
fs_id = mlx5_macsec_fs_get_fs_id_from_hashtable(macsec->mdev->macsec_fs,
|
||||
&md_dst->u.macsec_info.sci);
|
||||
if (!fs_id)
|
||||
goto err_out;
|
||||
|
||||
@ -1729,7 +1646,8 @@ void mlx5e_macsec_tx_build_eseg(struct mlx5e_macsec *macsec,
|
||||
struct metadata_dst *md_dst = skb_metadata_dst(skb);
|
||||
u32 fs_id;
|
||||
|
||||
fs_id = mlx5e_macsec_get_sa_from_hashtable(&macsec->sci_hash, &md_dst->u.macsec_info.sci);
|
||||
fs_id = mlx5_macsec_fs_get_fs_id_from_hashtable(macsec->mdev->macsec_fs,
|
||||
&md_dst->u.macsec_info.sci);
|
||||
if (!fs_id)
|
||||
return;
|
||||
|
||||
@ -1782,7 +1700,7 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = priv->mdev;
|
||||
struct mlx5e_macsec *macsec = NULL;
|
||||
struct mlx5e_macsec_fs *macsec_fs;
|
||||
struct mlx5_macsec_fs *macsec_fs;
|
||||
int err;
|
||||
|
||||
if (!mlx5e_is_macsec_device(priv->mdev)) {
|
||||
@ -1797,13 +1715,6 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
|
||||
INIT_LIST_HEAD(&macsec->macsec_device_list_head);
|
||||
mutex_init(&macsec->lock);
|
||||
|
||||
err = rhashtable_init(&macsec->sci_hash, &rhash_sci);
|
||||
if (err) {
|
||||
mlx5_core_err(mdev, "MACsec offload: Failed to init SCI hash table, err=%d\n",
|
||||
err);
|
||||
goto err_hash;
|
||||
}
|
||||
|
||||
err = mlx5e_macsec_aso_init(&macsec->aso, priv->mdev);
|
||||
if (err) {
|
||||
mlx5_core_err(mdev, "MACsec offload: Failed to init aso, err=%d\n", err);
|
||||
@ -1822,13 +1733,13 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv)
|
||||
|
||||
macsec->mdev = mdev;
|
||||
|
||||
macsec_fs = mlx5e_macsec_fs_init(mdev, priv->netdev);
|
||||
macsec_fs = mlx5_macsec_fs_init(mdev);
|
||||
if (!macsec_fs) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
macsec->macsec_fs = macsec_fs;
|
||||
mdev->macsec_fs = macsec_fs;
|
||||
|
||||
macsec->nb.notifier_call = macsec_obj_change_event;
|
||||
mlx5_notifier_register(mdev, &macsec->nb);
|
||||
@ -1842,8 +1753,6 @@ err_out:
|
||||
err_wq:
|
||||
mlx5e_macsec_aso_cleanup(&macsec->aso, priv->mdev);
|
||||
err_aso:
|
||||
rhashtable_destroy(&macsec->sci_hash);
|
||||
err_hash:
|
||||
kfree(macsec);
|
||||
priv->macsec = NULL;
|
||||
return err;
|
||||
@ -1858,10 +1767,9 @@ void mlx5e_macsec_cleanup(struct mlx5e_priv *priv)
|
||||
return;
|
||||
|
||||
mlx5_notifier_unregister(mdev, &macsec->nb);
|
||||
mlx5e_macsec_fs_cleanup(macsec->macsec_fs);
|
||||
mlx5_macsec_fs_cleanup(mdev->macsec_fs);
|
||||
destroy_workqueue(macsec->wq);
|
||||
mlx5e_macsec_aso_cleanup(&macsec->aso, mdev);
|
||||
rhashtable_destroy(&macsec->sci_hash);
|
||||
mutex_destroy(&macsec->lock);
|
||||
kfree(macsec);
|
||||
}
|
||||
|
@ -4,32 +4,16 @@
|
||||
#ifndef __MLX5_EN_ACCEL_MACSEC_H__
|
||||
#define __MLX5_EN_ACCEL_MACSEC_H__
|
||||
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include <net/macsec.h>
|
||||
#include <net/dst_metadata.h>
|
||||
|
||||
/* Bit31 - 30: MACsec marker, Bit15-0: MACsec id */
|
||||
#define MLX5_MACEC_RX_FS_ID_MAX USHRT_MAX /* Must be power of two */
|
||||
#define MLX5_MACSEC_RX_FS_ID_MASK MLX5_MACEC_RX_FS_ID_MAX
|
||||
#define MLX5_MACSEC_METADATA_MARKER(metadata) ((((metadata) >> 30) & 0x3) == 0x1)
|
||||
#define MLX5_MACSEC_RX_METADAT_HANDLE(metadata) ((metadata) & MLX5_MACSEC_RX_FS_ID_MASK)
|
||||
#include "lib/macsec_fs.h"
|
||||
|
||||
struct mlx5e_priv;
|
||||
struct mlx5e_macsec;
|
||||
|
||||
struct mlx5e_macsec_stats {
|
||||
u64 macsec_rx_pkts;
|
||||
u64 macsec_rx_bytes;
|
||||
u64 macsec_rx_pkts_drop;
|
||||
u64 macsec_rx_bytes_drop;
|
||||
u64 macsec_tx_pkts;
|
||||
u64 macsec_tx_bytes;
|
||||
u64 macsec_tx_pkts_drop;
|
||||
u64 macsec_tx_bytes_drop;
|
||||
};
|
||||
|
||||
void mlx5e_macsec_build_netdev(struct mlx5e_priv *priv);
|
||||
int mlx5e_macsec_init(struct mlx5e_priv *priv);
|
||||
void mlx5e_macsec_cleanup(struct mlx5e_priv *priv);
|
||||
@ -52,9 +36,6 @@ static inline bool mlx5e_macsec_is_rx_flow(struct mlx5_cqe64 *cqe)
|
||||
|
||||
void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev, struct sk_buff *skb,
|
||||
struct mlx5_cqe64 *cqe);
|
||||
bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev);
|
||||
void mlx5e_macsec_get_stats_fill(struct mlx5e_macsec *macsec, void *macsec_stats);
|
||||
struct mlx5e_macsec_stats *mlx5e_macsec_get_stats(struct mlx5e_macsec *macsec);
|
||||
|
||||
#else
|
||||
|
||||
@ -67,7 +48,6 @@ static inline void mlx5e_macsec_offload_handle_rx_skb(struct net_device *netdev,
|
||||
struct sk_buff *skb,
|
||||
struct mlx5_cqe64 *cqe)
|
||||
{}
|
||||
static inline bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev) { return false; }
|
||||
#endif /* CONFIG_MLX5_EN_MACSEC */
|
||||
#endif /* CONFIG_MLX5_MACSEC */
|
||||
|
||||
#endif /* __MLX5_ACCEL_EN_MACSEC_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,47 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
#ifndef __MLX5_MACSEC_STEERING_H__
|
||||
#define __MLX5_MACSEC_STEERING_H__
|
||||
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
|
||||
#include "en_accel/macsec.h"
|
||||
|
||||
#define MLX5_MACSEC_NUM_OF_SUPPORTED_INTERFACES 16
|
||||
|
||||
struct mlx5e_macsec_fs;
|
||||
union mlx5e_macsec_rule;
|
||||
|
||||
struct mlx5_macsec_rule_attrs {
|
||||
sci_t sci;
|
||||
u32 macsec_obj_id;
|
||||
u8 assoc_num;
|
||||
int action;
|
||||
};
|
||||
|
||||
enum mlx5_macsec_action {
|
||||
MLX5_ACCEL_MACSEC_ACTION_ENCRYPT,
|
||||
MLX5_ACCEL_MACSEC_ACTION_DECRYPT,
|
||||
};
|
||||
|
||||
void mlx5e_macsec_fs_cleanup(struct mlx5e_macsec_fs *macsec_fs);
|
||||
|
||||
struct mlx5e_macsec_fs *
|
||||
mlx5e_macsec_fs_init(struct mlx5_core_dev *mdev, struct net_device *netdev);
|
||||
|
||||
union mlx5e_macsec_rule *
|
||||
mlx5e_macsec_fs_add_rule(struct mlx5e_macsec_fs *macsec_fs,
|
||||
const struct macsec_context *ctx,
|
||||
struct mlx5_macsec_rule_attrs *attrs,
|
||||
u32 *sa_fs_id);
|
||||
|
||||
void mlx5e_macsec_fs_del_rule(struct mlx5e_macsec_fs *macsec_fs,
|
||||
union mlx5e_macsec_rule *macsec_rule,
|
||||
int action);
|
||||
|
||||
void mlx5e_macsec_fs_get_stats_fill(struct mlx5e_macsec_fs *macsec_fs, void *macsec_stats);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __MLX5_MACSEC_STEERING_H__ */
|
@ -8,14 +8,14 @@
|
||||
#include "en_accel/macsec.h"
|
||||
|
||||
static const struct counter_desc mlx5e_macsec_hw_stats_desc[] = {
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_pkts) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_bytes) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_pkts_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_rx_bytes_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_pkts) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_bytes) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_pkts_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5e_macsec_stats, macsec_tx_bytes_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_pkts) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_bytes) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_pkts_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_rx_bytes_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_pkts) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_bytes) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_pkts_drop) },
|
||||
{ MLX5E_DECLARE_STAT(struct mlx5_macsec_stats, macsec_tx_bytes_drop) },
|
||||
};
|
||||
|
||||
#define NUM_MACSEC_HW_COUNTERS ARRAY_SIZE(mlx5e_macsec_hw_stats_desc)
|
||||
@ -52,6 +52,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(macsec_hw)
|
||||
|
||||
static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(macsec_hw)
|
||||
{
|
||||
struct mlx5_macsec_fs *macsec_fs;
|
||||
int i;
|
||||
|
||||
if (!priv->macsec)
|
||||
@ -60,9 +61,10 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(macsec_hw)
|
||||
if (!mlx5e_is_macsec_device(priv->mdev))
|
||||
return idx;
|
||||
|
||||
mlx5e_macsec_get_stats_fill(priv->macsec, mlx5e_macsec_get_stats(priv->macsec));
|
||||
macsec_fs = priv->mdev->macsec_fs;
|
||||
mlx5_macsec_fs_get_stats_fill(macsec_fs, mlx5_macsec_fs_get_stats(macsec_fs));
|
||||
for (i = 0; i < NUM_MACSEC_HW_COUNTERS; i++)
|
||||
data[idx++] = MLX5E_READ_CTR64_CPU(mlx5e_macsec_get_stats(priv->macsec),
|
||||
data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_macsec_fs_get_stats(macsec_fs),
|
||||
mlx5e_macsec_hw_stats_desc,
|
||||
i);
|
||||
|
||||
|
@ -2502,7 +2502,7 @@ mlx5e_stats_grp_t mlx5e_nic_stats_grps[] = {
|
||||
&MLX5E_STATS_GRP(per_port_buff_congest),
|
||||
&MLX5E_STATS_GRP(ptp),
|
||||
&MLX5E_STATS_GRP(qos),
|
||||
#ifdef CONFIG_MLX5_EN_MACSEC
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
&MLX5E_STATS_GRP(macsec_hw),
|
||||
#endif
|
||||
};
|
||||
|
@ -975,6 +975,7 @@ static int mlx5_cmd_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
|
||||
max_actions = MLX5_CAP_ESW_INGRESS_ACL(dev, max_modify_header_actions);
|
||||
table_type = FS_FT_ESW_INGRESS_ACL;
|
||||
break;
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_TX_MACSEC:
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_TX:
|
||||
max_actions = MLX5_CAP_FLOWTABLE_RDMA_TX(dev, max_modify_header_actions);
|
||||
table_type = FS_FT_RDMA_TX;
|
||||
|
@ -107,7 +107,7 @@
|
||||
LEFTOVERS_NUM_PRIOS)
|
||||
|
||||
#define KERNEL_RX_MACSEC_NUM_PRIOS 1
|
||||
#define KERNEL_RX_MACSEC_NUM_LEVELS 2
|
||||
#define KERNEL_RX_MACSEC_NUM_LEVELS 3
|
||||
#define KERNEL_RX_MACSEC_MIN_LEVEL (BY_PASS_MIN_LEVEL + KERNEL_RX_MACSEC_NUM_PRIOS)
|
||||
|
||||
#define ETHTOOL_PRIO_NUM_LEVELS 1
|
||||
@ -224,6 +224,7 @@ static struct init_tree_node egress_root_fs = {
|
||||
|
||||
enum {
|
||||
RDMA_RX_IPSEC_PRIO,
|
||||
RDMA_RX_MACSEC_PRIO,
|
||||
RDMA_RX_COUNTERS_PRIO,
|
||||
RDMA_RX_BYPASS_PRIO,
|
||||
RDMA_RX_KERNEL_PRIO,
|
||||
@ -237,9 +238,13 @@ enum {
|
||||
#define RDMA_RX_KERNEL_MIN_LEVEL (RDMA_RX_BYPASS_MIN_LEVEL + 1)
|
||||
#define RDMA_RX_COUNTERS_MIN_LEVEL (RDMA_RX_KERNEL_MIN_LEVEL + 2)
|
||||
|
||||
#define RDMA_RX_MACSEC_NUM_PRIOS 1
|
||||
#define RDMA_RX_MACSEC_PRIO_NUM_LEVELS 2
|
||||
#define RDMA_RX_MACSEC_MIN_LEVEL (RDMA_RX_COUNTERS_MIN_LEVEL + RDMA_RX_MACSEC_NUM_PRIOS)
|
||||
|
||||
static struct init_tree_node rdma_rx_root_fs = {
|
||||
.type = FS_TYPE_NAMESPACE,
|
||||
.ar_size = 4,
|
||||
.ar_size = 5,
|
||||
.children = (struct init_tree_node[]) {
|
||||
[RDMA_RX_IPSEC_PRIO] =
|
||||
ADD_PRIO(0, RDMA_RX_IPSEC_MIN_LEVEL, 0,
|
||||
@ -247,6 +252,12 @@ static struct init_tree_node rdma_rx_root_fs = {
|
||||
ADD_NS(MLX5_FLOW_TABLE_MISS_ACTION_DEF,
|
||||
ADD_MULTIPLE_PRIO(RDMA_RX_IPSEC_NUM_PRIOS,
|
||||
RDMA_RX_IPSEC_NUM_LEVELS))),
|
||||
[RDMA_RX_MACSEC_PRIO] =
|
||||
ADD_PRIO(0, RDMA_RX_MACSEC_MIN_LEVEL, 0,
|
||||
FS_CHAINING_CAPS,
|
||||
ADD_NS(MLX5_FLOW_TABLE_MISS_ACTION_DEF,
|
||||
ADD_MULTIPLE_PRIO(RDMA_RX_MACSEC_NUM_PRIOS,
|
||||
RDMA_RX_MACSEC_PRIO_NUM_LEVELS))),
|
||||
[RDMA_RX_COUNTERS_PRIO] =
|
||||
ADD_PRIO(0, RDMA_RX_COUNTERS_MIN_LEVEL, 0,
|
||||
FS_CHAINING_CAPS,
|
||||
@ -270,6 +281,7 @@ static struct init_tree_node rdma_rx_root_fs = {
|
||||
enum {
|
||||
RDMA_TX_COUNTERS_PRIO,
|
||||
RDMA_TX_IPSEC_PRIO,
|
||||
RDMA_TX_MACSEC_PRIO,
|
||||
RDMA_TX_BYPASS_PRIO,
|
||||
};
|
||||
|
||||
@ -280,9 +292,13 @@ enum {
|
||||
#define RDMA_TX_IPSEC_PRIO_NUM_LEVELS 1
|
||||
#define RDMA_TX_IPSEC_MIN_LEVEL (RDMA_TX_COUNTERS_MIN_LEVEL + RDMA_TX_IPSEC_NUM_PRIOS)
|
||||
|
||||
#define RDMA_TX_MACSEC_NUM_PRIOS 1
|
||||
#define RDMA_TX_MACESC_PRIO_NUM_LEVELS 1
|
||||
#define RDMA_TX_MACSEC_MIN_LEVEL (RDMA_TX_COUNTERS_MIN_LEVEL + RDMA_TX_MACSEC_NUM_PRIOS)
|
||||
|
||||
static struct init_tree_node rdma_tx_root_fs = {
|
||||
.type = FS_TYPE_NAMESPACE,
|
||||
.ar_size = 3,
|
||||
.ar_size = 4,
|
||||
.children = (struct init_tree_node[]) {
|
||||
[RDMA_TX_COUNTERS_PRIO] =
|
||||
ADD_PRIO(0, RDMA_TX_COUNTERS_MIN_LEVEL, 0,
|
||||
@ -296,7 +312,12 @@ static struct init_tree_node rdma_tx_root_fs = {
|
||||
ADD_NS(MLX5_FLOW_TABLE_MISS_ACTION_DEF,
|
||||
ADD_MULTIPLE_PRIO(RDMA_TX_IPSEC_NUM_PRIOS,
|
||||
RDMA_TX_IPSEC_PRIO_NUM_LEVELS))),
|
||||
|
||||
[RDMA_TX_MACSEC_PRIO] =
|
||||
ADD_PRIO(0, RDMA_TX_MACSEC_MIN_LEVEL, 0,
|
||||
FS_CHAINING_CAPS,
|
||||
ADD_NS(MLX5_FLOW_TABLE_MISS_ACTION_DEF,
|
||||
ADD_MULTIPLE_PRIO(RDMA_TX_MACSEC_NUM_PRIOS,
|
||||
RDMA_TX_MACESC_PRIO_NUM_LEVELS))),
|
||||
[RDMA_TX_BYPASS_PRIO] =
|
||||
ADD_PRIO(0, RDMA_TX_BYPASS_MIN_LEVEL, 0,
|
||||
FS_CHAINING_CAPS_RDMA_TX,
|
||||
@ -2466,6 +2487,14 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
|
||||
root_ns = steering->rdma_tx_root_ns;
|
||||
prio = RDMA_TX_IPSEC_PRIO;
|
||||
break;
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_RX_MACSEC:
|
||||
root_ns = steering->rdma_rx_root_ns;
|
||||
prio = RDMA_RX_MACSEC_PRIO;
|
||||
break;
|
||||
case MLX5_FLOW_NAMESPACE_RDMA_TX_MACSEC:
|
||||
root_ns = steering->rdma_tx_root_ns;
|
||||
prio = RDMA_TX_MACSEC_PRIO;
|
||||
break;
|
||||
default: /* Must be NIC RX */
|
||||
WARN_ON(!is_nic_rx_ns(type));
|
||||
root_ns = steering->root_ns;
|
||||
|
2410
drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c
Normal file
2410
drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c
Normal file
File diff suppressed because it is too large
Load Diff
64
drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.h
Normal file
64
drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||
|
||||
#ifndef __MLX5_MACSEC_STEERING_H__
|
||||
#define __MLX5_MACSEC_STEERING_H__
|
||||
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
|
||||
/* Bit31 - 30: MACsec marker, Bit15-0: MACsec id */
|
||||
#define MLX5_MACEC_RX_FS_ID_MAX USHRT_MAX /* Must be power of two */
|
||||
#define MLX5_MACSEC_RX_FS_ID_MASK MLX5_MACEC_RX_FS_ID_MAX
|
||||
#define MLX5_MACSEC_METADATA_MARKER(metadata) ((((metadata) >> 30) & 0x3) == 0x1)
|
||||
#define MLX5_MACSEC_RX_METADAT_HANDLE(metadata) ((metadata) & MLX5_MACSEC_RX_FS_ID_MASK)
|
||||
|
||||
#define MLX5_MACSEC_NUM_OF_SUPPORTED_INTERFACES 16
|
||||
|
||||
struct mlx5_macsec_fs;
|
||||
union mlx5_macsec_rule;
|
||||
|
||||
struct mlx5_macsec_rule_attrs {
|
||||
sci_t sci;
|
||||
u32 macsec_obj_id;
|
||||
u8 assoc_num;
|
||||
int action;
|
||||
};
|
||||
|
||||
struct mlx5_macsec_stats {
|
||||
u64 macsec_rx_pkts;
|
||||
u64 macsec_rx_bytes;
|
||||
u64 macsec_rx_pkts_drop;
|
||||
u64 macsec_rx_bytes_drop;
|
||||
u64 macsec_tx_pkts;
|
||||
u64 macsec_tx_bytes;
|
||||
u64 macsec_tx_pkts_drop;
|
||||
u64 macsec_tx_bytes_drop;
|
||||
};
|
||||
|
||||
enum mlx5_macsec_action {
|
||||
MLX5_ACCEL_MACSEC_ACTION_ENCRYPT,
|
||||
MLX5_ACCEL_MACSEC_ACTION_DECRYPT,
|
||||
};
|
||||
|
||||
void mlx5_macsec_fs_cleanup(struct mlx5_macsec_fs *macsec_fs);
|
||||
|
||||
struct mlx5_macsec_fs *
|
||||
mlx5_macsec_fs_init(struct mlx5_core_dev *mdev);
|
||||
|
||||
union mlx5_macsec_rule *
|
||||
mlx5_macsec_fs_add_rule(struct mlx5_macsec_fs *macsec_fs,
|
||||
const struct macsec_context *ctx,
|
||||
struct mlx5_macsec_rule_attrs *attrs,
|
||||
u32 *sa_fs_id);
|
||||
|
||||
void mlx5_macsec_fs_del_rule(struct mlx5_macsec_fs *macsec_fs,
|
||||
union mlx5_macsec_rule *macsec_rule,
|
||||
int action, void *macdev, u32 sa_fs_id);
|
||||
|
||||
void mlx5_macsec_fs_get_stats_fill(struct mlx5_macsec_fs *macsec_fs, void *macsec_stats);
|
||||
struct mlx5_macsec_stats *mlx5_macsec_fs_get_stats(struct mlx5_macsec_fs *macsec_fs);
|
||||
u32 mlx5_macsec_fs_get_fs_id_from_hashtable(struct mlx5_macsec_fs *macsec_fs, sci_t *sci);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __MLX5_MACSEC_STEERING_H__ */
|
@ -4229,6 +4229,18 @@ static struct net *macsec_get_link_net(const struct net_device *dev)
|
||||
return dev_net(macsec_priv(dev)->real_dev);
|
||||
}
|
||||
|
||||
struct net_device *macsec_get_real_dev(const struct net_device *dev)
|
||||
{
|
||||
return macsec_priv(dev)->real_dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(macsec_get_real_dev);
|
||||
|
||||
bool macsec_netdev_is_offloaded(struct net_device *dev)
|
||||
{
|
||||
return macsec_is_offloaded(macsec_priv(dev));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(macsec_netdev_is_offloaded);
|
||||
|
||||
static size_t macsec_get_size(const struct net_device *dev)
|
||||
{
|
||||
return nla_total_size_64bit(8) + /* IFLA_MACSEC_SCI */
|
||||
|
@ -364,6 +364,8 @@ enum mlx5_event {
|
||||
enum mlx5_driver_event {
|
||||
MLX5_DRIVER_EVENT_TYPE_TRAP = 0,
|
||||
MLX5_DRIVER_EVENT_UPLINK_NETDEV,
|
||||
MLX5_DRIVER_EVENT_MACSEC_SA_ADDED,
|
||||
MLX5_DRIVER_EVENT_MACSEC_SA_DELETED,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -727,7 +727,6 @@ struct mlx5_fw_tracer;
|
||||
struct mlx5_vxlan;
|
||||
struct mlx5_geneve;
|
||||
struct mlx5_hv_vhca;
|
||||
struct mlx5_thermal;
|
||||
|
||||
#define MLX5_LOG_SW_ICM_BLOCK_SIZE(dev) (MLX5_CAP_DEV_MEM(dev, log_sw_icm_alloc_granularity))
|
||||
#define MLX5_SW_ICM_BLOCK_SIZE(dev) (1 << MLX5_LOG_SW_ICM_BLOCK_SIZE(dev))
|
||||
@ -809,6 +808,11 @@ struct mlx5_core_dev {
|
||||
struct mlx5_hwmon *hwmon;
|
||||
u64 num_block_tc;
|
||||
u64 num_block_ipsec;
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_macsec_fs *macsec_fs;
|
||||
/* MACsec notifier chain to sync MACsec core and IB database */
|
||||
struct blocking_notifier_head macsec_nh;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mlx5_db {
|
||||
@ -1322,6 +1326,52 @@ static inline bool mlx5_get_roce_state(struct mlx5_core_dev *dev)
|
||||
return mlx5_is_roce_on(dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
static inline bool mlx5e_is_macsec_device(const struct mlx5_core_dev *mdev)
|
||||
{
|
||||
if (!(MLX5_CAP_GEN_64(mdev, general_obj_types) &
|
||||
MLX5_GENERAL_OBJ_TYPES_CAP_MACSEC_OFFLOAD))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_GEN(mdev, log_max_dek))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, log_max_macsec_offload))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_RX(mdev, macsec_decrypt) ||
|
||||
!MLX5_CAP_FLOWTABLE_NIC_RX(mdev, reformat_remove_macsec))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, macsec_encrypt) ||
|
||||
!MLX5_CAP_FLOWTABLE_NIC_TX(mdev, reformat_add_macsec))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_encrypt) &&
|
||||
!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_encrypt))
|
||||
return false;
|
||||
|
||||
if (!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_128_decrypt) &&
|
||||
!MLX5_CAP_MACSEC(mdev, macsec_crypto_esp_aes_gcm_256_decrypt))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define NIC_RDMA_BOTH_DIRS_CAPS (MLX5_FT_NIC_RX_2_NIC_RX_RDMA | MLX5_FT_NIC_TX_RDMA_2_NIC_TX)
|
||||
|
||||
static inline bool mlx5_is_macsec_roce_supported(struct mlx5_core_dev *mdev)
|
||||
{
|
||||
if (((MLX5_CAP_GEN_2(mdev, flow_table_type_2_type) &
|
||||
NIC_RDMA_BOTH_DIRS_CAPS) != NIC_RDMA_BOTH_DIRS_CAPS) ||
|
||||
!MLX5_CAP_FLOWTABLE_RDMA_TX(mdev, max_modify_header_actions) ||
|
||||
!mlx5e_is_macsec_device(mdev) || !mdev->macsec_fs)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
MLX5_OCTWORD = 16,
|
||||
};
|
||||
|
@ -105,6 +105,8 @@ enum mlx5_flow_namespace_type {
|
||||
MLX5_FLOW_NAMESPACE_RDMA_TX_COUNTERS,
|
||||
MLX5_FLOW_NAMESPACE_RDMA_RX_IPSEC,
|
||||
MLX5_FLOW_NAMESPACE_RDMA_TX_IPSEC,
|
||||
MLX5_FLOW_NAMESPACE_RDMA_RX_MACSEC,
|
||||
MLX5_FLOW_NAMESPACE_RDMA_TX_MACSEC,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
32
include/linux/mlx5/macsec.h
Normal file
32
include/linux/mlx5/macsec.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
|
||||
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
|
||||
|
||||
#ifndef MLX5_MACSEC_H
|
||||
#define MLX5_MACSEC_H
|
||||
|
||||
#ifdef CONFIG_MLX5_MACSEC
|
||||
struct mlx5_macsec_event_data {
|
||||
struct mlx5_macsec_fs *macsec_fs;
|
||||
void *macdev;
|
||||
u32 fs_id;
|
||||
bool is_tx;
|
||||
};
|
||||
|
||||
int mlx5_macsec_add_roce_rule(void *macdev, const struct sockaddr *addr, u16 gid_idx,
|
||||
struct list_head *tx_rules_list, struct list_head *rx_rules_list,
|
||||
struct mlx5_macsec_fs *macsec_fs);
|
||||
|
||||
void mlx5_macsec_del_roce_rule(u16 gid_idx, struct mlx5_macsec_fs *macsec_fs,
|
||||
struct list_head *tx_rules_list, struct list_head *rx_rules_list);
|
||||
|
||||
void mlx5_macsec_add_roce_sa_rules(u32 fs_id, const struct sockaddr *addr, u16 gid_idx,
|
||||
struct list_head *tx_rules_list,
|
||||
struct list_head *rx_rules_list,
|
||||
struct mlx5_macsec_fs *macsec_fs, bool is_tx);
|
||||
|
||||
void mlx5_macsec_del_roce_sa_rules(u32 fs_id, struct mlx5_macsec_fs *macsec_fs,
|
||||
struct list_head *tx_rules_list,
|
||||
struct list_head *rx_rules_list, bool is_tx);
|
||||
|
||||
#endif
|
||||
#endif /* MLX5_MACSEC_H */
|
@ -312,6 +312,8 @@ static inline bool macsec_send_sci(const struct macsec_secy *secy)
|
||||
return tx_sc->send_sci ||
|
||||
(secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb);
|
||||
}
|
||||
struct net_device *macsec_get_real_dev(const struct net_device *dev);
|
||||
bool macsec_netdev_is_offloaded(struct net_device *dev);
|
||||
|
||||
static inline void *macsec_netdev_priv(const struct net_device *dev)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user