123458901SLorenz Bauer /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
223458901SLorenz Bauer /* Copyright 2019, 2020 Cloudflare */
323458901SLorenz Bauer 
423458901SLorenz Bauer #include <stdbool.h>
523458901SLorenz Bauer #include <stddef.h>
623458901SLorenz Bauer #include <stdint.h>
723458901SLorenz Bauer #include <string.h>
823458901SLorenz Bauer 
923458901SLorenz Bauer #include <linux/if_ether.h>
1023458901SLorenz Bauer #include <linux/in.h>
1123458901SLorenz Bauer #include <linux/ip.h>
1223458901SLorenz Bauer #include <linux/ipv6.h>
1323458901SLorenz Bauer #include <linux/udp.h>
1423458901SLorenz Bauer 
15*416c6d01SAlan Maguire /* offsetof() is used in static asserts, and the libbpf-redefined CO-RE
16*416c6d01SAlan Maguire  * friendly version breaks compilation for older clang versions <= 15
17*416c6d01SAlan Maguire  * when invoked in a static assert.  Restore original here.
18*416c6d01SAlan Maguire  */
19*416c6d01SAlan Maguire #ifdef offsetof
20*416c6d01SAlan Maguire #undef offsetof
21*416c6d01SAlan Maguire #define offsetof(type, member) __builtin_offsetof(type, member)
22*416c6d01SAlan Maguire #endif
23*416c6d01SAlan Maguire 
2423458901SLorenz Bauer struct gre_base_hdr {
2523458901SLorenz Bauer 	uint16_t flags;
2623458901SLorenz Bauer 	uint16_t protocol;
2723458901SLorenz Bauer } __attribute__((packed));
2823458901SLorenz Bauer 
2923458901SLorenz Bauer struct guehdr {
3023458901SLorenz Bauer #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
3123458901SLorenz Bauer 	uint8_t hlen : 5, control : 1, variant : 2;
3223458901SLorenz Bauer #else
3323458901SLorenz Bauer 	uint8_t variant : 2, control : 1, hlen : 5;
3423458901SLorenz Bauer #endif
3523458901SLorenz Bauer 	uint8_t proto_ctype;
3623458901SLorenz Bauer 	uint16_t flags;
3723458901SLorenz Bauer };
3823458901SLorenz Bauer 
3923458901SLorenz Bauer struct unigue {
4023458901SLorenz Bauer #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
4123458901SLorenz Bauer 	uint8_t _r : 2, last_hop_gre : 1, forward_syn : 1, version : 4;
4223458901SLorenz Bauer #else
4323458901SLorenz Bauer 	uint8_t version : 4, forward_syn : 1, last_hop_gre : 1, _r : 2;
4423458901SLorenz Bauer #endif
4523458901SLorenz Bauer 	uint8_t reserved;
4623458901SLorenz Bauer 	uint8_t next_hop;
4723458901SLorenz Bauer 	uint8_t hop_count;
4823458901SLorenz Bauer 	// Next hops go here
4923458901SLorenz Bauer } __attribute__((packed));
5023458901SLorenz Bauer 
5123458901SLorenz Bauer typedef struct {
5223458901SLorenz Bauer 	struct ethhdr eth;
5323458901SLorenz Bauer 	struct iphdr ip;
5423458901SLorenz Bauer 	struct gre_base_hdr gre;
5523458901SLorenz Bauer } __attribute__((packed)) encap_gre_t;
5623458901SLorenz Bauer 
5723458901SLorenz Bauer typedef struct {
5823458901SLorenz Bauer 	struct ethhdr eth;
5923458901SLorenz Bauer 	struct iphdr ip;
6023458901SLorenz Bauer 	struct udphdr udp;
6123458901SLorenz Bauer 	struct guehdr gue;
6223458901SLorenz Bauer 	struct unigue unigue;
6323458901SLorenz Bauer } __attribute__((packed)) encap_headers_t;
64