patches and low-level development discussion
 help / color / mirror / code / Atom feed
blob 1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26 5848 bytes (raw)
name: tools/xdp-forwarder/parsing_helpers.h 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
 
/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
/* SPDX-FileCopyrightText: 2021 The xdp-tutorial Authors */
/* Vendored from https://github.com/xdp-project/xdp-tutorial/blob/d3d3eed6ea9a63d1302bfa8b5a8e93862bfe11f0/common/parsing_helpers.h */
/*
 * This file contains parsing functions that are used in the packetXX XDP
 * programs. The functions are marked as __always_inline, and fully defined in
 * this header file to be included in the BPF program.
 *
 * Each helper parses a packet header, including doing bounds checking, and
 * returns the type of its contents if successful, and -1 otherwise.
 *
 * For Ethernet and IP headers, the content type is the type of the payload
 * (h_proto for Ethernet, nexthdr for IPv6), for ICMP it is the ICMP type field.
 * All return values are in host byte order.
 *
 * The versions of the functions included here are slightly expanded versions of
 * the functions in the packet01 lesson. For instance, the Ethernet header
 * parsing has support for parsing VLAN tags.
 */

#ifndef __PARSING_HELPERS_H
#define __PARSING_HELPERS_H

#include <stddef.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/tcp.h>

/* Header cursor to keep track of current parsing position */
struct hdr_cursor {
	void *pos;
};

/*
 *	struct vlan_hdr - vlan header
 *	@h_vlan_TCI: priority and VLAN ID
 *	@h_vlan_encapsulated_proto: packet type ID or len
 */
struct vlan_hdr {
	__be16 h_vlan_TCI;
	__be16 h_vlan_encapsulated_proto;
};

/* Allow users of header file to redefine VLAN max depth */
#ifndef VLAN_MAX_DEPTH
#define VLAN_MAX_DEPTH 2
#endif

#define VLAN_VID_MASK           0x0fff /* VLAN Identifier */
/* Struct for collecting VLANs after parsing via parse_ethhdr_vlan */
struct collect_vlans {
	__u16 id[VLAN_MAX_DEPTH];
};

static __always_inline int proto_is_vlan(__u16 h_proto)
{
	return !!(h_proto == bpf_htons(ETH_P_8021Q) ||
	          h_proto == bpf_htons(ETH_P_8021AD));
}

/* Notice, parse_ethhdr() will skip VLAN tags, by advancing nh->pos and returns
 * next header EtherType, BUT the ethhdr pointer supplied still points to the
 * Ethernet header. Thus, caller can look at eth->h_proto to see if this was a
 * VLAN tagged packet.
 */
static __always_inline int parse_ethhdr_vlan(struct hdr_cursor *nh,
                                             void *data_end,
                                             struct ethhdr **ethhdr,
                                             struct collect_vlans *vlans)
{
	struct ethhdr *eth = nh->pos;
	int hdrsize = sizeof(*eth);
	struct vlan_hdr *vlh;
	__u16 h_proto;
	int i;

	/* Byte-count bounds check; check if current pointer + size of header
	 * is after data_end.
	 */
	if (nh->pos + hdrsize > data_end)
		return -1;

	nh->pos += hdrsize;
	*ethhdr = eth;
	vlh = nh->pos;
	h_proto = eth->h_proto;

	/* Use loop unrolling to avoid the verifier restriction on loops;
	 * support up to VLAN_MAX_DEPTH layers of VLAN encapsulation.
	 */
	#pragma unroll
	for (i = 0; i < VLAN_MAX_DEPTH; i++) {
		if (!proto_is_vlan(h_proto))
			break;

		if (vlh + 1 > data_end)
			break;

		h_proto = vlh->h_vlan_encapsulated_proto;
		if (vlans) /* collect VLAN ids */
			vlans->id[i] =
				(bpf_ntohs(vlh->h_vlan_TCI) & VLAN_VID_MASK);

		vlh++;
	}

	nh->pos = vlh;
	return h_proto; /* network-byte-order */
}

static __always_inline int parse_ethhdr(struct hdr_cursor *nh,
                                        void *data_end,
                                        struct ethhdr **ethhdr)
{
	/* Expect compiler removes the code that collects VLAN ids */
	return parse_ethhdr_vlan(nh, data_end, ethhdr, NULL);
}

static __always_inline int parse_ip6hdr(struct hdr_cursor *nh,
                                        void *data_end,
                                        struct ipv6hdr **ip6hdr)
{
	struct ipv6hdr *ip6h = nh->pos;

	/* Pointer-arithmetic bounds check; pointer +1 points to after end of
	 * thing being pointed to. We will be using this style in the remainder
	 * of the tutorial.
	 */
	if (ip6h + 1 > data_end)
		return -1;

	nh->pos = ip6h + 1;
	*ip6hdr = ip6h;

	return ip6h->nexthdr;
}

static __always_inline int parse_iphdr(struct hdr_cursor *nh,
                                       void *data_end,
                                       struct iphdr **iphdr)
{
	struct iphdr *iph = nh->pos;
	int hdrsize;

	if (iph + 1 > data_end)
		return -1;

	hdrsize = iph->ihl * 4;
	/* Sanity check packet field is valid */
	if(hdrsize < sizeof(*iph))
		return -1;

	/* Variable-length IPv4 header, need to use byte-based arithmetic */
	if (nh->pos + hdrsize > data_end)
		return -1;

	nh->pos += hdrsize;
	*iphdr = iph;

	return iph->protocol;
}

/*
 * parse_udphdr: parse the udp header and return the length of the udp payload
 */
static __always_inline int parse_udphdr(struct hdr_cursor *nh,
                                        void *data_end,
                                        struct udphdr **udphdr)
{
	int len;
	struct udphdr *h = nh->pos;

	if (h + 1 > data_end)
		return -1;

	nh->pos  = h + 1;
	*udphdr = h;

	len = bpf_ntohs(h->len) - sizeof(struct udphdr);
	if (len < 0)
		return -1;

	return len;
}

/*
 * parse_tcphdr: parse and return the length of the tcp header
 */
static __always_inline int parse_tcphdr(struct hdr_cursor *nh,
                                        void *data_end,
                                        struct tcphdr **tcphdr)
{
	int len;
	struct tcphdr *h = nh->pos;

	if (h + 1 > data_end)
		return -1;

	len = h->doff * 4;
	/* Sanity check packet field is valid */
	if(len < sizeof(*h))
		return -1;

	/* Variable-length TCP header, need to use byte-based arithmetic */
	if (nh->pos + len > data_end)
		return -1;

	nh->pos += len;
	*tcphdr = h;

	return len;
}

#endif /* __PARSING_HELPERS_H */

debug log:

solving 1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26 ...
found 1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26 in https://inbox.spectrum-os.org/spectrum-devel/20251003-fix-forwarder-build-v1-1-856b78ae5656@gmail.com/ ||
	https://inbox.spectrum-os.org/spectrum-devel/20251021-fix-forwarder-build-v4-1-b978718c004d@gmail.com/
retrying da099346008bd58485af8308feb4d3391ceef8f5 as da099346008bd58485af8308feb4d3391ceef8f
retrying da099346008bd58485af8308feb4d3391ceef8f as da099346008bd58485af8308feb4d3391ceef8
retrying da099346008bd58485af8308feb4d3391ceef8 as da099346008bd58485af8308feb4d3391ceef
retrying da099346008bd58485af8308feb4d3391ceef as da099346008bd58485af8308feb4d3391cee
retrying da099346008bd58485af8308feb4d3391cee as da099346008bd58485af8308feb4d3391ce
retrying da099346008bd58485af8308feb4d3391ce as da099346008bd58485af8308feb4d3391c
retrying da099346008bd58485af8308feb4d3391c as da099346008bd58485af8308feb4d3391
retrying da099346008bd58485af8308feb4d3391 as da099346008bd58485af8308feb4d339
retrying da099346008bd58485af8308feb4d339 as da099346008bd58485af8308feb4d33
retrying da099346008bd58485af8308feb4d33 as da099346008bd58485af8308feb4d3
retrying da099346008bd58485af8308feb4d3 as da099346008bd58485af8308feb4d
retrying da099346008bd58485af8308feb4d as da099346008bd58485af8308feb4
retrying da099346008bd58485af8308feb4 as da099346008bd58485af8308feb
retrying da099346008bd58485af8308feb as da099346008bd58485af8308fe
retrying da099346008bd58485af8308fe as da099346008bd58485af8308f
retrying da099346008bd58485af8308f as da099346008bd58485af8308
retrying da099346008bd58485af8308 as da099346008bd58485af830
retrying da099346008bd58485af830 as da099346008bd58485af83
retrying da099346008bd58485af83 as da099346008bd58485af8
retrying da099346008bd58485af8 as da099346008bd58485af
retrying da099346008bd58485af as da099346008bd58485a
retrying da099346008bd58485a as da099346008bd58485
retrying da099346008bd58485 as da099346008bd5848
retrying da099346008bd5848 as da099346008bd584
retrying da099346008bd584 as da099346008bd58
retrying da099346008bd58 as da099346008bd5
retrying da099346008bd5 as da099346008bd
retrying da099346008bd as da099346008b
retrying da099346008b as da099346008
retrying da099346008 as da09934600
retrying da09934600 as da0993460
retrying da0993460 as da099346
retrying da099346 as da09934
found da09934 in https://inbox.spectrum-os.org/spectrum-devel/20250924114300.100541-2-yureka@cyberchaos.dev/

applying [1/2] https://inbox.spectrum-os.org/spectrum-devel/20250924114300.100541-2-yureka@cyberchaos.dev/
diff --git a/tools/xdp-forwarder/parsing_helpers.h b/tools/xdp-forwarder/parsing_helpers.h
new file mode 100644
index 0000000..da09934


applying [2/2] https://inbox.spectrum-os.org/spectrum-devel/20251003-fix-forwarder-build-v1-1-856b78ae5656@gmail.com/
diff --git a/tools/xdp-forwarder/parsing_helpers.h b/tools/xdp-forwarder/parsing_helpers.h
index da099346008bd58485af8308feb4d3391ceef8f5..1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26 100644

Checking patch tools/xdp-forwarder/parsing_helpers.h...
Applied patch tools/xdp-forwarder/parsing_helpers.h cleanly.
Checking patch tools/xdp-forwarder/parsing_helpers.h...
Applied patch tools/xdp-forwarder/parsing_helpers.h cleanly.

skipping https://inbox.spectrum-os.org/spectrum-devel/20251021-fix-forwarder-build-v4-1-b978718c004d@gmail.com/ for 1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26
index at:
100644 1ea822100fdb9a75c2d28d34d93e6bb2b5d3ae26	tools/xdp-forwarder/parsing_helpers.h

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://spectrum-os.org/git/crosvm
	https://spectrum-os.org/git/doc
	https://spectrum-os.org/git/mktuntap
	https://spectrum-os.org/git/nixpkgs
	https://spectrum-os.org/git/spectrum
	https://spectrum-os.org/git/ucspi-vsock
	https://spectrum-os.org/git/www

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).