xref: /f-stack/dpdk/app/test/test_kni.c (revision 2d9fd380)
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
test_kni(void)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 *
test_kni_create_mempool(void)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 *
test_kni_lookup_mempool(void)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
kni_change_mtu(uint16_t port_id,unsigned int new_mtu)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
test_kni_link_change(void)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
test_kni_loop(__rte_unused void * arg)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
test_kni_allocate_lcores(void)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
test_kni_register_handler_mp(void)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
test_kni_processing(uint16_t port_id,struct rte_mempool * mp)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
test_kni(void)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 subsytem */
566 	rte_kni_init(KNI_TEST_MAX_PORTS);
567 
568 	if (test_kni_allocate_lcores() < 0) {
569 		printf("No enough lcores for kni processing\n");
570 		return -1;
571 	}
572 
573 	mp = test_kni_create_mempool();
574 	if (!mp) {
575 		printf("fail to create mempool for kni\n");
576 		return -1;
577 	}
578 
579 	/* configuring port 0 for the test is enough */
580 	port_id = 0;
581 	ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf);
582 	if (ret < 0) {
583 		printf("fail to configure port %d\n", port_id);
584 		return -1;
585 	}
586 
587 	ret = rte_eth_rx_queue_setup(port_id, 0, NB_RXD, SOCKET, &rx_conf, mp);
588 	if (ret < 0) {
589 		printf("fail to setup rx queue for port %d\n", port_id);
590 		return -1;
591 	}
592 
593 	ret = rte_eth_tx_queue_setup(port_id, 0, NB_TXD, SOCKET, &tx_conf);
594 	if (ret < 0) {
595 		printf("fail to setup tx queue for port %d\n", port_id);
596 		return -1;
597 	}
598 
599 	ret = rte_eth_dev_start(port_id);
600 	if (ret < 0) {
601 		printf("fail to start port %d\n", port_id);
602 		return -1;
603 	}
604 	ret = rte_eth_promiscuous_enable(port_id);
605 	if (ret != 0) {
606 		printf("fail to enable promiscuous mode for port %d: %s\n",
607 			port_id, rte_strerror(-ret));
608 		return -1;
609 	}
610 
611 	/* basic test of kni processing */
612 	fd = fopen(KNI_MODULE_PARAM_LO, "r");
613 	if (fd == NULL) {
614 		printf("fopen: %s", strerror(errno));
615 		return -1;
616 	}
617 	memset(&buf, 0, sizeof(buf));
618 	if (fgets(buf, sizeof(buf), fd)) {
619 		if (!strncmp(buf, "lo_mode_fifo", strlen("lo_mode_fifo")) ||
620 			!strncmp(buf, "lo_mode_fifo_skb",
621 				  strlen("lo_mode_fifo_skb"))) {
622 			ret = test_kni_processing(port_id, mp);
623 			if (ret < 0) {
624 				fclose(fd);
625 				goto fail;
626 			}
627 		} else
628 			printf("test_kni_processing skipped because of missing rte_kni module lo_mode argument\n");
629 	}
630 	fclose(fd);
631 
632 	/* test of allocating KNI with NULL mempool pointer */
633 	memset(&info, 0, sizeof(info));
634 	memset(&conf, 0, sizeof(conf));
635 	memset(&ops, 0, sizeof(ops));
636 
637 	ret = rte_eth_dev_info_get(port_id, &info);
638 	if (ret != 0) {
639 		printf("Error during getting device (port %u) info: %s\n",
640 				port_id, strerror(-ret));
641 		return -1;
642 	}
643 
644 	if (info.device)
645 		bus = rte_bus_find_by_device(info.device);
646 	else
647 		bus = NULL;
648 	if (bus && !strcmp(bus->name, "pci")) {
649 		pci_dev = RTE_DEV_TO_PCI(info.device);
650 		conf.addr = pci_dev->addr;
651 		conf.id = pci_dev->id;
652 	}
653 	conf.group_id = port_id;
654 	conf.mbuf_size = MAX_PACKET_SZ;
655 
656 	ops = kni_ops;
657 	ops.port_id = port_id;
658 	kni = rte_kni_alloc(NULL, &conf, &ops);
659 	if (kni) {
660 		ret = -1;
661 		printf("unexpectedly creates kni successfully with NULL "
662 							"mempool pointer\n");
663 		goto fail;
664 	}
665 
666 	/* test of allocating KNI without configurations */
667 	kni = rte_kni_alloc(mp, NULL, NULL);
668 	if (kni) {
669 		ret = -1;
670 		printf("Unexpectedly allocate KNI device successfully "
671 					"without configurations\n");
672 		goto fail;
673 	}
674 
675 	/* test of allocating KNI without a name */
676 	memset(&conf, 0, sizeof(conf));
677 	memset(&info, 0, sizeof(info));
678 	memset(&ops, 0, sizeof(ops));
679 
680 	ret = rte_eth_dev_info_get(port_id, &info);
681 	if (ret != 0) {
682 		printf("Error during getting device (port %u) info: %s\n",
683 				port_id, strerror(-ret));
684 		ret = -1;
685 		goto fail;
686 	}
687 
688 	if (info.device)
689 		bus = rte_bus_find_by_device(info.device);
690 	else
691 		bus = NULL;
692 	if (bus && !strcmp(bus->name, "pci")) {
693 		pci_dev = RTE_DEV_TO_PCI(info.device);
694 		conf.addr = pci_dev->addr;
695 		conf.id = pci_dev->id;
696 	}
697 	conf.group_id = port_id;
698 	conf.mbuf_size = MAX_PACKET_SZ;
699 
700 	ops = kni_ops;
701 	ops.port_id = port_id;
702 	kni = rte_kni_alloc(mp, &conf, &ops);
703 	if (kni) {
704 		ret = -1;
705 		printf("Unexpectedly allocate a KNI device successfully "
706 						"without a name\n");
707 		goto fail;
708 	}
709 
710 	/* test of releasing NULL kni context */
711 	ret = rte_kni_release(NULL);
712 	if (ret == 0) {
713 		ret = -1;
714 		printf("unexpectedly release kni successfully\n");
715 		goto fail;
716 	}
717 
718 	/* test of handling request on NULL device pointer */
719 	ret = rte_kni_handle_request(NULL);
720 	if (ret == 0) {
721 		ret = -1;
722 		printf("Unexpectedly handle request on NULL device pointer\n");
723 		goto fail;
724 	}
725 
726 	/* test of getting KNI device with pointer to NULL */
727 	kni = rte_kni_get(NULL);
728 	if (kni) {
729 		ret = -1;
730 		printf("Unexpectedly get a KNI device with "
731 					"NULL name pointer\n");
732 		goto fail;
733 	}
734 
735 	/* test of getting KNI device with an zero length name string */
736 	memset(&conf, 0, sizeof(conf));
737 	kni = rte_kni_get(conf.name);
738 	if (kni) {
739 		ret = -1;
740 		printf("Unexpectedly get a KNI device with "
741 				"zero length name string\n");
742 		goto fail;
743 	}
744 
745 	/* test of getting KNI device with an invalid string name */
746 	memset(&conf, 0, sizeof(conf));
747 	snprintf(conf.name, sizeof(conf.name), "testing");
748 	kni = rte_kni_get(conf.name);
749 	if (kni) {
750 		ret = -1;
751 		printf("Unexpectedly get a KNI device with "
752 				"a never used name string\n");
753 		goto fail;
754 	}
755 	ret = 0;
756 
757 fail:
758 	if (rte_eth_dev_stop(port_id) != 0)
759 		printf("Failed to stop port %u\n", port_id);
760 
761 	return ret;
762 }
763 
764 #endif
765 
766 REGISTER_TEST_COMMAND(kni_autotest, test_kni);
767