blob: c1917d968fb4ce59a69527bfdab247031ad33d81 [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>
12#include <uapi/linux/in.h>
13#include <uapi/linux/tcp.h>
14#include <uapi/linux/filter.h>
15#include <uapi/linux/pkt_cls.h>
16#include "bpf_helpers.h"
17
18#define ERROR(ret) do {\
19 char fmt[] = "ERROR line:%d ret:%d\n";\
20 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
21 } while(0)
22
23struct geneve_opt {
24 __be16 opt_class;
25 u8 type;
26 u8 length:5;
27 u8 r3:1;
28 u8 r2:1;
29 u8 r1:1;
30 u8 opt_data[8]; /* hard-coded to 8 byte */
31};
32
33struct vxlan_metadata {
34 u32 gbp;
35};
36
37SEC("gre_set_tunnel")
38int _gre_set_tunnel(struct __sk_buff *skb)
39{
40 int ret;
41 struct bpf_tunnel_key key;
42
43 __builtin_memset(&key, 0x0, sizeof(key));
44 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
45 key.tunnel_id = 2;
46 key.tunnel_tos = 0;
47 key.tunnel_ttl = 64;
48
49 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
50 if (ret < 0) {
51 ERROR(ret);
52 return TC_ACT_SHOT;
53 }
54
55 return TC_ACT_OK;
56}
57
58SEC("gre_get_tunnel")
59int _gre_get_tunnel(struct __sk_buff *skb)
60{
61 int ret;
62 struct bpf_tunnel_key key;
63 char fmt[] = "key %d remote ip 0x%x\n";
64
65 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
66 if (ret < 0) {
67 ERROR(ret);
68 return TC_ACT_SHOT;
69 }
70
71 bpf_trace_printk(fmt, sizeof(fmt), key.tunnel_id, key.remote_ipv4);
72 return TC_ACT_OK;
73}
74
75SEC("vxlan_set_tunnel")
76int _vxlan_set_tunnel(struct __sk_buff *skb)
77{
78 int ret;
79 struct bpf_tunnel_key key;
80 struct vxlan_metadata md;
81
82 __builtin_memset(&key, 0x0, sizeof(key));
83 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
84 key.tunnel_id = 2;
85 key.tunnel_tos = 0;
86 key.tunnel_ttl = 64;
87
88 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
89 if (ret < 0) {
90 ERROR(ret);
91 return TC_ACT_SHOT;
92 }
93
94 md.gbp = 0x800FF; /* Set VXLAN Group Policy extension */
95 ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
96 if (ret < 0) {
97 ERROR(ret);
98 return TC_ACT_SHOT;
99 }
100
101 return TC_ACT_OK;
102}
103
104SEC("vxlan_get_tunnel")
105int _vxlan_get_tunnel(struct __sk_buff *skb)
106{
107 int ret;
108 struct bpf_tunnel_key key;
109 struct vxlan_metadata md;
110 char fmt[] = "key %d remote ip 0x%x vxlan gbp 0x%x\n";
111
112 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
113 if (ret < 0) {
114 ERROR(ret);
115 return TC_ACT_SHOT;
116 }
117
118 ret = bpf_skb_get_tunnel_opt(skb, &md, sizeof(md));
119 if (ret < 0) {
120 ERROR(ret);
121 return TC_ACT_SHOT;
122 }
123
124 bpf_trace_printk(fmt, sizeof(fmt),
125 key.tunnel_id, key.remote_ipv4, md.gbp);
126
127 return TC_ACT_OK;
128}
129
130SEC("geneve_set_tunnel")
131int _geneve_set_tunnel(struct __sk_buff *skb)
132{
133 int ret, ret2;
134 struct bpf_tunnel_key key;
135 struct geneve_opt gopt;
136
137 __builtin_memset(&key, 0x0, sizeof(key));
138 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
139 key.tunnel_id = 2;
140 key.tunnel_tos = 0;
141 key.tunnel_ttl = 64;
142
143 __builtin_memset(&gopt, 0x0, sizeof(gopt));
144 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
145 gopt.type = 0x08;
146 gopt.r1 = 1;
147 gopt.r2 = 0;
148 gopt.r3 = 1;
149 gopt.length = 2; /* 4-byte multiple */
150 *(int *) &gopt.opt_data = 0xdeadbeef;
151
152 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
153 if (ret < 0) {
154 ERROR(ret);
155 return TC_ACT_SHOT;
156 }
157
158 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
159 if (ret < 0) {
160 ERROR(ret);
161 return TC_ACT_SHOT;
162 }
163
164 return TC_ACT_OK;
165}
166
167SEC("geneve_get_tunnel")
168int _geneve_get_tunnel(struct __sk_buff *skb)
169{
170 int ret;
171 struct bpf_tunnel_key key;
172 struct geneve_opt gopt;
173 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
174
175 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
176 if (ret < 0) {
177 ERROR(ret);
178 return TC_ACT_SHOT;
179 }
180
181 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
182 if (ret < 0) {
183 ERROR(ret);
184 return TC_ACT_SHOT;
185 }
186
187 bpf_trace_printk(fmt, sizeof(fmt),
188 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
189 return TC_ACT_OK;
190}
191
Alexei Starovoitova1c82702016-09-15 13:00:31 -0700192SEC("ipip_set_tunnel")
193int _ipip_set_tunnel(struct __sk_buff *skb)
194{
195 struct bpf_tunnel_key key = {};
196 void *data = (void *)(long)skb->data;
197 struct iphdr *iph = data;
198 struct tcphdr *tcp = data + sizeof(*iph);
199 void *data_end = (void *)(long)skb->data_end;
200 int ret;
201
202 /* single length check */
203 if (data + sizeof(*iph) + sizeof(*tcp) > data_end) {
204 ERROR(1);
205 return TC_ACT_SHOT;
206 }
207
208 key.tunnel_ttl = 64;
209 if (iph->protocol == IPPROTO_ICMP) {
210 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
211 } else {
212 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
213 return TC_ACT_SHOT;
214
215 if (tcp->dest == htons(5200))
216 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
217 else if (tcp->dest == htons(5201))
218 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
219 else
220 return TC_ACT_SHOT;
221 }
222
223 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), 0);
224 if (ret < 0) {
225 ERROR(ret);
226 return TC_ACT_SHOT;
227 }
228
229 return TC_ACT_OK;
230}
231
232SEC("ipip_get_tunnel")
233int _ipip_get_tunnel(struct __sk_buff *skb)
234{
235 int ret;
236 struct bpf_tunnel_key key;
237 char fmt[] = "remote ip 0x%x\n";
238
239 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
240 if (ret < 0) {
241 ERROR(ret);
242 return TC_ACT_SHOT;
243 }
244
245 bpf_trace_printk(fmt, sizeof(fmt), key.remote_ipv4);
246 return TC_ACT_OK;
247}
248
William Tu6afb1e22016-08-19 11:55:44 -0700249char _license[] SEC("license") = "GPL";