xref: /f-stack/dpdk/drivers/net/tap/tap_bpf_api.c (revision d30ea906)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017 Mellanox Technologies, Ltd
3  */
4 
5 #include <errno.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/queue.h>
9 
10 #include <rte_malloc.h>
11 #include <rte_eth_tap.h>
12 #include <tap_flow.h>
13 #include <tap_autoconf.h>
14 #include <tap_tcmsgs.h>
15 #include <tap_bpf.h>
16 #include <tap_bpf_insns.h>
17 
18 /**
19  * Load BPF program (section cls_q) into the kernel and return a bpf fd
20  *
21  * @param queue_idx
22  *   Queue index matching packet cb
23  *
24  * @return
25  *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
26  */
tap_flow_bpf_cls_q(__u32 queue_idx)27 int tap_flow_bpf_cls_q(__u32 queue_idx)
28 {
29 	cls_q_insns[1].imm = queue_idx;
30 
31 	return bpf_load(BPF_PROG_TYPE_SCHED_CLS,
32 		(struct bpf_insn *)cls_q_insns,
33 		RTE_DIM(cls_q_insns),
34 		"Dual BSD/GPL");
35 }
36 
37 /**
38  * Load BPF program (section l3_l4) into the kernel and return a bpf fd.
39  *
40  * @param[in] key_idx
41  *   RSS MAP key index
42  *
43  * @param[in] map_fd
44  *   BPF RSS map file descriptor
45  *
46  * @return
47  *   -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
48  */
tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx,int map_fd)49 int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
50 {
51 	l3_l4_hash_insns[4].imm = key_idx;
52 	l3_l4_hash_insns[9].imm = map_fd;
53 
54 	return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
55 		(struct bpf_insn *)l3_l4_hash_insns,
56 		RTE_DIM(l3_l4_hash_insns),
57 		"Dual BSD/GPL");
58 }
59 
60 /**
61  * Helper function to convert a pointer to unsigned 64 bits
62  *
63  * @param[in] ptr
64  *   pointer to address
65  *
66  * @return
67  *   64 bit unsigned long type of pointer address
68  */
ptr_to_u64(const void * ptr)69 static inline __u64 ptr_to_u64(const void *ptr)
70 {
71 	return (__u64)(unsigned long)ptr;
72 }
73 
74 /**
75  * Call BPF system call
76  *
77  * @param[in] cmd
78  *   BPF command for program loading, map creation, map entry update, etc
79  *
80  * @param[in] attr
81  *   System call attributes relevant to system call command
82  *
83  * @param[in] size
84  *   size of attr parameter
85  *
86  * @return
87  *   -1 if BPF system call failed, 0 otherwise
88  */
sys_bpf(enum bpf_cmd cmd,union bpf_attr * attr,unsigned int size)89 static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
90 			unsigned int size)
91 {
92 	return syscall(__NR_bpf, cmd, attr, size);
93 }
94 
95 /**
96  * Load BPF instructions to kernel
97  *
98  * @param[in] type
99  *   BPF program type: classifieir or action
100  *
101  * @param[in] insns
102  *   Array of BPF instructions (equivalent to BPF instructions)
103  *
104  * @param[in] insns_cnt
105  *   Number of BPF instructions (size of array)
106  *
107  * @param[in] lincense
108  *   License string that must be acknowledged by the kernel
109  *
110  * @return
111  *   -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise
112  */
bpf_load(enum bpf_prog_type type,const struct bpf_insn * insns,size_t insns_cnt,const char * license)113 static int bpf_load(enum bpf_prog_type type,
114 		  const struct bpf_insn *insns,
115 		  size_t insns_cnt,
116 		  const char *license)
117 {
118 	union bpf_attr attr = {};
119 
120 	bzero(&attr, sizeof(attr));
121 	attr.prog_type = type;
122 	attr.insn_cnt = (__u32)insns_cnt;
123 	attr.insns = ptr_to_u64(insns);
124 	attr.license = ptr_to_u64(license);
125 	attr.log_buf = ptr_to_u64(NULL);
126 	attr.log_level = 0;
127 	attr.kern_version = 0;
128 
129 	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
130 }
131 
132 /**
133  * Create BPF map for RSS rules
134  *
135  * @param[in] key_size
136  *   map RSS key size
137  *
138  * @param[in] value_size
139  *   Map RSS value size
140  *
141  * @param[in] max_entries
142  *   Map max number of RSS entries (limit on max RSS rules)
143  *
144  * @return
145  *   -1 if BPF map couldn't be created, map fd otherwise
146  */
tap_flow_bpf_rss_map_create(unsigned int key_size,unsigned int value_size,unsigned int max_entries)147 int tap_flow_bpf_rss_map_create(unsigned int key_size,
148 		unsigned int value_size,
149 		unsigned int max_entries)
150 {
151 	union bpf_attr attr = {};
152 
153 	bzero(&attr, sizeof(attr));
154 	attr.map_type    = BPF_MAP_TYPE_HASH;
155 	attr.key_size    = key_size;
156 	attr.value_size  = value_size;
157 	attr.max_entries = max_entries;
158 
159 	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
160 }
161 
162 /**
163  * Update RSS entry in BPF map
164  *
165  * @param[in] fd
166  *   RSS map fd
167  *
168  * @param[in] key
169  *   Pointer to RSS key whose entry is updated
170  *
171  * @param[in] value
172  *   Pointer to RSS new updated value
173  *
174  * @return
175  *   -1 if RSS entry failed to be updated, 0 otherwise
176  */
tap_flow_bpf_update_rss_elem(int fd,void * key,void * value)177 int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value)
178 {
179 	union bpf_attr attr = {};
180 
181 	bzero(&attr, sizeof(attr));
182 
183 	attr.map_type = BPF_MAP_TYPE_HASH;
184 	attr.map_fd = fd;
185 	attr.key = ptr_to_u64(key);
186 	attr.value = ptr_to_u64(value);
187 	attr.flags = BPF_ANY;
188 
189 	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
190 }
191