[API-NEXT,v16,5/9] linux-gen: packet: support parsing of just L3/L4 headers

Message ID 1504782024-26631-6-git-send-email-odpbot@yandex.ru
State Superseded
Headers show
Series
  • [API-NEXT,v16,1/9] test: validation: add IPsec API testsuite
Related show

Commit Message

Github ODP bot Sept. 7, 2017, 11 a.m.
From: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>


IPsec packet postprocessing needs parsing of packets which guarantee
only L3/L4 headers. Separate parsing function doing L3/L4 headers
parsing.

Signed-off-by: Dmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>

---
/** Email created from pull request 81 (lumag:ipsec-packet-impl-2)
 ** https://github.com/Linaro/odp/pull/81
 ** Patch: https://github.com/Linaro/odp/pull/81.patch
 ** Base sha: 7fa8e2c97ed18f8dd6e95cbc78b7e668ccb98869
 ** Merge commit sha: d0f4ea10655492b00c1a40e85a0ba837f06f97c5
 **/
 .../linux-generic/include/odp_packet_internal.h    |  6 ++
 platform/linux-generic/odp_packet.c                | 84 ++++++++++++++--------
 2 files changed, 61 insertions(+), 29 deletions(-)

Patch

diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h
index 91fba1ea..1f215d7d 100644
--- a/platform/linux-generic/include/odp_packet_internal.h
+++ b/platform/linux-generic/include/odp_packet_internal.h
@@ -356,6 +356,12 @@  int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
 int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
 		       odp_pktio_parser_layer_t layer);
 
+/* Perform L3 and L4 parsing up to a given protocol layer */
+int packet_parse_l3_l4(odp_packet_hdr_t *pkt_hdr,
+		       odp_pktio_parser_layer_t layer,
+		       uint32_t l3_offset,
+		       uint16_t ethtype);
+
 /* Reset parser metadata for a new parse */
 void packet_parse_reset(odp_packet_hdr_t *pkt_hdr);
 
diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c
index 2038f60d..1d09fe80 100644
--- a/platform/linux-generic/odp_packet.c
+++ b/platform/linux-generic/odp_packet.c
@@ -262,7 +262,7 @@  void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
 	pkt_hdr->p.error_flags.all  = 0;
 	pkt_hdr->p.input_flags.all  = 0;
 	pkt_hdr->p.output_flags.all = 0;
-	pkt_hdr->p.l2_offset        = 0;
+	pkt_hdr->p.l2_offset        = ODP_PACKET_OFFSET_INVALID;
 	pkt_hdr->p.l3_offset        = ODP_PACKET_OFFSET_INVALID;
 	pkt_hdr->p.l4_offset        = ODP_PACKET_OFFSET_INVALID;
 
@@ -2332,37 +2332,15 @@  static inline void parse_udp(packet_parser_t *prs,
 	*parseptr += sizeof(_odp_udphdr_t);
 }
 
-/**
- * Parse common packet headers up to given layer
- *
- * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be
- * available from the ptr.
- */
-int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
-			uint32_t frame_len, uint32_t seg_len,
-			odp_pktio_parser_layer_t layer)
+static inline
+int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr,
+			      uint32_t offset,
+			      uint32_t frame_len, uint32_t seg_len,
+			      odp_pktio_parser_layer_t layer,
+			      uint16_t ethtype)
 {
-	uint32_t offset;
-	uint16_t ethtype;
-	const uint8_t *parseptr;
 	uint8_t  ip_proto;
 
-	parseptr = ptr;
-	offset = 0;
-
-	if (layer == ODP_PKTIO_PARSER_LAYER_NONE)
-		return 0;
-
-	/* We only support Ethernet for now */
-	prs->input_flags.eth = 1;
-	/* Assume valid L2 header, no CRC/FCS check in SW */
-	prs->input_flags.l2 = 1;
-
-	ethtype = parse_eth(prs, &parseptr, &offset, frame_len);
-
-	if (layer == ODP_PKTIO_PARSER_LAYER_L2)
-		return prs->error_flags.all != 0;
-
 	/* Set l3_offset+flag only for known ethtypes */
 	prs->l3_offset = offset;
 	prs->input_flags.l3 = 1;
@@ -2445,6 +2423,41 @@  int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
 }
 
 /**
+ * Parse common packet headers up to given layer
+ *
+ * The function expects at least PACKET_PARSE_SEG_LEN bytes of data to be
+ * available from the ptr.
+ */
+int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
+			uint32_t frame_len, uint32_t seg_len,
+			odp_pktio_parser_layer_t layer)
+{
+	uint32_t offset;
+	uint16_t ethtype;
+	const uint8_t *parseptr;
+
+	parseptr = ptr;
+	offset = 0;
+
+	if (layer == ODP_PKTIO_PARSER_LAYER_NONE)
+		return 0;
+
+	/* Assume valid L2 header, no CRC/FCS check in SW */
+	prs->l2_offset = offset;
+	prs->input_flags.l2 = 1;
+	/* We only support Ethernet for now */
+	prs->input_flags.eth = 1;
+
+	ethtype = parse_eth(prs, &parseptr, &offset, frame_len);
+
+	if (layer == ODP_PKTIO_PARSER_LAYER_L2)
+		return prs->error_flags.all != 0;
+
+	return packet_parse_common_l3_l4(prs, parseptr, offset, frame_len,
+					 seg_len, layer, ethtype);
+}
+
+/**
  * Simple packet parser
  */
 int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
@@ -2457,6 +2470,19 @@  int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
 				   seg_len, layer);
 }
 
+int packet_parse_l3_l4(odp_packet_hdr_t *pkt_hdr,
+		       odp_pktio_parser_layer_t layer,
+		       uint32_t l3_offset,
+		       uint16_t ethtype)
+{
+	uint32_t seg_len = 0;
+	void *base = packet_map(pkt_hdr, l3_offset, &seg_len, NULL);
+
+	return packet_parse_common_l3_l4(&pkt_hdr->p, base, l3_offset,
+					 pkt_hdr->frame_len, seg_len,
+					 layer, ethtype);
+}
+
 uint64_t odp_packet_to_u64(odp_packet_t hdl)
 {
 	return _odp_pri(hdl);