-
- if (l4_proto == IPPROTO_UDP) {
- udp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,
- unsigned char *) + l2_len + l3_len);
- if (tx_ol_flags & 0x2) {
- /* HW Offload */
- ol_flags |= PKT_TX_UDP_CKSUM;
- if (ipv4_tunnel)
- udp_hdr->dgram_cksum = 0;
- else
- /* Pseudo header sum need be set properly */
- udp_hdr->dgram_cksum =
- get_ipv4_psd_sum(ipv4_hdr);
- }
- else {
- /* SW Implementation, clear checksum field first */
- udp_hdr->dgram_cksum = 0;
- udp_hdr->dgram_cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
- (uint16_t *)udp_hdr);
- }
-
- if (ipv4_tunnel) {
-
- uint16_t len;
-
- /* Check if inner L3/L4 checkum flag is set */
- if (tx_ol_flags & 0xF0)
- ol_flags |= PKT_TX_VXLAN_CKSUM;
-
- inner_l2_len = sizeof(struct ether_hdr);
- inner_eth_hdr = (struct ether_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + l2_len + l3_len
- + ETHER_VXLAN_HLEN);
-
- eth_type = rte_be_to_cpu_16(inner_eth_hdr->ether_type);
- if (eth_type == ETHER_TYPE_VLAN) {
- inner_l2_len += sizeof(struct vlan_hdr);
- eth_type = rte_be_to_cpu_16(*(uint16_t *)
- ((uintptr_t)ð_hdr->ether_type +
- sizeof(struct vlan_hdr)));
- }
-
- len = l2_len + l3_len + ETHER_VXLAN_HLEN + inner_l2_len;
- if (eth_type == ETHER_TYPE_IPv4) {
- inner_l3_len = sizeof(struct ipv4_hdr);
- inner_ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + len);
- inner_l4_proto = inner_ipv4_hdr->next_proto_id;
-
- if (tx_ol_flags & 0x10) {
-
- /* Do not delete, this is required by HW*/
- inner_ipv4_hdr->hdr_checksum = 0;
- ol_flags |= PKT_TX_IPV4_CSUM;
- }
-
- } else if (eth_type == ETHER_TYPE_IPv6) {
- inner_l3_len = sizeof(struct ipv6_hdr);
- inner_ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + len);
- inner_l4_proto = inner_ipv6_hdr->proto;
- }
- if ((inner_l4_proto == IPPROTO_UDP) && (tx_ol_flags & 0x20)) {
-
- /* HW Offload */
- ol_flags |= PKT_TX_UDP_CKSUM;
- inner_udp_hdr = (struct udp_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + len + inner_l3_len);
- if (eth_type == ETHER_TYPE_IPv4)
- inner_udp_hdr->dgram_cksum = get_ipv4_psd_sum(inner_ipv4_hdr);
- else if (eth_type == ETHER_TYPE_IPv6)
- inner_udp_hdr->dgram_cksum = get_ipv6_psd_sum(inner_ipv6_hdr);
-
- } else if ((inner_l4_proto == IPPROTO_TCP) && (tx_ol_flags & 0x40)) {
- /* HW Offload */
- ol_flags |= PKT_TX_TCP_CKSUM;
- inner_tcp_hdr = (struct tcp_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + len + inner_l3_len);
- if (eth_type == ETHER_TYPE_IPv4)
- inner_tcp_hdr->cksum = get_ipv4_psd_sum(inner_ipv4_hdr);
- else if (eth_type == ETHER_TYPE_IPv6)
- inner_tcp_hdr->cksum = get_ipv6_psd_sum(inner_ipv6_hdr);
- } else if ((inner_l4_proto == IPPROTO_SCTP) && (tx_ol_flags & 0x80)) {
- /* HW Offload */
- ol_flags |= PKT_TX_SCTP_CKSUM;
- inner_sctp_hdr = (struct sctp_hdr *) (rte_pktmbuf_mtod(mb,
- unsigned char *) + len + inner_l3_len);
- inner_sctp_hdr->cksum = 0;
- }
-
- }
-
- } else if (l4_proto == IPPROTO_TCP) {
- tcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,
- unsigned char *) + l2_len + l3_len);
- if (tx_ol_flags & 0x4) {
- ol_flags |= PKT_TX_TCP_CKSUM;
- tcp_hdr->cksum = get_ipv4_psd_sum(ipv4_hdr);
- }
- else {
- tcp_hdr->cksum = 0;
- tcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
- (uint16_t*)tcp_hdr);
- }
- } else if (l4_proto == IPPROTO_SCTP) {
- sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
- unsigned char *) + l2_len + l3_len);
-
- if (tx_ol_flags & 0x8) {
- ol_flags |= PKT_TX_SCTP_CKSUM;
- sctp_hdr->cksum = 0;
-
- /* Sanity check, only number of 4 bytes supported */
- if ((rte_be_to_cpu_16(ipv4_hdr->total_length) % 4) != 0)
- printf("sctp payload must be a multiple "
- "of 4 bytes for checksum offload");
- }
- else {
- sctp_hdr->cksum = 0;
- /* CRC32c sample code available in RFC3309 */
- }