Branch data Line data Source code
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 : : */
27 : 0 : int tap_flow_bpf_cls_q(__u32 queue_idx)
28 : : {
29 : 0 : cls_q_insns[1].imm = queue_idx;
30 : :
31 : 0 : 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 : : */
49 : 0 : int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd)
50 : : {
51 : 0 : l3_l4_hash_insns[4].imm = key_idx;
52 : 0 : l3_l4_hash_insns[9].imm = map_fd;
53 : :
54 : 0 : 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 : : */
69 : : static inline __u64 ptr_to_u64(const void *ptr)
70 : : {
71 : 0 : 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 : : */
89 : : static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
90 : : unsigned int size)
91 : : {
92 : 0 : 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: classifier 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] license
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 : : */
113 : 0 : 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 : 0 : attr.prog_type = type;
122 : 0 : attr.insn_cnt = (__u32)insns_cnt;
123 : 0 : attr.insns = ptr_to_u64(insns);
124 : 0 : 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 : 0 : 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 : : */
147 : 0 : 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 : 0 : attr.map_type = BPF_MAP_TYPE_HASH;
155 : 0 : attr.key_size = key_size;
156 : 0 : attr.value_size = value_size;
157 : 0 : attr.max_entries = max_entries;
158 : :
159 : 0 : 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 : : */
177 : 0 : 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 : 0 : attr.map_fd = fd;
185 : 0 : attr.key = ptr_to_u64(key);
186 : 0 : attr.value = ptr_to_u64(value);
187 : : attr.flags = BPF_ANY;
188 : :
189 : 0 : return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
190 : : }
|