Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 6 additions & 11 deletions platform/linux-generic/odp_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -2065,10 +2065,13 @@ int _odp_packet_sctp_chksum_insert(odp_packet_t pkt)
int _odp_packet_l4_chksum(odp_packet_hdr_t *pkt_hdr,
odp_pktin_config_opt_t opt, uint64_t l4_part_sum)
{
/* Skip fragmented packets */
if (pkt_hdr->p.input_flags.ipfrag)
return pkt_hdr->p.flags.all.error != 0;

/* UDP chksum == 0 case is covered in parse_udp() */
if (opt.bit.udp_chksum &&
pkt_hdr->p.input_flags.udp &&
!pkt_hdr->p.input_flags.ipfrag &&
!pkt_hdr->p.input_flags.udp_chksum_zero) {
uint16_t sum = ~packet_sum(pkt_hdr,
pkt_hdr->p.l3_offset,
Expand All @@ -2085,11 +2088,7 @@ int _odp_packet_l4_chksum(odp_packet_hdr_t *pkt_hdr,
if (opt.bit.drop_udp_err)
return -1;
}
}

if (opt.bit.tcp_chksum &&
pkt_hdr->p.input_flags.tcp &&
!pkt_hdr->p.input_flags.ipfrag) {
} else if (opt.bit.tcp_chksum && pkt_hdr->p.input_flags.tcp) {
uint16_t sum = ~packet_sum(pkt_hdr,
pkt_hdr->p.l3_offset,
pkt_hdr->p.l4_offset,
Expand All @@ -2105,11 +2104,7 @@ int _odp_packet_l4_chksum(odp_packet_hdr_t *pkt_hdr,
if (opt.bit.drop_tcp_err)
return -1;
}
}

if (opt.bit.sctp_chksum &&
pkt_hdr->p.input_flags.sctp &&
!pkt_hdr->p.input_flags.ipfrag) {
} else if (opt.bit.sctp_chksum && pkt_hdr->p.input_flags.sctp) {
uint32_t seg_len = 0;
_odp_sctphdr_t hdr_copy;
uint32_t sum = ~packet_sum_crc32c(pkt_hdr,
Expand Down
28 changes: 22 additions & 6 deletions platform/linux-generic/odp_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ uint16_t _odp_parse_eth(packet_parser_t *prs, const uint8_t **parseptr,
static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr,
uint32_t *offset, uint32_t frame_len,
odp_pktin_config_opt_t opt,
uint64_t *l4_part_sum)
uint64_t *l4_part_sum,
odp_bool_t *non_first_frag)
{
const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr;
uint32_t dstaddr = odp_be_to_cpu_32(ipv4->dst_addr);
Expand Down Expand Up @@ -154,9 +155,13 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr,
* OR
* "fragment offset" field is nonzero (all fragments except the first)
*/
if (odp_unlikely(_ODP_IPV4HDR_IS_FRAGMENT(frag_offset)))
if (odp_unlikely(_ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) {
prs->input_flags.ipfrag = 1;

if (_ODP_IPV4HDR_FRAG_OFFSET(frag_offset) != 0)
*non_first_frag = true;
}

/* Handle IPv4 broadcast / multicast */
if (odp_unlikely(dstaddr == 0xffffffff))
prs->input_flags.ip_bcast = 1;
Expand Down Expand Up @@ -362,6 +367,7 @@ int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,
odp_pktin_config_opt_t opt)
{
uint8_t ip_proto;
odp_bool_t non_first_frag = false;

prs->l3_offset = offset;

Expand All @@ -376,7 +382,7 @@ int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,
case _ODP_ETHTYPE_IPV4:
prs->input_flags.ipv4 = 1;
ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len,
opt, l4_part_sum);
opt, l4_part_sum, &non_first_frag);
if (odp_likely(!prs->flags.ip_err))
prs->l4_offset = offset;
else if (opt.bit.drop_ipv4_err)
Expand Down Expand Up @@ -406,7 +412,6 @@ int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,
if (layer == ODP_PROTO_LAYER_L3)
return prs->flags.all.error != 0;

/* Set l4 flag only for known ip_proto */
prs->input_flags.l4 = 1;

/* Parse Layer 4 headers */
Expand All @@ -423,19 +428,25 @@ int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,
break;

case _ODP_IPPROTO_TCP:
prs->input_flags.tcp = 1;
/* Non-first IP fragments do not contain an L4 header */
if (odp_unlikely(non_first_frag))
return prs->flags.all.error != 0;
if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_end))
return -1;
prs->input_flags.tcp = 1;
parse_tcp(prs, &parseptr, frame_len - prs->l4_offset, opt,
l4_part_sum);
if (prs->flags.tcp_err && opt.bit.drop_tcp_err)
return -1; /* drop */
break;

case _ODP_IPPROTO_UDP:
prs->input_flags.udp = 1;
/* Non-first IP fragments do not contain an L4 header */
if (odp_unlikely(non_first_frag))
return prs->flags.all.error != 0;
if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_end))
return -1;
prs->input_flags.udp = 1;
parse_udp(prs, &parseptr, opt, l4_part_sum);
if (prs->flags.udp_err && opt.bit.drop_udp_err)
return -1; /* drop */
Expand All @@ -453,6 +464,11 @@ int _odp_packet_parse_common_l3_l4(packet_parser_t *prs,

case _ODP_IPPROTO_SCTP:
prs->input_flags.sctp = 1;
/* Non-first IP fragments do not contain an L4 header */
if (odp_unlikely(non_first_frag))
return prs->flags.all.error != 0;
if (odp_unlikely(offset + _ODP_SCTPHDR_LEN > seg_end))
return -1;
parse_sctp(prs, &parseptr, frame_len - prs->l4_offset, opt,
l4_part_sum);
if (prs->flags.sctp_err && opt.bit.drop_sctp_err)
Expand Down