| 319 | } |
| 320 | |
| 321 | static void |
| 322 | tap_verify_csum(struct rte_mbuf *mbuf) |
| 323 | { |
| 324 | uint32_t l2 = mbuf->packet_type & RTE_PTYPE_L2_MASK; |
| 325 | uint32_t l3 = mbuf->packet_type & RTE_PTYPE_L3_MASK; |
| 326 | uint32_t l4 = mbuf->packet_type & RTE_PTYPE_L4_MASK; |
| 327 | unsigned int l2_len = sizeof(struct rte_ether_hdr); |
| 328 | unsigned int l3_len; |
| 329 | uint16_t cksum = 0; |
| 330 | void *l3_hdr; |
| 331 | void *l4_hdr; |
| 332 | struct rte_udp_hdr *udp_hdr; |
| 333 | |
| 334 | if (l2 == RTE_PTYPE_L2_ETHER_VLAN) |
| 335 | l2_len += 4; |
| 336 | else if (l2 == RTE_PTYPE_L2_ETHER_QINQ) |
| 337 | l2_len += 8; |
| 338 | /* Don't verify checksum for packets with discontinuous L2 header */ |
| 339 | if (unlikely(l2_len + sizeof(struct rte_ipv4_hdr) > |
| 340 | rte_pktmbuf_data_len(mbuf))) |
| 341 | return; |
| 342 | l3_hdr = rte_pktmbuf_mtod_offset(mbuf, void *, l2_len); |
| 343 | if (l3 == RTE_PTYPE_L3_IPV4 || l3 == RTE_PTYPE_L3_IPV4_EXT) { |
| 344 | struct rte_ipv4_hdr *iph = l3_hdr; |
| 345 | |
| 346 | l3_len = rte_ipv4_hdr_len(iph); |
| 347 | if (unlikely(l2_len + l3_len > rte_pktmbuf_data_len(mbuf))) |
| 348 | return; |
| 349 | /* check that the total length reported by header is not |
| 350 | * greater than the total received size |
| 351 | */ |
| 352 | if (l2_len + rte_be_to_cpu_16(iph->total_length) > |
| 353 | rte_pktmbuf_data_len(mbuf)) |
| 354 | return; |
| 355 | |
| 356 | cksum = ~rte_raw_cksum(iph, l3_len); |
| 357 | mbuf->ol_flags |= cksum ? |
| 358 | RTE_MBUF_F_RX_IP_CKSUM_BAD : |
| 359 | RTE_MBUF_F_RX_IP_CKSUM_GOOD; |
| 360 | } else if (l3 == RTE_PTYPE_L3_IPV6) { |
| 361 | struct rte_ipv6_hdr *iph = l3_hdr; |
| 362 | |
| 363 | l3_len = sizeof(struct rte_ipv6_hdr); |
| 364 | /* check that the total length reported by header is not |
| 365 | * greater than the total received size |
| 366 | */ |
| 367 | if (l2_len + l3_len + rte_be_to_cpu_16(iph->payload_len) > |
| 368 | rte_pktmbuf_data_len(mbuf)) |
| 369 | return; |
| 370 | } else { |
| 371 | /* - RTE_PTYPE_L3_IPV4_EXT_UNKNOWN cannot happen because |
| 372 | * mbuf->packet_type is filled by rte_net_get_ptype() which |
| 373 | * never returns this value. |
| 374 | * - IPv6 extensions are not supported. |
| 375 | */ |
| 376 | return; |
| 377 | } |
| 378 | if (l4 == RTE_PTYPE_L4_UDP || l4 == RTE_PTYPE_L4_TCP) { |
no test coverage detected