FILE
smc_hs_bpf.c
File preview with syntax highlighting.
linux-6.19.14/net/smc/smc_hs_bpf.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.