breaks build: https://travis-ci.org/muvarov/odp/jobs/218496566
On 4 April 2017 at 09:28, Matias Elo <[email protected]> wrote: > Replace old lazy parsing code with a new packet parsing implementation > which follows the latest API (parsing level is selected using > odp_pktio_config()). > > Signed-off-by: Matias Elo <[email protected]> > Reviewed-and-tested-by: Bill Fischofer <[email protected]> > --- > .../include/odp/api/plat/packet_types.h | 1 - > .../linux-generic/include/odp_packet_internal.h | 39 +-- > platform/linux-generic/odp_classification.c | 7 +- > platform/linux-generic/odp_packet.c | 382 > ++++++++------------- > platform/linux-generic/odp_packet_flags.c | 111 +++--- > platform/linux-generic/odp_packet_io.c | 2 + > platform/linux-generic/pktio/dpdk.c | 3 +- > platform/linux-generic/pktio/loop.c | 3 +- > platform/linux-generic/pktio/netmap.c | 3 +- > platform/linux-generic/pktio/pcap.c | 3 +- > platform/linux-generic/pktio/socket.c | 3 +- > platform/linux-generic/pktio/socket_mmap.c | 3 +- > platform/linux-generic/pktio/tap.c | 3 +- > 13 files changed, 217 insertions(+), 346 deletions(-) > > diff --git a/platform/linux-generic/include/odp/api/plat/packet_types.h > b/platform/linux-generic/include/odp/api/plat/packet_types.h > index b8f665d..f4e8501 100644 > --- a/platform/linux-generic/include/odp/api/plat/packet_types.h > +++ b/platform/linux-generic/include/odp/api/plat/packet_types.h > @@ -96,7 +96,6 @@ typedef union { > uint64_t all; > > struct { > - uint64_t parsed_l2:1; /**< L2 parsed */ > uint64_t dst_queue:1; /**< Dst queue present */ > > uint64_t flow_hash:1; /**< Flow hash present */ > diff --git a/platform/linux-generic/include/odp_packet_internal.h > b/platform/linux-generic/include/odp_packet_internal.h > index 0a9f177..d0db700 100644 > --- a/platform/linux-generic/include/odp_packet_internal.h > +++ b/platform/linux-generic/include/odp_packet_internal.h > @@ -80,18 +80,6 @@ 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 { > @@ -102,14 +90,6 @@ typedef struct { > uint32_t l2_offset; /**< offset to L2 hdr, e.g. Eth */ > uint32_t l3_offset; /**< offset to L3 hdr, e.g. IPv4, IPv6 */ > uint32_t l4_offset; /**< offset to L4 hdr (TCP, UDP, SCTP, also > ICMP) */ > - > - uint32_t l3_len; /**< Layer 3 length */ > - uint32_t l4_len; /**< Layer 4 length */ > - > - uint16_t ethtype; /**< EtherType */ > - uint8_t ip_proto; /**< IP protocol */ > - uint8_t parsed_layers; /**< Highest parsed protocol stack layer */ > - > } packet_parser_t; > > /** > @@ -203,16 +183,6 @@ static inline void packet_set_len(odp_packet_hdr_t > *pkt_hdr, uint32_t len) > pkt_hdr->frame_len = len; > } > > -static inline int packet_parse_l2_not_done(packet_parser_t *prs) > -{ > - return !prs->input_flags.parsed_l2; > -} > - > -static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr) > -{ > - return pkt_hdr->p.parsed_layers != LAYER_ALL; > -} > - > /* Forward declarations */ > int _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t > dstpkt); > > @@ -220,11 +190,9 @@ int _odp_packet_copy_md_to_packet(odp_packet_t > srcpkt, odp_packet_t dstpkt); > int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len, > odp_packet_t pkt[], int max_num); > > -/* Fill in parser metadata for L2 */ > -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len); > - > /* Perform packet parse up to a given protocol layer */ > -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer); > +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, > + odp_pktio_parser_layer_t layer); > > /* Reset parser metadata for a new parse */ > void packet_parse_reset(odp_packet_hdr_t *pkt_hdr); > @@ -264,7 +232,8 @@ 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, layer_t layer); > + uint32_t pkt_len, uint32_t seg_len, > + odp_pktio_parser_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 5d96b00..7ebc47d 100644 > --- a/platform/linux-generic/odp_classification.c > +++ b/platform/linux-generic/odp_classification.c > @@ -790,10 +790,6 @@ static inline cos_t *cls_select_cos(pktio_entry_t > *entry, > cls = &entry->s.cls; > default_cos = cls->default_cos; > > - /* Check for lazy parse needed */ > - if (packet_parse_not_complete(pkt_hdr)) > - packet_parse_layer(pkt_hdr, LAYER_ALL); > - > /* Return error cos for error packet */ > if (pkt_hdr->p.error_flags.all) > return cls->error_cos; > @@ -838,7 +834,8 @@ 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, > LAYER_ALL); > + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, > + ODP_PKTIO_PARSER_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 a75c191..0b70c5c 100644 > --- a/platform/linux-generic/odp_packet.c > +++ b/platform/linux-generic/odp_packet.c > @@ -220,16 +220,9 @@ static inline void *packet_map(odp_packet_hdr_t > *pkt_hdr, > return addr; > } > > -static inline void packet_parse_disable(odp_packet_hdr_t *pkt_hdr) > -{ > - pkt_hdr->p.input_flags.parsed_l2 = 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; > @@ -241,8 +234,7 @@ void packet_parse_reset(odp_packet_hdr_t *pkt_hdr) > /** > * Initialize packet > */ > -static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len, > - int parse) > +static inline void packet_init(odp_packet_hdr_t *pkt_hdr, uint32_t len) > { > uint32_t seg_len; > int num = pkt_hdr->buf_hdr.segcount; > @@ -257,7 +249,6 @@ static inline void packet_init(odp_packet_hdr_t > *pkt_hdr, uint32_t len, > pkt_hdr->buf_hdr.seg[num - 1].len = seg_len; > } > > - 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; > @@ -266,10 +257,6 @@ static inline void packet_init(odp_packet_hdr_t > *pkt_hdr, uint32_t len, > pkt_hdr->p.l3_offset = ODP_PACKET_OFFSET_INVALID; > pkt_hdr->p.l4_offset = ODP_PACKET_OFFSET_INVALID; > > - /* Disable lazy parsing on user allocated packets */ > - if (!parse) > - packet_parse_disable(pkt_hdr); > - > /* > * Packet headroom is set from the pool's headroom > * Packet tailroom is rounded up to fill the last > @@ -485,7 +472,7 @@ static inline odp_packet_hdr_t > *free_segments(odp_packet_hdr_t *pkt_hdr, > } > > static inline int packet_alloc(pool_t *pool, uint32_t len, int max_pkt, > - int num_seg, odp_packet_t *pkt, int parse) > + int num_seg, odp_packet_t *pkt) > { > int num_buf, i; > int num = max_pkt; > @@ -518,7 +505,7 @@ static inline int packet_alloc(pool_t *pool, uint32_t > len, int max_pkt, > pkt[i] = packet_handle(hdr); > init_segments(&pkt_hdr[i * num_seg], num_seg); > > - packet_init(hdr, len, parse); > + packet_init(hdr, len); > } > > return num; > @@ -531,7 +518,7 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t > len, > int num, num_seg; > > num_seg = num_segments(len); > - num = packet_alloc(pool, len, max_num, num_seg, pkt, 1); > + num = packet_alloc(pool, len, max_num, num_seg, pkt); > > return num; > } > @@ -551,7 +538,7 @@ odp_packet_t odp_packet_alloc(odp_pool_t pool_hdl, > uint32_t len) > return ODP_PACKET_INVALID; > > num_seg = num_segments(len); > - num = packet_alloc(pool, len, 1, num_seg, &pkt, 0); > + num = packet_alloc(pool, len, 1, num_seg, &pkt); > > if (odp_unlikely(num == 0)) > return ODP_PACKET_INVALID; > @@ -574,7 +561,7 @@ int odp_packet_alloc_multi(odp_pool_t pool_hdl, > uint32_t len, > return -1; > > num_seg = num_segments(len); > - num = packet_alloc(pool, len, max_num, num_seg, pkt, 0); > + num = packet_alloc(pool, len, max_num, num_seg, pkt); > > return num; > } > @@ -630,7 +617,7 @@ int odp_packet_reset(odp_packet_t pkt, uint32_t len) > if (len > pool->headroom + pool->data_size + pool->tailroom) > return -1; > > - packet_init(pkt_hdr, len, 0); > + packet_init(pkt_hdr, len); > > return 0; > } > @@ -1241,8 +1228,6 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t > *len) > { > odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); > > - 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, NULL); > } > > @@ -1250,8 +1235,6 @@ uint32_t odp_packet_l3_offset(odp_packet_t pkt) > { > odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); > > - if (pkt_hdr->p.parsed_layers < LAYER_L3) > - packet_parse_layer(pkt_hdr, LAYER_L3); > return pkt_hdr->p.l3_offset; > } > > @@ -1262,8 +1245,6 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, > uint32_t offset) > if (offset >= pkt_hdr->frame_len) > return -1; > > - if (pkt_hdr->p.parsed_layers < LAYER_L3) > - packet_parse_layer(pkt_hdr, LAYER_L3); > pkt_hdr->p.l3_offset = offset; > return 0; > } > @@ -1272,8 +1253,6 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t > *len) > { > odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); > > - 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, NULL); > } > > @@ -1281,8 +1260,6 @@ uint32_t odp_packet_l4_offset(odp_packet_t pkt) > { > odp_packet_hdr_t *pkt_hdr = packet_hdr(pkt); > > - if (pkt_hdr->p.parsed_layers < LAYER_L4) > - packet_parse_layer(pkt_hdr, LAYER_L4); > return pkt_hdr->p.l4_offset; > } > > @@ -1293,8 +1270,6 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, > uint32_t offset) > if (offset >= pkt_hdr->frame_len) > return -1; > > - if (pkt_hdr->p.parsed_layers < LAYER_L4) > - packet_parse_layer(pkt_hdr, LAYER_L4); > pkt_hdr->p.l4_offset = offset; > return 0; > } > @@ -1773,12 +1748,11 @@ static inline uint8_t parse_ipv4(packet_parser_t > *prs, const uint8_t **parseptr, > uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); > uint16_t frag_offset; > uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr); > - > - prs->l3_len = odp_be_to_cpu_16(ipv4->tot_len); > + uint32_t l3_len = odp_be_to_cpu_16(ipv4->tot_len); > > if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN) || > odp_unlikely(ver != 4) || > - (prs->l3_len > frame_len - *offset)) { > + (l3_len > frame_len - *offset)) { > prs->error_flags.ip_err = 1; > return 0; > } > @@ -1815,13 +1789,12 @@ static inline uint8_t parse_ipv6(packet_parser_t > *prs, const uint8_t **parseptr, > const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; > const _odp_ipv6hdr_ext_t *ipv6ext; > uint32_t dstaddr0 = odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); > - > - prs->l3_len = odp_be_to_cpu_16(ipv6->payload_len) + > - _ODP_IPV6HDR_LEN; > + uint32_t l3_len = odp_be_to_cpu_16(ipv6->payload_len) + > + _ODP_IPV6HDR_LEN; > > /* Basic sanity checks on IPv6 header */ > if ((odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || > - prs->l3_len > frame_len - *offset) { > + l3_len > frame_len - *offset) { > prs->error_flags.ip_err = 1; > return 0; > } > @@ -1882,9 +1855,6 @@ static inline void parse_tcp(packet_parser_t *prs, > else if ((uint32_t)tcp->hl * 4 > sizeof(_odp_tcphdr_t)) > prs->input_flags.tcpopt = 1; > > - prs->l4_len = prs->l3_len + > - prs->l3_offset - prs->l4_offset; > - > if (offset) > *offset += (uint32_t)tcp->hl * 4; > *parseptr += (uint32_t)tcp->hl * 4; > @@ -1899,13 +1869,8 @@ static inline void parse_udp(packet_parser_t *prs, > const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; > uint32_t udplen = odp_be_to_cpu_16(udp->length); > > - if (udplen < sizeof(_odp_udphdr_t) || > - udplen > (prs->l3_len + > - prs->l4_offset - prs->l3_offset)) { > + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) > prs->error_flags.udp_err = 1; > - } > - > - prs->l4_len = udplen; > > if (offset) > *offset += sizeof(_odp_udphdr_t); > @@ -1913,218 +1878,170 @@ static inline void parse_udp(packet_parser_t > *prs, > } > > /** > - * Initialize L2 related parser flags and metadata > - */ > -void packet_parse_l2(packet_parser_t *prs, uint32_t frame_len) > -{ > - /* Packet alloc or reset have already init other offsets and flags > */ > - > - /* We only support Ethernet for now */ > - prs->input_flags.eth = 1; > - > - /* Detect jumbo frames */ > - if (frame_len > _ODP_ETH_LEN_MAX) > - prs->input_flags.jumbo = 1; > - > - /* Assume valid L2 header, no CRC/FCS check in SW */ > - prs->input_flags.l2 = 1; > - > - prs->input_flags.parsed_l2 = 1; > -} > - > -/** > * 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, layer_t > layer) > + uint32_t frame_len, uint32_t seg_len, > + odp_pktio_parser_layer_t layer) > { > uint32_t offset; > + uint16_t ethtype; > const uint8_t *parseptr; > + uint8_t ip_proto; > + const _odp_ethhdr_t *eth; > + uint16_t macaddr0, macaddr2, macaddr4; > + const _odp_vlanhdr_t *vlan; > + > + 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; > + /* Detect jumbo frames */ > + if (frame_len > _ODP_ETH_LEN_MAX) > + prs->input_flags.jumbo = 1; > + > + offset = sizeof(_odp_ethhdr_t); > + 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; > + } > > - switch (prs->parsed_layers) { > - case LAYER_NONE: > - /* Fall through */ > + /* Get Ethertype */ > + ethtype = odp_be_to_cpu_16(eth->type); > + parseptr = (const uint8_t *)(eth + 1); > > - 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; > + /* 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; > } > + ethtype = odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) > + (parseptr + 6))); > + offset += 8; > + parseptr += 8; > + } > > - /* 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 the VLAN header(s), if present */ > + if (ethtype == _ODP_ETHTYPE_VLAN_OUTER) { > + prs->input_flags.vlan_qinq = 1; > + prs->input_flags.vlan = 1; > > - /* 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; > + vlan = (const _odp_vlanhdr_t *)parseptr; > + ethtype = odp_be_to_cpu_16(vlan->type); > + offset += sizeof(_odp_vlanhdr_t); > + parseptr += sizeof(_odp_vlanhdr_t); > + } > > - 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); > - } > + 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); > + } > > - 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); > - } > + if (layer == ODP_PKTIO_PARSER_LAYER_L2) > + return prs->error_flags.all != 0; > > - prs->l3_offset = offset; > - prs->parsed_layers = LAYER_L2; > - if (layer == LAYER_L2) > - return prs->error_flags.all != 0; > - } > - /* Fall through */ > + /* Set l3_offset+flag only for known ethtypes */ > + prs->l3_offset = offset; > + prs->input_flags.l3 = 1; > > - 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 > */ > - } > + /* 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; > + > + case _ODP_ETHTYPE_IPV6: > + prs->input_flags.ipv6 = 1; > + ip_proto = parse_ipv6(prs, &parseptr, &offset, frame_len, > + seg_len); > + break; > + > + case _ODP_ETHTYPE_ARP: > + prs->input_flags.arp = 1; > + ip_proto = 255; /* Reserved invalid by IANA */ > + 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; > + default: > + prs->input_flags.l3 = 0; > + prs->l3_offset = ODP_PACKET_OFFSET_INVALID; > + ip_proto = 255; /* Reserved invalid by IANA */ > } > + > + if (layer == ODP_PKTIO_PARSER_LAYER_L3) > + return prs->error_flags.all != 0; > + > + /* Set l4_offset+flag only for known ip_proto */ > + prs->l4_offset = offset; > + prs->input_flags.l4 = 1; > + > + /* Parse Layer 4 headers */ > + switch (ip_proto) { > + case _ODP_IPPROTO_ICMPv4: > /* Fall through */ > > - 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_ICMPv4: > - /* Fall through */ > - > - case _ODP_IPPROTO_ICMPv6: > - 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; > - > - case _ODP_IPPROTO_SCTP: > - prs->input_flags.sctp = 1; > - break; > - > - default: > - prs->input_flags.l4 = 0; > - prs->l4_offset = ODP_PACKET_OFFSET_INVALID; > - break; > - } > + case _ODP_IPPROTO_ICMPv6: > + prs->input_flags.icmp = 1; > + break; > > - prs->parsed_layers = LAYER_L4; > + 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 LAYER_ALL: > + 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; > > - default: > - ODP_ERR("Invalid parse layer: %d\n", (int)layer); > - return -1; > - } > + 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; > > - prs->parsed_layers = LAYER_ALL; > + case _ODP_IPPROTO_SCTP: > + prs->input_flags.sctp = 1; > + break; > > + default: > + prs->input_flags.l4 = 0; > + prs->l4_offset = ODP_PACKET_OFFSET_INVALID; > + break; > + } > parse_exit: > return prs->error_flags.all != 0; > } > @@ -2132,7 +2049,8 @@ parse_exit: > /** > * Simple packet parser > */ > -int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, layer_t layer) > +int packet_parse_layer(odp_packet_hdr_t *pkt_hdr, > + odp_pktio_parser_layer_t layer) > { > uint32_t seg_len = packet_first_seg_len(pkt_hdr); > void *base = packet_data(pkt_hdr); > diff --git a/platform/linux-generic/odp_packet_flags.c > b/platform/linux-generic/odp_packet_flags.c > index ea9a227..bb993e8 100644 > --- a/platform/linux-generic/odp_packet_flags.c > +++ b/platform/linux-generic/odp_packet_flags.c > @@ -8,17 +8,13 @@ > #include <odp/api/packet_flags.h> > #include <odp_packet_internal.h> > > -#define retflag(pkt, x, layer) do { \ > +#define retflag(pkt, x) do { \ > odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ > - 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, layer) do { \ > +#define setflag(pkt, x, v) do { \ > odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); \ > - if (pkt_hdr->p.parsed_layers < layer) \ > - packet_parse_layer(pkt_hdr, layer); \ > pkt_hdr->p.x = v & 1; \ > } while (0) > > @@ -26,9 +22,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_layer(pkt_hdr, LAYER_ALL); > - return odp_packet_hdr(pkt)->p.error_flags.all != 0; > + return pkt_hdr->p.error_flags.all != 0; > } > > /* Get Input Flags */ > @@ -45,126 +39,117 @@ int odp_packet_has_l2_error(odp_packet_t pkt) > > int odp_packet_has_l3(odp_packet_t pkt) > { > - retflag(pkt, input_flags.l3, LAYER_L3); > + retflag(pkt, input_flags.l3); > } > > int odp_packet_has_l3_error(odp_packet_t pkt) > { > odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); > > - 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, LAYER_L4); > + retflag(pkt, input_flags.l4); > } > > int odp_packet_has_l4_error(odp_packet_t pkt) > { > odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt); > > - 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; > } > > int odp_packet_has_eth_bcast(odp_packet_t pkt) > { > - retflag(pkt, input_flags.eth_bcast, LAYER_L2); > + retflag(pkt, input_flags.eth_bcast); > } > > int odp_packet_has_eth_mcast(odp_packet_t pkt) > { > - retflag(pkt, input_flags.eth_mcast, LAYER_L2); > + retflag(pkt, input_flags.eth_mcast); > } > > int odp_packet_has_vlan(odp_packet_t pkt) > { > - retflag(pkt, input_flags.vlan, LAYER_L2); > + retflag(pkt, input_flags.vlan); > } > > int odp_packet_has_vlan_qinq(odp_packet_t pkt) > { > - retflag(pkt, input_flags.vlan_qinq, LAYER_L2); > + retflag(pkt, input_flags.vlan_qinq); > } > > int odp_packet_has_arp(odp_packet_t pkt) > { > - retflag(pkt, input_flags.arp, LAYER_L3); > + retflag(pkt, input_flags.arp); > } > > int odp_packet_has_ipv4(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ipv4, LAYER_L3); > + retflag(pkt, input_flags.ipv4); > } > > int odp_packet_has_ipv6(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ipv6, LAYER_L3); > + retflag(pkt, input_flags.ipv6); > } > > int odp_packet_has_ip_bcast(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ip_bcast, LAYER_L3); > + retflag(pkt, input_flags.ip_bcast); > } > > int odp_packet_has_ip_mcast(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ip_mcast, LAYER_L3); > + retflag(pkt, input_flags.ip_mcast); > } > > int odp_packet_has_ipfrag(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ipfrag, LAYER_L3); > + retflag(pkt, input_flags.ipfrag); > } > > int odp_packet_has_ipopt(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ipopt, LAYER_L3); > + retflag(pkt, input_flags.ipopt); > } > > int odp_packet_has_ipsec(odp_packet_t pkt) > { > - retflag(pkt, input_flags.ipsec, LAYER_L4); > + retflag(pkt, input_flags.ipsec); > } > > int odp_packet_has_udp(odp_packet_t pkt) > { > - retflag(pkt, input_flags.udp, LAYER_L4); > + retflag(pkt, input_flags.udp); > } > > int odp_packet_has_tcp(odp_packet_t pkt) > { > - retflag(pkt, input_flags.tcp, LAYER_L4); > + retflag(pkt, input_flags.tcp); > } > > int odp_packet_has_sctp(odp_packet_t pkt) > { > - retflag(pkt, input_flags.sctp, LAYER_L4); > + retflag(pkt, input_flags.sctp); > } > > int odp_packet_has_icmp(odp_packet_t pkt) > { > - retflag(pkt, input_flags.icmp, LAYER_L4); > + retflag(pkt, input_flags.icmp); > } > > odp_packet_color_t odp_packet_color(odp_packet_t pkt) > { > - retflag(pkt, input_flags.color, LAYER_ALL); > + retflag(pkt, input_flags.color); > } > > 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_layer(pkt_hdr, LAYER_ALL); > - > pkt_hdr->p.input_flags.color = color; > } > > @@ -172,29 +157,23 @@ 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_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, LAYER_ALL); > + setflag(pkt, input_flags.nodrop, !drop); > } > > int8_t odp_packet_shaper_len_adjust(odp_packet_t pkt) > { > - retflag(pkt, output_flags.shaper_len_adj, LAYER_ALL); > + retflag(pkt, output_flags.shaper_len_adj); > } > > 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_layer(pkt_hdr, LAYER_ALL); > - > pkt_hdr->p.output_flags.shaper_len_adj = adj; > } > > @@ -202,107 +181,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, LAYER_L2); > + setflag(pkt, input_flags.l2, val); > } > > void odp_packet_has_l3_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.l3, val, LAYER_L3); > + setflag(pkt, input_flags.l3, val); > } > > void odp_packet_has_l4_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.l4, val, LAYER_L4); > + setflag(pkt, input_flags.l4, val); > } > > void odp_packet_has_eth_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.eth, val, LAYER_L2); > + setflag(pkt, input_flags.eth, val); > } > > void odp_packet_has_eth_bcast_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.eth_bcast, val, LAYER_L2); > + setflag(pkt, input_flags.eth_bcast, val); > } > > void odp_packet_has_eth_mcast_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.eth_mcast, val, LAYER_L2); > + setflag(pkt, input_flags.eth_mcast, val); > } > > void odp_packet_has_jumbo_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.jumbo, val, LAYER_L2); > + setflag(pkt, input_flags.jumbo, val); > } > > void odp_packet_has_vlan_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.vlan, val, LAYER_L2); > + setflag(pkt, input_flags.vlan, val); > } > > void odp_packet_has_vlan_qinq_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.vlan_qinq, val, LAYER_L2); > + setflag(pkt, input_flags.vlan_qinq, val); > } > > void odp_packet_has_arp_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.arp, val, LAYER_L3); > + setflag(pkt, input_flags.arp, val); > } > > void odp_packet_has_ipv4_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ipv4, val, LAYER_L3); > + setflag(pkt, input_flags.ipv4, val); > } > > void odp_packet_has_ipv6_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ipv6, val, LAYER_L3); > + setflag(pkt, input_flags.ipv6, val); > } > > void odp_packet_has_ip_bcast_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ip_bcast, val, LAYER_L3); > + setflag(pkt, input_flags.ip_bcast, val); > } > > void odp_packet_has_ip_mcast_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ip_mcast, val, LAYER_L3); > + setflag(pkt, input_flags.ip_mcast, val); > } > > void odp_packet_has_ipfrag_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ipfrag, val, LAYER_L3); > + setflag(pkt, input_flags.ipfrag, val); > } > > void odp_packet_has_ipopt_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ipopt, val, LAYER_L3); > + setflag(pkt, input_flags.ipopt, val); > } > > void odp_packet_has_ipsec_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.ipsec, val, LAYER_L4); > + setflag(pkt, input_flags.ipsec, val); > } > > void odp_packet_has_udp_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.udp, val, LAYER_L4); > + setflag(pkt, input_flags.udp, val); > } > > void odp_packet_has_tcp_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.tcp, val, LAYER_L4); > + setflag(pkt, input_flags.tcp, val); > } > > void odp_packet_has_sctp_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.sctp, val, LAYER_L4); > + setflag(pkt, input_flags.sctp, val); > } > > void odp_packet_has_icmp_set(odp_packet_t pkt, int val) > { > - setflag(pkt, input_flags.icmp, val, LAYER_L4); > + setflag(pkt, input_flags.icmp, val); > } > > void odp_packet_has_flow_hash_clr(odp_packet_t pkt) > diff --git a/platform/linux-generic/odp_packet_io.c > b/platform/linux-generic/odp_packet_io.c > index 5e783d8..d8cae15 100644 > --- a/platform/linux-generic/odp_packet_io.c > +++ b/platform/linux-generic/odp_packet_io.c > @@ -206,6 +206,8 @@ static odp_pktio_t setup_pktio_entry(const char *name, > odp_pool_t pool, > memcpy(&pktio_entry->s.param, param, sizeof(odp_pktio_param_t)); > pktio_entry->s.handle = hdl; > > + odp_pktio_config_init(&pktio_entry->s.config); > + > for (pktio_if = 0; pktio_if_ops[pktio_if]; ++pktio_if) { > ret = pktio_if_ops[pktio_if]->open(hdl, pktio_entry, name, > pool); > diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/ > pktio/dpdk.c > index 6ac89bd..c52cd09 100644 > --- a/platform/linux-generic/pktio/dpdk.c > +++ b/platform/linux-generic/pktio/dpdk.c > @@ -653,7 +653,8 @@ static inline int mbuf_to_pkt(pktio_entry_t > *pktio_entry, > if (pktio_cls_enabled(pktio_entry)) > copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); > else > - packet_parse_l2(&pkt_hdr->p, pkt_len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser. > layer); > > if (mbuf->ol_flags & PKT_RX_RSS_HASH) > odp_packet_flow_hash_set(pkt, mbuf->hash.rss); > diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/ > pktio/loop.c > index 7096283..237a7e3 100644 > --- a/platform/linux-generic/pktio/loop.c > +++ b/platform/linux-generic/pktio/loop.c > @@ -132,7 +132,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, > int index ODP_UNUSED, > if (pktio_cls_enabled(pktio_entry)) > copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); > else > - packet_parse_l2(&pkt_hdr->p, pkt_len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser. > layer); > > packet_set_ts(pkt_hdr, ts); > > diff --git a/platform/linux-generic/pktio/netmap.c > b/platform/linux-generic/pktio/netmap.c > index ae3db34..928bb00 100644 > --- a/platform/linux-generic/pktio/netmap.c > +++ b/platform/linux-generic/pktio/netmap.c > @@ -663,7 +663,8 @@ static inline int netmap_pkt_to_odp(pktio_entry_t > *pktio_entry, > if (pktio_cls_enabled(pktio_entry)) > copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); > else > - packet_parse_l2(&pkt_hdr->p, len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser. > layer); > > packet_set_ts(pkt_hdr, ts); > } > diff --git a/platform/linux-generic/pktio/pcap.c b/platform/linux-generic/ > pktio/pcap.c > index e54a56f..a467b64 100644 > --- a/platform/linux-generic/pktio/pcap.c > +++ b/platform/linux-generic/pktio/pcap.c > @@ -252,7 +252,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, > int index ODP_UNUSED, > break; > } > > - packet_parse_l2(&pkt_hdr->p, pkt_len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser.layer); > pktio_entry->s.stats.in_octets += pkt_hdr->frame_len; > > packet_set_ts(pkt_hdr, ts); > diff --git a/platform/linux-generic/pktio/socket.c > b/platform/linux-generic/pktio/socket.c > index 7d23968..89c6d46 100644 > --- a/platform/linux-generic/pktio/socket.c > +++ b/platform/linux-generic/pktio/socket.c > @@ -749,7 +749,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, > int index ODP_UNUSED, > } > > pkt_hdr = odp_packet_hdr(pkt); > - packet_parse_l2(&pkt_hdr->p, pkt_hdr->frame_len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser. > layer); > packet_set_ts(pkt_hdr, ts); > pkt_hdr->input = pktio_entry->s.handle; > > diff --git a/platform/linux-generic/pktio/socket_mmap.c > b/platform/linux-generic/pktio/socket_mmap.c > index fdf8cca..2dba7b0 100644 > --- a/platform/linux-generic/pktio/socket_mmap.c > +++ b/platform/linux-generic/pktio/socket_mmap.c > @@ -231,7 +231,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t > *pktio_entry, > if (pktio_cls_enabled(pktio_entry)) > copy_packet_cls_metadata(&parsed_hdr, hdr); > else > - packet_parse_l2(&hdr->p, pkt_len); > + packet_parse_layer(hdr, > + pktio_entry->s.config.parser. > layer); > > packet_set_ts(hdr, ts); > > diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/ > pktio/tap.c > index ac20456..650c12a 100644 > --- a/platform/linux-generic/pktio/tap.c > +++ b/platform/linux-generic/pktio/tap.c > @@ -213,7 +213,8 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t > *pktio_entry, const void *data, > if (pktio_cls_enabled(pktio_entry)) > copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); > else > - packet_parse_l2(&pkt_hdr->p, len); > + packet_parse_layer(pkt_hdr, > + pktio_entry->s.config.parser.layer); > > packet_set_ts(pkt_hdr, ts); > pkt_hdr->input = pktio_entry->s.handle; > -- > 2.7.4 > >
