LCOV - code coverage report
Current view: top level - app/test - test_pmd_tap.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 395 532 74.2 %
Date: 2026-04-01 20:02:27 Functions: 39 39 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 166 314 52.9 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2026 Stephen Hemminger
       3                 :            :  */
       4                 :            : 
       5                 :            : /*
       6                 :            :  * Basic test of TAP device functionality
       7                 :            :  * based off of PMD ring test.
       8                 :            :  */
       9                 :            : 
      10                 :            : #include "test.h"
      11                 :            : 
      12                 :            : #include <stdio.h>
      13                 :            : 
      14                 :            : #ifndef RTE_EXEC_ENV_LINUX
      15                 :            : 
      16                 :            : /* TAP PMD is only available on Linux */
      17                 :            : static int
      18                 :            : test_pmd_tap(void)
      19                 :            : {
      20                 :            :         printf("TAP PMD not supported on this platform, skipping test\n");
      21                 :            :         return TEST_SKIPPED;
      22                 :            : }
      23                 :            : 
      24                 :            : #else /* RTE_EXEC_ENV_LINUX */
      25                 :            : 
      26                 :            : #include <string.h>
      27                 :            : #include <unistd.h>
      28                 :            : #include <limits.h>
      29                 :            : #include <net/if.h>
      30                 :            : #include <sys/socket.h>
      31                 :            : #include <linux/if_packet.h>
      32                 :            : 
      33                 :            : #include <rte_ethdev.h>
      34                 :            : #include <rte_bus_vdev.h>
      35                 :            : #include <rte_mbuf.h>
      36                 :            : #include <rte_ether.h>
      37                 :            : #include <rte_ip.h>
      38                 :            : 
      39                 :            : #define SOCKET0 0
      40                 :            : #define RING_SIZE 256
      41                 :            : #define NB_MBUF 4096
      42                 :            : #define MAX_PKT_BURST 32
      43                 :            : #define PKT_LEN 64
      44                 :            : 
      45                 :            : static struct rte_mempool *mp;
      46                 :            : static int tap_port0 = -1;
      47                 :            : static int tap_port1 = -1;
      48                 :            : 
      49                 :            : static int
      50                 :          2 : test_tap_ethdev_configure(int port)
      51                 :            : {
      52                 :            :         struct rte_eth_conf port_conf;
      53                 :            :         struct rte_eth_link link;
      54                 :            :         int ret;
      55                 :            : 
      56                 :            :         memset(&port_conf, 0, sizeof(struct rte_eth_conf));
      57                 :            : 
      58                 :          2 :         ret = rte_eth_dev_configure(port, 1, 1, &port_conf);
      59         [ -  + ]:          2 :         if (ret < 0) {
      60                 :          0 :                 printf("Configure failed for port %d: %s\n",
      61                 :            :                        port, rte_strerror(-ret));
      62                 :          0 :                 return -1;
      63                 :            :         }
      64                 :            : 
      65                 :          2 :         ret = rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL);
      66         [ -  + ]:          2 :         if (ret < 0) {
      67                 :          0 :                 printf("TX queue setup failed for port %d: %s\n",
      68                 :            :                        port, rte_strerror(-ret));
      69                 :          0 :                 return -1;
      70                 :            :         }
      71                 :            : 
      72                 :          2 :         ret = rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL, mp);
      73         [ -  + ]:          2 :         if (ret < 0) {
      74                 :          0 :                 printf("RX queue setup failed for port %d: %s\n",
      75                 :            :                        port, rte_strerror(-ret));
      76                 :          0 :                 return -1;
      77                 :            :         }
      78                 :            : 
      79                 :          2 :         ret = rte_eth_dev_start(port);
      80         [ -  + ]:          2 :         if (ret < 0) {
      81                 :          0 :                 printf("Error starting port %d: %s\n",
      82                 :            :                        port, rte_strerror(-ret));
      83                 :          0 :                 return -1;
      84                 :            :         }
      85                 :            : 
      86                 :          2 :         ret = rte_eth_link_get(port, &link);
      87         [ -  + ]:          2 :         if (ret < 0) {
      88                 :          0 :                 printf("Link get failed for port %d: %s\n",
      89                 :            :                        port, rte_strerror(-ret));
      90                 :          0 :                 return -1;
      91                 :            :         }
      92                 :            : 
      93                 :          2 :         printf("Port %d: link status %s, speed %u Mbps\n",
      94                 :            :                port,
      95         [ -  + ]:          2 :                link.link_status ? "up" : "down",
      96                 :            :                link.link_speed);
      97                 :            : 
      98                 :          2 :         return 0;
      99                 :            : }
     100                 :            : 
     101                 :            : static struct rte_mbuf *
     102                 :         16 : create_test_packet(struct rte_mempool *pool, uint16_t pkt_len)
     103                 :            : {
     104                 :            :         struct rte_mbuf *mbuf;
     105                 :            :         struct rte_ether_hdr *eth_hdr;
     106                 :            :         struct rte_ipv4_hdr *ip_hdr;
     107                 :            :         uint8_t *payload;
     108                 :            :         uint16_t i;
     109                 :            : 
     110                 :         16 :         mbuf = rte_pktmbuf_alloc(pool);
     111         [ -  + ]:         16 :         if (mbuf == NULL) {
     112                 :            :                 printf("%s(): mbuf alloc failed\n", __func__);
     113                 :          0 :                 return NULL;
     114                 :            :         }
     115                 :            : 
     116                 :            :         /* Ensure minimum packet size for Ethernet */
     117                 :            :         if (pkt_len < RTE_ETHER_MIN_LEN)
     118                 :            :                 pkt_len = RTE_ETHER_MIN_LEN;
     119                 :            : 
     120                 :         16 :         eth_hdr = (struct rte_ether_hdr *)rte_pktmbuf_append(mbuf, pkt_len);
     121         [ -  + ]:         16 :         if (eth_hdr == NULL) {
     122                 :            :                 printf("%s(): append %u bytes failed\n", __func__, pkt_len);
     123                 :          0 :                 rte_pktmbuf_free(mbuf);
     124                 :          0 :                 return NULL;
     125                 :            :         }
     126                 :            : 
     127                 :            :         /* Create Ethernet header */
     128                 :         16 :         eth_hdr = rte_pktmbuf_mtod(mbuf, struct rte_ether_hdr *);
     129         [ +  - ]:         16 :         memset(&eth_hdr->dst_addr, 0xFF, RTE_ETHER_ADDR_LEN); /* broadcast */
     130                 :         16 :         memset(&eth_hdr->src_addr, 0x02, RTE_ETHER_ADDR_LEN);
     131                 :         16 :         eth_hdr->src_addr.addr_bytes[5] = 0x01;
     132                 :         16 :         eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
     133                 :            : 
     134                 :            :         /* Create simple IPv4 header */
     135                 :         16 :         ip_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
     136                 :            :         memset(ip_hdr, 0, sizeof(*ip_hdr));
     137                 :         16 :         ip_hdr->version_ihl = 0x45; /* IPv4, 20 byte header */
     138         [ +  - ]:         16 :         ip_hdr->total_length = rte_cpu_to_be_16(pkt_len - sizeof(*eth_hdr));
     139                 :         16 :         ip_hdr->time_to_live = 64;
     140                 :         16 :         ip_hdr->next_proto_id = IPPROTO_UDP;
     141                 :         16 :         ip_hdr->src_addr = rte_cpu_to_be_32(0x0A000001); /* 10.0.0.1 */
     142                 :         16 :         ip_hdr->dst_addr = rte_cpu_to_be_32(0x0A000002); /* 10.0.0.2 */
     143                 :            : 
     144                 :            :         /* Fill payload with pattern */
     145                 :         16 :         payload = (uint8_t *)(ip_hdr + 1);
     146         [ +  + ]:        496 :         for (i = 0; i < pkt_len - sizeof(*eth_hdr) - sizeof(*ip_hdr); i++)
     147                 :        480 :                 payload[i] = (uint8_t)(i & 0xFF);
     148                 :            : 
     149                 :            :         return mbuf;
     150                 :            : }
     151                 :            : 
     152                 :            : static int
     153                 :          1 : test_tap_send_receive(void)
     154                 :            : {
     155                 :            :         struct rte_mbuf *tx_mbufs[MAX_PKT_BURST];
     156                 :            :         struct rte_mbuf *rx_mbufs[MAX_PKT_BURST];
     157                 :            :         uint16_t nb_tx, nb_rx;
     158                 :            :         int i;
     159                 :            : 
     160                 :            :         printf("Testing TAP packet send and receive\n");
     161                 :            : 
     162                 :            :         /* Create test packets */
     163         [ +  + ]:         17 :         for (i = 0; i < MAX_PKT_BURST / 2; i++) {
     164                 :         16 :                 tx_mbufs[i] = create_test_packet(mp, PKT_LEN);
     165         [ -  + ]:         16 :                 if (tx_mbufs[i] == NULL) {
     166                 :            :                         printf("Failed to create test packet %d\n", i);
     167                 :            :                         /* Free already allocated packets */
     168         [ #  # ]:          0 :                         while (--i >= 0)
     169                 :          0 :                                 rte_pktmbuf_free(tx_mbufs[i]);
     170                 :            :                         return TEST_FAILED;
     171                 :            :                 }
     172                 :            :         }
     173                 :            : 
     174                 :            :         /* Send packets */
     175                 :          1 :         nb_tx = rte_eth_tx_burst(tap_port0, 0, tx_mbufs, MAX_PKT_BURST / 2);
     176                 :          1 :         printf("Transmitted %u packets on port %d\n", nb_tx, tap_port0);
     177                 :            : 
     178                 :            :         /* Free any unsent packets */
     179         [ -  + ]:          1 :         for (i = nb_tx; i < MAX_PKT_BURST / 2; i++)
     180                 :          0 :                 rte_pktmbuf_free(tx_mbufs[i]);
     181                 :            : 
     182         [ -  + ]:          1 :         if (nb_tx == 0) {
     183                 :            :                 printf("Warning: No packets transmitted (this may be expected if interface is not up)\n");
     184                 :          0 :                 return TEST_SUCCESS;
     185                 :            :         }
     186                 :            : 
     187                 :            :         /* Small delay to allow packets to be processed */
     188                 :          1 :         usleep(10000);
     189                 :            : 
     190                 :            :         /* Try to receive packets (note: TAP loopback depends on kernel config) */
     191                 :          1 :         nb_rx = rte_eth_rx_burst(tap_port0, 0, rx_mbufs, MAX_PKT_BURST);
     192                 :          1 :         printf("Received %u packets on port %d\n", nb_rx, tap_port0);
     193                 :            : 
     194                 :            :         /* Free received packets */
     195         [ -  + ]:          1 :         for (i = 0; i < nb_rx; i++)
     196                 :          0 :                 rte_pktmbuf_free(rx_mbufs[i]);
     197                 :            : 
     198                 :            :         return TEST_SUCCESS;
     199                 :            : }
     200                 :            : 
     201                 :            : static int
     202                 :          2 : test_tap_stats_get(int port)
     203                 :            : {
     204                 :            :         struct rte_eth_stats stats;
     205                 :            :         int ret;
     206                 :            : 
     207                 :            :         printf("Testing TAP PMD stats_get for port %d\n", port);
     208                 :            : 
     209                 :          2 :         ret = rte_eth_stats_get(port, &stats);
     210         [ -  + ]:          2 :         if (ret != 0) {
     211                 :          0 :                 printf("Error: failed to get stats for port %d: %s\n",
     212                 :            :                        port, rte_strerror(-ret));
     213                 :          0 :                 return -1;
     214                 :            :         }
     215                 :            : 
     216                 :            :         printf("Port %d stats:\n", port);
     217                 :          2 :         printf("  ipackets: %"PRIu64"\n", stats.ipackets);
     218                 :          2 :         printf("  opackets: %"PRIu64"\n", stats.opackets);
     219                 :          2 :         printf("  ibytes:   %"PRIu64"\n", stats.ibytes);
     220                 :          2 :         printf("  obytes:   %"PRIu64"\n", stats.obytes);
     221                 :          2 :         printf("  ierrors:  %"PRIu64"\n", stats.ierrors);
     222                 :          2 :         printf("  oerrors:  %"PRIu64"\n", stats.oerrors);
     223                 :            : 
     224                 :          2 :         return 0;
     225                 :            : }
     226                 :            : 
     227                 :            : static int
     228                 :          2 : test_tap_stats_reset(int port)
     229                 :            : {
     230                 :            :         struct rte_eth_stats stats;
     231                 :            :         int ret;
     232                 :            : 
     233                 :            :         printf("Testing TAP PMD stats_reset for port %d\n", port);
     234                 :            : 
     235                 :          2 :         ret = rte_eth_stats_reset(port);
     236         [ -  + ]:          2 :         if (ret != 0) {
     237                 :          0 :                 printf("Error: failed to reset stats for port %d: %s\n",
     238                 :            :                        port, rte_strerror(-ret));
     239                 :          0 :                 return -1;
     240                 :            :         }
     241                 :            : 
     242                 :          2 :         ret = rte_eth_stats_get(port, &stats);
     243         [ -  + ]:          2 :         if (ret != 0) {
     244                 :            :                 printf("Error: failed to get stats after reset for port %d\n",
     245                 :            :                        port);
     246                 :          0 :                 return -1;
     247                 :            :         }
     248                 :            : 
     249                 :            :         /* After reset, all stats should be zero */
     250   [ +  -  +  - ]:          2 :         if (stats.ipackets != 0 || stats.opackets != 0 ||
     251   [ +  -  +  - ]:          2 :             stats.ibytes != 0 || stats.obytes != 0 ||
     252   [ +  -  -  + ]:          2 :             stats.ierrors != 0 || stats.oerrors != 0) {
     253                 :            :                 printf("Error: port %d stats are not zero after reset\n", port);
     254                 :          0 :                 return -1;
     255                 :            :         }
     256                 :            : 
     257                 :            :         printf("Stats reset successful for port %d\n", port);
     258                 :          2 :         return 0;
     259                 :            : }
     260                 :            : 
     261                 :            : static int
     262                 :          2 : test_tap_link_status(int port)
     263                 :            : {
     264                 :            :         struct rte_eth_link link;
     265                 :            :         int ret;
     266                 :            : 
     267                 :            :         printf("Testing TAP PMD link status for port %d\n", port);
     268                 :            : 
     269                 :          2 :         ret = rte_eth_link_get_nowait(port, &link);
     270         [ -  + ]:          2 :         if (ret < 0) {
     271                 :          0 :                 printf("Error: failed to get link status for port %d: %s\n",
     272                 :            :                        port, rte_strerror(-ret));
     273                 :          0 :                 return -1;
     274                 :            :         }
     275                 :            : 
     276                 :          4 :         printf("Port %d link: status=%s speed=%u duplex=%s\n",
     277                 :            :                port,
     278         [ -  + ]:          2 :                link.link_status ? "up" : "down",
     279                 :            :                link.link_speed,
     280         [ -  + ]:          2 :                link.link_duplex ? "full" : "half");
     281                 :            : 
     282                 :          2 :         return 0;
     283                 :            : }
     284                 :            : 
     285                 :            : static int
     286                 :          2 : test_tap_dev_info(int port)
     287                 :            : {
     288                 :            :         struct rte_eth_dev_info dev_info;
     289                 :            :         int ret;
     290                 :            : 
     291                 :            :         printf("Testing TAP PMD dev_info for port %d\n", port);
     292                 :            : 
     293                 :          2 :         ret = rte_eth_dev_info_get(port, &dev_info);
     294         [ -  + ]:          2 :         if (ret != 0) {
     295                 :          0 :                 printf("Error: failed to get dev info for port %d: %s\n",
     296                 :            :                        port, rte_strerror(-ret));
     297                 :          0 :                 return -1;
     298                 :            :         }
     299                 :            : 
     300                 :            :         printf("Port %d device info:\n", port);
     301                 :          2 :         printf("  driver_name: %s\n", dev_info.driver_name);
     302                 :          2 :         printf("  if_index: %u\n", dev_info.if_index);
     303                 :          2 :         printf("  max_rx_queues: %u\n", dev_info.max_rx_queues);
     304                 :          2 :         printf("  max_tx_queues: %u\n", dev_info.max_tx_queues);
     305                 :          2 :         printf("  max_rx_pktlen: %u\n", dev_info.max_rx_pktlen);
     306                 :            : 
     307                 :            :         /* Verify this is indeed a TAP device */
     308         [ -  + ]:          2 :         if (strcmp(dev_info.driver_name, "net_tap") != 0 &&
     309         [ #  # ]:          0 :             strcmp(dev_info.driver_name, "net_tun") != 0) {
     310                 :            :                 printf("Warning: unexpected driver name: %s\n",
     311                 :            :                        dev_info.driver_name);
     312                 :            :         }
     313                 :            : 
     314                 :            :         return 0;
     315                 :            : }
     316                 :            : 
     317                 :            : static int
     318                 :          1 : test_tap_mtu(int port)
     319                 :            : {
     320                 :            :         uint16_t mtu;
     321                 :            :         int ret;
     322                 :            : 
     323                 :            :         printf("Testing TAP PMD MTU operations for port %d\n", port);
     324                 :            : 
     325                 :            :         /* Get current MTU */
     326                 :          1 :         ret = rte_eth_dev_get_mtu(port, &mtu);
     327         [ -  + ]:          1 :         if (ret != 0) {
     328                 :          0 :                 printf("Error: failed to get MTU for port %d: %s\n",
     329                 :            :                        port, rte_strerror(-ret));
     330                 :          0 :                 return -1;
     331                 :            :         }
     332                 :          1 :         printf("Current MTU for port %d: %u\n", port, mtu);
     333                 :            : 
     334                 :            :         /* Try to set a new MTU */
     335                 :          1 :         ret = rte_eth_dev_set_mtu(port, 1400);
     336         [ -  + ]:          1 :         if (ret != 0) {
     337                 :          0 :                 printf("Warning: failed to set MTU to 1400 for port %d: %s\n",
     338                 :            :                        port, rte_strerror(-ret));
     339                 :            :                 /* Not a fatal error - may require privileges */
     340                 :            :         } else {
     341                 :            :                 printf("MTU set to 1400 for port %d\n", port);
     342                 :            : 
     343                 :            :                 /* Restore original MTU */
     344                 :          1 :                 ret = rte_eth_dev_set_mtu(port, mtu);
     345         [ -  + ]:          1 :                 if (ret != 0)
     346                 :            :                         printf("Warning: failed to restore MTU for port %d\n", port);
     347                 :            :         }
     348                 :            : 
     349                 :            :         return 0;
     350                 :            : }
     351                 :            : 
     352                 :            : static int
     353                 :          2 : test_tap_mac_addr(int port)
     354                 :            : {
     355                 :            :         struct rte_ether_addr mac_addr;
     356                 :            :         int ret;
     357                 :            : 
     358                 :            :         printf("Testing TAP PMD MAC address for port %d\n", port);
     359                 :            : 
     360                 :          2 :         ret = rte_eth_macaddr_get(port, &mac_addr);
     361         [ -  + ]:          2 :         if (ret != 0) {
     362                 :          0 :                 printf("Error: failed to get MAC address for port %d: %s\n",
     363                 :            :                        port, rte_strerror(-ret));
     364                 :          0 :                 return -1;
     365                 :            :         }
     366                 :            : 
     367                 :          2 :         printf("Port %d MAC address: " RTE_ETHER_ADDR_PRT_FMT "\n",
     368                 :          2 :                port, RTE_ETHER_ADDR_BYTES(&mac_addr));
     369                 :            : 
     370                 :          2 :         return 0;
     371                 :            : }
     372                 :            : 
     373                 :            : static int
     374                 :          1 : test_tap_promiscuous(int port)
     375                 :            : {
     376                 :            :         int ret;
     377                 :            :         int promisc_enabled;
     378                 :            : 
     379                 :            :         printf("Testing TAP PMD promiscuous mode for port %d\n", port);
     380                 :            : 
     381                 :            :         /* Get current promiscuous state */
     382                 :          1 :         promisc_enabled = rte_eth_promiscuous_get(port);
     383         [ +  - ]:          1 :         printf("Promiscuous mode initially %s for port %d\n",
     384                 :            :                promisc_enabled ? "enabled" : "disabled", port);
     385                 :            : 
     386                 :            :         /* Enable promiscuous mode */
     387                 :          1 :         ret = rte_eth_promiscuous_enable(port);
     388         [ -  + ]:          1 :         if (ret != 0) {
     389                 :          0 :                 printf("Warning: failed to enable promiscuous mode for port %d: %s\n",
     390                 :            :                        port, rte_strerror(-ret));
     391                 :            :         } else {
     392         [ -  + ]:          1 :                 if (rte_eth_promiscuous_get(port) != 1) {
     393                 :            :                         printf("Error: promiscuous mode not enabled after enable call\n");
     394                 :          0 :                         return -1;
     395                 :            :                 }
     396                 :            :                 printf("Promiscuous mode enabled for port %d\n", port);
     397                 :            :         }
     398                 :            : 
     399                 :            :         /* Disable promiscuous mode */
     400                 :          1 :         ret = rte_eth_promiscuous_disable(port);
     401         [ -  + ]:          1 :         if (ret != 0) {
     402                 :          0 :                 printf("Warning: failed to disable promiscuous mode for port %d: %s\n",
     403                 :            :                        port, rte_strerror(-ret));
     404                 :            :         } else {
     405         [ -  + ]:          1 :                 if (rte_eth_promiscuous_get(port) != 0) {
     406                 :            :                         printf("Error: promiscuous mode not disabled after disable call\n");
     407                 :          0 :                         return -1;
     408                 :            :                 }
     409                 :            :                 printf("Promiscuous mode disabled for port %d\n", port);
     410                 :            :         }
     411                 :            : 
     412                 :            :         return 0;
     413                 :            : }
     414                 :            : 
     415                 :            : static int
     416                 :          1 : test_tap_allmulti(int port)
     417                 :            : {
     418                 :            :         int ret;
     419                 :            :         int allmulti_enabled;
     420                 :            : 
     421                 :            :         printf("Testing TAP PMD allmulticast mode for port %d\n", port);
     422                 :            : 
     423                 :            :         /* Get current allmulticast state */
     424                 :          1 :         allmulti_enabled = rte_eth_allmulticast_get(port);
     425         [ +  - ]:          1 :         printf("Allmulticast mode initially %s for port %d\n",
     426                 :            :                allmulti_enabled ? "enabled" : "disabled", port);
     427                 :            : 
     428                 :            :         /* Enable allmulticast mode */
     429                 :          1 :         ret = rte_eth_allmulticast_enable(port);
     430         [ -  + ]:          1 :         if (ret != 0) {
     431                 :          0 :                 printf("Warning: failed to enable allmulticast mode for port %d: %s\n",
     432                 :            :                        port, rte_strerror(-ret));
     433                 :            :         } else {
     434         [ -  + ]:          1 :                 if (rte_eth_allmulticast_get(port) != 1) {
     435                 :            :                         printf("Error: allmulticast mode not enabled after enable call\n");
     436                 :          0 :                         return -1;
     437                 :            :                 }
     438                 :            :                 printf("Allmulticast mode enabled for port %d\n", port);
     439                 :            :         }
     440                 :            : 
     441                 :            :         /* Disable allmulticast mode */
     442                 :          1 :         ret = rte_eth_allmulticast_disable(port);
     443         [ -  + ]:          1 :         if (ret != 0) {
     444                 :          0 :                 printf("Warning: failed to disable allmulticast mode for port %d: %s\n",
     445                 :            :                        port, rte_strerror(-ret));
     446                 :            :         } else {
     447         [ -  + ]:          1 :                 if (rte_eth_allmulticast_get(port) != 0) {
     448                 :            :                         printf("Error: allmulticast mode not disabled after disable call\n");
     449                 :          0 :                         return -1;
     450                 :            :                 }
     451                 :            :                 printf("Allmulticast mode disabled for port %d\n", port);
     452                 :            :         }
     453                 :            : 
     454                 :            :         return 0;
     455                 :            : }
     456                 :            : 
     457                 :            : static int
     458                 :          1 : test_tap_queue_start_stop(int port)
     459                 :            : {
     460                 :            :         int ret;
     461                 :            : 
     462                 :            :         printf("Testing TAP PMD queue start/stop for port %d\n", port);
     463                 :            : 
     464                 :            :         /* Stop RX queue */
     465                 :          1 :         ret = rte_eth_dev_rx_queue_stop(port, 0);
     466         [ -  + ]:          1 :         if (ret != 0 && ret != -ENOTSUP) {
     467                 :          0 :                 printf("Error: failed to stop RX queue for port %d: %s\n",
     468                 :            :                        port, rte_strerror(-ret));
     469                 :          0 :                 return -1;
     470                 :            :         }
     471                 :            :         printf("RX queue stopped for port %d\n", port);
     472                 :            : 
     473                 :            :         /* Stop TX queue */
     474                 :          1 :         ret = rte_eth_dev_tx_queue_stop(port, 0);
     475         [ -  + ]:          1 :         if (ret != 0 && ret != -ENOTSUP) {
     476                 :          0 :                 printf("Error: failed to stop TX queue for port %d: %s\n",
     477                 :            :                        port, rte_strerror(-ret));
     478                 :          0 :                 return -1;
     479                 :            :         }
     480                 :            :         printf("TX queue stopped for port %d\n", port);
     481                 :            : 
     482                 :            :         /* Start RX queue */
     483                 :          1 :         ret = rte_eth_dev_rx_queue_start(port, 0);
     484         [ -  + ]:          1 :         if (ret != 0 && ret != -ENOTSUP) {
     485                 :          0 :                 printf("Error: failed to start RX queue for port %d: %s\n",
     486                 :            :                        port, rte_strerror(-ret));
     487                 :          0 :                 return -1;
     488                 :            :         }
     489                 :            :         printf("RX queue started for port %d\n", port);
     490                 :            : 
     491                 :            :         /* Start TX queue */
     492                 :          1 :         ret = rte_eth_dev_tx_queue_start(port, 0);
     493         [ -  + ]:          1 :         if (ret != 0 && ret != -ENOTSUP) {
     494                 :          0 :                 printf("Error: failed to start TX queue for port %d: %s\n",
     495                 :            :                        port, rte_strerror(-ret));
     496                 :          0 :                 return -1;
     497                 :            :         }
     498                 :            :         printf("TX queue started for port %d\n", port);
     499                 :            : 
     500                 :          1 :         return 0;
     501                 :            : }
     502                 :            : 
     503                 :            : static int
     504                 :          1 : test_tap_link_up_down(int port)
     505                 :            : {
     506                 :            :         struct rte_eth_link link;
     507                 :            :         int ret;
     508                 :            : 
     509                 :            :         printf("Testing TAP PMD link up/down for port %d\n", port);
     510                 :            : 
     511                 :            :         /* Set link down */
     512                 :          1 :         ret = rte_eth_dev_set_link_down(port);
     513         [ -  + ]:          1 :         if (ret != 0) {
     514                 :          0 :                 printf("Warning: failed to set link down for port %d: %s\n",
     515                 :            :                        port, rte_strerror(-ret));
     516                 :            :         } else {
     517                 :          1 :                 ret = rte_eth_link_get_nowait(port, &link);
     518         [ +  - ]:          1 :                 if (ret == 0)
     519                 :          1 :                         printf("Link status after set_link_down: %s\n",
     520         [ +  - ]:          1 :                                link.link_status ? "up" : "down");
     521                 :            :         }
     522                 :            : 
     523                 :            :         /* Set link up */
     524                 :          1 :         ret = rte_eth_dev_set_link_up(port);
     525         [ -  + ]:          1 :         if (ret != 0) {
     526                 :          0 :                 printf("Warning: failed to set link up for port %d: %s\n",
     527                 :            :                        port, rte_strerror(-ret));
     528                 :            :         } else {
     529                 :          1 :                 ret = rte_eth_link_get_nowait(port, &link);
     530         [ +  - ]:          1 :                 if (ret == 0)
     531                 :          1 :                         printf("Link status after set_link_up: %s\n",
     532         [ -  + ]:          1 :                                link.link_status ? "up" : "down");
     533                 :            :         }
     534                 :            : 
     535                 :          1 :         return 0;
     536                 :            : }
     537                 :            : 
     538                 :            : static int
     539                 :          1 : test_tap_dev_stop_start(int port)
     540                 :            : {
     541                 :            :         int ret;
     542                 :            : 
     543                 :            :         printf("Testing TAP PMD device stop/start for port %d\n", port);
     544                 :            : 
     545                 :            :         /* Stop the device */
     546                 :          1 :         ret = rte_eth_dev_stop(port);
     547         [ -  + ]:          1 :         if (ret != 0) {
     548                 :          0 :                 printf("Error: failed to stop port %d: %s\n",
     549                 :            :                        port, rte_strerror(-ret));
     550                 :          0 :                 return -1;
     551                 :            :         }
     552                 :            :         printf("Device stopped for port %d\n", port);
     553                 :            : 
     554                 :            :         /* Start the device again */
     555                 :          1 :         ret = rte_eth_dev_start(port);
     556         [ -  + ]:          1 :         if (ret != 0) {
     557                 :          0 :                 printf("Error: failed to start port %d: %s\n",
     558                 :            :                        port, rte_strerror(-ret));
     559                 :          0 :                 return -1;
     560                 :            :         }
     561                 :            :         printf("Device started for port %d\n", port);
     562                 :            : 
     563                 :          1 :         return 0;
     564                 :            : }
     565                 :            : 
     566                 :            : static int
     567                 :          1 : test_tap_multi_queue(void)
     568                 :            : {
     569                 :          1 :         struct rte_eth_conf port_conf = { 0 };
     570                 :            :         const uint16_t nb_queues = 2;
     571                 :            : 
     572                 :            :         printf("Testing TAP PMD multi-queue configuration\n");
     573                 :            : 
     574                 :            :         /* Create a separate mempool for multi-queue test */
     575                 :            :         struct rte_mempool *mq_mp
     576                 :          1 :                 = rte_pktmbuf_pool_create("tap_mq_pool", NB_MBUF, 32, 0,
     577                 :          1 :                                           RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
     578         [ -  + ]:          1 :         if (mq_mp == NULL) {
     579                 :          0 :                 printf("Warning: failed to create mempool for multi-queue test: %s\n",
     580                 :            :                        rte_strerror(rte_errno));
     581                 :          0 :                 return TEST_SKIPPED;
     582                 :            :         }
     583                 :            : 
     584                 :            :         /* Create a new TAP device for multi-queue test */
     585                 :          1 :         int ret = rte_vdev_init("net_tap_mq", "iface=dtap_mq");
     586         [ -  + ]:          1 :         if (ret < 0) {
     587                 :          0 :                 printf("Warning: failed to create multi-queue TAP device: %s\n",
     588                 :            :                        rte_strerror(-ret));
     589                 :          0 :                 rte_mempool_free(mq_mp);
     590                 :          0 :                 return TEST_SKIPPED;
     591                 :            :         }
     592                 :            : 
     593                 :            :         /* Find the port */
     594                 :            :         uint16_t port;
     595         [ +  - ]:          3 :         RTE_ETH_FOREACH_DEV(port) {
     596                 :            :                 char name[RTE_ETH_NAME_MAX_LEN];
     597         [ +  - ]:          3 :                 if (rte_eth_dev_get_name_by_port(port, name) == 0 &&
     598         [ +  + ]:          3 :                     strstr(name, "net_tap_mq"))
     599                 :          1 :                         goto found;
     600                 :            :         }
     601                 :            : 
     602                 :            :         printf("Error: could not find multi-queue TAP device\n");
     603                 :          0 :         rte_vdev_uninit("net_tap_mq");
     604                 :          0 :         rte_mempool_free(mq_mp);
     605                 :          0 :         return TEST_FAILED;
     606                 :            : 
     607                 :            : found:
     608                 :            :         /* Configure with multiple queues */
     609                 :          1 :         ret = rte_eth_dev_configure(port, nb_queues, nb_queues, &port_conf);
     610         [ -  + ]:          1 :         if (ret < 0) {
     611                 :          0 :                 printf("Warning: multi-queue configure failed: %s\n",
     612                 :            :                        rte_strerror(-ret));
     613                 :          0 :                 rte_vdev_uninit("net_tap_mq");
     614                 :          0 :                 rte_mempool_free(mq_mp);
     615                 :          0 :                 return TEST_SKIPPED;
     616                 :            :         }
     617                 :            : 
     618                 :            :         /* Setup TX queues */
     619         [ +  + ]:          3 :         for (uint16_t q = 0; q < nb_queues; q++) {
     620                 :          2 :                 ret = rte_eth_tx_queue_setup(port, q, RING_SIZE, SOCKET0, NULL);
     621         [ -  + ]:          2 :                 if (ret < 0) {
     622                 :          0 :                         printf("Error: TX queue %u setup failed: %s\n",
     623                 :            :                                q, rte_strerror(-ret));
     624                 :          0 :                         rte_vdev_uninit("net_tap_mq");
     625                 :          0 :                         rte_mempool_free(mq_mp);
     626                 :          0 :                         return TEST_FAILED;
     627                 :            :                 }
     628                 :            :         }
     629                 :            : 
     630                 :            :         /* Setup RX queues */
     631         [ +  + ]:          3 :         for (uint16_t q = 0; q < nb_queues; q++) {
     632                 :          2 :                 ret = rte_eth_rx_queue_setup(port, q, RING_SIZE, SOCKET0, NULL, mq_mp);
     633         [ -  + ]:          2 :                 if (ret < 0) {
     634                 :          0 :                         printf("Error: RX queue %u setup failed: %s\n",
     635                 :            :                                q, rte_strerror(-ret));
     636                 :          0 :                         rte_vdev_uninit("net_tap_mq");
     637                 :          0 :                         rte_mempool_free(mq_mp);
     638                 :          0 :                         return TEST_FAILED;
     639                 :            :                 }
     640                 :            :         }
     641                 :            : 
     642                 :          1 :         ret = rte_eth_dev_start(port);
     643         [ -  + ]:          1 :         if (ret < 0) {
     644                 :          0 :                 printf("Error: failed to start multi-queue port: %s\n",
     645                 :            :                        rte_strerror(-ret));
     646                 :          0 :                 rte_vdev_uninit("net_tap_mq");
     647                 :          0 :                 rte_mempool_free(mq_mp);
     648                 :          0 :                 return TEST_FAILED;
     649                 :            :         }
     650                 :            : 
     651                 :            :         printf("Multi-queue TAP device configured with %u queues\n", nb_queues);
     652                 :            : 
     653                 :            :         /* Cleanup */
     654                 :          1 :         ret = rte_eth_dev_stop(port);
     655         [ -  + ]:          1 :         if (ret != 0) {
     656                 :            :                 printf("Error: rte_eth_dev_stop failed\n");
     657                 :          0 :                 return TEST_FAILED;
     658                 :            :         }
     659                 :          1 :         rte_eth_dev_close(port);
     660                 :          1 :         rte_vdev_uninit("net_tap_mq");
     661                 :          1 :         rte_mempool_free(mq_mp);
     662                 :            : 
     663                 :          1 :         return TEST_SUCCESS;
     664                 :            : }
     665                 :            : 
     666                 :            : static void
     667                 :          1 : test_tap_cleanup(void)
     668                 :            : {
     669                 :            :         int ret;
     670                 :            : 
     671                 :            :         printf("Cleaning up TAP PMD test resources\n");
     672                 :            : 
     673         [ +  - ]:          1 :         if (tap_port0 >= 0) {
     674                 :          1 :                 ret = rte_eth_dev_stop(tap_port0);
     675         [ -  + ]:          1 :                 if (ret != 0)
     676                 :          0 :                         printf("Warning: failed to stop port %d: %s\n",
     677                 :            :                                tap_port0, rte_strerror(-ret));
     678                 :          1 :                 rte_eth_dev_close(tap_port0);
     679                 :            :         }
     680                 :            : 
     681         [ +  - ]:          1 :         if (tap_port1 >= 0) {
     682                 :          1 :                 ret = rte_eth_dev_stop(tap_port1);
     683         [ -  + ]:          1 :                 if (ret != 0)
     684                 :          0 :                         printf("Warning: failed to stop port %d: %s\n",
     685                 :            :                                tap_port1, rte_strerror(-ret));
     686                 :          1 :                 rte_eth_dev_close(tap_port1);
     687                 :            :         }
     688                 :            : 
     689                 :          1 :         rte_vdev_uninit("net_tap0");
     690                 :          1 :         rte_vdev_uninit("net_tap1");
     691                 :            : 
     692         [ +  - ]:          1 :         if (mp != NULL) {
     693                 :          1 :                 rte_mempool_free(mp);
     694                 :          1 :                 mp = NULL;
     695                 :            :         }
     696                 :            : 
     697                 :          1 :         tap_port0 = -1;
     698                 :          1 :         tap_port1 = -1;
     699                 :          1 : }
     700                 :            : 
     701                 :            : static int
     702                 :          1 : test_tap_setup(void)
     703                 :            : {
     704                 :            :         int ret;
     705                 :            :         uint16_t port_id;
     706                 :            : 
     707                 :            :         printf("Setting up TAP PMD test\n");
     708                 :            : 
     709                 :            :         /* Create mempool */
     710                 :          1 :         mp = rte_pktmbuf_pool_create("tap_test_pool", NB_MBUF, 32, 0,
     711                 :          1 :                                      RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
     712         [ -  + ]:          1 :         if (mp == NULL) {
     713                 :          0 :                 printf("Error: failed to create mempool: %s\n",
     714                 :            :                        rte_strerror(rte_errno));
     715                 :          0 :                 return -1;
     716                 :            :         }
     717                 :            : 
     718                 :            :         /* Create first TAP device */
     719                 :          1 :         ret = rte_vdev_init("net_tap0", "iface=dtap_test0");
     720         [ -  + ]:          1 :         if (ret < 0) {
     721                 :          0 :                 printf("Error: failed to create TAP device net_tap0: %s\n",
     722                 :            :                        rte_strerror(-ret));
     723                 :          0 :                 rte_mempool_free(mp);
     724                 :          0 :                 mp = NULL;
     725                 :          0 :                 return TEST_SKIPPED;
     726                 :            :         }
     727                 :            : 
     728                 :            :         /* Create second TAP device */
     729                 :          1 :         ret = rte_vdev_init("net_tap1", "iface=dtap_test1");
     730         [ -  + ]:          1 :         if (ret < 0) {
     731                 :          0 :                 printf("Error: failed to create TAP device net_tap1: %s\n",
     732                 :            :                        rte_strerror(-ret));
     733                 :          0 :                 rte_vdev_uninit("net_tap0");
     734                 :          0 :                 rte_mempool_free(mp);
     735                 :          0 :                 mp = NULL;
     736                 :          0 :                 return -1;
     737                 :            :         }
     738                 :            : 
     739                 :            :         /* Find the port IDs */
     740         [ +  + ]:          3 :         RTE_ETH_FOREACH_DEV(port_id) {
     741                 :            :                 char name[RTE_ETH_NAME_MAX_LEN];
     742         [ -  + ]:          2 :                 if (rte_eth_dev_get_name_by_port(port_id, name) != 0)
     743                 :          0 :                         continue;
     744                 :            : 
     745         [ +  + ]:          2 :                 if (strstr(name, "net_tap0"))
     746                 :          1 :                         tap_port0 = port_id;
     747         [ +  - ]:          1 :                 else if (strstr(name, "net_tap1"))
     748                 :          1 :                         tap_port1 = port_id;
     749                 :            :         }
     750                 :            : 
     751   [ +  -  -  + ]:          1 :         if (tap_port0 < 0 || tap_port1 < 0) {
     752                 :            :                 printf("Error: failed to find TAP port IDs\n");
     753                 :          0 :                 test_tap_cleanup();
     754                 :          0 :                 return -1;
     755                 :            :         }
     756                 :            : 
     757                 :            :         printf("Created TAP devices: tap_port0=%d, tap_port1=%d\n",
     758                 :            :                tap_port0, tap_port1);
     759                 :            : 
     760                 :          1 :         return 0;
     761                 :            : }
     762                 :            : 
     763                 :            : /* Individual test case wrappers */
     764                 :            : 
     765                 :            : static int
     766                 :          1 : test_tap_rx_queue_setup(void)
     767                 :            : {
     768                 :          1 :         struct rte_eth_conf port_conf = { 0 };
     769                 :            :         struct rte_mempool *tiny_mp = NULL;
     770                 :            :         int port, ret;
     771                 :            :         int result = TEST_FAILED;
     772                 :            : 
     773                 :            :         printf("Testing TAP RX queue setup parameter validation\n");
     774                 :            : 
     775                 :            :         /* Create a dedicated TAP device for negative tests */
     776                 :          1 :         ret = rte_vdev_init("net_tap_neg", "iface=dtap_neg");
     777         [ -  + ]:          1 :         if (ret < 0) {
     778                 :          0 :                 printf("Warning: failed to create TAP device for negative test: %s\n",
     779                 :            :                        rte_strerror(-ret));
     780                 :          0 :                 return TEST_SKIPPED;
     781                 :            :         }
     782                 :            : 
     783                 :            :         /* Find the port */
     784                 :            :         uint16_t port_id;
     785                 :            :         port = -1;
     786         [ +  - ]:          3 :         RTE_ETH_FOREACH_DEV(port_id) {
     787                 :            :                 char name[RTE_ETH_NAME_MAX_LEN];
     788         [ +  - ]:          3 :                 if (rte_eth_dev_get_name_by_port(port_id, name) == 0 &&
     789         [ +  + ]:          3 :                     strstr(name, "net_tap_neg")) {
     790                 :            :                         port = port_id;
     791                 :          1 :                         break;
     792                 :            :                 }
     793                 :            :         }
     794                 :            : 
     795         [ -  + ]:          1 :         if (port < 0) {
     796                 :            :                 printf("Error: could not find negative test TAP device\n");
     797                 :          0 :                 goto cleanup;
     798                 :            :         }
     799                 :            : 
     800                 :          1 :         ret = rte_eth_dev_configure(port, 1, 1, &port_conf);
     801         [ -  + ]:          1 :         if (ret < 0) {
     802                 :          0 :                 printf("Error: configure failed for negative test port: %s\n",
     803                 :            :                        rte_strerror(-ret));
     804                 :          0 :                 goto cleanup;
     805                 :            :         }
     806                 :            : 
     807                 :            :         /* TX queue is needed since TAP requires nb_rx == nb_tx */
     808                 :          1 :         ret = rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL);
     809         [ -  + ]:          1 :         if (ret < 0) {
     810                 :          0 :                 printf("Error: TX queue setup failed for negative test port: %s\n",
     811                 :            :                        rte_strerror(-ret));
     812                 :          0 :                 goto cleanup;
     813                 :            :         }
     814                 :            : 
     815                 :            :         /* Test 1: NULL mempool should fail */
     816                 :            :         printf("  Test: NULL mempool\n");
     817                 :          1 :         ret = rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL, NULL);
     818         [ -  + ]:          1 :         if (ret == 0) {
     819                 :            :                 printf("Error: RX queue setup with NULL mempool should have failed\n");
     820                 :          0 :                 goto cleanup;
     821                 :            :         }
     822                 :            :         printf("    Correctly rejected NULL mempool (ret=%d)\n", ret);
     823                 :            : 
     824                 :            :         /* Test 2: Invalid queue ID should fail */
     825                 :            :         printf("  Test: invalid queue ID\n");
     826                 :          1 :         ret = rte_eth_rx_queue_setup(port, 99, RING_SIZE, SOCKET0, NULL, mp);
     827         [ -  + ]:          1 :         if (ret == 0) {
     828                 :            :                 printf("Error: RX queue setup with invalid queue ID should have failed\n");
     829                 :          0 :                 goto cleanup;
     830                 :            :         }
     831                 :            :         printf("    Correctly rejected invalid queue ID (ret=%d)\n", ret);
     832                 :            : 
     833                 :            :         /* Test 3: Mempool with data room too small for headroom should fail.
     834                 :            :          * Create a pool where data_room_size equals headroom, leaving
     835                 :            :          * zero usable space in the first segment.
     836                 :            :          */
     837                 :            :         printf("  Test: mempool with no usable data room\n");
     838                 :          1 :         tiny_mp = rte_pktmbuf_pool_create("tap_tiny_pool", 64, 0, 0,
     839                 :          1 :                                           RTE_PKTMBUF_HEADROOM, rte_socket_id());
     840         [ -  + ]:          1 :         if (tiny_mp == NULL) {
     841                 :          0 :                 printf("Warning: could not create tiny mempool: %s\n",
     842                 :            :                        rte_strerror(rte_errno));
     843                 :            :                 /* Can still pass on the tests above */
     844                 :            :                 printf("  Skipping tiny mempool test\n");
     845                 :            :         } else {
     846                 :          1 :                 ret = rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL, tiny_mp);
     847         [ -  + ]:          1 :                 if (ret == 0) {
     848                 :            :                         printf("Error: RX queue setup with tiny mempool should have failed\n");
     849                 :          0 :                         goto cleanup;
     850                 :            :                 }
     851                 :            :                 printf("    Correctly rejected tiny mempool (ret=%d)\n", ret);
     852                 :            :         }
     853                 :            : 
     854                 :            :         /* Test 4: Valid setup should succeed after all the negative tests */
     855                 :            :         printf("  Test: valid setup after negative tests\n");
     856                 :          1 :         ret = rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL, mp);
     857         [ -  + ]:          1 :         if (ret < 0) {
     858                 :          0 :                 printf("Error: valid RX queue setup failed after negative tests: %s\n",
     859                 :            :                        rte_strerror(-ret));
     860                 :          0 :                 goto cleanup;
     861                 :            :         }
     862                 :            :         printf("    Valid setup succeeded\n");
     863                 :            : 
     864                 :            :         result = TEST_SUCCESS;
     865                 :            : 
     866                 :          1 : cleanup:
     867                 :          1 :         rte_eth_dev_close(port);
     868                 :          1 :         rte_vdev_uninit("net_tap_neg");
     869                 :          1 :         rte_mempool_free(tiny_mp);
     870                 :            : 
     871                 :          1 :         return result;
     872                 :            : }
     873                 :            : 
     874                 :            : static int
     875                 :          1 : test_tap_configure_port0(void)
     876                 :            : {
     877                 :          1 :         return test_tap_ethdev_configure(tap_port0) == 0 ?
     878         [ -  + ]:          1 :                TEST_SUCCESS : TEST_FAILED;
     879                 :            : }
     880                 :            : 
     881                 :            : static int
     882                 :          1 : test_tap_configure_port1(void)
     883                 :            : {
     884                 :          1 :         return test_tap_ethdev_configure(tap_port1) == 0 ?
     885         [ -  + ]:          1 :                TEST_SUCCESS : TEST_FAILED;
     886                 :            : }
     887                 :            : 
     888                 :            : static int
     889                 :          1 : test_tap_packet_send_receive(void)
     890                 :            : {
     891                 :          1 :         return test_tap_send_receive();
     892                 :            : }
     893                 :            : 
     894                 :            : static int
     895                 :          1 : test_tap_get_stats(void)
     896                 :            : {
     897         [ +  - ]:          1 :         if (test_tap_stats_get(tap_port0) != 0)
     898                 :            :                 return TEST_FAILED;
     899         [ -  + ]:          1 :         if (test_tap_stats_get(tap_port1) != 0)
     900                 :          0 :                 return TEST_FAILED;
     901                 :            :         return TEST_SUCCESS;
     902                 :            : }
     903                 :            : 
     904                 :            : static int
     905                 :          1 : test_tap_reset_stats(void)
     906                 :            : {
     907         [ +  - ]:          1 :         if (test_tap_stats_reset(tap_port0) != 0)
     908                 :            :                 return TEST_FAILED;
     909         [ -  + ]:          1 :         if (test_tap_stats_reset(tap_port1) != 0)
     910                 :          0 :                 return TEST_FAILED;
     911                 :            :         return TEST_SUCCESS;
     912                 :            : }
     913                 :            : 
     914                 :            : static int
     915                 :          1 : test_tap_get_link_status(void)
     916                 :            : {
     917         [ +  - ]:          1 :         if (test_tap_link_status(tap_port0) != 0)
     918                 :            :                 return TEST_FAILED;
     919         [ -  + ]:          1 :         if (test_tap_link_status(tap_port1) != 0)
     920                 :          0 :                 return TEST_FAILED;
     921                 :            :         return TEST_SUCCESS;
     922                 :            : }
     923                 :            : 
     924                 :            : static int
     925                 :          1 : test_tap_get_dev_info(void)
     926                 :            : {
     927         [ +  - ]:          1 :         if (test_tap_dev_info(tap_port0) != 0)
     928                 :            :                 return TEST_FAILED;
     929         [ -  + ]:          1 :         if (test_tap_dev_info(tap_port1) != 0)
     930                 :          0 :                 return TEST_FAILED;
     931                 :            :         return TEST_SUCCESS;
     932                 :            : }
     933                 :            : 
     934                 :            : static int
     935                 :          1 : test_tap_mtu_ops(void)
     936                 :            : {
     937         [ -  + ]:          1 :         return test_tap_mtu(tap_port0) == 0 ? TEST_SUCCESS : TEST_FAILED;
     938                 :            : }
     939                 :            : 
     940                 :            : static int
     941                 :          1 : test_tap_mac_addr_get(void)
     942                 :            : {
     943         [ +  - ]:          1 :         if (test_tap_mac_addr(tap_port0) != 0)
     944                 :            :                 return TEST_FAILED;
     945         [ -  + ]:          1 :         if (test_tap_mac_addr(tap_port1) != 0)
     946                 :          0 :                 return TEST_FAILED;
     947                 :            :         return TEST_SUCCESS;
     948                 :            : }
     949                 :            : 
     950                 :            : static int
     951                 :          1 : test_tap_promisc_mode(void)
     952                 :            : {
     953         [ -  + ]:          1 :         return test_tap_promiscuous(tap_port0) == 0 ? TEST_SUCCESS : TEST_FAILED;
     954                 :            : }
     955                 :            : 
     956                 :            : static int
     957                 :          1 : test_tap_allmulti_mode(void)
     958                 :            : {
     959         [ -  + ]:          1 :         return test_tap_allmulti(tap_port0) == 0 ? TEST_SUCCESS : TEST_FAILED;
     960                 :            : }
     961                 :            : 
     962                 :            : static int
     963                 :          1 : test_tap_queue_ops(void)
     964                 :            : {
     965                 :          1 :         return test_tap_queue_start_stop(tap_port0) == 0 ?
     966         [ -  + ]:          1 :                TEST_SUCCESS : TEST_FAILED;
     967                 :            : }
     968                 :            : 
     969                 :            : static int
     970                 :          1 : test_tap_link_ops(void)
     971                 :            : {
     972         [ -  + ]:          1 :         return test_tap_link_up_down(tap_port0) == 0 ? TEST_SUCCESS : TEST_FAILED;
     973                 :            : }
     974                 :            : 
     975                 :            : static int
     976                 :          1 : test_tap_stop_start(void)
     977                 :            : {
     978                 :          1 :         return test_tap_dev_stop_start(tap_port0) == 0 ?
     979         [ -  + ]:          1 :                TEST_SUCCESS : TEST_FAILED;
     980                 :            : }
     981                 :            : 
     982                 :            : static int
     983                 :          1 : test_tap_multiqueue(void)
     984                 :            : {
     985                 :          1 :         return test_tap_multi_queue();
     986                 :            : }
     987                 :            : 
     988                 :            : static int
     989                 :          1 : test_tap_tx_burst(void)
     990                 :            : {
     991                 :            :         struct rte_eth_stats stats_before, stats_after;
     992                 :            :         struct rte_mbuf *mbuf;
     993                 :            :         uint16_t nb_tx;
     994                 :            :         int ret;
     995                 :            : 
     996                 :            :         printf("Testing TAP TX burst with invalid mbuf chains\n");
     997                 :            : 
     998                 :          1 :         ret = rte_eth_stats_reset(tap_port0);
     999         [ -  + ]:          1 :         if (ret != 0) {
    1000                 :          0 :                 printf("Error: stats reset failed: %s\n", rte_strerror(-ret));
    1001                 :          0 :                 return TEST_FAILED;
    1002                 :            :         }
    1003                 :            : 
    1004                 :            :         /* Test 1: Oversized packet should be rejected.
    1005                 :            :          * Create a single-segment packet larger than MTU + L2 overhead.
    1006                 :            :          */
    1007                 :            :         printf("  Test: oversized packet\n");
    1008                 :          1 :         mbuf = rte_pktmbuf_alloc(mp);
    1009         [ -  + ]:          1 :         if (mbuf == NULL) {
    1010                 :            :                 printf("Error: mbuf alloc failed\n");
    1011                 :          0 :                 return TEST_FAILED;
    1012                 :            :         }
    1013                 :            : 
    1014                 :            :         /* Fill with data exceeding default MTU (1500) + headers */
    1015         [ -  + ]:          1 :         if (rte_pktmbuf_append(mbuf, 1600) == NULL) {
    1016                 :            :                 printf("Error: pktmbuf_append failed\n");
    1017                 :          0 :                 rte_pktmbuf_free(mbuf);
    1018                 :          0 :                 return TEST_FAILED;
    1019                 :            :         }
    1020                 :          1 :         memset(rte_pktmbuf_mtod(mbuf, void *), 0, 1600);
    1021                 :            : 
    1022                 :          1 :         rte_eth_stats_get(tap_port0, &stats_before);
    1023                 :          1 :         nb_tx = rte_eth_tx_burst(tap_port0, 0, &mbuf, 1);
    1024                 :          1 :         rte_eth_stats_get(tap_port0, &stats_after);
    1025                 :            : 
    1026         [ -  + ]:          1 :         if (nb_tx != 0) {
    1027                 :          0 :                 printf("Error: oversized packet was accepted (nb_tx=%u)\n", nb_tx);
    1028                 :          0 :                 return TEST_FAILED;
    1029                 :            :         }
    1030                 :          1 :         rte_pktmbuf_free(mbuf);
    1031                 :            : 
    1032         [ -  + ]:          1 :         if (stats_after.oerrors <= stats_before.oerrors) {
    1033                 :            :                 printf("Error: oerrors not incremented for oversized packet\n");
    1034                 :          0 :                 return TEST_FAILED;
    1035                 :            :         }
    1036                 :            :         printf("    Correctly rejected oversized packet\n");
    1037                 :            : 
    1038                 :            :         /* Test 2: mbuf chain with nb_segs >= IOV_MAX.
    1039                 :            :          * The tun_pi header takes one iovec slot, so a chain with
    1040                 :            :          * IOV_MAX segments requires IOV_MAX + 1 iovecs total,
    1041                 :            :          * which must be rejected by tap_write_mbufs.
    1042                 :            :          */
    1043                 :            :         printf("  Test: mbuf chain with nb_segs >= IOV_MAX (%d)\n", IOV_MAX);
    1044                 :            : 
    1045                 :          1 :         struct rte_mbuf *head = rte_pktmbuf_alloc(mp);
    1046         [ -  + ]:          1 :         if (head == NULL) {
    1047                 :            :                 printf("Error: head mbuf alloc failed\n");
    1048                 :          0 :                 return TEST_FAILED;
    1049                 :            :         }
    1050                 :            : 
    1051                 :            :         struct rte_ether_hdr *eth = (struct rte_ether_hdr *)
    1052                 :            :                 rte_pktmbuf_append(head, RTE_ETHER_MIN_LEN);
    1053         [ -  + ]:          1 :         if (eth == NULL) {
    1054                 :            :                 printf("Error: append to head failed\n");
    1055                 :          0 :                 rte_pktmbuf_free(head);
    1056                 :          0 :                 return TEST_FAILED;
    1057                 :            :         }
    1058                 :            :         memset(eth, 0, RTE_ETHER_MIN_LEN);
    1059                 :          1 :         eth->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
    1060                 :            : 
    1061                 :            :         int nsegs;
    1062         [ +  + ]:       1024 :         for (nsegs = 1; nsegs < IOV_MAX; nsegs++) {
    1063                 :       1023 :                 struct rte_mbuf *seg = rte_pktmbuf_alloc(mp);
    1064         [ -  + ]:       1023 :                 if (seg == NULL) {
    1065                 :            :                         printf("Warning: could only allocate %d of %d segments\n",
    1066                 :            :                                nsegs, IOV_MAX);
    1067                 :            :                         break;
    1068                 :            :                 }
    1069         [ -  + ]:       1023 :                 if (rte_pktmbuf_append(seg, 1) == NULL) {
    1070                 :          0 :                         rte_pktmbuf_free(seg);
    1071                 :          0 :                         break;
    1072                 :            :                 }
    1073                 :            : 
    1074         [ +  - ]:       1023 :                 ret = rte_pktmbuf_chain(head, seg);
    1075                 :            :                 if (ret != 0) {
    1076                 :          0 :                         rte_pktmbuf_free(seg);
    1077                 :          0 :                         break;
    1078                 :            :                 }
    1079                 :            :         }
    1080                 :            : 
    1081         [ -  + ]:          1 :         if (head->nb_segs < IOV_MAX) {
    1082                 :          0 :                 printf("Warning: only built %u segments, need %d to test IOV_MAX\n",
    1083                 :            :                        head->nb_segs, IOV_MAX);
    1084                 :          0 :                 rte_pktmbuf_free(head);
    1085                 :            :                 printf("  Skipping IOV_MAX test (insufficient mbufs)\n");
    1086                 :          0 :                 return TEST_SUCCESS;
    1087                 :            :         }
    1088                 :            : 
    1089                 :          1 :         printf("    Built chain with %u segments\n", head->nb_segs);
    1090                 :            : 
    1091                 :          1 :         rte_eth_stats_get(tap_port0, &stats_before);
    1092                 :          1 :         nb_tx = rte_eth_tx_burst(tap_port0, 0, &head, 1);
    1093                 :          1 :         rte_eth_stats_get(tap_port0, &stats_after);
    1094                 :            : 
    1095         [ -  + ]:          1 :         if (nb_tx != 0) {
    1096                 :          0 :                 printf("Error: chain with %u segments (>= IOV_MAX) should be rejected\n",
    1097                 :          0 :                        head->nb_segs);
    1098                 :          0 :                 return TEST_FAILED;
    1099                 :            :         }
    1100                 :          1 :         rte_pktmbuf_free(head);
    1101                 :            : 
    1102         [ -  + ]:          1 :         if (stats_after.oerrors <= stats_before.oerrors) {
    1103                 :            :                 printf("Error: oerrors not incremented for IOV_MAX chain\n");
    1104                 :          0 :                 return TEST_FAILED;
    1105                 :            :         }
    1106                 :            :         printf("    Correctly rejected chain with nb_segs >= IOV_MAX\n");
    1107                 :            : 
    1108                 :            :         printf("  TX validation tests passed\n");
    1109                 :          1 :         return TEST_SUCCESS;
    1110                 :            : }
    1111                 :            : 
    1112                 :            : /*
    1113                 :            :  * Inject a raw Ethernet frame via an AF_PACKET socket bound to the TAP's
    1114                 :            :  * Linux interface and attempt to receive it with rte_eth_rx_burst.
    1115                 :            :  */
    1116                 :            : static int
    1117                 :          9 : tap_inject_packet(const char *ifname, const struct rte_ether_addr *dst)
    1118                 :            : {
    1119                 :            :         uint8_t frame[RTE_ETHER_MIN_LEN - RTE_ETHER_CRC_LEN];
    1120                 :            :         union {
    1121                 :            :                 struct sockaddr_ll sll;
    1122                 :            :                 struct sockaddr sock;
    1123                 :            :         } addr;
    1124                 :            :         struct rte_ether_hdr *eth;
    1125                 :            :         unsigned int ifindex;
    1126                 :            :         int fd, ret;
    1127                 :            : 
    1128                 :          9 :         ifindex = if_nametoindex(ifname);
    1129         [ -  + ]:          9 :         TEST_ASSERT(ifindex != 0, "if_nametoindex(%s) failed", ifname);
    1130                 :            : 
    1131                 :          9 :         fd = socket(AF_PACKET, SOCK_RAW, RTE_BE16(RTE_ETHER_TYPE_IPV4));
    1132         [ -  + ]:          9 :         TEST_ASSERT(fd >= 0, "AF_PACKET socket failed: %s", strerror(errno));
    1133                 :            : 
    1134                 :            :         memset(&addr, 0, sizeof(addr));
    1135                 :          9 :         addr.sll.sll_family = AF_PACKET;
    1136                 :          9 :         addr.sll.sll_ifindex = ifindex;
    1137                 :          9 :         addr.sll.sll_protocol = RTE_BE16(RTE_ETHER_TYPE_IPV4);
    1138                 :            : 
    1139                 :          9 :         ret = bind(fd, &addr.sock, sizeof(addr.sll));
    1140         [ -  + ]:          9 :         TEST_ASSERT(ret == 0, "bind to %s failed: %s", ifname, strerror(errno));
    1141                 :            : 
    1142                 :            :         memset(frame, 0, sizeof(frame));
    1143                 :            :         eth = (struct rte_ether_hdr *)frame;
    1144                 :          9 :         eth->dst_addr = *dst;
    1145                 :          9 :         eth->src_addr = (struct rte_ether_addr){{0x02, 0, 0, 0xbb, 0, 0xaa}};
    1146                 :          9 :         eth->ether_type = RTE_BE16(RTE_ETHER_TYPE_IPV4);
    1147                 :            : 
    1148                 :          9 :         ret = send(fd, frame, sizeof(frame), 0);
    1149         [ -  + ]:          9 :         TEST_ASSERT(ret == sizeof(frame), "send failed: %s", strerror(errno));
    1150                 :            : 
    1151                 :          9 :         close(fd);
    1152                 :          9 :         return 0;
    1153                 :            : }
    1154                 :            : 
    1155                 :            : static uint16_t
    1156                 :         10 : tap_drain_rx(int port, const struct rte_ether_addr *dst)
    1157                 :            : {
    1158                 :            :         struct rte_mbuf *mbufs[MAX_PKT_BURST];
    1159                 :            :         struct rte_ether_hdr *eth;
    1160                 :            :         uint16_t total = 0;
    1161                 :            : 
    1162                 :            :         /* drain the rxq 10 times to ensure the kernel has sent the packet */
    1163         [ +  + ]:        110 :         for (uint16_t i = 0; i < 10; i++) {
    1164                 :        100 :                 uint16_t nb_rx = rte_eth_rx_burst(port, 0, mbufs, MAX_PKT_BURST);
    1165         [ +  + ]:        106 :                 for (uint16_t j = 0; j < nb_rx; j++) {
    1166                 :          6 :                         eth = rte_pktmbuf_mtod(mbufs[j], struct rte_ether_hdr *);
    1167   [ +  -  +  - ]:          6 :                         if (dst != NULL && rte_is_same_ether_addr(&eth->dst_addr, dst))
    1168                 :          6 :                                 total += 1;
    1169                 :          6 :                         rte_pktmbuf_free(mbufs[j]);
    1170                 :            :                 }
    1171                 :        100 :                 usleep(1000);
    1172                 :            :         }
    1173                 :            : 
    1174                 :         10 :         return total;
    1175                 :            : }
    1176                 :            : 
    1177                 :            : static int
    1178                 :          1 : test_tap_mac_filter(void)
    1179                 :            : {
    1180                 :          1 :         struct rte_ether_addr bcast_mac = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
    1181                 :          1 :         struct rte_ether_addr mcast_mac = {{0x01, 0, 0x5e, 0, 0, 0x01}};
    1182                 :          1 :         struct rte_ether_addr foreign_mac = {{0x02, 0, 0, 0, 0, 0xaa}};
    1183                 :            :         static const char *ifname = "dtap_test0";
    1184                 :            :         struct rte_ether_addr port_mac;
    1185                 :            :         uint16_t nb_rx;
    1186                 :            :         int ret;
    1187                 :            : 
    1188                 :            :         printf("Testing TAP MAC address filtering\n");
    1189                 :            : 
    1190                 :          1 :         ret = rte_eth_macaddr_get(tap_port0, &port_mac);
    1191         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "failed to get MAC for port %d", tap_port0);
    1192                 :            : 
    1193                 :            :         /* Disable promisc so MAC filter is active */
    1194                 :          1 :         rte_eth_promiscuous_disable(tap_port0);
    1195                 :          1 :         rte_eth_allmulticast_disable(tap_port0);
    1196                 :            : 
    1197                 :            :         /* Drain any stale packets */
    1198                 :          1 :         tap_drain_rx(tap_port0, NULL);
    1199                 :            : 
    1200                 :            :         /* Test 1: packet to port's own MAC should be received */
    1201                 :            :         printf("  Test: unicast to own MAC\n");
    1202                 :          1 :         ret = tap_inject_packet(ifname, &port_mac);
    1203         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1204                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &port_mac);
    1205         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "packet to own MAC was not received");
    1206                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1207                 :            : 
    1208                 :            :         /* Test 2: packet to foreign unicast MAC should be dropped */
    1209                 :            :         printf("  Test: unicast to foreign MAC\n");
    1210                 :          1 :         ret = tap_inject_packet(ifname, &foreign_mac);
    1211         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1212                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &foreign_mac);
    1213         [ -  + ]:          1 :         TEST_ASSERT(nb_rx == 0, "packet to foreign MAC was not dropped");
    1214                 :            :         printf("    Dropped - OK\n");
    1215                 :            : 
    1216                 :            :         /* Test 3: broadcast should always be received */
    1217                 :            :         printf("  Test: broadcast\n");
    1218                 :          1 :         ret = tap_inject_packet(ifname, &bcast_mac);
    1219         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1220                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &bcast_mac);
    1221         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "broadcast packet was not received");
    1222                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1223                 :            : 
    1224                 :            :         /* Test 4: promisc mode should bypass the filter */
    1225                 :            :         printf("  Test: promisc receives foreign MAC\n");
    1226                 :          1 :         rte_eth_promiscuous_enable(tap_port0);
    1227                 :          1 :         ret = tap_inject_packet(ifname, &foreign_mac);
    1228         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1229                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &foreign_mac);
    1230         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "promisc mode did not receive foreign MAC");
    1231                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1232                 :          1 :         rte_eth_promiscuous_disable(tap_port0);
    1233                 :            : 
    1234                 :            :         /* Test 5: multicast without allmulti and without mc list should drop */
    1235                 :            :         printf("  Test: multicast dropped without mc list\n");
    1236                 :          1 :         ret = tap_inject_packet(ifname, &mcast_mac);
    1237         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1238                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &mcast_mac);
    1239         [ -  + ]:          1 :         TEST_ASSERT(nb_rx == 0, "multicast was not dropped");
    1240                 :            :         printf("    Dropped - OK\n");
    1241                 :            : 
    1242                 :            :         /* Test 6: multicast with matching mc list should be received */
    1243                 :            :         printf("  Test: multicast received with mc list\n");
    1244                 :          1 :         ret = rte_eth_dev_set_mc_addr_list(tap_port0, &mcast_mac, 1);
    1245         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "set_mc_addr_list failed: %s", rte_strerror(-ret));
    1246                 :          1 :         ret = tap_inject_packet(ifname, &mcast_mac);
    1247         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1248                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &mcast_mac);
    1249         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "multicast with matching mc list was not received");
    1250                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1251                 :          1 :         rte_eth_dev_set_mc_addr_list(tap_port0, NULL, 0);
    1252                 :            : 
    1253                 :            :         /* Test 7: allmulti should receive any multicast */
    1254                 :            :         printf("  Test: allmulti receives multicast\n");
    1255                 :          1 :         rte_eth_allmulticast_enable(tap_port0);
    1256                 :          1 :         ret = tap_inject_packet(ifname, &mcast_mac);
    1257         [ +  - ]:          1 :         if (ret < 0)
    1258                 :            :                 return TEST_FAILED;
    1259                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &mcast_mac);
    1260         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "allmulti did not receive multicast");
    1261                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1262                 :          1 :         rte_eth_allmulticast_disable(tap_port0);
    1263                 :            : 
    1264                 :            :         /* Test 8: secondary unicast MAC via mac_addr_add */
    1265                 :            :         printf("  Test: secondary unicast MAC\n");
    1266                 :          1 :         ret = rte_eth_dev_mac_addr_add(tap_port0, &foreign_mac, 0);
    1267         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "mac_addr_add failed: %s", rte_strerror(-ret));
    1268                 :          1 :         ret = tap_inject_packet(ifname, &foreign_mac);
    1269         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1270                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &foreign_mac);
    1271         [ -  + ]:          1 :         TEST_ASSERT(nb_rx > 0, "packet to added MAC was not received");
    1272                 :          1 :         printf("    Received %u packet(s) - OK\n", nb_rx);
    1273                 :            : 
    1274                 :            :         /* Remove and verify it's dropped again */
    1275                 :          1 :         rte_eth_dev_mac_addr_remove(tap_port0, &foreign_mac);
    1276                 :          1 :         ret = tap_inject_packet(ifname, &foreign_mac);
    1277         [ -  + ]:          1 :         TEST_ASSERT(ret == 0, "packet inject failed");
    1278                 :          1 :         nb_rx = tap_drain_rx(tap_port0, &foreign_mac);
    1279         [ -  + ]:          1 :         TEST_ASSERT(nb_rx == 0, "packet to removed MAC was not dropped");
    1280                 :            :         printf("    Dropped after remove - OK\n");
    1281                 :            : 
    1282                 :            :         /* Restore promisc (default state) */
    1283                 :          1 :         rte_eth_promiscuous_enable(tap_port0);
    1284                 :            : 
    1285                 :          1 :         return TEST_SUCCESS;
    1286                 :            : }
    1287                 :            : 
    1288                 :            : static struct unit_test_suite test_pmd_tap_suite = {
    1289                 :            :         .setup = test_tap_setup,
    1290                 :            :         .teardown = test_tap_cleanup,
    1291                 :            :         .suite_name = "TAP PMD Unit Test Suite",
    1292                 :            :         .unit_test_cases = {
    1293                 :            :                 TEST_CASE(test_tap_configure_port0),
    1294                 :            :                 TEST_CASE(test_tap_configure_port1),
    1295                 :            :                 TEST_CASE(test_tap_get_dev_info),
    1296                 :            :                 TEST_CASE(test_tap_get_link_status),
    1297                 :            :                 TEST_CASE(test_tap_mac_addr_get),
    1298                 :            :                 TEST_CASE(test_tap_get_stats),
    1299                 :            :                 TEST_CASE(test_tap_reset_stats),
    1300                 :            :                 TEST_CASE(test_tap_packet_send_receive),
    1301                 :            :                 TEST_CASE(test_tap_promisc_mode),
    1302                 :            :                 TEST_CASE(test_tap_allmulti_mode),
    1303                 :            :                 TEST_CASE(test_tap_mtu_ops),
    1304                 :            :                 TEST_CASE(test_tap_queue_ops),
    1305                 :            :                 TEST_CASE(test_tap_link_ops),
    1306                 :            :                 TEST_CASE(test_tap_stop_start),
    1307                 :            :                 TEST_CASE(test_tap_multiqueue),
    1308                 :            :                 TEST_CASE(test_tap_rx_queue_setup),
    1309                 :            :                 TEST_CASE(test_tap_tx_burst),
    1310                 :            :                 TEST_CASE(test_tap_mac_filter),
    1311                 :            :                 TEST_CASES_END()
    1312                 :            :         }
    1313                 :            : };
    1314                 :            : 
    1315                 :            : static int
    1316                 :          1 : test_pmd_tap(void)
    1317                 :            : {
    1318                 :          1 :         return unit_test_suite_runner(&test_pmd_tap_suite);
    1319                 :            : }
    1320                 :            : 
    1321                 :            : #endif /* RTE_EXEC_ENV_LINUX */
    1322                 :            : 
    1323                 :        276 : REGISTER_FAST_TEST(tap_pmd_autotest, NOHUGE_OK, ASAN_OK, test_pmd_tap);

Generated by: LCOV version 1.14