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";