| 2618 | } |
| 2619 | |
| 2620 | static int |
| 2621 | parse_headers(struct rte_mbuf *m, uint8_t *l4_proto) |
| 2622 | { |
| 2623 | struct rte_ipv4_hdr *ipv4_hdr; |
| 2624 | struct rte_ipv6_hdr *ipv6_hdr; |
| 2625 | struct rte_ether_hdr *eth_hdr; |
| 2626 | uint16_t ethertype; |
| 2627 | uint16_t data_len = rte_pktmbuf_data_len(m); |
| 2628 | |
| 2629 | if (data_len < sizeof(struct rte_ether_hdr)) |
| 2630 | return -EINVAL; |
| 2631 | |
| 2632 | eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); |
| 2633 | |
| 2634 | m->l2_len = sizeof(struct rte_ether_hdr); |
| 2635 | ethertype = rte_be_to_cpu_16(eth_hdr->ether_type); |
| 2636 | |
| 2637 | if (ethertype == RTE_ETHER_TYPE_VLAN) { |
| 2638 | if (data_len < sizeof(struct rte_ether_hdr) + |
| 2639 | sizeof(struct rte_vlan_hdr)) |
| 2640 | goto error; |
| 2641 | |
| 2642 | struct rte_vlan_hdr *vlan_hdr = |
| 2643 | (struct rte_vlan_hdr *)(eth_hdr + 1); |
| 2644 | |
| 2645 | m->l2_len += sizeof(struct rte_vlan_hdr); |
| 2646 | ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto); |
| 2647 | } |
| 2648 | |
| 2649 | switch (ethertype) { |
| 2650 | case RTE_ETHER_TYPE_IPV4: |
| 2651 | if (data_len < m->l2_len + sizeof(struct rte_ipv4_hdr)) |
| 2652 | goto error; |
| 2653 | ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, |
| 2654 | m->l2_len); |
| 2655 | m->l3_len = rte_ipv4_hdr_len(ipv4_hdr); |
| 2656 | if (data_len < m->l2_len + m->l3_len) |
| 2657 | goto error; |
| 2658 | m->ol_flags |= RTE_MBUF_F_TX_IPV4; |
| 2659 | *l4_proto = ipv4_hdr->next_proto_id; |
| 2660 | break; |
| 2661 | case RTE_ETHER_TYPE_IPV6: |
| 2662 | if (data_len < m->l2_len + sizeof(struct rte_ipv6_hdr)) |
| 2663 | goto error; |
| 2664 | ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *, |
| 2665 | m->l2_len); |
| 2666 | m->l3_len = sizeof(struct rte_ipv6_hdr); |
| 2667 | m->ol_flags |= RTE_MBUF_F_TX_IPV6; |
| 2668 | *l4_proto = ipv6_hdr->proto; |
| 2669 | break; |
| 2670 | default: |
| 2671 | /* a valid L3 header is needed for further L4 parsing */ |
| 2672 | goto error; |
| 2673 | } |
| 2674 | |
| 2675 | /* both CSUM and GSO need a valid L4 header */ |
| 2676 | switch (*l4_proto) { |
| 2677 | case IPPROTO_TCP: |
no test coverage detected