1d862c45bSRaslan Darawsheh /* SPDX-License-Identifier: BSD-3-Clause 2d862c45bSRaslan Darawsheh * Copyright(c) 2010-2014 Intel Corporation 3d862c45bSRaslan Darawsheh * Copyright(c) 2018 Mellanox Technology 4d862c45bSRaslan Darawsheh */ 5d862c45bSRaslan Darawsheh 6d862c45bSRaslan Darawsheh #include <stdio.h> 7d862c45bSRaslan Darawsheh 8d862c45bSRaslan Darawsheh #include <rte_net.h> 9d862c45bSRaslan Darawsheh #include <rte_mbuf.h> 10d862c45bSRaslan Darawsheh #include <rte_ether.h> 11d862c45bSRaslan Darawsheh #include <rte_ethdev.h> 12d862c45bSRaslan Darawsheh #include <rte_flow.h> 13d862c45bSRaslan Darawsheh 14d862c45bSRaslan Darawsheh #include "testpmd.h" 15d862c45bSRaslan Darawsheh 16d862c45bSRaslan Darawsheh static inline void 176d13ea8eSOlivier Matz print_ether_addr(const char *what, struct rte_ether_addr *eth_addr) 18d862c45bSRaslan Darawsheh { 1935b2d13fSOlivier Matz char buf[RTE_ETHER_ADDR_FMT_SIZE]; 2035b2d13fSOlivier Matz rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); 21d862c45bSRaslan Darawsheh printf("%s%s", what, buf); 22d862c45bSRaslan Darawsheh } 23d862c45bSRaslan Darawsheh 24c77ad9deSRaslan Darawsheh static inline void 25d862c45bSRaslan Darawsheh dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], 26d862c45bSRaslan Darawsheh uint16_t nb_pkts, int is_rx) 27d862c45bSRaslan Darawsheh { 28d862c45bSRaslan Darawsheh struct rte_mbuf *mb; 296d13ea8eSOlivier Matz struct rte_ether_hdr *eth_hdr; 30d862c45bSRaslan Darawsheh uint16_t eth_type; 31d862c45bSRaslan Darawsheh uint64_t ol_flags; 32d862c45bSRaslan Darawsheh uint16_t i, packet_type; 33d862c45bSRaslan Darawsheh uint16_t is_encapsulation; 34d862c45bSRaslan Darawsheh char buf[256]; 35d862c45bSRaslan Darawsheh struct rte_net_hdr_lens hdr_lens; 36d862c45bSRaslan Darawsheh uint32_t sw_packet_type; 37d862c45bSRaslan Darawsheh uint16_t udp_port; 38d862c45bSRaslan Darawsheh uint32_t vx_vni; 39b6ec9ce9SDavid Marchand const char *reason; 40d862c45bSRaslan Darawsheh 41d862c45bSRaslan Darawsheh if (!nb_pkts) 42d862c45bSRaslan Darawsheh return; 43d862c45bSRaslan Darawsheh printf("port %u/queue %u: %s %u packets\n", 44d862c45bSRaslan Darawsheh port_id, queue, 45d862c45bSRaslan Darawsheh is_rx ? "received" : "sent", 46d862c45bSRaslan Darawsheh (unsigned int) nb_pkts); 47d862c45bSRaslan Darawsheh for (i = 0; i < nb_pkts; i++) { 48d862c45bSRaslan Darawsheh mb = pkts[i]; 496d13ea8eSOlivier Matz eth_hdr = rte_pktmbuf_mtod(mb, struct rte_ether_hdr *); 50d862c45bSRaslan Darawsheh eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type); 51d862c45bSRaslan Darawsheh ol_flags = mb->ol_flags; 52d862c45bSRaslan Darawsheh packet_type = mb->packet_type; 53d862c45bSRaslan Darawsheh is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type); 54d862c45bSRaslan Darawsheh 55d862c45bSRaslan Darawsheh print_ether_addr(" src=", ð_hdr->s_addr); 56d862c45bSRaslan Darawsheh print_ether_addr(" - dst=", ð_hdr->d_addr); 57d862c45bSRaslan Darawsheh printf(" - type=0x%04x - length=%u - nb_segs=%d", 58d862c45bSRaslan Darawsheh eth_type, (unsigned int) mb->pkt_len, 59d862c45bSRaslan Darawsheh (int)mb->nb_segs); 60d862c45bSRaslan Darawsheh if (ol_flags & PKT_RX_RSS_HASH) { 61d862c45bSRaslan Darawsheh printf(" - RSS hash=0x%x", (unsigned int) mb->hash.rss); 62d862c45bSRaslan Darawsheh printf(" - RSS queue=0x%x", (unsigned int) queue); 63d862c45bSRaslan Darawsheh } 64d862c45bSRaslan Darawsheh if (ol_flags & PKT_RX_FDIR) { 65d862c45bSRaslan Darawsheh printf(" - FDIR matched "); 66d862c45bSRaslan Darawsheh if (ol_flags & PKT_RX_FDIR_ID) 67d862c45bSRaslan Darawsheh printf("ID=0x%x", 68d862c45bSRaslan Darawsheh mb->hash.fdir.hi); 69d862c45bSRaslan Darawsheh else if (ol_flags & PKT_RX_FDIR_FLX) 70d862c45bSRaslan Darawsheh printf("flex bytes=0x%08x %08x", 71d862c45bSRaslan Darawsheh mb->hash.fdir.hi, mb->hash.fdir.lo); 72d862c45bSRaslan Darawsheh else 73d862c45bSRaslan Darawsheh printf("hash=0x%x ID=0x%x ", 74d862c45bSRaslan Darawsheh mb->hash.fdir.hash, mb->hash.fdir.id); 75d862c45bSRaslan Darawsheh } 76d862c45bSRaslan Darawsheh if (ol_flags & PKT_RX_TIMESTAMP) 77d862c45bSRaslan Darawsheh printf(" - timestamp %"PRIu64" ", mb->timestamp); 78d862c45bSRaslan Darawsheh if (ol_flags & PKT_RX_QINQ) 79d862c45bSRaslan Darawsheh printf(" - QinQ VLAN tci=0x%x, VLAN tci outer=0x%x", 80d862c45bSRaslan Darawsheh mb->vlan_tci, mb->vlan_tci_outer); 81d862c45bSRaslan Darawsheh else if (ol_flags & PKT_RX_VLAN) 82d862c45bSRaslan Darawsheh printf(" - VLAN tci=0x%x", mb->vlan_tci); 83d862c45bSRaslan Darawsheh if (mb->packet_type) { 84d862c45bSRaslan Darawsheh rte_get_ptype_name(mb->packet_type, buf, sizeof(buf)); 85d862c45bSRaslan Darawsheh printf(" - hw ptype: %s", buf); 86d862c45bSRaslan Darawsheh } 87d862c45bSRaslan Darawsheh sw_packet_type = rte_net_get_ptype(mb, &hdr_lens, 88d862c45bSRaslan Darawsheh RTE_PTYPE_ALL_MASK); 89d862c45bSRaslan Darawsheh rte_get_ptype_name(sw_packet_type, buf, sizeof(buf)); 90d862c45bSRaslan Darawsheh printf(" - sw ptype: %s", buf); 91d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_L2_MASK) 92d862c45bSRaslan Darawsheh printf(" - l2_len=%d", hdr_lens.l2_len); 93d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_L3_MASK) 94d862c45bSRaslan Darawsheh printf(" - l3_len=%d", hdr_lens.l3_len); 95d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_L4_MASK) 96d862c45bSRaslan Darawsheh printf(" - l4_len=%d", hdr_lens.l4_len); 97d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_TUNNEL_MASK) 98d862c45bSRaslan Darawsheh printf(" - tunnel_len=%d", hdr_lens.tunnel_len); 99d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_INNER_L2_MASK) 100d862c45bSRaslan Darawsheh printf(" - inner_l2_len=%d", hdr_lens.inner_l2_len); 101d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_INNER_L3_MASK) 102d862c45bSRaslan Darawsheh printf(" - inner_l3_len=%d", hdr_lens.inner_l3_len); 103d862c45bSRaslan Darawsheh if (sw_packet_type & RTE_PTYPE_INNER_L4_MASK) 104d862c45bSRaslan Darawsheh printf(" - inner_l4_len=%d", hdr_lens.inner_l4_len); 105d862c45bSRaslan Darawsheh if (is_encapsulation) { 106*a7c528e5SOlivier Matz struct rte_ipv4_hdr *ipv4_hdr; 107*a7c528e5SOlivier Matz struct rte_ipv6_hdr *ipv6_hdr; 108d862c45bSRaslan Darawsheh struct udp_hdr *udp_hdr; 109d862c45bSRaslan Darawsheh uint8_t l2_len; 110d862c45bSRaslan Darawsheh uint8_t l3_len; 111d862c45bSRaslan Darawsheh uint8_t l4_len; 112d862c45bSRaslan Darawsheh uint8_t l4_proto; 1136d13ea8eSOlivier Matz struct rte_vxlan_hdr *vxlan_hdr; 114d862c45bSRaslan Darawsheh 1156d13ea8eSOlivier Matz l2_len = sizeof(struct rte_ether_hdr); 116d862c45bSRaslan Darawsheh 117d862c45bSRaslan Darawsheh /* Do not support ipv4 option field */ 118d862c45bSRaslan Darawsheh if (RTE_ETH_IS_IPV4_HDR(packet_type)) { 119*a7c528e5SOlivier Matz l3_len = sizeof(struct rte_ipv4_hdr); 120d862c45bSRaslan Darawsheh ipv4_hdr = rte_pktmbuf_mtod_offset(mb, 121*a7c528e5SOlivier Matz struct rte_ipv4_hdr *, 122d862c45bSRaslan Darawsheh l2_len); 123d862c45bSRaslan Darawsheh l4_proto = ipv4_hdr->next_proto_id; 124d862c45bSRaslan Darawsheh } else { 125*a7c528e5SOlivier Matz l3_len = sizeof(struct rte_ipv6_hdr); 126d862c45bSRaslan Darawsheh ipv6_hdr = rte_pktmbuf_mtod_offset(mb, 127*a7c528e5SOlivier Matz struct rte_ipv6_hdr *, 128d862c45bSRaslan Darawsheh l2_len); 129d862c45bSRaslan Darawsheh l4_proto = ipv6_hdr->proto; 130d862c45bSRaslan Darawsheh } 131d862c45bSRaslan Darawsheh if (l4_proto == IPPROTO_UDP) { 132d862c45bSRaslan Darawsheh udp_hdr = rte_pktmbuf_mtod_offset(mb, 133d862c45bSRaslan Darawsheh struct udp_hdr *, 134d862c45bSRaslan Darawsheh l2_len + l3_len); 135d862c45bSRaslan Darawsheh l4_len = sizeof(struct udp_hdr); 136d862c45bSRaslan Darawsheh vxlan_hdr = rte_pktmbuf_mtod_offset(mb, 1376d13ea8eSOlivier Matz struct rte_vxlan_hdr *, 138d862c45bSRaslan Darawsheh l2_len + l3_len + l4_len); 139d862c45bSRaslan Darawsheh udp_port = RTE_BE_TO_CPU_16(udp_hdr->dst_port); 140d862c45bSRaslan Darawsheh vx_vni = rte_be_to_cpu_32(vxlan_hdr->vx_vni); 141d862c45bSRaslan Darawsheh printf(" - VXLAN packet: packet type =%d, " 142d862c45bSRaslan Darawsheh "Destination UDP port =%d, VNI = %d", 143d862c45bSRaslan Darawsheh packet_type, udp_port, vx_vni >> 8); 144d862c45bSRaslan Darawsheh } 145d862c45bSRaslan Darawsheh } 146d862c45bSRaslan Darawsheh printf(" - %s queue=0x%x", is_rx ? "Receive" : "Send", 147d862c45bSRaslan Darawsheh (unsigned int) queue); 148d862c45bSRaslan Darawsheh printf("\n"); 149d862c45bSRaslan Darawsheh rte_get_rx_ol_flag_list(mb->ol_flags, buf, sizeof(buf)); 150d862c45bSRaslan Darawsheh printf(" ol_flags: %s\n", buf); 151b6ec9ce9SDavid Marchand if (rte_mbuf_check(mb, 1, &reason) < 0) 152b6ec9ce9SDavid Marchand printf("INVALID mbuf: %s\n", reason); 153d862c45bSRaslan Darawsheh } 154d862c45bSRaslan Darawsheh } 155c77ad9deSRaslan Darawsheh 156c77ad9deSRaslan Darawsheh uint16_t 157c77ad9deSRaslan Darawsheh dump_rx_pkts(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], 158c77ad9deSRaslan Darawsheh uint16_t nb_pkts, __rte_unused uint16_t max_pkts, 159c77ad9deSRaslan Darawsheh __rte_unused void *user_param) 160c77ad9deSRaslan Darawsheh { 161c77ad9deSRaslan Darawsheh dump_pkt_burst(port_id, queue, pkts, nb_pkts, 1); 162c77ad9deSRaslan Darawsheh return nb_pkts; 163c77ad9deSRaslan Darawsheh } 164c77ad9deSRaslan Darawsheh 165c77ad9deSRaslan Darawsheh uint16_t 166c77ad9deSRaslan Darawsheh dump_tx_pkts(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[], 167c77ad9deSRaslan Darawsheh uint16_t nb_pkts, __rte_unused void *user_param) 168c77ad9deSRaslan Darawsheh { 169c77ad9deSRaslan Darawsheh dump_pkt_burst(port_id, queue, pkts, nb_pkts, 0); 170c77ad9deSRaslan Darawsheh return nb_pkts; 171c77ad9deSRaslan Darawsheh } 1721e45c908SDekel Peled 1731e45c908SDekel Peled uint16_t 1741e45c908SDekel Peled tx_pkt_set_md(uint16_t port_id, __rte_unused uint16_t queue, 1751e45c908SDekel Peled struct rte_mbuf *pkts[], uint16_t nb_pkts, 1761e45c908SDekel Peled __rte_unused void *user_param) 1771e45c908SDekel Peled { 1781e45c908SDekel Peled uint16_t i = 0; 1791e45c908SDekel Peled 1801e45c908SDekel Peled /* 1811e45c908SDekel Peled * Add metadata value to every Tx packet, 1821e45c908SDekel Peled * and set ol_flags accordingly. 1831e45c908SDekel Peled */ 1841e45c908SDekel Peled for (i = 0; i < nb_pkts; i++) { 1851e45c908SDekel Peled pkts[i]->tx_metadata = ports[port_id].tx_metadata; 1861e45c908SDekel Peled pkts[i]->ol_flags |= PKT_TX_METADATA; 1871e45c908SDekel Peled } 1881e45c908SDekel Peled return nb_pkts; 1891e45c908SDekel Peled } 1901e45c908SDekel Peled 1911e45c908SDekel Peled void 1921e45c908SDekel Peled add_tx_md_callback(portid_t portid) 1931e45c908SDekel Peled { 1941e45c908SDekel Peled struct rte_eth_dev_info dev_info; 1951e45c908SDekel Peled uint16_t queue; 1961e45c908SDekel Peled 1971e45c908SDekel Peled if (port_id_is_invalid(portid, ENABLED_WARN)) 1981e45c908SDekel Peled return; 1991e45c908SDekel Peled rte_eth_dev_info_get(portid, &dev_info); 2001e45c908SDekel Peled for (queue = 0; queue < dev_info.nb_tx_queues; queue++) 2011e45c908SDekel Peled if (!ports[portid].tx_set_md_cb[queue]) 2021e45c908SDekel Peled ports[portid].tx_set_md_cb[queue] = 2031e45c908SDekel Peled rte_eth_add_tx_callback(portid, queue, 2041e45c908SDekel Peled tx_pkt_set_md, NULL); 2051e45c908SDekel Peled } 2061e45c908SDekel Peled 2071e45c908SDekel Peled void 2081e45c908SDekel Peled remove_tx_md_callback(portid_t portid) 2091e45c908SDekel Peled { 2101e45c908SDekel Peled struct rte_eth_dev_info dev_info; 2111e45c908SDekel Peled uint16_t queue; 2121e45c908SDekel Peled 2131e45c908SDekel Peled if (port_id_is_invalid(portid, ENABLED_WARN)) 2141e45c908SDekel Peled return; 2151e45c908SDekel Peled rte_eth_dev_info_get(portid, &dev_info); 2161e45c908SDekel Peled for (queue = 0; queue < dev_info.nb_tx_queues; queue++) 2171e45c908SDekel Peled if (ports[portid].tx_set_md_cb[queue]) { 2181e45c908SDekel Peled rte_eth_remove_tx_callback(portid, queue, 2191e45c908SDekel Peled ports[portid].tx_set_md_cb[queue]); 2201e45c908SDekel Peled ports[portid].tx_set_md_cb[queue] = NULL; 2211e45c908SDekel Peled } 2221e45c908SDekel Peled } 223