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