xref: /linux/tools/testing/selftests/bpf/progs/bpf_flow.c (revision f6d08d9d8543c8ee494b307804b28e2750ffedb9)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <limits.h>
3 #include <stddef.h>
4 #include <stdbool.h>
5 #include <string.h>
6 #include <linux/pkt_cls.h>
7 #include <linux/bpf.h>
8 #include <linux/in.h>
9 #include <linux/if_ether.h>
10 #include <linux/icmp.h>
11 #include <linux/ip.h>
12 #include <linux/ipv6.h>
13 #include <linux/tcp.h>
14 #include <linux/udp.h>
15 #include <linux/if_packet.h>
16 #include <sys/socket.h>
17 #include <linux/if_tunnel.h>
18 #include <linux/mpls.h>
19 #include "bpf_helpers.h"
20 #include "bpf_endian.h"
21 
22 int _version SEC("version") = 1;
23 #define PROG(F) SEC(#F) int bpf_func_##F
24 
25 /* These are the identifiers of the BPF programs that will be used in tail
26  * calls. Name is limited to 16 characters, with the terminating character and
27  * bpf_func_ above, we have only 6 to work with, anything after will be cropped.
28  */
29 enum {
30 	IP,
31 	IPV6,
32 	IPV6OP,	/* Destination/Hop-by-Hop Options IPv6 Extension header */
33 	IPV6FR,	/* Fragmentation IPv6 Extension Header */
34 	MPLS,
35 	VLAN,
36 };
37 
38 #define IP_MF		0x2000
39 #define IP_OFFSET	0x1FFF
40 #define IP6_MF		0x0001
41 #define IP6_OFFSET	0xFFF8
42 
43 struct vlan_hdr {
44 	__be16 h_vlan_TCI;
45 	__be16 h_vlan_encapsulated_proto;
46 };
47 
48 struct gre_hdr {
49 	__be16 flags;
50 	__be16 proto;
51 };
52 
53 struct frag_hdr {
54 	__u8 nexthdr;
55 	__u8 reserved;
56 	__be16 frag_off;
57 	__be32 identification;
58 };
59 
60 struct {
61 	__u32 type;
62 	__u32 max_entries;
63 	__u32 key_size;
64 	__u32 value_size;
65 } jmp_table SEC(".maps") = {
66 	.type = BPF_MAP_TYPE_PROG_ARRAY,
67 	.max_entries = 8,
68 	.key_size = sizeof(__u32),
69 	.value_size = sizeof(__u32),
70 };
71 
72 struct {
73 	__u32 type;
74 	__u32 max_entries;
75 	__u32 *key;
76 	struct bpf_flow_keys *value;
77 } last_dissection SEC(".maps") = {
78 	.type = BPF_MAP_TYPE_ARRAY,
79 	.max_entries = 1,
80 };
81 
82 static __always_inline int export_flow_keys(struct bpf_flow_keys *keys,
83 					    int ret)
84 {
85 	struct bpf_flow_keys *val;
86 	__u32 key = 0;
87 
88 	val = bpf_map_lookup_elem(&last_dissection, &key);
89 	if (val)
90 		memcpy(val, keys, sizeof(*val));
91 	return ret;
92 }
93 
94 static __always_inline void *bpf_flow_dissect_get_header(struct __sk_buff *skb,
95 							 __u16 hdr_size,
96 							 void *buffer)
97 {
98 	void *data_end = (void *)(long)skb->data_end;
99 	void *data = (void *)(long)skb->data;
100 	__u16 thoff = skb->flow_keys->thoff;
101 	__u8 *hdr;
102 
103 	/* Verifies this variable offset does not overflow */
104 	if (thoff > (USHRT_MAX - hdr_size))
105 		return NULL;
106 
107 	hdr = data + thoff;
108 	if (hdr + hdr_size <= data_end)
109 		return hdr;
110 
111 	if (bpf_skb_load_bytes(skb, thoff, buffer, hdr_size))
112 		return NULL;
113 
114 	return buffer;
115 }
116 
117 /* Dispatches on ETHERTYPE */
118 static __always_inline int parse_eth_proto(struct __sk_buff *skb, __be16 proto)
119 {
120 	struct bpf_flow_keys *keys = skb->flow_keys;
121 
122 	switch (proto) {
123 	case bpf_htons(ETH_P_IP):
124 		bpf_tail_call(skb, &jmp_table, IP);
125 		break;
126 	case bpf_htons(ETH_P_IPV6):
127 		bpf_tail_call(skb, &jmp_table, IPV6);
128 		break;
129 	case bpf_htons(ETH_P_MPLS_MC):
130 	case bpf_htons(ETH_P_MPLS_UC):
131 		bpf_tail_call(skb, &jmp_table, MPLS);
132 		break;
133 	case bpf_htons(ETH_P_8021Q):
134 	case bpf_htons(ETH_P_8021AD):
135 		bpf_tail_call(skb, &jmp_table, VLAN);
136 		break;
137 	default:
138 		/* Protocol not supported */
139 		return export_flow_keys(keys, BPF_DROP);
140 	}
141 
142 	return export_flow_keys(keys, BPF_DROP);
143 }
144 
145 SEC("flow_dissector")
146 int _dissect(struct __sk_buff *skb)
147 {
148 	struct bpf_flow_keys *keys = skb->flow_keys;
149 
150 	return parse_eth_proto(skb, keys->n_proto);
151 }
152 
153 /* Parses on IPPROTO_* */
154 static __always_inline int parse_ip_proto(struct __sk_buff *skb, __u8 proto)
155 {
156 	struct bpf_flow_keys *keys = skb->flow_keys;
157 	void *data_end = (void *)(long)skb->data_end;
158 	struct icmphdr *icmp, _icmp;
159 	struct gre_hdr *gre, _gre;
160 	struct ethhdr *eth, _eth;
161 	struct tcphdr *tcp, _tcp;
162 	struct udphdr *udp, _udp;
163 
164 	keys->ip_proto = proto;
165 	switch (proto) {
166 	case IPPROTO_ICMP:
167 		icmp = bpf_flow_dissect_get_header(skb, sizeof(*icmp), &_icmp);
168 		if (!icmp)
169 			return export_flow_keys(keys, BPF_DROP);
170 		return export_flow_keys(keys, BPF_OK);
171 	case IPPROTO_IPIP:
172 		keys->is_encap = true;
173 		return parse_eth_proto(skb, bpf_htons(ETH_P_IP));
174 	case IPPROTO_IPV6:
175 		keys->is_encap = true;
176 		return parse_eth_proto(skb, bpf_htons(ETH_P_IPV6));
177 	case IPPROTO_GRE:
178 		gre = bpf_flow_dissect_get_header(skb, sizeof(*gre), &_gre);
179 		if (!gre)
180 			return export_flow_keys(keys, BPF_DROP);
181 
182 		if (bpf_htons(gre->flags & GRE_VERSION))
183 			/* Only inspect standard GRE packets with version 0 */
184 			return export_flow_keys(keys, BPF_OK);
185 
186 		keys->thoff += sizeof(*gre); /* Step over GRE Flags and Proto */
187 		if (GRE_IS_CSUM(gre->flags))
188 			keys->thoff += 4; /* Step over chksum and Padding */
189 		if (GRE_IS_KEY(gre->flags))
190 			keys->thoff += 4; /* Step over key */
191 		if (GRE_IS_SEQ(gre->flags))
192 			keys->thoff += 4; /* Step over sequence number */
193 
194 		keys->is_encap = true;
195 
196 		if (gre->proto == bpf_htons(ETH_P_TEB)) {
197 			eth = bpf_flow_dissect_get_header(skb, sizeof(*eth),
198 							  &_eth);
199 			if (!eth)
200 				return export_flow_keys(keys, BPF_DROP);
201 
202 			keys->thoff += sizeof(*eth);
203 
204 			return parse_eth_proto(skb, eth->h_proto);
205 		} else {
206 			return parse_eth_proto(skb, gre->proto);
207 		}
208 	case IPPROTO_TCP:
209 		tcp = bpf_flow_dissect_get_header(skb, sizeof(*tcp), &_tcp);
210 		if (!tcp)
211 			return export_flow_keys(keys, BPF_DROP);
212 
213 		if (tcp->doff < 5)
214 			return export_flow_keys(keys, BPF_DROP);
215 
216 		if ((__u8 *)tcp + (tcp->doff << 2) > data_end)
217 			return export_flow_keys(keys, BPF_DROP);
218 
219 		keys->sport = tcp->source;
220 		keys->dport = tcp->dest;
221 		return export_flow_keys(keys, BPF_OK);
222 	case IPPROTO_UDP:
223 	case IPPROTO_UDPLITE:
224 		udp = bpf_flow_dissect_get_header(skb, sizeof(*udp), &_udp);
225 		if (!udp)
226 			return export_flow_keys(keys, BPF_DROP);
227 
228 		keys->sport = udp->source;
229 		keys->dport = udp->dest;
230 		return export_flow_keys(keys, BPF_OK);
231 	default:
232 		return export_flow_keys(keys, BPF_DROP);
233 	}
234 
235 	return export_flow_keys(keys, BPF_DROP);
236 }
237 
238 static __always_inline int parse_ipv6_proto(struct __sk_buff *skb, __u8 nexthdr)
239 {
240 	struct bpf_flow_keys *keys = skb->flow_keys;
241 
242 	keys->ip_proto = nexthdr;
243 	switch (nexthdr) {
244 	case IPPROTO_HOPOPTS:
245 	case IPPROTO_DSTOPTS:
246 		bpf_tail_call(skb, &jmp_table, IPV6OP);
247 		break;
248 	case IPPROTO_FRAGMENT:
249 		bpf_tail_call(skb, &jmp_table, IPV6FR);
250 		break;
251 	default:
252 		return parse_ip_proto(skb, nexthdr);
253 	}
254 
255 	return export_flow_keys(keys, BPF_DROP);
256 }
257 
258 PROG(IP)(struct __sk_buff *skb)
259 {
260 	void *data_end = (void *)(long)skb->data_end;
261 	struct bpf_flow_keys *keys = skb->flow_keys;
262 	void *data = (void *)(long)skb->data;
263 	struct iphdr *iph, _iph;
264 	bool done = false;
265 
266 	iph = bpf_flow_dissect_get_header(skb, sizeof(*iph), &_iph);
267 	if (!iph)
268 		return export_flow_keys(keys, BPF_DROP);
269 
270 	/* IP header cannot be smaller than 20 bytes */
271 	if (iph->ihl < 5)
272 		return export_flow_keys(keys, BPF_DROP);
273 
274 	keys->addr_proto = ETH_P_IP;
275 	keys->ipv4_src = iph->saddr;
276 	keys->ipv4_dst = iph->daddr;
277 
278 	keys->thoff += iph->ihl << 2;
279 	if (data + keys->thoff > data_end)
280 		return export_flow_keys(keys, BPF_DROP);
281 
282 	if (iph->frag_off & bpf_htons(IP_MF | IP_OFFSET)) {
283 		keys->is_frag = true;
284 		if (iph->frag_off & bpf_htons(IP_OFFSET))
285 			/* From second fragment on, packets do not have headers
286 			 * we can parse.
287 			 */
288 			done = true;
289 		else
290 			keys->is_first_frag = true;
291 	}
292 
293 	if (done)
294 		return export_flow_keys(keys, BPF_OK);
295 
296 	return parse_ip_proto(skb, iph->protocol);
297 }
298 
299 PROG(IPV6)(struct __sk_buff *skb)
300 {
301 	struct bpf_flow_keys *keys = skb->flow_keys;
302 	struct ipv6hdr *ip6h, _ip6h;
303 
304 	ip6h = bpf_flow_dissect_get_header(skb, sizeof(*ip6h), &_ip6h);
305 	if (!ip6h)
306 		return export_flow_keys(keys, BPF_DROP);
307 
308 	keys->addr_proto = ETH_P_IPV6;
309 	memcpy(&keys->ipv6_src, &ip6h->saddr, 2*sizeof(ip6h->saddr));
310 
311 	keys->thoff += sizeof(struct ipv6hdr);
312 
313 	return parse_ipv6_proto(skb, ip6h->nexthdr);
314 }
315 
316 PROG(IPV6OP)(struct __sk_buff *skb)
317 {
318 	struct bpf_flow_keys *keys = skb->flow_keys;
319 	struct ipv6_opt_hdr *ip6h, _ip6h;
320 
321 	ip6h = bpf_flow_dissect_get_header(skb, sizeof(*ip6h), &_ip6h);
322 	if (!ip6h)
323 		return export_flow_keys(keys, BPF_DROP);
324 
325 	/* hlen is in 8-octets and does not include the first 8 bytes
326 	 * of the header
327 	 */
328 	skb->flow_keys->thoff += (1 + ip6h->hdrlen) << 3;
329 
330 	return parse_ipv6_proto(skb, ip6h->nexthdr);
331 }
332 
333 PROG(IPV6FR)(struct __sk_buff *skb)
334 {
335 	struct bpf_flow_keys *keys = skb->flow_keys;
336 	struct frag_hdr *fragh, _fragh;
337 
338 	fragh = bpf_flow_dissect_get_header(skb, sizeof(*fragh), &_fragh);
339 	if (!fragh)
340 		return export_flow_keys(keys, BPF_DROP);
341 
342 	keys->thoff += sizeof(*fragh);
343 	keys->is_frag = true;
344 	if (!(fragh->frag_off & bpf_htons(IP6_OFFSET)))
345 		keys->is_first_frag = true;
346 
347 	return parse_ipv6_proto(skb, fragh->nexthdr);
348 }
349 
350 PROG(MPLS)(struct __sk_buff *skb)
351 {
352 	struct bpf_flow_keys *keys = skb->flow_keys;
353 	struct mpls_label *mpls, _mpls;
354 
355 	mpls = bpf_flow_dissect_get_header(skb, sizeof(*mpls), &_mpls);
356 	if (!mpls)
357 		return export_flow_keys(keys, BPF_DROP);
358 
359 	return export_flow_keys(keys, BPF_OK);
360 }
361 
362 PROG(VLAN)(struct __sk_buff *skb)
363 {
364 	struct bpf_flow_keys *keys = skb->flow_keys;
365 	struct vlan_hdr *vlan, _vlan;
366 
367 	/* Account for double-tagging */
368 	if (keys->n_proto == bpf_htons(ETH_P_8021AD)) {
369 		vlan = bpf_flow_dissect_get_header(skb, sizeof(*vlan), &_vlan);
370 		if (!vlan)
371 			return export_flow_keys(keys, BPF_DROP);
372 
373 		if (vlan->h_vlan_encapsulated_proto != bpf_htons(ETH_P_8021Q))
374 			return export_flow_keys(keys, BPF_DROP);
375 
376 		keys->nhoff += sizeof(*vlan);
377 		keys->thoff += sizeof(*vlan);
378 	}
379 
380 	vlan = bpf_flow_dissect_get_header(skb, sizeof(*vlan), &_vlan);
381 	if (!vlan)
382 		return export_flow_keys(keys, BPF_DROP);
383 
384 	keys->nhoff += sizeof(*vlan);
385 	keys->thoff += sizeof(*vlan);
386 	/* Only allow 8021AD + 8021Q double tagging and no triple tagging.*/
387 	if (vlan->h_vlan_encapsulated_proto == bpf_htons(ETH_P_8021AD) ||
388 	    vlan->h_vlan_encapsulated_proto == bpf_htons(ETH_P_8021Q))
389 		return export_flow_keys(keys, BPF_DROP);
390 
391 	keys->n_proto = vlan->h_vlan_encapsulated_proto;
392 	return parse_eth_proto(skb, vlan->h_vlan_encapsulated_proto);
393 }
394 
395 char __license[] SEC("license") = "GPL";
396