@@ -296,7 +296,8 @@ int packet_alloc_multi(odp_pool_t pool_hdl, uint32_t len,
/* Perform packet parse up to a given protocol layer */
int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
- odp_proto_layer_t layer);
+ odp_proto_layer_t layer,
+ odp_proto_chksums_t chksums);
/* Reset parser metadata for a new parse */
void packet_parse_reset(odp_packet_hdr_t *pkt_hdr);
@@ -333,7 +334,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, int layer);
+ uint32_t pkt_len, uint32_t seg_len, int layer,
+ odp_proto_chksums_t chksums);
int _odp_cls_parse(odp_packet_hdr_t *pkt_hdr, const uint8_t *parseptr);
@@ -973,7 +973,8 @@ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base,
packet_set_len(pkt_hdr, pkt_len);
packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len,
- ODP_PROTO_LAYER_ALL);
+ ODP_PROTO_LAYER_ALL,
+ entry->s.in_chksums);
cos = cls_select_cos(entry, base, pkt_hdr);
if (cos == NULL)
@@ -2024,7 +2024,8 @@ static inline uint16_t parse_eth(packet_parser_t *prs, const uint8_t **parseptr,
* Parser helper function for IPv4
*/
static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr,
- uint32_t *offset, uint32_t frame_len)
+ uint32_t *offset, uint32_t frame_len,
+ odp_proto_chksums_t chksums)
{
const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr;
uint8_t ver = _ODP_IPV4HDR_VER(ipv4->ver_ihl);
@@ -2040,6 +2041,14 @@ static inline uint8_t parse_ipv4(packet_parser_t *prs, const uint8_t **parseptr,
return 0;
}
+ if (chksums.chksum.ipv4) {
+ prs->input_flags.l3_chksum_done = 1;
+ if (odp_chksum_ones_comp16(ipv4, ihl * 4) != 0xffff) {
+ prs->error_flags.l3_chksum = 1;
+ return 0;
+ }
+ }
+
*offset += ihl * 4;
*parseptr += ihl * 4;
@@ -2175,7 +2184,8 @@ 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,
- int layer, uint16_t ethtype)
+ int layer, uint16_t ethtype,
+ odp_proto_chksums_t chksums)
{
uint8_t ip_proto;
@@ -2191,7 +2201,7 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr,
switch (ethtype) {
case _ODP_ETHTYPE_IPV4:
prs->input_flags.ipv4 = 1;
- ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len);
+ ip_proto = parse_ipv4(prs, &parseptr, &offset, frame_len, chksums);
prs->l4_offset = offset;
break;
@@ -2275,7 +2285,7 @@ int packet_parse_common_l3_l4(packet_parser_t *prs, const uint8_t *parseptr,
*/
int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
uint32_t frame_len, uint32_t seg_len,
- int layer)
+ int layer, odp_proto_chksums_t chksums)
{
uint32_t offset;
uint16_t ethtype;
@@ -2296,20 +2306,21 @@ int packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
ethtype = parse_eth(prs, &parseptr, &offset, frame_len);
return packet_parse_common_l3_l4(prs, parseptr, offset, frame_len,
- seg_len, layer, ethtype);
+ seg_len, layer, ethtype, chksums);
}
/**
* Simple packet parser
*/
int packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
- odp_proto_layer_t layer)
+ odp_proto_layer_t layer,
+ odp_proto_chksums_t chksums)
{
uint32_t seg_len = packet_first_seg_len(pkt_hdr);
void *base = packet_data(pkt_hdr);
return packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len,
- seg_len, layer);
+ seg_len, layer, chksums);
}
int odp_packet_parse(odp_packet_t pkt, uint32_t offset,
@@ -2336,7 +2347,8 @@ int odp_packet_parse(odp_packet_t pkt, uint32_t offset,
if (proto == ODP_PROTO_ETH) {
ret = packet_parse_common(&pkt_hdr->p, data, packet_len,
- seg_len, layer);
+ seg_len, layer,
+ param->chksums);
if (ret)
return -1;
@@ -2348,7 +2360,9 @@ int odp_packet_parse(odp_packet_t pkt, uint32_t offset,
ret = packet_parse_common_l3_l4(&pkt_hdr->p, data, offset,
packet_len, seg_len,
- layer, ethtype);
+ layer, ethtype,
+ param->chksums);
+
if (ret)
return -1;
@@ -146,7 +146,8 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
}
} else {
packet_parse_layer(pkt_hdr,
- pktio_entry->s.config.parser.layer);
+ pktio_entry->s.config.parser.layer,
+ pktio_entry->s.in_chksums);
}
packet_set_ts(pkt_hdr, ts);
@@ -255,7 +255,8 @@ static int pcapif_recv_pkt(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
}
packet_parse_layer(pkt_hdr,
- pktio_entry->s.config.parser.layer);
+ pktio_entry->s.config.parser.layer,
+ pktio_entry->s.in_chksums);
pktio_entry->s.stats.in_octets += pkt_hdr->frame_len;
packet_set_ts(pkt_hdr, ts);
@@ -676,7 +676,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED,
if (!pktio_cls_enabled(pktio_entry))
packet_parse_layer(pkt_hdr,
- pktio_entry->s.config.parser.layer);
+ pktio_entry->s.config.parser.layer,
+ pktio_entry->s.in_chksums);
pkt_hdr->input = pktio_entry->s.handle;
packet_set_ts(pkt_hdr, ts);
@@ -234,7 +234,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry,
copy_packet_cls_metadata(&parsed_hdr, hdr);
else
packet_parse_layer(hdr,
- pktio_entry->s.config.parser.layer);
+ pktio_entry->s.config.parser.layer,
+ pktio_entry->s.in_chksums);
packet_set_ts(hdr, ts);
@@ -285,7 +285,8 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data,
copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
else
packet_parse_layer(pkt_hdr,
- pktio_entry->s.config.parser.layer);
+ pktio_entry->s.config.parser.layer,
+ pktio_entry->s.in_chksums);
packet_set_ts(pkt_hdr, ts);
pkt_hdr->input = pktio_entry->s.handle;