File Index
Files and directories
Sign in
FILE

smc_hs_bpf.c

File preview with syntax highlighting.

linux-6.19.14/net/smc/smc_hs_bpf.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
  4 *
  5 *  Generic hook for SMC handshake flow.
  6 *
  7 *  Copyright IBM Corp. 2016
  8 *  Copyright (c) 2025, Alibaba Inc.
  9 *
 10 *  Author: D. Wythe <alibuda@linux.alibaba.com>
 11 */
 12
 13#include <linux/bpf_verifier.h>
 14#include <linux/bpf.h>
 15#include <linux/btf.h>
 16#include <linux/rculist.h>
 17
 18#include "smc_hs_bpf.h"
 19
 20static DEFINE_SPINLOCK(smc_hs_ctrl_list_lock);
 21static LIST_HEAD(smc_hs_ctrl_list);
 22
 23static int smc_hs_ctrl_reg(struct smc_hs_ctrl *ctrl)
 24{
 25	int ret = 0;
 26
 27	spin_lock(&smc_hs_ctrl_list_lock);
 28	/* already exist or duplicate name */
 29	if (smc_hs_ctrl_find_by_name(ctrl->name))
 30		ret = -EEXIST;
 31	else
 32		list_add_tail_rcu(&ctrl->list, &smc_hs_ctrl_list);
 33	spin_unlock(&smc_hs_ctrl_list_lock);
 34	return ret;
 35}
 36
 37static void smc_hs_ctrl_unreg(struct smc_hs_ctrl *ctrl)
 38{
 39	spin_lock(&smc_hs_ctrl_list_lock);
 40	list_del_rcu(&ctrl->list);
 41	spin_unlock(&smc_hs_ctrl_list_lock);
 42
 43	/* Ensure that all readers to complete */
 44	synchronize_rcu();
 45}
 46
 47struct smc_hs_ctrl *smc_hs_ctrl_find_by_name(const char *name)
 48{
 49	struct smc_hs_ctrl *ctrl;
 50
 51	list_for_each_entry_rcu(ctrl, &smc_hs_ctrl_list, list) {
 52		if (strcmp(ctrl->name, name) == 0)
 53			return ctrl;
 54	}
 55	return NULL;
 56}
 57
 58static int __smc_bpf_stub_set_tcp_option(struct tcp_sock *tp) { return 1; }
 59static int __smc_bpf_stub_set_tcp_option_cond(const struct tcp_sock *tp,
 60					      struct inet_request_sock *ireq)
 61{
 62	return 1;
 63}
 64
 65static struct smc_hs_ctrl __smc_bpf_hs_ctrl = {
 66	.syn_option	= __smc_bpf_stub_set_tcp_option,
 67	.synack_option	= __smc_bpf_stub_set_tcp_option_cond,
 68};
 69
 70static int smc_bpf_hs_ctrl_init(struct btf *btf) { return 0; }
 71
 72static int smc_bpf_hs_ctrl_reg(void *kdata, struct bpf_link *link)
 73{
 74	if (link)
 75		return -EOPNOTSUPP;
 76
 77	return smc_hs_ctrl_reg(kdata);
 78}
 79
 80static void smc_bpf_hs_ctrl_unreg(void *kdata, struct bpf_link *link)
 81{
 82	smc_hs_ctrl_unreg(kdata);
 83}
 84
 85static int smc_bpf_hs_ctrl_init_member(const struct btf_type *t,
 86				       const struct btf_member *member,
 87				       void *kdata, const void *udata)
 88{
 89	const struct smc_hs_ctrl *u_ctrl;
 90	struct smc_hs_ctrl *k_ctrl;
 91	u32 moff;
 92
 93	u_ctrl = (const struct smc_hs_ctrl *)udata;
 94	k_ctrl = (struct smc_hs_ctrl *)kdata;
 95
 96	moff = __btf_member_bit_offset(t, member) / 8;
 97	switch (moff) {
 98	case offsetof(struct smc_hs_ctrl, name):
 99		if (bpf_obj_name_cpy(k_ctrl->name, u_ctrl->name,
100				     sizeof(u_ctrl->name)) <= 0)
101			return -EINVAL;
102		return 1;
103	case offsetof(struct smc_hs_ctrl, flags):
104		if (u_ctrl->flags & ~SMC_HS_CTRL_ALL_FLAGS)
105			return -EINVAL;
106		k_ctrl->flags = u_ctrl->flags;
107		return 1;
108	default:
109		break;
110	}
111
112	return 0;
113}
114
115static const struct bpf_func_proto *
116bpf_smc_hs_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
117{
118	return bpf_base_func_proto(func_id, prog);
119}
120
121static const struct bpf_verifier_ops smc_bpf_verifier_ops = {
122	.get_func_proto		= bpf_smc_hs_func_proto,
123	.is_valid_access	= bpf_tracing_btf_ctx_access,
124};
125
126static struct bpf_struct_ops bpf_smc_hs_ctrl_ops = {
127	.name		= "smc_hs_ctrl",
128	.init		= smc_bpf_hs_ctrl_init,
129	.reg		= smc_bpf_hs_ctrl_reg,
130	.unreg		= smc_bpf_hs_ctrl_unreg,
131	.cfi_stubs	= &__smc_bpf_hs_ctrl,
132	.verifier_ops	= &smc_bpf_verifier_ops,
133	.init_member	= smc_bpf_hs_ctrl_init_member,
134	.owner		= THIS_MODULE,
135};
136
137int bpf_smc_hs_ctrl_init(void)
138{
139	return register_bpf_struct_ops(&bpf_smc_hs_ctrl_ops, smc_hs_ctrl);
140}
~/ Read-only file preview.