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"
21 #define _htonl __builtin_bswap32
22 #define ERROR(ret) do {\
23 char fmt[] = "ERROR line:%d ret:%d\n";\
24 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
34 u8 opt_data
[8]; /* hard-coded to 8 byte */
37 struct vxlan_metadata
{
42 int _gre_set_tunnel(struct __sk_buff
*skb
)
45 struct bpf_tunnel_key key
;
47 __builtin_memset(&key
, 0x0, sizeof(key
));
48 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
53 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_ZERO_CSUM_TX
);
63 int _gre_get_tunnel(struct __sk_buff
*skb
)
66 struct bpf_tunnel_key key
;
67 char fmt
[] = "key %d remote ip 0x%x\n";
69 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
75 bpf_trace_printk(fmt
, sizeof(fmt
), key
.tunnel_id
, key
.remote_ipv4
);
79 SEC("vxlan_set_tunnel")
80 int _vxlan_set_tunnel(struct __sk_buff
*skb
)
83 struct bpf_tunnel_key key
;
84 struct vxlan_metadata md
;
86 __builtin_memset(&key
, 0x0, sizeof(key
));
87 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
92 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_ZERO_CSUM_TX
);
98 md
.gbp
= 0x800FF; /* Set VXLAN Group Policy extension */
99 ret
= bpf_skb_set_tunnel_opt(skb
, &md
, sizeof(md
));
108 SEC("vxlan_get_tunnel")
109 int _vxlan_get_tunnel(struct __sk_buff
*skb
)
112 struct bpf_tunnel_key key
;
113 struct vxlan_metadata md
;
114 char fmt
[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
116 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
122 ret
= bpf_skb_get_tunnel_opt(skb
, &md
, sizeof(md
));
128 bpf_trace_printk(fmt
, sizeof(fmt
),
129 key
.tunnel_id
, key
.remote_ipv4
, md
.gbp
);
134 SEC("geneve_set_tunnel")
135 int _geneve_set_tunnel(struct __sk_buff
*skb
)
138 struct bpf_tunnel_key key
;
139 struct geneve_opt gopt
;
141 __builtin_memset(&key
, 0x0, sizeof(key
));
142 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
147 __builtin_memset(&gopt
, 0x0, sizeof(gopt
));
148 gopt
.opt_class
= 0x102; /* Open Virtual Networking (OVN) */
153 gopt
.length
= 2; /* 4-byte multiple */
154 *(int *) &gopt
.opt_data
= 0xdeadbeef;
156 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_ZERO_CSUM_TX
);
162 ret
= bpf_skb_set_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
171 SEC("geneve_get_tunnel")
172 int _geneve_get_tunnel(struct __sk_buff
*skb
)
175 struct bpf_tunnel_key key
;
176 struct geneve_opt gopt
;
177 char fmt
[] = "key %d remote ip 0x%x geneve class 0x%x\n";
179 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
185 ret
= bpf_skb_get_tunnel_opt(skb
, &gopt
, sizeof(gopt
));
191 bpf_trace_printk(fmt
, sizeof(fmt
),
192 key
.tunnel_id
, key
.remote_ipv4
, gopt
.opt_class
);
196 SEC("ipip_set_tunnel")
197 int _ipip_set_tunnel(struct __sk_buff
*skb
)
199 struct bpf_tunnel_key key
= {};
200 void *data
= (void *)(long)skb
->data
;
201 struct iphdr
*iph
= data
;
202 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
203 void *data_end
= (void *)(long)skb
->data_end
;
206 /* single length check */
207 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
213 if (iph
->protocol
== IPPROTO_ICMP
) {
214 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
216 if (iph
->protocol
!= IPPROTO_TCP
|| iph
->ihl
!= 5)
219 if (tcp
->dest
== htons(5200))
220 key
.remote_ipv4
= 0xac100164; /* 172.16.1.100 */
221 else if (tcp
->dest
== htons(5201))
222 key
.remote_ipv4
= 0xac100165; /* 172.16.1.101 */
227 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), 0);
236 SEC("ipip_get_tunnel")
237 int _ipip_get_tunnel(struct __sk_buff
*skb
)
240 struct bpf_tunnel_key key
;
241 char fmt
[] = "remote ip 0x%x\n";
243 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), 0);
249 bpf_trace_printk(fmt
, sizeof(fmt
), key
.remote_ipv4
);
253 SEC("ipip6_set_tunnel")
254 int _ipip6_set_tunnel(struct __sk_buff
*skb
)
256 struct bpf_tunnel_key key
= {};
257 void *data
= (void *)(long)skb
->data
;
258 struct iphdr
*iph
= data
;
259 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
260 void *data_end
= (void *)(long)skb
->data_end
;
263 /* single length check */
264 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
269 key
.remote_ipv6
[0] = _htonl(0x2401db00);
272 if (iph
->protocol
== IPPROTO_ICMP
) {
273 key
.remote_ipv6
[3] = _htonl(1);
275 if (iph
->protocol
!= IPPROTO_TCP
|| iph
->ihl
!= 5) {
276 ERROR(iph
->protocol
);
280 if (tcp
->dest
== htons(5200)) {
281 key
.remote_ipv6
[3] = _htonl(1);
282 } else if (tcp
->dest
== htons(5201)) {
283 key
.remote_ipv6
[3] = _htonl(2);
290 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_TUNINFO_IPV6
);
299 SEC("ipip6_get_tunnel")
300 int _ipip6_get_tunnel(struct __sk_buff
*skb
)
303 struct bpf_tunnel_key key
;
304 char fmt
[] = "remote ip6 %x::%x\n";
306 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_TUNINFO_IPV6
);
312 bpf_trace_printk(fmt
, sizeof(fmt
), _htonl(key
.remote_ipv6
[0]),
313 _htonl(key
.remote_ipv6
[3]));
317 SEC("ip6ip6_set_tunnel")
318 int _ip6ip6_set_tunnel(struct __sk_buff
*skb
)
320 struct bpf_tunnel_key key
= {};
321 void *data
= (void *)(long)skb
->data
;
322 struct ipv6hdr
*iph
= data
;
323 struct tcphdr
*tcp
= data
+ sizeof(*iph
);
324 void *data_end
= (void *)(long)skb
->data_end
;
327 /* single length check */
328 if (data
+ sizeof(*iph
) + sizeof(*tcp
) > data_end
) {
333 key
.remote_ipv6
[0] = _htonl(0x2401db00);
336 if (iph
->nexthdr
== NEXTHDR_ICMP
) {
337 key
.remote_ipv6
[3] = _htonl(1);
339 if (iph
->nexthdr
!= NEXTHDR_TCP
) {
344 if (tcp
->dest
== htons(5200)) {
345 key
.remote_ipv6
[3] = _htonl(1);
346 } else if (tcp
->dest
== htons(5201)) {
347 key
.remote_ipv6
[3] = _htonl(2);
354 ret
= bpf_skb_set_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_TUNINFO_IPV6
);
363 SEC("ip6ip6_get_tunnel")
364 int _ip6ip6_get_tunnel(struct __sk_buff
*skb
)
367 struct bpf_tunnel_key key
;
368 char fmt
[] = "remote ip6 %x::%x\n";
370 ret
= bpf_skb_get_tunnel_key(skb
, &key
, sizeof(key
), BPF_F_TUNINFO_IPV6
);
376 bpf_trace_printk(fmt
, sizeof(fmt
), _htonl(key
.remote_ipv6
[0]),
377 _htonl(key
.remote_ipv6
[3]));
382 char _license
[] SEC("license") = "GPL";