96733554b6c493bad182703f50a7428f974d0450
[dpdk.git] / app / test / test_kni.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include <sys/wait.h>
10 #include <dirent.h>
11
12 #include "test.h"
13
14 #if !defined(RTE_EXEC_ENV_LINUX) || !defined(RTE_LIB_KNI)
15
16 static int
17 test_kni(void)
18 {
19         printf("KNI not supported, skipping test\n");
20         return TEST_SKIPPED;
21 }
22
23 #else
24
25 #include <rte_string_fns.h>
26 #include <rte_mempool.h>
27 #include <rte_ethdev.h>
28 #include <rte_bus_pci.h>
29 #include <rte_cycles.h>
30 #include <rte_kni.h>
31
32 #define NB_MBUF          8192
33 #define MAX_PACKET_SZ    2048
34 #define MBUF_DATA_SZ     (MAX_PACKET_SZ + RTE_PKTMBUF_HEADROOM)
35 #define PKT_BURST_SZ     32
36 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ
37 #define SOCKET           0
38 #define NB_RXD           1024
39 #define NB_TXD           1024
40 #define KNI_TIMEOUT_MS   5000 /* ms */
41
42 #define IFCONFIG      "/sbin/ifconfig "
43 #define TEST_KNI_PORT "test_kni_port"
44 #define KNI_MODULE_PATH "/sys/module/rte_kni"
45 #define KNI_MODULE_PARAM_LO KNI_MODULE_PATH"/parameters/lo_mode"
46 #define KNI_TEST_MAX_PORTS 4
47 /* The threshold number of mbufs to be transmitted or received. */
48 #define KNI_NUM_MBUF_THRESHOLD 100
49 static int kni_pkt_mtu = 0;
50
51 struct test_kni_stats {
52         volatile uint64_t ingress;
53         volatile uint64_t egress;
54 };
55
56 static const struct rte_eth_rxconf rx_conf = {
57         .rx_thresh = {
58                 .pthresh = 8,
59                 .hthresh = 8,
60                 .wthresh = 4,
61         },
62         .rx_free_thresh = 0,
63 };
64
65 static const struct rte_eth_txconf tx_conf = {
66         .tx_thresh = {
67                 .pthresh = 36,
68                 .hthresh = 0,
69                 .wthresh = 0,
70         },
71         .tx_free_thresh = 0,
72         .tx_rs_thresh = 0,
73 };
74
75 static const struct rte_eth_conf port_conf = {
76         .txmode = {
77                 .mq_mode = ETH_DCB_NONE,
78         },
79 };
80
81 static struct rte_kni_ops kni_ops = {
82         .change_mtu = NULL,
83         .config_network_if = NULL,
84         .config_mac_address = NULL,
85         .config_promiscusity = NULL,
86 };
87
88 static unsigned int lcore_main, lcore_ingress, lcore_egress;
89 static struct rte_kni *test_kni_ctx;
90 static struct test_kni_stats stats;
91
92 static volatile uint32_t test_kni_processing_flag;
93
94 static struct rte_mempool *
95 test_kni_create_mempool(void)
96 {
97         struct rte_mempool * mp;
98
99         mp = rte_mempool_lookup("kni_mempool");
100         if (!mp)
101                 mp = rte_pktmbuf_pool_create("kni_mempool",
102                                 NB_MBUF,
103                                 MEMPOOL_CACHE_SZ, 0, MBUF_DATA_SZ,
104                                 SOCKET);
105
106         return mp;
107 }
108
109 static struct rte_mempool *
110 test_kni_lookup_mempool(void)
111 {
112         return rte_mempool_lookup("kni_mempool");
113 }
114 /* Callback for request of changing MTU */
115 static int
116 kni_change_mtu(uint16_t port_id, unsigned int new_mtu)
117 {
118         printf("Change MTU of port %d to %u\n", port_id, new_mtu);
119         kni_pkt_mtu = new_mtu;
120         printf("Change MTU of port %d to %i successfully.\n",
121                                          port_id, kni_pkt_mtu);
122         return 0;
123 }
124
125 static int
126 test_kni_link_change(void)
127 {
128         int ret;
129         int pid;
130
131         pid = fork();
132         if (pid < 0) {
133                 printf("Error: Failed to fork a process\n");
134                 return -1;
135         }
136
137         if (pid == 0) {
138                 printf("Starting KNI Link status change tests.\n");
139                 if (system(IFCONFIG TEST_KNI_PORT" up") == -1) {
140                         ret = -1;
141                         goto error;
142                 }
143
144                 ret = rte_kni_update_link(test_kni_ctx, 1);
145                 if (ret < 0) {
146                         printf("Failed to change link state to Up ret=%d.\n",
147                                 ret);
148                         goto error;
149                 }
150                 rte_delay_ms(1000);
151                 printf("KNI: Set LINKUP, previous state=%d\n", ret);
152
153                 ret = rte_kni_update_link(test_kni_ctx, 0);
154                 if (ret != 1) {
155                         printf(
156                 "Failed! Previous link state should be 1, returned %d.\n",
157                                 ret);
158                         goto error;
159                 }
160                 rte_delay_ms(1000);
161                 printf("KNI: Set LINKDOWN, previous state=%d\n", ret);
162
163                 ret = rte_kni_update_link(test_kni_ctx, 1);
164                 if (ret != 0) {
165                         printf(
166                 "Failed! Previous link state should be 0, returned %d.\n",
167                                 ret);
168                         goto error;
169                 }
170                 printf("KNI: Set LINKUP, previous state=%d\n", ret);
171
172                 ret = 0;
173                 rte_delay_ms(1000);
174
175 error:
176                 if (system(IFCONFIG TEST_KNI_PORT" down") == -1)
177                         ret = -1;
178
179                 printf("KNI: Link status change tests: %s.\n",
180                         (ret == 0) ? "Passed" : "Failed");
181                 exit(ret);
182         } else {
183                 int p_ret, status;
184
185                 while (1) {
186                         p_ret = waitpid(pid, &status, WNOHANG);
187                         if (p_ret != 0) {
188                                 if (WIFEXITED(status))
189                                         return WEXITSTATUS(status);
190                                 return -1;
191                         }
192                         rte_delay_ms(10);
193                         rte_kni_handle_request(test_kni_ctx);
194                 }
195         }
196 }
197 /**
198  * This loop fully tests the basic functions of KNI. e.g. transmitting,
199  * receiving to, from kernel space, and kernel requests.
200  *
201  * This is the loop to transmit/receive mbufs to/from kernel interface with
202  * supported by KNI kernel module. The ingress lcore will allocate mbufs and
203  * transmit them to kernel space; while the egress lcore will receive the mbufs
204  * from kernel space and free them.
205  * On the main lcore, several commands will be run to check handling the
206  * kernel requests. And it will finally set the flag to exit the KNI
207  * transmitting/receiving to/from the kernel space.
208  *
209  * Note: To support this testing, the KNI kernel module needs to be insmodded
210  * in one of its loopback modes.
211  */
212 static int
213 test_kni_loop(__rte_unused void *arg)
214 {
215         int ret = 0;
216         unsigned nb_rx, nb_tx, num, i;
217         const unsigned lcore_id = rte_lcore_id();
218         struct rte_mbuf *pkts_burst[PKT_BURST_SZ];
219
220         if (lcore_id == lcore_main) {
221                 rte_delay_ms(KNI_TIMEOUT_MS);
222                 /* tests of handling kernel request */
223                 if (system(IFCONFIG TEST_KNI_PORT" up") == -1)
224                         ret = -1;
225                 if (system(IFCONFIG TEST_KNI_PORT" mtu 1400") == -1)
226                         ret = -1;
227                 if (system(IFCONFIG TEST_KNI_PORT" down") == -1)
228                         ret = -1;
229                 rte_delay_ms(KNI_TIMEOUT_MS);
230                 test_kni_processing_flag = 1;
231         } else if (lcore_id == lcore_ingress) {
232                 struct rte_mempool *mp = test_kni_lookup_mempool();
233
234                 if (mp == NULL)
235                         return -1;
236
237                 while (1) {
238                         if (test_kni_processing_flag)
239                                 break;
240
241                         for (nb_rx = 0; nb_rx < PKT_BURST_SZ; nb_rx++) {
242                                 pkts_burst[nb_rx] = rte_pktmbuf_alloc(mp);
243                                 if (!pkts_burst[nb_rx])
244                                         break;
245                         }
246
247                         num = rte_kni_tx_burst(test_kni_ctx, pkts_burst,
248                                                                 nb_rx);
249                         stats.ingress += num;
250                         rte_kni_handle_request(test_kni_ctx);
251                         if (num < nb_rx) {
252                                 for (i = num; i < nb_rx; i++) {
253                                         rte_pktmbuf_free(pkts_burst[i]);
254                                 }
255                         }
256                         rte_delay_ms(10);
257                 }
258         } else if (lcore_id == lcore_egress) {
259                 while (1) {
260                         if (test_kni_processing_flag)
261                                 break;
262                         num = rte_kni_rx_burst(test_kni_ctx, pkts_burst,
263                                                         PKT_BURST_SZ);
264                         stats.egress += num;
265                         for (nb_tx = 0; nb_tx < num; nb_tx++)
266                                 rte_pktmbuf_free(pkts_burst[nb_tx]);
267                         rte_delay_ms(10);
268                 }
269         }
270
271         return ret;
272 }
273
274 static int
275 test_kni_allocate_lcores(void)
276 {
277         unsigned i, count = 0;
278
279         lcore_main = rte_get_main_lcore();
280         printf("main lcore: %u\n", lcore_main);
281         for (i = 0; i < RTE_MAX_LCORE; i++) {
282                 if (count >=2 )
283                         break;
284                 if (rte_lcore_is_enabled(i) && i != lcore_main) {
285                         count ++;
286                         if (count == 1)
287                                 lcore_ingress = i;
288                         else if (count == 2)
289                                 lcore_egress = i;
290                 }
291         }
292         printf("count: %u\n", count);
293
294         return count == 2 ? 0 : -1;
295 }
296
297 static int
298 test_kni_register_handler_mp(void)
299 {
300 #define TEST_KNI_HANDLE_REQ_COUNT    10  /* 5s */
301 #define TEST_KNI_HANDLE_REQ_INTERVAL 500 /* ms */
302 #define TEST_KNI_MTU                 1450
303 #define TEST_KNI_MTU_STR             " 1450"
304         int pid;
305
306         pid = fork();
307         if (pid < 0) {
308                 printf("Failed to fork a process\n");
309                 return -1;
310         } else if (pid == 0) {
311                 int i;
312                 struct rte_kni *kni = rte_kni_get(TEST_KNI_PORT);
313                 struct rte_kni_ops ops = {
314                         .change_mtu = kni_change_mtu,
315                         .config_network_if = NULL,
316                         .config_mac_address = NULL,
317                         .config_promiscusity = NULL,
318                 };
319
320                 if (!kni) {
321                         printf("Failed to get KNI named %s\n", TEST_KNI_PORT);
322                         exit(-1);
323                 }
324
325                 kni_pkt_mtu = 0;
326
327                 /* Check with the invalid parameters */
328                 if (rte_kni_register_handlers(kni, NULL) == 0) {
329                         printf("Unexpectedly register successuflly "
330                                         "with NULL ops pointer\n");
331                         exit(-1);
332                 }
333                 if (rte_kni_register_handlers(NULL, &ops) == 0) {
334                         printf("Unexpectedly register successfully "
335                                         "to NULL KNI device pointer\n");
336                         exit(-1);
337                 }
338
339                 if (rte_kni_register_handlers(kni, &ops)) {
340                         printf("Fail to register ops\n");
341                         exit(-1);
342                 }
343
344                 /* Check registering again after it has been registered */
345                 if (rte_kni_register_handlers(kni, &ops) == 0) {
346                         printf("Unexpectedly register successfully after "
347                                         "it has already been registered\n");
348                         exit(-1);
349                 }
350
351                 /**
352                  * Handle the request of setting MTU,
353                  * with registered handlers.
354                  */
355                 for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) {
356                         rte_kni_handle_request(kni);
357                         if (kni_pkt_mtu == TEST_KNI_MTU)
358                                 break;
359                         rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL);
360                 }
361                 if (i >= TEST_KNI_HANDLE_REQ_COUNT) {
362                         printf("MTU has not been set\n");
363                         exit(-1);
364                 }
365
366                 kni_pkt_mtu = 0;
367                 if (rte_kni_unregister_handlers(kni) < 0) {
368                         printf("Fail to unregister ops\n");
369                         exit(-1);
370                 }
371
372                 /* Check with invalid parameter */
373                 if (rte_kni_unregister_handlers(NULL) == 0) {
374                         exit(-1);
375                 }
376
377                 /**
378                  * Handle the request of setting MTU,
379                  * without registered handlers.
380                  */
381                 for (i = 0; i < TEST_KNI_HANDLE_REQ_COUNT; i++) {
382                         rte_kni_handle_request(kni);
383                         if (kni_pkt_mtu != 0)
384                                 break;
385                         rte_delay_ms(TEST_KNI_HANDLE_REQ_INTERVAL);
386                 }
387                 if (kni_pkt_mtu != 0) {
388                         printf("MTU shouldn't be set\n");
389                         exit(-1);
390                 }
391
392                 exit(0);
393         } else {
394                 int p_ret, status;
395
396                 rte_delay_ms(1000);
397                 if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR)
398                                                                 == -1)
399                         return -1;
400
401                 rte_delay_ms(1000);
402                 if (system(IFCONFIG TEST_KNI_PORT " mtu" TEST_KNI_MTU_STR)
403                                                                 == -1)
404                         return -1;
405
406                 p_ret = wait(&status);
407                 if (!WIFEXITED(status)) {
408                         printf("Child process (%d) exit abnormally\n", p_ret);
409                         return -1;
410                 }
411                 if (WEXITSTATUS(status) != 0) {
412                         printf("Child process exit with failure\n");
413                         return -1;
414                 }
415         }
416
417         return 0;
418 }
419
420 static int
421 test_kni_processing(uint16_t port_id, struct rte_mempool *mp)
422 {
423         int ret = 0;
424         unsigned i;
425         struct rte_kni *kni;
426         struct rte_kni_conf conf;
427         struct rte_eth_dev_info info;
428         struct rte_kni_ops ops;
429         const struct rte_pci_device *pci_dev;
430         const struct rte_bus *bus = NULL;
431
432         if (!mp)
433                 return -1;
434
435         memset(&conf, 0, sizeof(conf));
436         memset(&info, 0, sizeof(info));
437         memset(&ops, 0, sizeof(ops));
438
439         ret = rte_eth_dev_info_get(port_id, &info);
440         if (ret != 0) {
441                 printf("Error during getting device (port %u) info: %s\n",
442                                 port_id, strerror(-ret));
443                 return -1;
444         }
445
446         if (info.device)
447                 bus = rte_bus_find_by_device(info.device);
448         if (bus && !strcmp(bus->name, "pci")) {
449                 pci_dev = RTE_DEV_TO_PCI(info.device);
450                 conf.addr = pci_dev->addr;
451                 conf.id = pci_dev->id;
452         }
453         snprintf(conf.name, sizeof(conf.name), TEST_KNI_PORT);
454
455         /* core id 1 configured for kernel thread */
456         conf.core_id = 1;
457         conf.force_bind = 1;
458         conf.mbuf_size = MAX_PACKET_SZ;
459         conf.group_id = port_id;
460
461         ops = kni_ops;
462         ops.port_id = port_id;
463
464         /* basic test of kni processing */
465         kni = rte_kni_alloc(mp, &conf, &ops);
466         if (!kni) {
467                 printf("fail to create kni\n");
468                 return -1;
469         }
470
471         test_kni_ctx = kni;
472         test_kni_processing_flag = 0;
473         stats.ingress = 0;
474         stats.egress = 0;
475
476         /**
477          * Check multiple processes support on
478          * registerring/unregisterring handlers.
479          */
480         if (test_kni_register_handler_mp() < 0) {
481                 printf("fail to check multiple process support\n");
482                 ret = -1;
483                 goto fail_kni;
484         }
485
486         ret = test_kni_link_change();
487         if (ret != 0)
488                 goto fail_kni;
489
490         rte_eal_mp_remote_launch(test_kni_loop, NULL, CALL_MAIN);
491         RTE_LCORE_FOREACH_WORKER(i) {
492                 if (rte_eal_wait_lcore(i) < 0) {
493                         ret = -1;
494                         goto fail_kni;
495                 }
496         }
497         /**
498          * Check if the number of mbufs received from kernel space is equal
499          * to that of transmitted to kernel space
500          */
501         if (stats.ingress < KNI_NUM_MBUF_THRESHOLD ||
502                 stats.egress < KNI_NUM_MBUF_THRESHOLD) {
503                 printf("The ingress/egress number should not be "
504                         "less than %u\n", (unsigned)KNI_NUM_MBUF_THRESHOLD);
505                 ret = -1;
506                 goto fail_kni;
507         }
508
509         if (rte_kni_release(kni) < 0) {
510                 printf("fail to release kni\n");
511                 return -1;
512         }
513         test_kni_ctx = NULL;
514
515         /* test of reusing memzone */
516         kni = rte_kni_alloc(mp, &conf, &ops);
517         if (!kni) {
518                 printf("fail to create kni\n");
519                 return -1;
520         }
521
522         /* Release the kni for following testing */
523         if (rte_kni_release(kni) < 0) {
524                 printf("fail to release kni\n");
525                 return -1;
526         }
527
528         return ret;
529 fail_kni:
530         if (rte_kni_release(kni) < 0) {
531                 printf("fail to release kni\n");
532                 ret = -1;
533         }
534
535         return ret;
536 }
537
538 static int
539 test_kni(void)
540 {
541         int ret = -1;
542         uint16_t port_id;
543         struct rte_kni *kni;
544         struct rte_mempool *mp;
545         struct rte_kni_conf conf;
546         struct rte_eth_dev_info info;
547         struct rte_kni_ops ops;
548         const struct rte_pci_device *pci_dev;
549         const struct rte_bus *bus;
550         FILE *fd;
551         DIR *dir;
552         char buf[16];
553
554         dir = opendir(KNI_MODULE_PATH);
555         if (!dir) {
556                 if (errno == ENOENT) {
557                         printf("Cannot run UT due to missing rte_kni module\n");
558                         return TEST_SKIPPED;
559                 }
560                 printf("opendir: %s", strerror(errno));
561                 return -1;
562         }
563         closedir(dir);
564
565         /* Initialize KNI subsystem */
566         ret = rte_kni_init(KNI_TEST_MAX_PORTS);
567         if (ret < 0) {
568                 printf("fail to initialize KNI subsystem\n");
569                 return -1;
570         }
571
572         if (test_kni_allocate_lcores() < 0) {
573                 printf("No enough lcores for kni processing\n");
574                 return -1;
575         }
576
577         mp = test_kni_create_mempool();
578         if (!mp) {
579                 printf("fail to create mempool for kni\n");
580                 return -1;
581         }
582
583         /* configuring port 0 for the test is enough */
584         port_id = 0;
585         ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf);
586         if (ret < 0) {
587                 printf("fail to configure port %d\n", port_id);
588                 return -1;
589         }
590
591         ret = rte_eth_rx_queue_setup(port_id, 0, NB_RXD, SOCKET, &rx_conf, mp);
592         if (ret < 0) {
593                 printf("fail to setup rx queue for port %d\n", port_id);
594                 return -1;
595         }
596
597         ret = rte_eth_tx_queue_setup(port_id, 0, NB_TXD, SOCKET, &tx_conf);
598         if (ret < 0) {
599                 printf("fail to setup tx queue for port %d\n", port_id);
600                 return -1;
601         }
602
603         ret = rte_eth_dev_start(port_id);
604         if (ret < 0) {
605                 printf("fail to start port %d\n", port_id);
606                 return -1;
607         }
608         ret = rte_eth_promiscuous_enable(port_id);
609         if (ret != 0) {
610                 printf("fail to enable promiscuous mode for port %d: %s\n",
611                         port_id, rte_strerror(-ret));
612                 return -1;
613         }
614
615         /* basic test of kni processing */
616         fd = fopen(KNI_MODULE_PARAM_LO, "r");
617         if (fd == NULL) {
618                 printf("fopen: %s", strerror(errno));
619                 return -1;
620         }
621         memset(&buf, 0, sizeof(buf));
622         if (fgets(buf, sizeof(buf), fd)) {
623                 if (!strncmp(buf, "lo_mode_fifo", strlen("lo_mode_fifo")) ||
624                         !strncmp(buf, "lo_mode_fifo_skb",
625                                   strlen("lo_mode_fifo_skb"))) {
626                         ret = test_kni_processing(port_id, mp);
627                         if (ret < 0) {
628                                 fclose(fd);
629                                 goto fail;
630                         }
631                 } else
632                         printf("test_kni_processing skipped because of missing rte_kni module lo_mode argument\n");
633         }
634         fclose(fd);
635
636         /* test of allocating KNI with NULL mempool pointer */
637         memset(&info, 0, sizeof(info));
638         memset(&conf, 0, sizeof(conf));
639         memset(&ops, 0, sizeof(ops));
640
641         ret = rte_eth_dev_info_get(port_id, &info);
642         if (ret != 0) {
643                 printf("Error during getting device (port %u) info: %s\n",
644                                 port_id, strerror(-ret));
645                 return -1;
646         }
647
648         if (info.device)
649                 bus = rte_bus_find_by_device(info.device);
650         else
651                 bus = NULL;
652         if (bus && !strcmp(bus->name, "pci")) {
653                 pci_dev = RTE_DEV_TO_PCI(info.device);
654                 conf.addr = pci_dev->addr;
655                 conf.id = pci_dev->id;
656         }
657         conf.group_id = port_id;
658         conf.mbuf_size = MAX_PACKET_SZ;
659
660         ops = kni_ops;
661         ops.port_id = port_id;
662         kni = rte_kni_alloc(NULL, &conf, &ops);
663         if (kni) {
664                 ret = -1;
665                 printf("unexpectedly creates kni successfully with NULL "
666                                                         "mempool pointer\n");
667                 goto fail;
668         }
669
670         /* test of allocating KNI without configurations */
671         kni = rte_kni_alloc(mp, NULL, NULL);
672         if (kni) {
673                 ret = -1;
674                 printf("Unexpectedly allocate KNI device successfully "
675                                         "without configurations\n");
676                 goto fail;
677         }
678
679         /* test of allocating KNI without a name */
680         memset(&conf, 0, sizeof(conf));
681         memset(&info, 0, sizeof(info));
682         memset(&ops, 0, sizeof(ops));
683
684         ret = rte_eth_dev_info_get(port_id, &info);
685         if (ret != 0) {
686                 printf("Error during getting device (port %u) info: %s\n",
687                                 port_id, strerror(-ret));
688                 ret = -1;
689                 goto fail;
690         }
691
692         if (info.device)
693                 bus = rte_bus_find_by_device(info.device);
694         else
695                 bus = NULL;
696         if (bus && !strcmp(bus->name, "pci")) {
697                 pci_dev = RTE_DEV_TO_PCI(info.device);
698                 conf.addr = pci_dev->addr;
699                 conf.id = pci_dev->id;
700         }
701         conf.group_id = port_id;
702         conf.mbuf_size = MAX_PACKET_SZ;
703
704         ops = kni_ops;
705         ops.port_id = port_id;
706         kni = rte_kni_alloc(mp, &conf, &ops);
707         if (kni) {
708                 ret = -1;
709                 printf("Unexpectedly allocate a KNI device successfully "
710                                                 "without a name\n");
711                 goto fail;
712         }
713
714         /* test of releasing NULL kni context */
715         ret = rte_kni_release(NULL);
716         if (ret == 0) {
717                 ret = -1;
718                 printf("unexpectedly release kni successfully\n");
719                 goto fail;
720         }
721
722         /* test of handling request on NULL device pointer */
723         ret = rte_kni_handle_request(NULL);
724         if (ret == 0) {
725                 ret = -1;
726                 printf("Unexpectedly handle request on NULL device pointer\n");
727                 goto fail;
728         }
729
730         /* test of getting KNI device with pointer to NULL */
731         kni = rte_kni_get(NULL);
732         if (kni) {
733                 ret = -1;
734                 printf("Unexpectedly get a KNI device with "
735                                         "NULL name pointer\n");
736                 goto fail;
737         }
738
739         /* test of getting KNI device with an zero length name string */
740         memset(&conf, 0, sizeof(conf));
741         kni = rte_kni_get(conf.name);
742         if (kni) {
743                 ret = -1;
744                 printf("Unexpectedly get a KNI device with "
745                                 "zero length name string\n");
746                 goto fail;
747         }
748
749         /* test of getting KNI device with an invalid string name */
750         memset(&conf, 0, sizeof(conf));
751         snprintf(conf.name, sizeof(conf.name), "testing");
752         kni = rte_kni_get(conf.name);
753         if (kni) {
754                 ret = -1;
755                 printf("Unexpectedly get a KNI device with "
756                                 "a never used name string\n");
757                 goto fail;
758         }
759         ret = 0;
760
761 fail:
762         if (rte_eth_dev_stop(port_id) != 0)
763                 printf("Failed to stop port %u\n", port_id);
764
765         return ret;
766 }
767
768 #endif
769
770 REGISTER_TEST_COMMAND(kni_autotest, test_kni);