This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "".
The branch, master has been updated via 5fff93ce094807c460ab7a1bf9b7af429143a19d (commit) via f73efb129c474301d6f70d727452c0c69ce0e309 (commit) via 144a1d8c4d0265ff3ff6ae740b4e99045645e59d (commit) from e89d5d15852b9a64e3aaf115b59c87d07092717d (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 5fff93ce094807c460ab7a1bf9b7af429143a19d Author: Matias Elo matias.elo@nokia.com Date: Tue Sep 13 17:30:12 2016 +0300
linux-gen: packet: identify sctp packets
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/protocols/ip.h b/platform/linux-generic/include/protocols/ip.h index d5277fb..6c089e3 100644 --- a/platform/linux-generic/include/protocols/ip.h +++ b/platform/linux-generic/include/protocols/ip.h @@ -154,6 +154,8 @@ typedef struct ODP_PACKED { #define _ODP_IPPROTO_FRAG 0x2C /**< IPv6 Fragment (44) */ #define _ODP_IPPROTO_AH 0x33 /**< Authentication Header (51) */ #define _ODP_IPPROTO_ESP 0x32 /**< Encapsulating Security Payload (50) */ +#define _ODP_IPPROTO_SCTP 0x84 /**< Stream Control Transmission protocol + (132) */ #define _ODP_IPPROTO_INVALID 0xFF /**< Reserved invalid by IANA */
/**@}*/ diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index df6fd1e..714794a 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -1328,6 +1328,10 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, prs->input_flags.ipsec_esp = 1; break;
+ case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; + break; + default: prs->input_flags.l4 = 0; prs->l4_offset = ODP_PACKET_OFFSET_INVALID;
commit f73efb129c474301d6f70d727452c0c69ce0e309 Author: Matias Elo matias.elo@nokia.com Date: Tue Sep 13 17:30:11 2016 +0300
linux-gen: packet: parse only required packet header layers
Improve performance by parsing only the required protocol layers.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 9b4f59e..b23ad9c 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -328,9 +328,6 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, /* Fill in parser metadata for L2 */ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len);
-/* Perform full packet parse */ -int packet_parse_full(odp_packet_hdr_t *pkt_hdr); - /* Perform packet parse up to a given protocol layer */ int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer);
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 868058d..82760e8 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -775,7 +775,7 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry,
/* Check for lazy parse needed */ if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + packet_parse_layer(pkt_hdr, LAYER_ALL);
/* Return error cos for error packet */ if (pkt_hdr->p.error_flags.all) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index 5f84869..df6fd1e 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -476,8 +476,8 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L3) + packet_parse_layer(pkt_hdr, LAYER_L3); return packet_map(pkt_hdr, pkt_hdr->p.l3_offset, len); }
@@ -485,8 +485,8 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L3) + packet_parse_layer(pkt_hdr, LAYER_L3); return pkt_hdr->p.l3_offset; }
@@ -497,8 +497,8 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1;
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L3) + packet_parse_layer(pkt_hdr, LAYER_L3); pkt_hdr->p.l3_offset = offset; return 0; } @@ -507,8 +507,8 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L4) + packet_parse_layer(pkt_hdr, LAYER_L4); return packet_map(pkt_hdr, pkt_hdr->p.l4_offset, len); }
@@ -516,8 +516,8 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L4) + packet_parse_layer(pkt_hdr, LAYER_L4); return pkt_hdr->p.l4_offset; }
@@ -528,8 +528,8 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset) if (offset >= pkt_hdr->frame_len) return -1;
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L4) + packet_parse_layer(pkt_hdr, LAYER_L4); pkt_hdr->p.l4_offset = offset; return 0; } @@ -1354,18 +1354,6 @@ parse_exit: /** * Simple packet parser */ -int packet_parse_full(odp_packet_hdr_t *pkt_hdr) -{ - uint32_t seg_len; - void *base = packet_map(pkt_hdr, 0, &seg_len); - - return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, - seg_len, LAYER_ALL); -} - -/** - * Simple packet parser - */ int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) { uint32_t seg_len; diff --git a/platform/linux-generic/odp_packet_flags.c b/platform/linux-generic/odp_packet_flags.c index b88324c..798fa11 100644 --- a/platform/linux-generic/odp_packet_flags.c +++ b/platform/linux-generic/odp_packet_flags.c @@ -7,17 +7,17 @@ #include <odp/api/packet_flags.h> #include <odp_packet_internal.h>
-#define retflag(pkt, x) do { \ +#define retflag(pkt, x, layer) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (packet_parse_not_complete(pkt_hdr)) \ - packet_parse_full(pkt_hdr); \ + if (pkt_hdr->p.parsed_layers < layer) \ + packet_parse_layer(pkt_hdr, layer); \ return pkt_hdr->p.x; \ } while (0)
-#define setflag(pkt, x, v) do { \ +#define setflag(pkt, x, v, layer) do { \ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ - if (packet_parse_not_complete(pkt_hdr)) \ - packet_parse_full(pkt_hdr); \ + if (pkt_hdr->p.parsed_layers < layer) \ + packet_parse_layer(pkt_hdr, layer); \ pkt_hdr->p.x = v & 1; \ } while (0)
@@ -26,7 +26,7 @@ int odp_packet_has_error(odp_packet_t pkt) odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + packet_parse_layer(pkt_hdr, LAYER_ALL); return odp_packet_hdr(pkt)->p.error_flags.all != 0; }
@@ -51,30 +51,30 @@ int odp_packet_has_l2_error(odp_packet_t pkt)
int odp_packet_has_l3(odp_packet_t pkt) { - retflag(pkt, input_flags.l3); + retflag(pkt, input_flags.l3, LAYER_L3); }
int odp_packet_has_l3_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L3) + packet_parse_layer(pkt_hdr, LAYER_L3);
return pkt_hdr->p.error_flags.ip_err; }
int odp_packet_has_l4(odp_packet_t pkt) { - retflag(pkt, input_flags.l4); + retflag(pkt, input_flags.l4, LAYER_L4); }
int odp_packet_has_l4_error(odp_packet_t pkt) { odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + if (pkt_hdr->p.parsed_layers < LAYER_L4) + packet_parse_layer(pkt_hdr, LAYER_L4);
return pkt_hdr->p.error_flags.tcp_err | pkt_hdr->p.error_flags.udp_err; } @@ -88,12 +88,12 @@ int odp_packet_has_eth(odp_packet_t pkt)
int odp_packet_has_eth_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_bcast); + retflag(pkt, input_flags.eth_bcast, LAYER_L2); }
int odp_packet_has_eth_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.eth_mcast); + retflag(pkt, input_flags.eth_mcast, LAYER_L2); }
int odp_packet_has_jumbo(odp_packet_t pkt) @@ -105,72 +105,72 @@ int odp_packet_has_jumbo(odp_packet_t pkt)
int odp_packet_has_vlan(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan); + retflag(pkt, input_flags.vlan, LAYER_L2); }
int odp_packet_has_vlan_qinq(odp_packet_t pkt) { - retflag(pkt, input_flags.vlan_qinq); + retflag(pkt, input_flags.vlan_qinq, LAYER_L2); }
int odp_packet_has_arp(odp_packet_t pkt) { - retflag(pkt, input_flags.arp); + retflag(pkt, input_flags.arp, LAYER_L3); }
int odp_packet_has_ipv4(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv4); + retflag(pkt, input_flags.ipv4, LAYER_L3); }
int odp_packet_has_ipv6(odp_packet_t pkt) { - retflag(pkt, input_flags.ipv6); + retflag(pkt, input_flags.ipv6, LAYER_L3); }
int odp_packet_has_ip_bcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_bcast); + retflag(pkt, input_flags.ip_bcast, LAYER_L3); }
int odp_packet_has_ip_mcast(odp_packet_t pkt) { - retflag(pkt, input_flags.ip_mcast); + retflag(pkt, input_flags.ip_mcast, LAYER_L3); }
int odp_packet_has_ipfrag(odp_packet_t pkt) { - retflag(pkt, input_flags.ipfrag); + retflag(pkt, input_flags.ipfrag, LAYER_L3); }
int odp_packet_has_ipopt(odp_packet_t pkt) { - retflag(pkt, input_flags.ipopt); + retflag(pkt, input_flags.ipopt, LAYER_L3); }
int odp_packet_has_ipsec(odp_packet_t pkt) { - retflag(pkt, input_flags.ipsec); + retflag(pkt, input_flags.ipsec, LAYER_L4); }
int odp_packet_has_udp(odp_packet_t pkt) { - retflag(pkt, input_flags.udp); + retflag(pkt, input_flags.udp, LAYER_L4); }
int odp_packet_has_tcp(odp_packet_t pkt) { - retflag(pkt, input_flags.tcp); + retflag(pkt, input_flags.tcp, LAYER_L4); }
int odp_packet_has_sctp(odp_packet_t pkt) { - retflag(pkt, input_flags.sctp); + retflag(pkt, input_flags.sctp, LAYER_L4); }
int odp_packet_has_icmp(odp_packet_t pkt) { - retflag(pkt, input_flags.icmp); + retflag(pkt, input_flags.icmp, LAYER_L4); }
int odp_packet_has_flow_hash(odp_packet_t pkt) @@ -189,7 +189,7 @@ int odp_packet_has_ts(odp_packet_t pkt)
odp_packet_color_t odp_packet_color(odp_packet_t pkt) { - retflag(pkt, input_flags.color); + retflag(pkt, input_flags.color, LAYER_ALL); }
void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) @@ -197,7 +197,7 @@ void odp_packet_color_set(odp_packet_t pkt, odp_packet_color_t color) odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + packet_parse_layer(pkt_hdr, LAYER_ALL);
pkt_hdr->p.input_flags.color = color; } @@ -207,19 +207,19 @@ odp_bool_t odp_packet_drop_eligible(odp_packet_t pkt) odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + packet_parse_layer(pkt_hdr, LAYER_ALL);
return !pkt_hdr->p.input_flags.nodrop; }
void odp_packet_drop_eligible_set(odp_packet_t pkt, odp_bool_t drop) { - setflag(pkt, input_flags.nodrop, !drop); + setflag(pkt, input_flags.nodrop, !drop, LAYER_ALL); }
int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) { - retflag(pkt, output_flags.shaper_len_adj); + retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); }
void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) @@ -227,7 +227,7 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj) odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (packet_parse_not_complete(pkt_hdr)) - packet_parse_full(pkt_hdr); + packet_parse_layer(pkt_hdr, LAYER_ALL);
pkt_hdr->p.output_flags.shaper_len_adj = adj; } @@ -236,107 +236,107 @@ void odp_packet_shaper_len_adjust_set(odp_packet_t pkt, int8_t adj)
void odp_packet_has_l2_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l2, val); + setflag(pkt, input_flags.l2, val, LAYER_L2); }
void odp_packet_has_l3_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l3, val); + setflag(pkt, input_flags.l3, val, LAYER_L3); }
void odp_packet_has_l4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.l4, val); + setflag(pkt, input_flags.l4, val, LAYER_L4); }
void odp_packet_has_eth_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth, val); + setflag(pkt, input_flags.eth, val, LAYER_L2); }
void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_bcast, val); + setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); }
void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.eth_mcast, val); + setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); }
void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.jumbo, val); + setflag(pkt, input_flags.jumbo, val, LAYER_L2); }
void odp_packet_has_vlan_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan, val); + setflag(pkt, input_flags.vlan, val, LAYER_L2); }
void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.vlan_qinq, val); + setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); }
void odp_packet_has_arp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.arp, val); + setflag(pkt, input_flags.arp, val, LAYER_L3); }
void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv4, val); + setflag(pkt, input_flags.ipv4, val, LAYER_L3); }
void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipv6, val); + setflag(pkt, input_flags.ipv6, val, LAYER_L3); }
void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_bcast, val); + setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); }
void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ip_mcast, val); + setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); }
void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipfrag, val); + setflag(pkt, input_flags.ipfrag, val, LAYER_L3); }
void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipopt, val); + setflag(pkt, input_flags.ipopt, val, LAYER_L3); }
void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.ipsec, val); + setflag(pkt, input_flags.ipsec, val, LAYER_L4); }
void odp_packet_has_udp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.udp, val); + setflag(pkt, input_flags.udp, val, LAYER_L4); }
void odp_packet_has_tcp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.tcp, val); + setflag(pkt, input_flags.tcp, val, LAYER_L4); }
void odp_packet_has_sctp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.sctp, val); + setflag(pkt, input_flags.sctp, val, LAYER_L4); }
void odp_packet_has_icmp_set(odp_packet_t pkt, int val) { - setflag(pkt, input_flags.icmp, val); + setflag(pkt, input_flags.icmp, val, LAYER_L4); }
void odp_packet_has_flow_hash_clr(odp_packet_t pkt)
commit 144a1d8c4d0265ff3ff6ae740b4e99045645e59d Author: Matias Elo matias.elo@nokia.com Date: Tue Sep 13 17:30:10 2016 +0300
linux-gen: packet: enable parsing only selected packet header layers
Enable parsing packet headers up to a given protocol layer.
Signed-off-by: Matias Elo matias.elo@nokia.com Reviewed-and-tested-by: Bill Fischofer bill.fischofer@linaro.org Signed-off-by: Maxim Uvarov maxim.uvarov@linaro.org
diff --git a/platform/linux-generic/include/odp_packet_internal.h b/platform/linux-generic/include/odp_packet_internal.h index 392d670..9b4f59e 100644 --- a/platform/linux-generic/include/odp_packet_internal.h +++ b/platform/linux-generic/include/odp_packet_internal.h @@ -41,7 +41,6 @@ typedef union {
struct { uint64_t parsed_l2:1; /**< L2 parsed */ - uint64_t parsed_all:1;/**< Parsing complete */ uint64_t dst_queue:1; /**< Dst queue present */
uint64_t flow_hash:1; /**< Flow hash present */ @@ -131,6 +130,18 @@ ODP_STATIC_ASSERT(sizeof(output_flags_t) == sizeof(uint32_t), "OUTPUT_FLAGS_SIZE_ERROR");
/** + * Protocol stack layers + */ +typedef enum { + LAYER_NONE = 0, + LAYER_L1, + LAYER_L2, + LAYER_L3, + LAYER_L4, + LAYER_ALL +} layer_t; + +/** * Packet parser metadata */ typedef struct { @@ -145,6 +156,10 @@ typedef struct { uint32_t l3_len; /**< Layer 3 length */ uint32_t l4_len; /**< Layer 4 length */
+ layer_t parsed_layers; /**< Highest parsed protocol stack layer */ + uint16_t ethtype; /**< EtherType */ + uint8_t ip_proto; /**< IP protocol */ + } packet_parser_t;
/** @@ -300,7 +315,7 @@ static inline int packet_parse_l2_not_done(packet_parser_t *prs)
static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) { - return !pkt_hdr->p.input_flags.parsed_all; + return pkt_hdr->p.parsed_layers != LAYER_ALL; }
/* Forward declarations */ @@ -316,6 +331,9 @@ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len); /* Perform full packet parse */ int packet_parse_full(odp_packet_hdr_t *pkt_hdr);
+/* Perform packet parse up to a given protocol layer */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); + /* Reset parser metadata for a new parse */ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr);
@@ -349,7 +367,7 @@ static inline void packet_set_ts(odp_packet_hdr_t *pkt_hdr, odp_time_t *ts) }
int packet_parse_common(packet_parser_t *pkt_hdr, const uint8_t *ptr, - uint32_t pkt_len, uint32_t seg_len); + uint32_t pkt_len, uint32_t seg_len, layer_t layer);
int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr);
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index ea223bf..868058d 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -821,7 +821,7 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, packet_parse_reset(pkt_hdr); packet_set_len(pkt_hdr, pkt_len);
- packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len); + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, LAYER_ALL); cos = cls_select_cos(entry, base, pkt_hdr);
if (cos == NULL) diff --git a/platform/linux-generic/odp_packet.c b/platform/linux-generic/odp_packet.c index c4cf324..5f84869 100644 --- a/platform/linux-generic/odp_packet.c +++ b/platform/linux-generic/odp_packet.c @@ -30,12 +30,13 @@ static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) { pkt_hdr->p.input_flags.parsed_l2 = 1; - pkt_hdr->p.input_flags.parsed_all = 1; + pkt_hdr->p.parsed_layers = LAYER_ALL; }
void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) { /* Reset parser metadata before new parse */ + pkt_hdr->p.parsed_layers = LAYER_NONE; pkt_hdr->p.error_flags.all = 0; pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; @@ -50,6 +51,8 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) static void packet_init(pool_entry_t *pool, odp_packet_hdr_t *pkt_hdr, size_t size, int parse) { + pkt_hdr->p.parsed_layers = LAYER_NONE; + pkt_hdr->p.input_flags.all = 0; pkt_hdr->p.output_flags.all = 0; pkt_hdr->p.error_flags.all = 0; @@ -1166,151 +1169,185 @@ void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) }
/** - * Parse common packet headers + * 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) + uint32_t frame_len, uint32_t seg_len, layer_t layer) { - const _odp_ethhdr_t *eth; - const _odp_vlanhdr_t *vlan; - uint16_t ethtype; uint32_t offset; - uint8_t ip_proto = 0; const uint8_t *parseptr; - uint16_t macaddr0, macaddr2, macaddr4; - - offset = sizeof(_odp_ethhdr_t); - if (packet_parse_l2_not_done(prs)) - packet_parse_l2(prs, frame_len); - - eth = (const _odp_ethhdr_t *)ptr; - - /* Handle Ethernet broadcast/multicast addresses */ - macaddr0 = odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); - prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; - - if (macaddr0 == 0xffff) { - macaddr2 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 1)); - macaddr4 = - odp_be_to_cpu_16(*((const uint16_t *) - (const void *)eth + 2)); - prs->input_flags.eth_bcast = - (macaddr2 == 0xffff) && (macaddr4 == 0xffff); - } else { - prs->input_flags.eth_bcast = 0; - }
- /* Get Ethertype */ - ethtype = odp_be_to_cpu_16(eth->type); - parseptr = (const uint8_t *)(eth + 1); - - /* Check for SNAP vs. DIX */ - if (ethtype < _ODP_ETH_LEN_MAX) { - prs->input_flags.snap = 1; - if (ethtype > frame_len - offset) { - prs->error_flags.snap_len = 1; - goto parse_exit; + switch (prs->parsed_layers) { + case LAYER_NONE: + case LAYER_L2: + { + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; + + offset = sizeof(_odp_ethhdr_t); + if (packet_parse_l2_not_done(prs)) + packet_parse_l2(prs, frame_len); + + eth = (const _odp_ethhdr_t *)ptr; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth)); + prs->input_flags.eth_mcast = (macaddr0 & 0x0100) == 0x0100; + + if (macaddr0 == 0xffff) { + macaddr2 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + prs->input_flags.eth_bcast = + (macaddr2 == 0xffff) && (macaddr4 == 0xffff); + } else { + prs->input_flags.eth_bcast = 0; } - ethtype = odp_be_to_cpu_16(*((const uint16_t *) - (uintptr_t)(parseptr + 6))); - offset += 8; - parseptr += 8; - } - - /* Parse the VLAN header(s), if present */ - if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { - prs->input_flags.vlan_qinq = 1; - prs->input_flags.vlan = 1;
- vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } - - if (ethtype == _ODP_ETHTYPE_VLAN) { - prs->input_flags.vlan = 1; - vlan = (const _odp_vlanhdr_t *)parseptr; - ethtype = odp_be_to_cpu_16(vlan->type); - offset += sizeof(_odp_vlanhdr_t); - parseptr += sizeof(_odp_vlanhdr_t); - } - - /* Set l3_offset+flag only for known ethtypes */ - prs->input_flags.l3 = 1; - prs->l3_offset = offset; + /* Get Ethertype */ + prs->ethtype = odp_be_to_cpu_16(eth->type); + parseptr = (const uint8_t *)(eth + 1); + + /* Check for SNAP vs. DIX */ + if (prs->ethtype < _ODP_ETH_LEN_MAX) { + prs->input_flags.snap = 1; + if (prs->ethtype > frame_len - offset) { + prs->error_flags.snap_len = 1; + goto parse_exit; + } + prs->ethtype = odp_be_to_cpu_16(*((const uint16_t *) + (uintptr_t) + (parseptr + 6))); + offset += 8; + parseptr += 8; + }
- /* Parse Layer 3 headers */ - switch (ethtype) { - case _ODP_ETHTYPE_IPV4: - prs->input_flags.ipv4 = 1; - ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len); - break; + /* Parse the VLAN header(s), if present */ + if (prs->ethtype == _ODP_ETHTYPE_VLAN_OUTER) { + prs->input_flags.vlan_qinq = 1; + prs->input_flags.vlan = 1;
- case _ODP_ETHTYPE_IPV6: - prs->input_flags.ipv6 = 1; - ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, - seg_len); - break; + vlan = (const _odp_vlanhdr_t *)parseptr; + prs->ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + }
- case _ODP_ETHTYPE_ARP: - prs->input_flags.arp = 1; - ip_proto = 255; /* Reserved invalid by IANA */ - break; + if (prs->ethtype == _ODP_ETHTYPE_VLAN) { + prs->input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)parseptr; + prs->ethtype = odp_be_to_cpu_16(vlan->type); + offset += sizeof(_odp_vlanhdr_t); + parseptr += sizeof(_odp_vlanhdr_t); + }
- default: - prs->input_flags.l3 = 0; - prs->l3_offset = ODP_PACKET_OFFSET_INVALID; - ip_proto = 255; /* Reserved invalid by IANA */ + prs->l3_offset = offset; + prs->parsed_layers = LAYER_L2; + if (layer == LAYER_L2) + return prs->error_flags.all != 0; } + case LAYER_L3: + { + offset = prs->l3_offset; + parseptr = (const uint8_t *)(ptr + offset); + /* Set l3_offset+flag only for known ethtypes */ + prs->input_flags.l3 = 1; + + /* Parse Layer 3 headers */ + switch (prs->ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + prs->ip_proto = parse_ipv4(prs, &parseptr, &offset, + frame_len); + break; + + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + prs->ip_proto = parse_ipv6(prs, &parseptr, &offset, + frame_len, seg_len); + break; + + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + prs->ip_proto = 255; /* Reserved invalid by IANA */ + break; + + default: + prs->input_flags.l3 = 0; + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; + prs->ip_proto = 255; /* Reserved invalid by IANA */ + }
- /* Set l4_offset+flag only for known ip_proto */ - prs->input_flags.l4 = 1; - prs->l4_offset = offset; - - /* Parse Layer 4 headers */ - switch (ip_proto) { - case _ODP_IPPROTO_ICMP: - prs->input_flags.icmp = 1; - break; - - case _ODP_IPPROTO_TCP: - if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) - return -1; - prs->input_flags.tcp = 1; - parse_tcp(prs, &parseptr, NULL); - break; - - case _ODP_IPPROTO_UDP: - if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) - return -1; - prs->input_flags.udp = 1; - parse_udp(prs, &parseptr, NULL); - break; + /* Set l4_offset+flag only for known ip_proto */ + prs->l4_offset = offset; + prs->parsed_layers = LAYER_L3; + if (layer == LAYER_L3) + return prs->error_flags.all != 0; + } + case LAYER_L4: + { + offset = prs->l4_offset; + parseptr = (const uint8_t *)(ptr + offset); + prs->input_flags.l4 = 1; + + /* Parse Layer 4 headers */ + switch (prs->ip_proto) { + case _ODP_IPPROTO_ICMP: + prs->input_flags.icmp = 1; + break; + + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; + prs->input_flags.tcp = 1; + parse_tcp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; + prs->input_flags.udp = 1; + parse_udp(prs, &parseptr, NULL); + break; + + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; + + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; + break; + + default: + prs->input_flags.l4 = 0; + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; + break; + }
- case _ODP_IPPROTO_AH: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_ah = 1; + prs->parsed_layers = LAYER_L4; break; - - case _ODP_IPPROTO_ESP: - prs->input_flags.ipsec = 1; - prs->input_flags.ipsec_esp = 1; + } + case LAYER_ALL: break;
default: - prs->input_flags.l4 = 0; - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; - break; + ODP_ERR("Invalid parse layer: %d\n", (int)layer); + return -1; }
+ prs->parsed_layers = LAYER_ALL; + parse_exit: - prs->input_flags.parsed_all = 1; return prs->error_flags.all != 0; }
@@ -1323,5 +1360,17 @@ int packet_parse_full(odp_packet_hdr_t *pkt_hdr) void *base = packet_map(pkt_hdr, 0, &seg_len);
return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, - seg_len); + seg_len, LAYER_ALL); +} + +/** + * Simple packet parser + */ +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) +{ + uint32_t seg_len; + void *base = packet_map(pkt_hdr, 0, &seg_len); + + return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, + seg_len, layer); }
-----------------------------------------------------------------------
Summary of changes: .../linux-generic/include/odp_packet_internal.h | 25 +- platform/linux-generic/include/protocols/ip.h | 2 + platform/linux-generic/odp_classification.c | 4 +- platform/linux-generic/odp_packet.c | 311 ++++++++++++--------- platform/linux-generic/odp_packet_flags.c | 112 ++++---- 5 files changed, 256 insertions(+), 198 deletions(-)
hooks/post-receive