1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2a9de470cSBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3a9de470cSBruce Richardson */ 4a9de470cSBruce Richardson 5a9de470cSBruce Richardson #include <rte_byteorder.h> 6a9de470cSBruce Richardson #include <rte_mbuf.h> 75fde1a75SReshma Pattan #include <rte_ip.h> 8987d40a0SJie Zhou #include <rte_os_shim.h> 9a9de470cSBruce Richardson 10a9de470cSBruce Richardson #include "packet_burst_generator.h" 11a9de470cSBruce Richardson 12a9de470cSBruce Richardson #define UDP_SRC_PORT 1024 13a9de470cSBruce Richardson #define UDP_DST_PORT 1024 14a9de470cSBruce Richardson 15a9de470cSBruce Richardson 16a9de470cSBruce Richardson #define IP_DEFTTL 64 /* from RFC 1340. */ 17a9de470cSBruce Richardson 18a9de470cSBruce Richardson static void 19a9de470cSBruce Richardson copy_buf_to_pkt_segs(void *buf, unsigned len, struct rte_mbuf *pkt, 20a9de470cSBruce Richardson unsigned offset) 21a9de470cSBruce Richardson { 22a9de470cSBruce Richardson struct rte_mbuf *seg; 23a9de470cSBruce Richardson void *seg_buf; 24a9de470cSBruce Richardson unsigned copy_len; 25a9de470cSBruce Richardson 26a9de470cSBruce Richardson seg = pkt; 27a9de470cSBruce Richardson while (offset >= seg->data_len) { 28a9de470cSBruce Richardson offset -= seg->data_len; 29a9de470cSBruce Richardson seg = seg->next; 30a9de470cSBruce Richardson } 31a9de470cSBruce Richardson copy_len = seg->data_len - offset; 32a9de470cSBruce Richardson seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset); 33a9de470cSBruce Richardson while (len > copy_len) { 34a9de470cSBruce Richardson rte_memcpy(seg_buf, buf, (size_t) copy_len); 35a9de470cSBruce Richardson len -= copy_len; 36a9de470cSBruce Richardson buf = ((char *) buf + copy_len); 37a9de470cSBruce Richardson seg = seg->next; 38a9de470cSBruce Richardson seg_buf = rte_pktmbuf_mtod(seg, void *); 39a9de470cSBruce Richardson } 40a9de470cSBruce Richardson rte_memcpy(seg_buf, buf, (size_t) len); 41a9de470cSBruce Richardson } 42a9de470cSBruce Richardson 43a9de470cSBruce Richardson static inline void 44a9de470cSBruce Richardson copy_buf_to_pkt(void *buf, unsigned len, struct rte_mbuf *pkt, unsigned offset) 45a9de470cSBruce Richardson { 46a9de470cSBruce Richardson if (offset + len <= pkt->data_len) { 47a9de470cSBruce Richardson rte_memcpy(rte_pktmbuf_mtod_offset(pkt, char *, offset), buf, 48a9de470cSBruce Richardson (size_t) len); 49a9de470cSBruce Richardson return; 50a9de470cSBruce Richardson } 51a9de470cSBruce Richardson copy_buf_to_pkt_segs(buf, len, pkt, offset); 52a9de470cSBruce Richardson } 53a9de470cSBruce Richardson 54a9de470cSBruce Richardson void 556d13ea8eSOlivier Matz initialize_eth_header(struct rte_ether_hdr *eth_hdr, 566d13ea8eSOlivier Matz struct rte_ether_addr *src_mac, 576d13ea8eSOlivier Matz struct rte_ether_addr *dst_mac, uint16_t ether_type, 58a9de470cSBruce Richardson uint8_t vlan_enabled, uint16_t van_id) 59a9de470cSBruce Richardson { 6004d43857SDmitry Kozlyuk rte_ether_addr_copy(dst_mac, ð_hdr->dst_addr); 6104d43857SDmitry Kozlyuk rte_ether_addr_copy(src_mac, ð_hdr->src_addr); 62a9de470cSBruce Richardson 63a9de470cSBruce Richardson if (vlan_enabled) { 646d13ea8eSOlivier Matz struct rte_vlan_hdr *vhdr = (struct rte_vlan_hdr *)( 656d13ea8eSOlivier Matz (uint8_t *)eth_hdr + sizeof(struct rte_ether_hdr)); 66a9de470cSBruce Richardson 6735b2d13fSOlivier Matz eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 68a9de470cSBruce Richardson 69a9de470cSBruce Richardson vhdr->eth_proto = rte_cpu_to_be_16(ether_type); 70a9de470cSBruce Richardson vhdr->vlan_tci = van_id; 71a9de470cSBruce Richardson } else { 72a9de470cSBruce Richardson eth_hdr->ether_type = rte_cpu_to_be_16(ether_type); 73a9de470cSBruce Richardson } 74a9de470cSBruce Richardson } 75a9de470cSBruce Richardson 76a9de470cSBruce Richardson void 776d13ea8eSOlivier Matz initialize_arp_header(struct rte_arp_hdr *arp_hdr, 786d13ea8eSOlivier Matz struct rte_ether_addr *src_mac, 796d13ea8eSOlivier Matz struct rte_ether_addr *dst_mac, 806d13ea8eSOlivier Matz uint32_t src_ip, uint32_t dst_ip, 81a9de470cSBruce Richardson uint32_t opcode) 82a9de470cSBruce Richardson { 83e482e0faSOlivier Matz arp_hdr->arp_hardware = rte_cpu_to_be_16(RTE_ARP_HRD_ETHER); 840c9da755SDavid Marchand arp_hdr->arp_protocol = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8535b2d13fSOlivier Matz arp_hdr->arp_hlen = RTE_ETHER_ADDR_LEN; 86f2745bfeSOlivier Matz arp_hdr->arp_plen = sizeof(uint32_t); 87f2745bfeSOlivier Matz arp_hdr->arp_opcode = rte_cpu_to_be_16(opcode); 88538da7a1SOlivier Matz rte_ether_addr_copy(src_mac, &arp_hdr->arp_data.arp_sha); 89a9de470cSBruce Richardson arp_hdr->arp_data.arp_sip = src_ip; 90538da7a1SOlivier Matz rte_ether_addr_copy(dst_mac, &arp_hdr->arp_data.arp_tha); 91a9de470cSBruce Richardson arp_hdr->arp_data.arp_tip = dst_ip; 92a9de470cSBruce Richardson } 93a9de470cSBruce Richardson 94a9de470cSBruce Richardson uint16_t 95e73e3547SOlivier Matz initialize_udp_header(struct rte_udp_hdr *udp_hdr, uint16_t src_port, 96a9de470cSBruce Richardson uint16_t dst_port, uint16_t pkt_data_len) 97a9de470cSBruce Richardson { 98a9de470cSBruce Richardson uint16_t pkt_len; 99a9de470cSBruce Richardson 100e73e3547SOlivier Matz pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_udp_hdr)); 101a9de470cSBruce Richardson 102a9de470cSBruce Richardson udp_hdr->src_port = rte_cpu_to_be_16(src_port); 103a9de470cSBruce Richardson udp_hdr->dst_port = rte_cpu_to_be_16(dst_port); 104a9de470cSBruce Richardson udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len); 105a9de470cSBruce Richardson udp_hdr->dgram_cksum = 0; /* No UDP checksum. */ 106a9de470cSBruce Richardson 107a9de470cSBruce Richardson return pkt_len; 108a9de470cSBruce Richardson } 109a9de470cSBruce Richardson 110a9de470cSBruce Richardson uint16_t 111f41b5156SOlivier Matz initialize_tcp_header(struct rte_tcp_hdr *tcp_hdr, uint16_t src_port, 112a9de470cSBruce Richardson uint16_t dst_port, uint16_t pkt_data_len) 113a9de470cSBruce Richardson { 114a9de470cSBruce Richardson uint16_t pkt_len; 115a9de470cSBruce Richardson 116f41b5156SOlivier Matz pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_tcp_hdr)); 117a9de470cSBruce Richardson 118f41b5156SOlivier Matz memset(tcp_hdr, 0, sizeof(struct rte_tcp_hdr)); 119a9de470cSBruce Richardson tcp_hdr->src_port = rte_cpu_to_be_16(src_port); 120a9de470cSBruce Richardson tcp_hdr->dst_port = rte_cpu_to_be_16(dst_port); 1219fdba327SLance Richardson tcp_hdr->data_off = (sizeof(struct rte_tcp_hdr) << 2) & 0xF0; 122a9de470cSBruce Richardson 123a9de470cSBruce Richardson return pkt_len; 124a9de470cSBruce Richardson } 125a9de470cSBruce Richardson 126a9de470cSBruce Richardson uint16_t 12709d9ae1aSOlivier Matz initialize_sctp_header(struct rte_sctp_hdr *sctp_hdr, uint16_t src_port, 128a9de470cSBruce Richardson uint16_t dst_port, uint16_t pkt_data_len) 129a9de470cSBruce Richardson { 130a9de470cSBruce Richardson uint16_t pkt_len; 131a9de470cSBruce Richardson 132e73e3547SOlivier Matz pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_udp_hdr)); 133a9de470cSBruce Richardson 134a9de470cSBruce Richardson sctp_hdr->src_port = rte_cpu_to_be_16(src_port); 135a9de470cSBruce Richardson sctp_hdr->dst_port = rte_cpu_to_be_16(dst_port); 136a9de470cSBruce Richardson sctp_hdr->tag = 0; 137a9de470cSBruce Richardson sctp_hdr->cksum = 0; /* No SCTP checksum. */ 138a9de470cSBruce Richardson 139a9de470cSBruce Richardson return pkt_len; 140a9de470cSBruce Richardson } 141a9de470cSBruce Richardson 142a9de470cSBruce Richardson uint16_t 143a7c528e5SOlivier Matz initialize_ipv6_header(struct rte_ipv6_hdr *ip_hdr, uint8_t *src_addr, 144a9de470cSBruce Richardson uint8_t *dst_addr, uint16_t pkt_data_len) 145a9de470cSBruce Richardson { 146a906371dSLance Richardson ip_hdr->vtc_flow = rte_cpu_to_be_32(0x60000000); /* Set version to 6. */ 147a906371dSLance Richardson ip_hdr->payload_len = rte_cpu_to_be_16(pkt_data_len); 148a9de470cSBruce Richardson ip_hdr->proto = IPPROTO_UDP; 149a9de470cSBruce Richardson ip_hdr->hop_limits = IP_DEFTTL; 150a9de470cSBruce Richardson 15189b5642dSRobin Jarry rte_memcpy(&ip_hdr->src_addr, src_addr, sizeof(ip_hdr->src_addr)); 15289b5642dSRobin Jarry rte_memcpy(&ip_hdr->dst_addr, dst_addr, sizeof(ip_hdr->dst_addr)); 153a9de470cSBruce Richardson 154a7c528e5SOlivier Matz return (uint16_t) (pkt_data_len + sizeof(struct rte_ipv6_hdr)); 155a9de470cSBruce Richardson } 156a9de470cSBruce Richardson 157a9de470cSBruce Richardson uint16_t 158a7c528e5SOlivier Matz initialize_ipv4_header(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr, 159a9de470cSBruce Richardson uint32_t dst_addr, uint16_t pkt_data_len) 160a9de470cSBruce Richardson { 161a9de470cSBruce Richardson uint16_t pkt_len; 162a9de470cSBruce Richardson 163a9de470cSBruce Richardson /* 164a9de470cSBruce Richardson * Initialize IP header. 165a9de470cSBruce Richardson */ 166a7c528e5SOlivier Matz pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_ipv4_hdr)); 167a9de470cSBruce Richardson 1685fde1a75SReshma Pattan ip_hdr->version_ihl = RTE_IPV4_VHL_DEF; 169a9de470cSBruce Richardson ip_hdr->type_of_service = 0; 170a9de470cSBruce Richardson ip_hdr->fragment_offset = 0; 171a9de470cSBruce Richardson ip_hdr->time_to_live = IP_DEFTTL; 172a9de470cSBruce Richardson ip_hdr->next_proto_id = IPPROTO_UDP; 173a9de470cSBruce Richardson ip_hdr->packet_id = 0; 174a9de470cSBruce Richardson ip_hdr->total_length = rte_cpu_to_be_16(pkt_len); 175a9de470cSBruce Richardson ip_hdr->src_addr = rte_cpu_to_be_32(src_addr); 176a9de470cSBruce Richardson ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr); 177a9de470cSBruce Richardson 178*f9e1d67fSBruce Richardson ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr); 179a9de470cSBruce Richardson 180a9de470cSBruce Richardson return pkt_len; 181a9de470cSBruce Richardson } 182a9de470cSBruce Richardson 183a9de470cSBruce Richardson uint16_t 184a7c528e5SOlivier Matz initialize_ipv4_header_proto(struct rte_ipv4_hdr *ip_hdr, uint32_t src_addr, 185a9de470cSBruce Richardson uint32_t dst_addr, uint16_t pkt_data_len, uint8_t proto) 186a9de470cSBruce Richardson { 187a9de470cSBruce Richardson uint16_t pkt_len; 188a9de470cSBruce Richardson 189a9de470cSBruce Richardson /* 190a9de470cSBruce Richardson * Initialize IP header. 191a9de470cSBruce Richardson */ 192a7c528e5SOlivier Matz pkt_len = (uint16_t) (pkt_data_len + sizeof(struct rte_ipv4_hdr)); 193a9de470cSBruce Richardson 1945fde1a75SReshma Pattan ip_hdr->version_ihl = RTE_IPV4_VHL_DEF; 195a9de470cSBruce Richardson ip_hdr->type_of_service = 0; 196a9de470cSBruce Richardson ip_hdr->fragment_offset = 0; 197a9de470cSBruce Richardson ip_hdr->time_to_live = IP_DEFTTL; 198a9de470cSBruce Richardson ip_hdr->next_proto_id = proto; 199a9de470cSBruce Richardson ip_hdr->packet_id = 0; 200a9de470cSBruce Richardson ip_hdr->total_length = rte_cpu_to_be_16(pkt_len); 201a9de470cSBruce Richardson ip_hdr->src_addr = rte_cpu_to_be_32(src_addr); 202a9de470cSBruce Richardson ip_hdr->dst_addr = rte_cpu_to_be_32(dst_addr); 203*f9e1d67fSBruce Richardson ip_hdr->hdr_checksum = rte_ipv4_cksum_simple(ip_hdr); 204a9de470cSBruce Richardson 205a9de470cSBruce Richardson return pkt_len; 206a9de470cSBruce Richardson } 207a9de470cSBruce Richardson 208a9de470cSBruce Richardson /* 209a9de470cSBruce Richardson * The maximum number of segments per packet is used when creating 210a9de470cSBruce Richardson * scattered transmit packets composed of a list of mbufs. 211a9de470cSBruce Richardson */ 212a9de470cSBruce Richardson #define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */ 213a9de470cSBruce Richardson 214a9de470cSBruce Richardson 215a9de470cSBruce Richardson int 216a9de470cSBruce Richardson generate_packet_burst(struct rte_mempool *mp, struct rte_mbuf **pkts_burst, 2176d13ea8eSOlivier Matz struct rte_ether_hdr *eth_hdr, uint8_t vlan_enabled, 218e73e3547SOlivier Matz void *ip_hdr, uint8_t ipv4, struct rte_udp_hdr *udp_hdr, 2196d13ea8eSOlivier Matz int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs) 220a9de470cSBruce Richardson { 221b88b8af2SZhuobin Huang const uint8_t pkt_seg_data_len = pkt_len / nb_pkt_segs; 222a9de470cSBruce Richardson struct rte_mbuf *pkt_seg; 223a9de470cSBruce Richardson struct rte_mbuf *pkt; 224b88b8af2SZhuobin Huang size_t eth_hdr_size; 225b88b8af2SZhuobin Huang int i, nb_pkt = 0; 226a9de470cSBruce Richardson 227a9de470cSBruce Richardson for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { 228a9de470cSBruce Richardson pkt = rte_pktmbuf_alloc(mp); 229a9de470cSBruce Richardson if (pkt == NULL) { 230a9de470cSBruce Richardson nomore_mbuf: 231a9de470cSBruce Richardson if (nb_pkt == 0) 232a9de470cSBruce Richardson return -1; 233a9de470cSBruce Richardson break; 234a9de470cSBruce Richardson } 235a9de470cSBruce Richardson 236b88b8af2SZhuobin Huang pkt->data_len = pkt_seg_data_len; 237a9de470cSBruce Richardson pkt_seg = pkt; 238a9de470cSBruce Richardson for (i = 1; i < nb_pkt_segs; i++) { 239a9de470cSBruce Richardson pkt_seg->next = rte_pktmbuf_alloc(mp); 240a9de470cSBruce Richardson if (pkt_seg->next == NULL) { 241a9de470cSBruce Richardson pkt->nb_segs = i; 242a9de470cSBruce Richardson rte_pktmbuf_free(pkt); 243a9de470cSBruce Richardson goto nomore_mbuf; 244a9de470cSBruce Richardson } 245a9de470cSBruce Richardson pkt_seg = pkt_seg->next; 246b88b8af2SZhuobin Huang if (i != nb_pkt_segs - 1) 247b88b8af2SZhuobin Huang pkt_seg->data_len = pkt_seg_data_len; 248b88b8af2SZhuobin Huang else 249b88b8af2SZhuobin Huang pkt_seg->data_len = pkt_seg_data_len + pkt_len % nb_pkt_segs; 250a9de470cSBruce Richardson } 251a9de470cSBruce Richardson pkt_seg->next = NULL; /* Last segment of packet. */ 252a9de470cSBruce Richardson 253a9de470cSBruce Richardson /* 254a9de470cSBruce Richardson * Copy headers in first packet segment(s). 255a9de470cSBruce Richardson */ 256a9de470cSBruce Richardson if (vlan_enabled) 2576d13ea8eSOlivier Matz eth_hdr_size = sizeof(struct rte_ether_hdr) + 2586d13ea8eSOlivier Matz sizeof(struct rte_vlan_hdr); 259a9de470cSBruce Richardson else 2606d13ea8eSOlivier Matz eth_hdr_size = sizeof(struct rte_ether_hdr); 261a9de470cSBruce Richardson 262a9de470cSBruce Richardson copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0); 263a9de470cSBruce Richardson 264a9de470cSBruce Richardson if (ipv4) { 265a7c528e5SOlivier Matz copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv4_hdr), 266a7c528e5SOlivier Matz pkt, eth_hdr_size); 267a7c528e5SOlivier Matz copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, 268a7c528e5SOlivier Matz eth_hdr_size + sizeof(struct rte_ipv4_hdr)); 269a9de470cSBruce Richardson } else { 270a7c528e5SOlivier Matz copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv6_hdr), 271a7c528e5SOlivier Matz pkt, eth_hdr_size); 272a7c528e5SOlivier Matz copy_buf_to_pkt(udp_hdr, sizeof(*udp_hdr), pkt, 273a7c528e5SOlivier Matz eth_hdr_size + sizeof(struct rte_ipv6_hdr)); 274a9de470cSBruce Richardson } 275a9de470cSBruce Richardson 276a9de470cSBruce Richardson /* 277a9de470cSBruce Richardson * Complete first mbuf of packet and append it to the 278a9de470cSBruce Richardson * burst of packets to be transmitted. 279a9de470cSBruce Richardson */ 280a9de470cSBruce Richardson pkt->nb_segs = nb_pkt_segs; 281a9de470cSBruce Richardson pkt->pkt_len = pkt_len; 282a9de470cSBruce Richardson pkt->l2_len = eth_hdr_size; 283a9de470cSBruce Richardson 284a9de470cSBruce Richardson if (ipv4) { 2850c9da755SDavid Marchand pkt->vlan_tci = RTE_ETHER_TYPE_IPV4; 286a7c528e5SOlivier Matz pkt->l3_len = sizeof(struct rte_ipv4_hdr); 287a9de470cSBruce Richardson } else { 2880c9da755SDavid Marchand pkt->vlan_tci = RTE_ETHER_TYPE_IPV6; 289a7c528e5SOlivier Matz pkt->l3_len = sizeof(struct rte_ipv6_hdr); 290a9de470cSBruce Richardson } 291a9de470cSBruce Richardson 292a9de470cSBruce Richardson pkts_burst[nb_pkt] = pkt; 293a9de470cSBruce Richardson } 294a9de470cSBruce Richardson 295a9de470cSBruce Richardson return nb_pkt; 296a9de470cSBruce Richardson } 297a9de470cSBruce Richardson 298a9de470cSBruce Richardson int 299a9de470cSBruce Richardson generate_packet_burst_proto(struct rte_mempool *mp, 3006d13ea8eSOlivier Matz struct rte_mbuf **pkts_burst, struct rte_ether_hdr *eth_hdr, 3016d13ea8eSOlivier Matz uint8_t vlan_enabled, void *ip_hdr, 302a9de470cSBruce Richardson uint8_t ipv4, uint8_t proto, void *proto_hdr, 303a9de470cSBruce Richardson int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs) 304a9de470cSBruce Richardson { 305b88b8af2SZhuobin Huang const uint8_t pkt_seg_data_len = pkt_len / nb_pkt_segs; 306a9de470cSBruce Richardson struct rte_mbuf *pkt_seg; 307a9de470cSBruce Richardson struct rte_mbuf *pkt; 308b88b8af2SZhuobin Huang size_t eth_hdr_size; 309b88b8af2SZhuobin Huang int i, nb_pkt = 0; 310a9de470cSBruce Richardson 311a9de470cSBruce Richardson for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { 312a9de470cSBruce Richardson pkt = rte_pktmbuf_alloc(mp); 313a9de470cSBruce Richardson if (pkt == NULL) { 314a9de470cSBruce Richardson nomore_mbuf: 315a9de470cSBruce Richardson if (nb_pkt == 0) 316a9de470cSBruce Richardson return -1; 317a9de470cSBruce Richardson break; 318a9de470cSBruce Richardson } 319a9de470cSBruce Richardson 320b88b8af2SZhuobin Huang pkt->data_len = pkt_seg_data_len; 321a9de470cSBruce Richardson pkt_seg = pkt; 322a9de470cSBruce Richardson for (i = 1; i < nb_pkt_segs; i++) { 323a9de470cSBruce Richardson pkt_seg->next = rte_pktmbuf_alloc(mp); 324a9de470cSBruce Richardson if (pkt_seg->next == NULL) { 325a9de470cSBruce Richardson pkt->nb_segs = i; 326a9de470cSBruce Richardson rte_pktmbuf_free(pkt); 327a9de470cSBruce Richardson goto nomore_mbuf; 328a9de470cSBruce Richardson } 329a9de470cSBruce Richardson pkt_seg = pkt_seg->next; 330b88b8af2SZhuobin Huang if (i != nb_pkt_segs - 1) 331b88b8af2SZhuobin Huang pkt_seg->data_len = pkt_seg_data_len; 332b88b8af2SZhuobin Huang else 333b88b8af2SZhuobin Huang pkt_seg->data_len = pkt_seg_data_len + pkt_len % nb_pkt_segs; 334a9de470cSBruce Richardson } 335a9de470cSBruce Richardson pkt_seg->next = NULL; /* Last segment of packet. */ 336a9de470cSBruce Richardson 337a9de470cSBruce Richardson /* 338a9de470cSBruce Richardson * Copy headers in first packet segment(s). 339a9de470cSBruce Richardson */ 340a9de470cSBruce Richardson if (vlan_enabled) 3416d13ea8eSOlivier Matz eth_hdr_size = sizeof(struct rte_ether_hdr) + 3426d13ea8eSOlivier Matz sizeof(struct rte_vlan_hdr); 343a9de470cSBruce Richardson else 3446d13ea8eSOlivier Matz eth_hdr_size = sizeof(struct rte_ether_hdr); 345a9de470cSBruce Richardson 346a9de470cSBruce Richardson copy_buf_to_pkt(eth_hdr, eth_hdr_size, pkt, 0); 347a9de470cSBruce Richardson 348a9de470cSBruce Richardson if (ipv4) { 349a7c528e5SOlivier Matz copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv4_hdr), 350a7c528e5SOlivier Matz pkt, eth_hdr_size); 351a9de470cSBruce Richardson switch (proto) { 352a9de470cSBruce Richardson case IPPROTO_UDP: 353a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 354e73e3547SOlivier Matz sizeof(struct rte_udp_hdr), pkt, 355a7c528e5SOlivier Matz eth_hdr_size + 356a7c528e5SOlivier Matz sizeof(struct rte_ipv4_hdr)); 357a9de470cSBruce Richardson break; 358a9de470cSBruce Richardson case IPPROTO_TCP: 359a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 360f41b5156SOlivier Matz sizeof(struct rte_tcp_hdr), pkt, 361a7c528e5SOlivier Matz eth_hdr_size + 362a7c528e5SOlivier Matz sizeof(struct rte_ipv4_hdr)); 363a9de470cSBruce Richardson break; 364a9de470cSBruce Richardson case IPPROTO_SCTP: 365a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 36609d9ae1aSOlivier Matz sizeof(struct rte_sctp_hdr), pkt, 367a7c528e5SOlivier Matz eth_hdr_size + 368a7c528e5SOlivier Matz sizeof(struct rte_ipv4_hdr)); 369a9de470cSBruce Richardson break; 370a9de470cSBruce Richardson default: 371a9de470cSBruce Richardson break; 372a9de470cSBruce Richardson } 373a9de470cSBruce Richardson } else { 374a7c528e5SOlivier Matz copy_buf_to_pkt(ip_hdr, sizeof(struct rte_ipv6_hdr), 375a7c528e5SOlivier Matz pkt, eth_hdr_size); 376a9de470cSBruce Richardson switch (proto) { 377a9de470cSBruce Richardson case IPPROTO_UDP: 378a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 379e73e3547SOlivier Matz sizeof(struct rte_udp_hdr), pkt, 380a7c528e5SOlivier Matz eth_hdr_size + 381a7c528e5SOlivier Matz sizeof(struct rte_ipv6_hdr)); 382a9de470cSBruce Richardson break; 383a9de470cSBruce Richardson case IPPROTO_TCP: 384a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 385f41b5156SOlivier Matz sizeof(struct rte_tcp_hdr), pkt, 386a7c528e5SOlivier Matz eth_hdr_size + 387a7c528e5SOlivier Matz sizeof(struct rte_ipv6_hdr)); 388a9de470cSBruce Richardson break; 389a9de470cSBruce Richardson case IPPROTO_SCTP: 390a9de470cSBruce Richardson copy_buf_to_pkt(proto_hdr, 39109d9ae1aSOlivier Matz sizeof(struct rte_sctp_hdr), pkt, 392a7c528e5SOlivier Matz eth_hdr_size + 393a7c528e5SOlivier Matz sizeof(struct rte_ipv6_hdr)); 394a9de470cSBruce Richardson break; 395a9de470cSBruce Richardson default: 396a9de470cSBruce Richardson break; 397a9de470cSBruce Richardson } 398a9de470cSBruce Richardson } 399a9de470cSBruce Richardson 400a9de470cSBruce Richardson /* 401a9de470cSBruce Richardson * Complete first mbuf of packet and append it to the 402a9de470cSBruce Richardson * burst of packets to be transmitted. 403a9de470cSBruce Richardson */ 404a9de470cSBruce Richardson pkt->nb_segs = nb_pkt_segs; 405a9de470cSBruce Richardson pkt->pkt_len = pkt_len; 406a9de470cSBruce Richardson pkt->l2_len = eth_hdr_size; 407a9de470cSBruce Richardson 408a9de470cSBruce Richardson if (ipv4) { 4090c9da755SDavid Marchand pkt->vlan_tci = RTE_ETHER_TYPE_IPV4; 410a7c528e5SOlivier Matz pkt->l3_len = sizeof(struct rte_ipv4_hdr); 411a9de470cSBruce Richardson } else { 4120c9da755SDavid Marchand pkt->vlan_tci = RTE_ETHER_TYPE_IPV6; 413a7c528e5SOlivier Matz pkt->l3_len = sizeof(struct rte_ipv6_hdr); 414a9de470cSBruce Richardson } 415a9de470cSBruce Richardson 416a9de470cSBruce Richardson pkts_burst[nb_pkt] = pkt; 417a9de470cSBruce Richardson } 418a9de470cSBruce Richardson 419a9de470cSBruce Richardson return nb_pkt; 420a9de470cSBruce Richardson } 421