• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2016 VMware
2  * Copyright (c) 2016 Facebook
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  */
8 #define KBUILD_MODNAME "foo"
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>
13 #include <uapi/linux/ipv6.h>
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>
18 #include <net/ipv6.h>
19 #include "bpf_helpers.h"
20 #include "bpf_endian.h"
21 
22 #define _htonl __builtin_bswap32
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 
28 struct 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 
38 struct vxlan_metadata {
39 	u32     gbp;
40 };
41 
42 struct erspan_metadata {
43 	__be32 index;
44 };
45 
46 SEC("gre_set_tunnel")
_gre_set_tunnel(struct __sk_buff * skb)47 int _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 
67 SEC("gre_get_tunnel")
_gre_get_tunnel(struct __sk_buff * skb)68 int _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 
84 SEC("erspan_set_tunnel")
_erspan_set_tunnel(struct __sk_buff * skb)85 int _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 
113 SEC("erspan_get_tunnel")
_erspan_get_tunnel(struct __sk_buff * skb)114 int _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 
141 SEC("vxlan_set_tunnel")
_vxlan_set_tunnel(struct __sk_buff * skb)142 int _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 
170 SEC("vxlan_get_tunnel")
_vxlan_get_tunnel(struct __sk_buff * skb)171 int _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 
196 SEC("geneve_set_tunnel")
_geneve_set_tunnel(struct __sk_buff * skb)197 int _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;
212 	gopt.r1 = 0;
213 	gopt.r2 = 0;
214 	gopt.r3 = 0;
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 
233 SEC("geneve_get_tunnel")
_geneve_get_tunnel(struct __sk_buff * skb)234 int _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 
258 SEC("ipip_set_tunnel")
_ipip_set_tunnel(struct __sk_buff * skb)259 int _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 
298 SEC("ipip_get_tunnel")
_ipip_get_tunnel(struct __sk_buff * skb)299 int _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 
315 SEC("ipip6_set_tunnel")
_ipip6_set_tunnel(struct __sk_buff * skb)316 int _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 
361 SEC("ipip6_get_tunnel")
_ipip6_get_tunnel(struct __sk_buff * skb)362 int _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 
379 SEC("ip6ip6_set_tunnel")
_ip6ip6_set_tunnel(struct __sk_buff * skb)380 int _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 
425 SEC("ip6ip6_get_tunnel")
_ip6ip6_get_tunnel(struct __sk_buff * skb)426 int _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 
443 char _license[] SEC("license") = "GPL";
444