mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
RDMA v7.1 first rc window
- syzbot triggred crash in rxe due to concurrent plug/unplug - Possible non-zero'd memory exposed to userspace in bnxt_re - Malicous 'magic packet' with SIW causes a buffer overflow - Tighten the new uAPI validation code to not crash in debugging prints and have the right module dependencies in drivers - mana was missing the max_msg_sz report to userspace - UAF in rtrs on an error path -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRRRCHOFoQz/8F5bUaFwuHvBreFYQUCahDmpgAKCRCFwuHvBreF YRRTAP0YXV95Y5gcli55IhetKjJUzQbaREz2NueqIpf1IorMbAD+Lns4DgZCU0KW bC81x7cGHBSyCju9zogIdBFJhsbxeQ4= =MxJz -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma Pull rdma fixes from Jason Gunthorpe: - syzbot triggred crash in rxe due to concurrent plug/unplug - Possible non-zero'd memory exposed to userspace in bnxt_re - Malicous 'magic packet' with SIW causes a buffer overflow - Tighten the new uAPI validation code to not crash in debugging prints and have the right module dependencies in drivers - mana was missing the max_msg_sz report to userspace - UAF in rtrs on an error path * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: RDMA/rtrs: Fix use-after-free in path file creation cleanup RDMA/mana_ib: Report max_msg_sz in mana_ib_query_port RDMA/core: Do not read wild stack memory in uverbs_get_handler_fn() RDMA/core: Move the _ib_copy_validate_udata* functions to ib_core_uverbs RDMA/siw: Reject MPA FPDU length underflow before signed receive math RDMA/bnxt_re: zero shared page before exposing to userspace selftests/rdma: explicitly skip tests when required modules are missing RDMA/nldev: Add mutual exclusion in nldev_dellink()
This commit is contained in:
commit
ab868c1097
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/dma-resv.h>
|
||||
#include "uverbs.h"
|
||||
#include "core_priv.h"
|
||||
#include "rdma_core.h"
|
||||
|
||||
MODULE_IMPORT_NS("DMA_BUF");
|
||||
|
||||
|
|
@ -416,3 +417,89 @@ struct ib_device *rdma_udata_to_dev(struct ib_udata *udata)
|
|||
}
|
||||
EXPORT_SYMBOL(rdma_udata_to_dev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
|
||||
uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
|
||||
{
|
||||
struct uverbs_attr_bundle *bundle =
|
||||
rdma_udata_to_uverbs_attr_bundle(udata);
|
||||
|
||||
lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
|
||||
|
||||
return srcu_dereference(bundle->method_elm->handler,
|
||||
&bundle->ufile->device->disassociate_srcu);
|
||||
}
|
||||
|
||||
int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
|
||||
size_t kernel_size, size_t minimum_size)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (udata->inlen < minimum_size) {
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
|
||||
udata->inlen, minimum_size,
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = copy_struct_from_user(req, kernel_size, udata->inbuf,
|
||||
udata->inlen);
|
||||
if (err) {
|
||||
if (err == -E2BIG) {
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
|
||||
minimum_size, udata->inlen,
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_copy_validate_udata_in);
|
||||
|
||||
int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
|
||||
u64 valid_cm)
|
||||
{
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
|
||||
req_cm, valid_cm, req_cm & ~valid_cm,
|
||||
uverbs_get_handler_fn(udata), __builtin_return_address(0));
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
|
||||
|
||||
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
|
||||
{
|
||||
size_t copy_len;
|
||||
|
||||
/* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
|
||||
copy_len = min(len, udata->outlen);
|
||||
if (copy_to_user(udata->outbuf, src, copy_len))
|
||||
goto err_fault;
|
||||
if (copy_len < udata->outlen) {
|
||||
if (clear_user(udata->outbuf + copy_len,
|
||||
udata->outlen - copy_len))
|
||||
goto err_fault;
|
||||
}
|
||||
return 0;
|
||||
err_fault:
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
|
||||
len, udata->outlen, uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EFAULT;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_respond_udata);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
* a controlled QKEY.
|
||||
*/
|
||||
static bool privileged_qkey;
|
||||
static DEFINE_MUTEX(nldev_dellink_mutex);
|
||||
|
||||
typedef int (*res_fill_func_t)(struct sk_buff*, bool,
|
||||
struct rdma_restrack_entry*, uint32_t);
|
||||
|
|
@ -1846,7 +1847,9 @@ static int nldev_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
* implicitly scoped to the driver supporting dynamic link deletion like RXE.
|
||||
*/
|
||||
if (device->link_ops && device->link_ops->dellink) {
|
||||
mutex_lock(&nldev_dellink_mutex);
|
||||
err = device->link_ops->dellink(device);
|
||||
mutex_unlock(&nldev_dellink_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,6 +229,40 @@ int uverbs_dealloc_mw(struct ib_mw *mw);
|
|||
void ib_uverbs_detach_umcast(struct ib_qp *qp,
|
||||
struct ib_uqp_object *uobj);
|
||||
|
||||
struct bundle_alloc_head {
|
||||
struct_group_tagged(bundle_alloc_head_hdr, hdr,
|
||||
struct bundle_alloc_head *next;
|
||||
);
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
struct bundle_priv {
|
||||
/* Must be first */
|
||||
struct bundle_alloc_head_hdr alloc_head;
|
||||
struct bundle_alloc_head *allocated_mem;
|
||||
size_t internal_avail;
|
||||
size_t internal_used;
|
||||
|
||||
struct radix_tree_root *radix;
|
||||
void __rcu **radix_slots;
|
||||
unsigned long radix_slots_len;
|
||||
u32 method_key;
|
||||
|
||||
struct ib_uverbs_attr __user *user_attrs;
|
||||
struct ib_uverbs_attr *uattrs;
|
||||
|
||||
DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
|
||||
DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
|
||||
DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
|
||||
|
||||
/*
|
||||
* Must be last. bundle ends in a flex array which overlaps
|
||||
* internal_buffer.
|
||||
*/
|
||||
struct uverbs_attr_bundle_hdr bundle;
|
||||
u64 internal_buffer[32];
|
||||
};
|
||||
|
||||
long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
|
||||
struct ib_uverbs_flow_spec {
|
||||
|
|
|
|||
|
|
@ -35,54 +35,6 @@
|
|||
#include "rdma_core.h"
|
||||
#include "uverbs.h"
|
||||
|
||||
struct bundle_alloc_head {
|
||||
struct_group_tagged(bundle_alloc_head_hdr, hdr,
|
||||
struct bundle_alloc_head *next;
|
||||
);
|
||||
u8 data[];
|
||||
};
|
||||
|
||||
struct bundle_priv {
|
||||
/* Must be first */
|
||||
struct bundle_alloc_head_hdr alloc_head;
|
||||
struct bundle_alloc_head *allocated_mem;
|
||||
size_t internal_avail;
|
||||
size_t internal_used;
|
||||
|
||||
struct radix_tree_root *radix;
|
||||
const struct uverbs_api_ioctl_method *method_elm;
|
||||
void __rcu **radix_slots;
|
||||
unsigned long radix_slots_len;
|
||||
u32 method_key;
|
||||
|
||||
struct ib_uverbs_attr __user *user_attrs;
|
||||
struct ib_uverbs_attr *uattrs;
|
||||
|
||||
DECLARE_BITMAP(uobj_finalize, UVERBS_API_ATTR_BKEY_LEN);
|
||||
DECLARE_BITMAP(spec_finalize, UVERBS_API_ATTR_BKEY_LEN);
|
||||
DECLARE_BITMAP(uobj_hw_obj_valid, UVERBS_API_ATTR_BKEY_LEN);
|
||||
|
||||
/*
|
||||
* Must be last. bundle ends in a flex array which overlaps
|
||||
* internal_buffer.
|
||||
*/
|
||||
struct uverbs_attr_bundle_hdr bundle;
|
||||
u64 internal_buffer[32];
|
||||
};
|
||||
|
||||
uverbs_api_ioctl_handler_fn uverbs_get_handler_fn(struct ib_udata *udata)
|
||||
{
|
||||
struct uverbs_attr_bundle *bundle =
|
||||
rdma_udata_to_uverbs_attr_bundle(udata);
|
||||
struct bundle_priv *pbundle =
|
||||
container_of(&bundle->hdr, struct bundle_priv, bundle);
|
||||
|
||||
lockdep_assert_held(&bundle->ufile->device->disassociate_srcu);
|
||||
|
||||
return srcu_dereference(pbundle->method_elm->handler,
|
||||
&bundle->ufile->device->disassociate_srcu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Each method has an absolute minimum amount of memory it needs to allocate,
|
||||
* precompute that amount and determine if the onstack memory can be used or
|
||||
|
|
@ -445,13 +397,13 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
|
|||
struct uverbs_attr_bundle *bundle =
|
||||
container_of(&pbundle->bundle, struct uverbs_attr_bundle, hdr);
|
||||
size_t uattrs_size = array_size(sizeof(*pbundle->uattrs), num_attrs);
|
||||
unsigned int destroy_bkey = pbundle->method_elm->destroy_bkey;
|
||||
unsigned int destroy_bkey = bundle->method_elm->destroy_bkey;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* See uverbs_disassociate_api() */
|
||||
handler = srcu_dereference(
|
||||
pbundle->method_elm->handler,
|
||||
bundle->method_elm->handler,
|
||||
&pbundle->bundle.ufile->device->disassociate_srcu);
|
||||
if (!handler)
|
||||
return -EIO;
|
||||
|
|
@ -469,12 +421,12 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
|
|||
}
|
||||
|
||||
/* User space did not provide all the mandatory attributes */
|
||||
if (unlikely(!bitmap_subset(pbundle->method_elm->attr_mandatory,
|
||||
if (unlikely(!bitmap_subset(bundle->method_elm->attr_mandatory,
|
||||
pbundle->bundle.attr_present,
|
||||
pbundle->method_elm->key_bitmap_len)))
|
||||
bundle->method_elm->key_bitmap_len)))
|
||||
return -EINVAL;
|
||||
|
||||
if (pbundle->method_elm->has_udata)
|
||||
if (bundle->method_elm->has_udata)
|
||||
uverbs_fill_udata(bundle, &pbundle->bundle.driver_udata,
|
||||
UVERBS_ATTR_UHW_IN, UVERBS_ATTR_UHW_OUT);
|
||||
else
|
||||
|
|
@ -499,7 +451,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
|
|||
* assume that the driver wrote to its UHW_OUT and flag userspace
|
||||
* appropriately.
|
||||
*/
|
||||
if (!ret && pbundle->method_elm->has_udata) {
|
||||
if (!ret && bundle->method_elm->has_udata) {
|
||||
const struct uverbs_attr *attr =
|
||||
uverbs_attr_get(bundle, UVERBS_ATTR_UHW_OUT);
|
||||
|
||||
|
|
@ -520,7 +472,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
|
|||
|
||||
static void bundle_destroy(struct bundle_priv *pbundle, bool commit)
|
||||
{
|
||||
unsigned int key_bitmap_len = pbundle->method_elm->key_bitmap_len;
|
||||
unsigned int key_bitmap_len = pbundle->bundle.method_elm->key_bitmap_len;
|
||||
struct uverbs_attr_bundle *bundle =
|
||||
container_of(&pbundle->bundle, struct uverbs_attr_bundle, hdr);
|
||||
struct bundle_alloc_head *memblock;
|
||||
|
|
@ -608,7 +560,7 @@ static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
|
|||
}
|
||||
|
||||
/* Space for the pbundle->bundle.attrs flex array */
|
||||
pbundle->method_elm = method_elm;
|
||||
pbundle->bundle.method_elm = method_elm;
|
||||
pbundle->method_key = attrs_iter.index;
|
||||
pbundle->bundle.ufile = ufile;
|
||||
pbundle->bundle.context = NULL; /* only valid if bundle has uobject */
|
||||
|
|
@ -617,10 +569,12 @@ static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
|
|||
pbundle->radix_slots_len = radix_tree_chunk_size(&attrs_iter);
|
||||
pbundle->user_attrs = user_attrs;
|
||||
|
||||
pbundle->internal_used = ALIGN(pbundle->method_elm->key_bitmap_len *
|
||||
sizeof(*container_of(&pbundle->bundle,
|
||||
struct uverbs_attr_bundle, hdr)->attrs),
|
||||
sizeof(*pbundle->internal_buffer));
|
||||
pbundle->internal_used = ALIGN(
|
||||
pbundle->bundle.method_elm->key_bitmap_len *
|
||||
sizeof(*container_of(&pbundle->bundle,
|
||||
struct uverbs_attr_bundle, hdr)
|
||||
->attrs),
|
||||
sizeof(*pbundle->internal_buffer));
|
||||
memset(pbundle->bundle.attr_present, 0,
|
||||
sizeof(pbundle->bundle.attr_present));
|
||||
memset(pbundle->uobj_finalize, 0, sizeof(pbundle->uobj_finalize));
|
||||
|
|
@ -860,77 +814,3 @@ void uverbs_finalize_uobj_create(const struct uverbs_attr_bundle *bundle,
|
|||
pbundle->uobj_hw_obj_valid);
|
||||
}
|
||||
EXPORT_SYMBOL(uverbs_finalize_uobj_create);
|
||||
|
||||
int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
|
||||
size_t kernel_size, size_t minimum_size)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (udata->inlen < minimum_size) {
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata too small (%zu < %zu) for ioctl %ps called by %pSR\n",
|
||||
udata->inlen, minimum_size,
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = copy_struct_from_user(req, kernel_size, udata->inbuf,
|
||||
udata->inlen);
|
||||
if (err) {
|
||||
if (err == -E2BIG) {
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata not zero from %zu -> %zu for ioctl %ps called by %pSR\n",
|
||||
minimum_size, udata->inlen,
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata EFAULT for ioctl %ps called by %pSR\n",
|
||||
uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_copy_validate_udata_in);
|
||||
|
||||
int _ib_copy_validate_udata_cm_fail(struct ib_udata *udata, u64 req_cm,
|
||||
u64 valid_cm)
|
||||
{
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver input udata has unsupported comp_mask %llx & ~%llx = %llx for ioctl %ps called by %pSR\n",
|
||||
req_cm, valid_cm, req_cm & ~valid_cm,
|
||||
uverbs_get_handler_fn(udata), __builtin_return_address(0));
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_copy_validate_udata_cm_fail);
|
||||
|
||||
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len)
|
||||
{
|
||||
size_t copy_len;
|
||||
|
||||
/* 0 length copy_len is a NOP for copy_to_user() and doesn't fail. */
|
||||
copy_len = min(len, udata->outlen);
|
||||
if (copy_to_user(udata->outbuf, src, copy_len))
|
||||
goto err_fault;
|
||||
if (copy_len < udata->outlen) {
|
||||
if (clear_user(udata->outbuf + copy_len,
|
||||
udata->outlen - copy_len))
|
||||
goto err_fault;
|
||||
}
|
||||
return 0;
|
||||
err_fault:
|
||||
ibdev_dbg(
|
||||
rdma_udata_to_dev(udata),
|
||||
"System call driver out udata has EFAULT (%zu into %zu) for ioctl %ps called by %pSR\n",
|
||||
len, udata->outlen, uverbs_get_handler_fn(udata),
|
||||
__builtin_return_address(0));
|
||||
return -EFAULT;
|
||||
}
|
||||
EXPORT_SYMBOL(_ib_respond_udata);
|
||||
|
|
|
|||
|
|
@ -4638,7 +4638,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
|
|||
|
||||
uctx->rdev = rdev;
|
||||
|
||||
uctx->shpg = (void *)__get_free_page(GFP_KERNEL);
|
||||
uctx->shpg = (void *)get_zeroed_page(GFP_KERNEL);
|
||||
if (!uctx->shpg) {
|
||||
rc = -ENOMEM;
|
||||
goto fail;
|
||||
|
|
|
|||
|
|
@ -606,6 +606,7 @@ int mana_ib_query_port(struct ib_device *ibdev, u32 port,
|
|||
if (mana_ib_is_rnic(dev)) {
|
||||
props->gid_tbl_len = 16;
|
||||
props->ip_gids = true;
|
||||
props->max_msg_sz = SZ_16M;
|
||||
if (port == 1)
|
||||
props->port_cap_flags = IB_PORT_CM_SUP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,21 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
|
|||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Peer-controlled mpa_len must not underflow srx->fpdu_part_rem
|
||||
* in siw_tcp_rx_data(); a negative value flows as a signed copy
|
||||
* length into siw_check_mem() and skb_copy_bits().
|
||||
*/
|
||||
if (unlikely(be16_to_cpu(c_hdr->mpa_len) + MPA_HDR_SIZE <
|
||||
iwarp_pktinfo[opcode].hdr_len)) {
|
||||
pr_warn_ratelimited("siw: short mpa_len %u for opcode %u (hdr_len %u)\n",
|
||||
be16_to_cpu(c_hdr->mpa_len), opcode,
|
||||
iwarp_pktinfo[opcode].hdr_len);
|
||||
siw_init_terminate(rx_qp(srx), TERM_ERROR_LAYER_LLP,
|
||||
LLP_ETYPE_MPA, LLP_ECODE_FPDU_START, 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* DDP/RDMAP header receive completed. Check if the current
|
||||
* DDP segment starts a new RDMAP message or continues a previously
|
||||
|
|
|
|||
|
|
@ -295,8 +295,8 @@ int rtrs_srv_create_path_files(struct rtrs_srv_path *srv_path)
|
|||
put_kobj:
|
||||
kobject_del(&srv_path->kobj);
|
||||
destroy_root:
|
||||
kobject_put(&srv_path->kobj);
|
||||
rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
|
||||
kobject_put(&srv_path->kobj);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ struct uverbs_attr_bundle {
|
|||
struct ib_uverbs_file *ufile;
|
||||
struct ib_ucontext *context;
|
||||
struct ib_uobject *uobject;
|
||||
const struct uverbs_api_ioctl_method *method_elm;
|
||||
DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN);
|
||||
);
|
||||
struct uverbs_attr attrs[];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ RXE_NAME="rxe6"
|
|||
PORT=4791
|
||||
IP6_ADDR="2001:db8::1/64"
|
||||
|
||||
source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
|
||||
|
||||
exec > /dev/null
|
||||
|
||||
# Cleanup function to run on exit (even on failure)
|
||||
|
|
@ -21,8 +23,8 @@ trap cleanup EXIT
|
|||
# 1. Prerequisites check
|
||||
for mod in tun veth rdma_rxe; do
|
||||
if ! modinfo "$mod" >/dev/null 2>&1; then
|
||||
echo "Error: Kernel module '$mod' not found."
|
||||
exit 1
|
||||
echo "SKIP: Kernel module '$mod' not found." >&2
|
||||
exit $KSFT_SKIP
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ IP_A="1.1.1.1"
|
|||
IP_B="1.1.1.2"
|
||||
PORT=4791
|
||||
|
||||
source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
|
||||
|
||||
exec > /dev/null
|
||||
|
||||
# --- Cleanup Routine ---
|
||||
|
|
@ -27,6 +29,11 @@ if [[ $EUID -ne 0 ]]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if ! modinfo rdma_rxe >/dev/null 2>&1; then
|
||||
echo "SKIP: Kernel module 'rdma_rxe' not found." >&2
|
||||
exit $KSFT_SKIP
|
||||
fi
|
||||
|
||||
modprobe rdma_rxe || { echo "Failed to load rdma_rxe"; exit 1; }
|
||||
|
||||
# --- Setup Network Topology ---
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
PORT=4791
|
||||
MODS=("tun" "rdma_rxe")
|
||||
|
||||
source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
|
||||
|
||||
exec > /dev/null
|
||||
|
||||
# --- Helper: Cleanup Routine ---
|
||||
|
|
@ -26,6 +28,10 @@ if [[ $EUID -ne 0 ]]; then
|
|||
fi
|
||||
|
||||
for m in "${MODS[@]}"; do
|
||||
if ! modinfo "$m" >/dev/null 2>&1; then
|
||||
echo "SKIP: Kernel module '$m' not found." >&2
|
||||
exit $KSFT_SKIP
|
||||
fi
|
||||
modprobe "$m" || { echo "Error: Failed to load $m"; exit 1; }
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ DEV_NAME="tun0"
|
|||
RXE_NAME="rxe0"
|
||||
RDMA_PORT=4791
|
||||
|
||||
source "$(dirname "$0")/../kselftest/ktap_helpers.sh"
|
||||
|
||||
exec > /dev/null
|
||||
|
||||
# --- Cleanup Routine ---
|
||||
|
|
@ -19,8 +21,8 @@ trap cleanup EXIT
|
|||
|
||||
# 1. Dependency Check
|
||||
if ! modinfo rdma_rxe >/dev/null 2>&1; then
|
||||
echo "Error: rdma_rxe module not found."
|
||||
exit 1
|
||||
echo "SKIP: rdma_rxe module not found." >&2
|
||||
exit $KSFT_SKIP
|
||||
fi
|
||||
|
||||
modprobe rdma_rxe
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user