]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - samples/bpf/tcbpf2_kern.c
kthread, sched/wait: Fix kthread_parkme() completion issue
[mirror_ubuntu-bionic-kernel.git] / samples / bpf / tcbpf2_kern.c
CommitLineData
6afb1e28 1/* Copyright (c) 2016 VMware
a1c82704 2 * Copyright (c) 2016 Facebook
6afb1e28
WT
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation.
7 */
96a8eb1e 8#define KBUILD_MODNAME "foo"
6afb1e28
WT
9#include <uapi/linux/bpf.h>
10#include <uapi/linux/if_ether.h>
11#include <uapi/linux/if_packet.h>
12#include <uapi/linux/ip.h>
173ca26e 13#include <uapi/linux/ipv6.h>
6afb1e28
WT
14#include <uapi/linux/in.h>
15#include <uapi/linux/tcp.h>
16#include <uapi/linux/filter.h>
17#include <uapi/linux/pkt_cls.h>
173ca26e 18#include <net/ipv6.h>
6afb1e28 19#include "bpf_helpers.h"
ef88f89c 20#include "bpf_endian.h"
6afb1e28 21
173ca26e 22#define _htonl __builtin_bswap32
6afb1e28
WT
23#define ERROR(ret) do {\
24 char fmt[] = "ERROR line:%d ret:%d\n";\
25 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
26 } while(0)
27
28struct geneve_opt {
29 __be16 opt_class;
30 u8 type;
31 u8 length:5;
32 u8 r3:1;
33 u8 r2:1;
34 u8 r1:1;
35 u8 opt_data[8]; /* hard-coded to 8 byte */
36};
37
38struct vxlan_metadata {
39 u32 gbp;
40};
41
ef88f89c
WT
42struct erspan_metadata {
43 __be32 index;
44};
45
6afb1e28
WT
46SEC("gre_set_tunnel")
47int _gre_set_tunnel(struct __sk_buff *skb)
48{
49 int ret;
50 struct bpf_tunnel_key key;
51
52 __builtin_memset(&key, 0x0, sizeof(key));
53 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
54 key.tunnel_id = 2;
55 key.tunnel_tos = 0;
56 key.tunnel_ttl = 64;
57
58 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
59 if (ret < 0) {
60 ERROR(ret);
61 return TC_ACT_SHOT;
62 }
63
64 return TC_ACT_OK;
65}
66
67SEC("gre_get_tunnel")
68int _gre_get_tunnel(struct __sk_buff *skb)
69{
70 int ret;
71 struct bpf_tunnel_key key;
72 char fmt[] = "key %d remote ip 0x%x\n";
73
74 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
75 if (ret < 0) {
76 ERROR(ret);
77 return TC_ACT_SHOT;
78 }
79
80 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
81 return TC_ACT_OK;
82}
83
ef88f89c
WT
84SEC("erspan_set_tunnel")
85int _erspan_set_tunnel(struct __sk_buff *skb)
86{
87 struct bpf_tunnel_key key;
88 struct erspan_metadata md;
89 int ret;
90
91 __builtin_memset(&key, 0x0, sizeof(key));
92 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
93 key.tunnel_id = 2;
94 key.tunnel_tos = 0;
95 key.tunnel_ttl = 64;
96
97 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
98 if (ret < 0) {
99 ERROR(ret);
100 return TC_ACT_SHOT;
101 }
102
103 md.index = htonl(123);
104 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
105 if (ret < 0) {
106 ERROR(ret);
107 return TC_ACT_SHOT;
108 }
109
110 return TC_ACT_OK;
111}
112
113SEC("erspan_get_tunnel")
114int _erspan_get_tunnel(struct __sk_buff *skb)
115{
116 char fmt[] = "key %d remote ip 0x%x erspan index 0x%x\n";
117 struct bpf_tunnel_key key;
118 struct erspan_metadata md;
119 u32 index;
120 int ret;
121
122 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
123 if (ret < 0) {
124 ERROR(ret);
125 return TC_ACT_SHOT;
126 }
127
128 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
129 if (ret < 0) {
130 ERROR(ret);
131 return TC_ACT_SHOT;
132 }
133
134 index = bpf_ntohl(md.index);
135 bpf_trace_printk(fmt, sizeof(fmt),
136 key.tunnel_id, key.remote_ipv4, index);
137
138 return TC_ACT_OK;
139}
140
6afb1e28
WT
141SEC("vxlan_set_tunnel")
142int _vxlan_set_tunnel(struct __sk_buff *skb)
143{
144 int ret;
145 struct bpf_tunnel_key key;
146 struct vxlan_metadata md;
147
148 __builtin_memset(&key, 0x0, sizeof(key));
149 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
150 key.tunnel_id = 2;
151 key.tunnel_tos = 0;
152 key.tunnel_ttl = 64;
153
154 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
155 if (ret < 0) {
156 ERROR(ret);
157 return TC_ACT_SHOT;
158 }
159
160 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
161 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
162 if (ret < 0) {
163 ERROR(ret);
164 return TC_ACT_SHOT;
165 }
166
167 return TC_ACT_OK;
168}
169
170SEC("vxlan_get_tunnel")
171int _vxlan_get_tunnel(struct __sk_buff *skb)
172{
173 int ret;
174 struct bpf_tunnel_key key;
175 struct vxlan_metadata md;
176 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
177
178 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
179 if (ret < 0) {
180 ERROR(ret);
181 return TC_ACT_SHOT;
182 }
183
184 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
185 if (ret < 0) {
186 ERROR(ret);
187 return TC_ACT_SHOT;
188 }
189
190 bpf_trace_printk(fmt, sizeof(fmt),
191 key.tunnel_id, key.remote_ipv4, md.gbp);
192
193 return TC_ACT_OK;
194}
195
196SEC("geneve_set_tunnel")
197int _geneve_set_tunnel(struct __sk_buff *skb)
198{
199 int ret, ret2;
200 struct bpf_tunnel_key key;
201 struct geneve_opt gopt;
202
203 __builtin_memset(&key, 0x0, sizeof(key));
204 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
205 key.tunnel_id = 2;
206 key.tunnel_tos = 0;
207 key.tunnel_ttl = 64;
208
209 __builtin_memset(&gopt, 0x0, sizeof(gopt));
210 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
211 gopt.type = 0x08;
cc75f851 212 gopt.r1 = 0;
6afb1e28 213 gopt.r2 = 0;
cc75f851 214 gopt.r3 = 0;
6afb1e28
WT
215 gopt.length = 2; /* 4-byte multiple */
216 *(int *) &gopt.opt_data = 0xdeadbeef;
217
218 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
219 if (ret < 0) {
220 ERROR(ret);
221 return TC_ACT_SHOT;
222 }
223
224 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
225 if (ret < 0) {
226 ERROR(ret);
227 return TC_ACT_SHOT;
228 }
229
230 return TC_ACT_OK;
231}
232
233SEC("geneve_get_tunnel")
234int _geneve_get_tunnel(struct __sk_buff *skb)
235{
236 int ret;
237 struct bpf_tunnel_key key;
238 struct geneve_opt gopt;
239 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
240
241 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
242 if (ret < 0) {
243 ERROR(ret);
244 return TC_ACT_SHOT;
245 }
246
247 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
248 if (ret < 0) {
249 ERROR(ret);
250 return TC_ACT_SHOT;
251 }
252
253 bpf_trace_printk(fmt, sizeof(fmt),
254 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
255 return TC_ACT_OK;
256}
257
a1c82704
AS
258SEC("ipip_set_tunnel")
259int _ipip_set_tunnel(struct __sk_buff *skb)
260{
261 struct bpf_tunnel_key key = {};
262 void *data = (void *)(long)skb->data;
263 struct iphdr *iph = data;
264 struct tcphdr *tcp = data + sizeof(*iph);
265 void *data_end = (void *)(long)skb->data_end;
266 int ret;
267
268 /* single length check */
269 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
270 ERROR(1);
271 return TC_ACT_SHOT;
272 }
273
274 key.tunnel_ttl = 64;
275 if (iph->protocol == IPPROTO_ICMP) {
276 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
277 } else {
278 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
279 return TC_ACT_SHOT;
280
281 if (tcp->dest == htons(5200))
282 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
283 else if (tcp->dest == htons(5201))
284 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
285 else
286 return TC_ACT_SHOT;
287 }
288
289 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
290 if (ret < 0) {
291 ERROR(ret);
292 return TC_ACT_SHOT;
293 }
294
295 return TC_ACT_OK;
296}
297
298SEC("ipip_get_tunnel")
299int _ipip_get_tunnel(struct __sk_buff *skb)
300{
301 int ret;
302 struct bpf_tunnel_key key;
303 char fmt[] = "remote ip 0x%x\n";
304
305 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
306 if (ret < 0) {
307 ERROR(ret);
308 return TC_ACT_SHOT;
309 }
310
311 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
312 return TC_ACT_OK;
313}
314
173ca26e
AS
315SEC("ipip6_set_tunnel")
316int _ipip6_set_tunnel(struct __sk_buff *skb)
317{
318 struct bpf_tunnel_key key = {};
319 void *data = (void *)(long)skb->data;
320 struct iphdr *iph = data;
321 struct tcphdr *tcp = data + sizeof(*iph);
322 void *data_end = (void *)(long)skb->data_end;
323 int ret;
324
325 /* single length check */
326 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
327 ERROR(1);
328 return TC_ACT_SHOT;
329 }
330
331 key.remote_ipv6[0] = _htonl(0x2401db00);
332 key.tunnel_ttl = 64;
333
334 if (iph->protocol == IPPROTO_ICMP) {
335 key.remote_ipv6[3] = _htonl(1);
336 } else {
337 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
338 ERROR(iph->protocol);
339 return TC_ACT_SHOT;
340 }
341
342 if (tcp->dest == htons(5200)) {
343 key.remote_ipv6[3] = _htonl(1);
344 } else if (tcp->dest == htons(5201)) {
345 key.remote_ipv6[3] = _htonl(2);
346 } else {
347 ERROR(tcp->dest);
348 return TC_ACT_SHOT;
349 }
350 }
351
352 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
353 if (ret < 0) {
354 ERROR(ret);
355 return TC_ACT_SHOT;
356 }
357
358 return TC_ACT_OK;
359}
360
361SEC("ipip6_get_tunnel")
362int _ipip6_get_tunnel(struct __sk_buff *skb)
363{
364 int ret;
365 struct bpf_tunnel_key key;
366 char fmt[] = "remote ip6 %x::%x\n";
367
368 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
369 if (ret < 0) {
370 ERROR(ret);
371 return TC_ACT_SHOT;
372 }
373
374 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
375 _htonl(key.remote_ipv6[3]));
376 return TC_ACT_OK;
377}
378
379SEC("ip6ip6_set_tunnel")
380int _ip6ip6_set_tunnel(struct __sk_buff *skb)
381{
382 struct bpf_tunnel_key key = {};
383 void *data = (void *)(long)skb->data;
384 struct ipv6hdr *iph = data;
385 struct tcphdr *tcp = data + sizeof(*iph);
386 void *data_end = (void *)(long)skb->data_end;
387 int ret;
388
389 /* single length check */
390 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
391 ERROR(1);
392 return TC_ACT_SHOT;
393 }
394
395 key.remote_ipv6[0] = _htonl(0x2401db00);
396 key.tunnel_ttl = 64;
397
398 if (iph->nexthdr == NEXTHDR_ICMP) {
399 key.remote_ipv6[3] = _htonl(1);
400 } else {
401 if (iph->nexthdr != NEXTHDR_TCP) {
402 ERROR(iph->nexthdr);
403 return TC_ACT_SHOT;
404 }
405
406 if (tcp->dest == htons(5200)) {
407 key.remote_ipv6[3] = _htonl(1);
408 } else if (tcp->dest == htons(5201)) {
409 key.remote_ipv6[3] = _htonl(2);
410 } else {
411 ERROR(tcp->dest);
412 return TC_ACT_SHOT;
413 }
414 }
415
416 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
417 if (ret < 0) {
418 ERROR(ret);
419 return TC_ACT_SHOT;
420 }
421
422 return TC_ACT_OK;
423}
424
425SEC("ip6ip6_get_tunnel")
426int _ip6ip6_get_tunnel(struct __sk_buff *skb)
427{
428 int ret;
429 struct bpf_tunnel_key key;
430 char fmt[] = "remote ip6 %x::%x\n";
431
432 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
433 if (ret < 0) {
434 ERROR(ret);
435 return TC_ACT_SHOT;
436 }
437
438 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
439 _htonl(key.remote_ipv6[3]));
440 return TC_ACT_OK;
441}
442
6afb1e28 443char _license[] SEC("license") = "GPL";