blob: 3303bb85593bc62a21afcf4f2864869a40543b4d [file] [log] [blame]
William Tu6afb1e22016-08-19 11:55:44 -07001/* Copyright (c) 2016 VMware
Alexei Starovoitova1c82702016-09-15 13:00:31 -07002 * Copyright (c) 2016 Facebook
William Tu6afb1e22016-08-19 11:55:44 -07003 *
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#include <uapi/linux/bpf.h>
9#include <uapi/linux/if_ether.h>
10#include <uapi/linux/if_packet.h>
11#include <uapi/linux/ip.h>
Alexei Starovoitov173ca262016-09-15 13:00:32 -070012#include <uapi/linux/ipv6.h>
William Tu6afb1e22016-08-19 11:55:44 -070013#include <uapi/linux/in.h>
14#include <uapi/linux/tcp.h>
15#include <uapi/linux/filter.h>
16#include <uapi/linux/pkt_cls.h>
Alexei Starovoitov173ca262016-09-15 13:00:32 -070017#include <net/ipv6.h>
William Tu6afb1e22016-08-19 11:55:44 -070018#include "bpf_helpers.h"
19
Alexei Starovoitov173ca262016-09-15 13:00:32 -070020#define _htonl __builtin_bswap32
William Tu6afb1e22016-08-19 11:55:44 -070021#define ERROR(ret) do {\
22 char fmt[] = "ERROR line:%d ret:%d\n";\
23 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
24 } while(0)
25
26struct geneve_opt {
27 __be16 opt_class;
28 u8 type;
29 u8 length:5;
30 u8 r3:1;
31 u8 r2:1;
32 u8 r1:1;
33 u8 opt_data[8]; /* hard-coded to 8 byte */
34};
35
36struct vxlan_metadata {
37 u32 gbp;
38};
39
40SEC("gre_set_tunnel")
41int _gre_set_tunnel(struct __sk_buff *skb)
42{
43 int ret;
44 struct bpf_tunnel_key key;
45
46 __builtin_memset(&key, 0x0, sizeof(key));
47 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
48 key.tunnel_id = 2;
49 key.tunnel_tos = 0;
50 key.tunnel_ttl = 64;
51
52 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
53 if (ret < 0) {
54 ERROR(ret);
55 return TC_ACT_SHOT;
56 }
57
58 return TC_ACT_OK;
59}
60
61SEC("gre_get_tunnel")
62int _gre_get_tunnel(struct __sk_buff *skb)
63{
64 int ret;
65 struct bpf_tunnel_key key;
66 char fmt[] = "key %d remote ip 0x%x\n";
67
68 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
69 if (ret < 0) {
70 ERROR(ret);
71 return TC_ACT_SHOT;
72 }
73
74 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
75 return TC_ACT_OK;
76}
77
78SEC("vxlan_set_tunnel")
79int _vxlan_set_tunnel(struct __sk_buff *skb)
80{
81 int ret;
82 struct bpf_tunnel_key key;
83 struct vxlan_metadata md;
84
85 __builtin_memset(&key, 0x0, sizeof(key));
86 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
87 key.tunnel_id = 2;
88 key.tunnel_tos = 0;
89 key.tunnel_ttl = 64;
90
91 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
92 if (ret < 0) {
93 ERROR(ret);
94 return TC_ACT_SHOT;
95 }
96
97 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
98 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
99 if (ret < 0) {
100 ERROR(ret);
101 return TC_ACT_SHOT;
102 }
103
104 return TC_ACT_OK;
105}
106
107SEC("vxlan_get_tunnel")
108int _vxlan_get_tunnel(struct __sk_buff *skb)
109{
110 int ret;
111 struct bpf_tunnel_key key;
112 struct vxlan_metadata md;
113 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
114
115 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
116 if (ret < 0) {
117 ERROR(ret);
118 return TC_ACT_SHOT;
119 }
120
121 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
122 if (ret < 0) {
123 ERROR(ret);
124 return TC_ACT_SHOT;
125 }
126
127 bpf_trace_printk(fmt, sizeof(fmt),
128 key.tunnel_id, key.remote_ipv4, md.gbp);
129
130 return TC_ACT_OK;
131}
132
133SEC("geneve_set_tunnel")
134int _geneve_set_tunnel(struct __sk_buff *skb)
135{
136 int ret, ret2;
137 struct bpf_tunnel_key key;
138 struct geneve_opt gopt;
139
140 __builtin_memset(&key, 0x0, sizeof(key));
141 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
142 key.tunnel_id = 2;
143 key.tunnel_tos = 0;
144 key.tunnel_ttl = 64;
145
146 __builtin_memset(&gopt, 0x0, sizeof(gopt));
147 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
148 gopt.type = 0x08;
149 gopt.r1 = 1;
150 gopt.r2 = 0;
151 gopt.r3 = 1;
152 gopt.length = 2; /* 4-byte multiple */
153 *(int *) &gopt.opt_data = 0xdeadbeef;
154
155 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
156 if (ret < 0) {
157 ERROR(ret);
158 return TC_ACT_SHOT;
159 }
160
161 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
162 if (ret < 0) {
163 ERROR(ret);
164 return TC_ACT_SHOT;
165 }
166
167 return TC_ACT_OK;
168}
169
170SEC("geneve_get_tunnel")
171int _geneve_get_tunnel(struct __sk_buff *skb)
172{
173 int ret;
174 struct bpf_tunnel_key key;
175 struct geneve_opt gopt;
176 char fmt[] = "key %d remote ip 0x%x geneve class 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, &gopt, sizeof(gopt));
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, gopt.opt_class);
192 return TC_ACT_OK;
193}
194
Alexei Starovoitova1c82702016-09-15 13:00:31 -0700195SEC("ipip_set_tunnel")
196int _ipip_set_tunnel(struct __sk_buff *skb)
197{
198 struct bpf_tunnel_key key = {};
199 void *data = (void *)(long)skb->data;
200 struct iphdr *iph = data;
201 struct tcphdr *tcp = data + sizeof(*iph);
202 void *data_end = (void *)(long)skb->data_end;
203 int ret;
204
205 /* single length check */
206 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
207 ERROR(1);
208 return TC_ACT_SHOT;
209 }
210
211 key.tunnel_ttl = 64;
212 if (iph->protocol == IPPROTO_ICMP) {
213 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
214 } else {
215 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
216 return TC_ACT_SHOT;
217
218 if (tcp->dest == htons(5200))
219 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
220 else if (tcp->dest == htons(5201))
221 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
222 else
223 return TC_ACT_SHOT;
224 }
225
226 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
227 if (ret < 0) {
228 ERROR(ret);
229 return TC_ACT_SHOT;
230 }
231
232 return TC_ACT_OK;
233}
234
235SEC("ipip_get_tunnel")
236int _ipip_get_tunnel(struct __sk_buff *skb)
237{
238 int ret;
239 struct bpf_tunnel_key key;
240 char fmt[] = "remote ip 0x%x\n";
241
242 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
243 if (ret < 0) {
244 ERROR(ret);
245 return TC_ACT_SHOT;
246 }
247
248 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
249 return TC_ACT_OK;
250}
251
Alexei Starovoitov173ca262016-09-15 13:00:32 -0700252SEC("ipip6_set_tunnel")
253int _ipip6_set_tunnel(struct __sk_buff *skb)
254{
255 struct bpf_tunnel_key key = {};
256 void *data = (void *)(long)skb->data;
257 struct iphdr *iph = data;
258 struct tcphdr *tcp = data + sizeof(*iph);
259 void *data_end = (void *)(long)skb->data_end;
260 int ret;
261
262 /* single length check */
263 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
264 ERROR(1);
265 return TC_ACT_SHOT;
266 }
267
268 key.remote_ipv6[0] = _htonl(0x2401db00);
269 key.tunnel_ttl = 64;
270
271 if (iph->protocol == IPPROTO_ICMP) {
272 key.remote_ipv6[3] = _htonl(1);
273 } else {
274 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
275 ERROR(iph->protocol);
276 return TC_ACT_SHOT;
277 }
278
279 if (tcp->dest == htons(5200)) {
280 key.remote_ipv6[3] = _htonl(1);
281 } else if (tcp->dest == htons(5201)) {
282 key.remote_ipv6[3] = _htonl(2);
283 } else {
284 ERROR(tcp->dest);
285 return TC_ACT_SHOT;
286 }
287 }
288
289 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
290 if (ret < 0) {
291 ERROR(ret);
292 return TC_ACT_SHOT;
293 }
294
295 return TC_ACT_OK;
296}
297
298SEC("ipip6_get_tunnel")
299int _ipip6_get_tunnel(struct __sk_buff *skb)
300{
301 int ret;
302 struct bpf_tunnel_key key;
303 char fmt[] = "remote ip6 %x::%x\n";
304
305 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
306 if (ret < 0) {
307 ERROR(ret);
308 return TC_ACT_SHOT;
309 }
310
311 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
312 _htonl(key.remote_ipv6[3]));
313 return TC_ACT_OK;
314}
315
316SEC("ip6ip6_set_tunnel")
317int _ip6ip6_set_tunnel(struct __sk_buff *skb)
318{
319 struct bpf_tunnel_key key = {};
320 void *data = (void *)(long)skb->data;
321 struct ipv6hdr *iph = data;
322 struct tcphdr *tcp = data + sizeof(*iph);
323 void *data_end = (void *)(long)skb->data_end;
324 int ret;
325
326 /* single length check */
327 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
328 ERROR(1);
329 return TC_ACT_SHOT;
330 }
331
332 key.remote_ipv6[0] = _htonl(0x2401db00);
333 key.tunnel_ttl = 64;
334
335 if (iph->nexthdr == NEXTHDR_ICMP) {
336 key.remote_ipv6[3] = _htonl(1);
337 } else {
338 if (iph->nexthdr != NEXTHDR_TCP) {
339 ERROR(iph->nexthdr);
340 return TC_ACT_SHOT;
341 }
342
343 if (tcp->dest == htons(5200)) {
344 key.remote_ipv6[3] = _htonl(1);
345 } else if (tcp->dest == htons(5201)) {
346 key.remote_ipv6[3] = _htonl(2);
347 } else {
348 ERROR(tcp->dest);
349 return TC_ACT_SHOT;
350 }
351 }
352
353 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
354 if (ret < 0) {
355 ERROR(ret);
356 return TC_ACT_SHOT;
357 }
358
359 return TC_ACT_OK;
360}
361
362SEC("ip6ip6_get_tunnel")
363int _ip6ip6_get_tunnel(struct __sk_buff *skb)
364{
365 int ret;
366 struct bpf_tunnel_key key;
367 char fmt[] = "remote ip6 %x::%x\n";
368
369 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
370 if (ret < 0) {
371 ERROR(ret);
372 return TC_ACT_SHOT;
373 }
374
375 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
376 _htonl(key.remote_ipv6[3]));
377 return TC_ACT_OK;
378}
379
380
William Tu6afb1e22016-08-19 11:55:44 -0700381char _license[] SEC("license") = "GPL";