1 /* Copyright (c) 2016 VMware
2 * Copyright (c) 2016 Facebook
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.
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>
19 #include "bpf_helpers.h"
20 #include "bpf_endian.h"
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); \
35 u8 opt_data[8]; /* hard-coded to 8 byte */
38 struct vxlan_metadata {
42 struct erspan_metadata {
47 int _gre_set_tunnel(struct __sk_buff *skb)
50 struct bpf_tunnel_key key;
52 __builtin_memset(&key, 0x0, sizeof(key));
53 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
58 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
68 int _gre_get_tunnel(struct __sk_buff *skb)
71 struct bpf_tunnel_key key;
72 char fmt[] = "key %d remote ip 0x%x\n";
74 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
80 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
84 SEC("erspan_set_tunnel")
85 int _erspan_set_tunnel(struct __sk_buff *skb)
87 struct bpf_tunnel_key key;
88 struct erspan_metadata md;
91 __builtin_memset(&key, 0x0, sizeof(key));
92 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
97 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
103 md.index = htonl(123);
104 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
113 SEC("erspan_get_tunnel")
114 int _erspan_get_tunnel(struct __sk_buff *skb)
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;
122 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
128 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
134 index = bpf_ntohl(md.index);
135 bpf_trace_printk(fmt, sizeof(fmt),
136 key.tunnel_id, key.remote_ipv4, index);
141 SEC("vxlan_set_tunnel")
142 int _vxlan_set_tunnel(struct __sk_buff *skb)
145 struct bpf_tunnel_key key;
146 struct vxlan_metadata md;
148 __builtin_memset(&key, 0x0, sizeof(key));
149 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
154 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
160 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
161 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
170 SEC("vxlan_get_tunnel")
171 int _vxlan_get_tunnel(struct __sk_buff *skb)
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";
178 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
184 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
190 bpf_trace_printk(fmt, sizeof(fmt),
191 key.tunnel_id, key.remote_ipv4, md.gbp);
196 SEC("geneve_set_tunnel")
197 int _geneve_set_tunnel(struct __sk_buff *skb)
200 struct bpf_tunnel_key key;
201 struct geneve_opt gopt;
203 __builtin_memset(&key, 0x0, sizeof(key));
204 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
209 __builtin_memset(&gopt, 0x0, sizeof(gopt));
210 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
215 gopt.length = 2; /* 4-byte multiple */
216 *(int *) &gopt.opt_data = 0xdeadbeef;
218 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
224 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
233 SEC("geneve_get_tunnel")
234 int _geneve_get_tunnel(struct __sk_buff *skb)
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";
241 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
247 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
253 bpf_trace_printk(fmt, sizeof(fmt),
254 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
258 SEC("ipip_set_tunnel")
259 int _ipip_set_tunnel(struct __sk_buff *skb)
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;
268 /* single length check */
269 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
275 if (iph->protocol == IPPROTO_ICMP) {
276 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
278 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
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 */
289 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
298 SEC("ipip_get_tunnel")
299 int _ipip_get_tunnel(struct __sk_buff *skb)
302 struct bpf_tunnel_key key;
303 char fmt[] = "remote ip 0x%x\n";
305 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
311 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
315 SEC("ipip6_set_tunnel")
316 int _ipip6_set_tunnel(struct __sk_buff *skb)
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;
325 /* single length check */
326 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
331 key.remote_ipv6[0] = _htonl(0x2401db00);
334 if (iph->protocol == IPPROTO_ICMP) {
335 key.remote_ipv6[3] = _htonl(1);
337 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
338 ERROR(iph->protocol);
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);
352 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
361 SEC("ipip6_get_tunnel")
362 int _ipip6_get_tunnel(struct __sk_buff *skb)
365 struct bpf_tunnel_key key;
366 char fmt[] = "remote ip6 %x::%x\n";
368 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
374 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
375 _htonl(key.remote_ipv6[3]));
379 SEC("ip6ip6_set_tunnel")
380 int _ip6ip6_set_tunnel(struct __sk_buff *skb)
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;
389 /* single length check */
390 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
395 key.remote_ipv6[0] = _htonl(0x2401db00);
398 if (iph->nexthdr == NEXTHDR_ICMP) {
399 key.remote_ipv6[3] = _htonl(1);
401 if (iph->nexthdr != NEXTHDR_TCP) {
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);
416 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
425 SEC("ip6ip6_get_tunnel")
426 int _ip6ip6_get_tunnel(struct __sk_buff *skb)
429 struct bpf_tunnel_key key;
430 char fmt[] = "remote ip6 %x::%x\n";
432 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
438 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
439 _htonl(key.remote_ipv6[3]));
443 char _license[] SEC("license") = "GPL";