aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/include/odp_parse_internal.h
blob: 22d8c2cf6811fc27e2a84017e304d150893603b4 (plain)
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
/* Copyright (c) 2013-2018, Linaro Limited
 * Copyright (c) 2019-2022, Nokia
 * All rights reserved.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 */

#ifndef ODP_PARSE_INTERNAL_H_
#define ODP_PARSE_INTERNAL_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <odp_packet_internal.h>
#include <odp_macros_internal.h>
#include <protocols/eth.h>
#include <protocols/ip.h>
#include <protocols/sctp.h>
#include <protocols/tcp.h>
#include <protocols/udp.h>
#include <odp/api/plat/packet_inline_types.h>
#include <odp/api/hints.h>
#include <odp/api/packet_io.h>
#include <odp/api/packet_types.h>
#include <stdint.h>

/*
 * In the worst case we look at the Ethernet header, 8 bytes of LLC/SNAP
 * header and two VLAN tags in the same packet.
 */
#define PARSE_ETH_BYTES (sizeof(_odp_ethhdr_t) + 8 + 2 * sizeof(_odp_vlanhdr_t))
#define PARSE_IPV4_BYTES (0xfU * 4) /* max IPv4 header length with options */
/*
 * Peek 2 bytes beyond IPv6 base header without length check if there are
 * extension headers.
 */
#define PARSE_IPV6_BYTES (sizeof(_odp_ipv6hdr_t) + 2)
#define PARSE_TCP_BYTES (sizeof(_odp_tcphdr_t))
/*
 * In the worst case we look at the UDP header and 4 bytes of the UDP
 * payload (the non-ESP marker to distinguish IKE packets from ESP packets).
 */
#define PARSE_UDP_BYTES (sizeof(_odp_udphdr_t) + 4)
#define PARSE_SCTP_BYTES (sizeof(_odp_sctphdr_t))

/* _odp_packet_parse_common_l3_l4() requires up to this many bytes. */
#define PARSE_L3_L4_BYTES (_ODP_MAX(PARSE_IPV4_BYTES, PARSE_IPV6_BYTES) + \
			   _ODP_MAX3(PARSE_TCP_BYTES, PARSE_UDP_BYTES, PARSE_SCTP_BYTES))

/* _odp_packet_parse_common() requires up to this many bytes. */
#define PARSE_BYTES (PARSE_ETH_BYTES + PARSE_L3_L4_BYTES)

uint16_t _odp_parse_eth(packet_parser_t *prs, const uint8_t **parseptr,
			uint32_t *offset, uint32_t frame_len);

/*
 * Parse common L3 and L4 packet headers up to given layer
 *
 * See _odp_packet_parse_common(). Requires up to PARSE_L3_L4_BYTES bytes of
 * contiguous packet data.
 */
int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,
				   const uint8_t *parseptr, uint32_t offset,
				   uint32_t frame_len, uint32_t seg_len,
				   int layer, uint16_t ethtype,
				   odp_proto_chksums_t chksums,
				   uint64_t *l4_part_sum,
				   odp_pktin_config_opt_t opt);

/**
 * Parse common packet headers up to given layer
 *
 * Requires up to PARSE_BYTES bytes of contiguous packet data. Also parse
 * metadata must be already initialized.
 *
 * Returns 0 on success, 1 on packet errors, and -1 if the packet should be
 * dropped.
 */
static inline int _odp_packet_parse_common(packet_parser_t *prs,
					   const uint8_t *ptr,
					   uint32_t frame_len, uint32_t seg_len,
					   int layer,
					   odp_proto_chksums_t chksums,
					   uint64_t *l4_part_sum,
					   odp_pktin_config_opt_t opt)
{
	uint32_t offset;
	uint16_t ethtype;
	const uint8_t *parseptr;

	parseptr = ptr;
	offset = 0;

	if (odp_unlikely(layer == ODP_PROTO_LAYER_NONE))
		return 0;

	/* Assume valid L2 header, no CRC/FCS check in SW */
	prs->l2_offset = offset;

	ethtype = _odp_parse_eth(prs, &parseptr, &offset, frame_len);

	return _odp_packet_parse_common_l3_l4(prs, parseptr, offset, frame_len,
					      seg_len, layer, ethtype, chksums,
					      l4_part_sum, opt);
}

#ifdef __cplusplus
}
#endif

#endif