1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2021 6WIND S.A. 3 */ 4 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 9 #include <rte_common.h> 10 #include <rte_kvargs.h> 11 #include <rte_bus_vdev.h> 12 13 #include "test.h" 14 15 #define TEST_VDEV_KEY_NAME "name" 16 17 static const char * const valid_keys[] = { 18 TEST_VDEV_KEY_NAME, 19 NULL, 20 }; 21 22 static int 23 cmp_dev_name(const struct rte_device *dev, const void *name) 24 { 25 return strcmp(dev->name, name); 26 } 27 28 static int 29 cmp_dev_match(const struct rte_device *dev, const void *_kvlist) 30 { 31 const struct rte_kvargs *kvlist = _kvlist; 32 const char *key = TEST_VDEV_KEY_NAME; 33 const char *name; 34 35 /* no kvlist arg, all devices match */ 36 if (kvlist == NULL) 37 return 0; 38 39 /* if key is present in kvlist and does not match, filter device */ 40 name = rte_kvargs_get(kvlist, key); 41 if (name != NULL && strcmp(name, dev->name)) 42 return -1; 43 44 return 0; 45 } 46 47 static struct rte_device * 48 get_matching_vdev(const char *match_str) 49 { 50 struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev"); 51 struct rte_kvargs *kvargs = NULL; 52 struct rte_device *dev; 53 54 if (match_str != NULL) { 55 kvargs = rte_kvargs_parse(match_str, valid_keys); 56 if (kvargs == NULL) { 57 printf("Failed to parse match string\n"); 58 return NULL; 59 } 60 } 61 62 dev = vdev_bus->find_device(NULL, cmp_dev_match, kvargs); 63 rte_kvargs_free(kvargs); 64 65 return dev; 66 } 67 68 static int 69 test_vdev_bus(void) 70 { 71 struct rte_bus *vdev_bus = rte_bus_find_by_name("vdev"); 72 struct rte_dev_iterator dev_iter = { 0 }; 73 struct rte_device *dev, *dev0, *dev1; 74 75 /* not supported */ 76 if (vdev_bus == NULL) 77 return 0; 78 79 /* create first vdev */ 80 if (rte_vdev_init("net_null_test0", "") < 0) { 81 printf("Failed to create vdev net_null_test0\n"); 82 goto fail; 83 } 84 dev0 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test0"); 85 if (dev0 == NULL) { 86 printf("Cannot find net_null_test0 vdev\n"); 87 goto fail; 88 } 89 90 /* create second vdev */ 91 if (rte_vdev_init("net_null_test1", "") < 0) { 92 printf("Failed to create vdev net_null_test1\n"); 93 goto fail; 94 } 95 dev1 = vdev_bus->find_device(NULL, cmp_dev_name, "net_null_test1"); 96 if (dev1 == NULL) { 97 printf("Cannot find net_null_test1 vdev\n"); 98 goto fail; 99 } 100 101 /* try to match vdevs */ 102 dev = get_matching_vdev("name=net_null_test0"); 103 if (dev != dev0) { 104 printf("Cannot match net_null_test0 vdev\n"); 105 goto fail; 106 } 107 108 dev = get_matching_vdev("name=net_null_test1"); 109 if (dev != dev1) { 110 printf("Cannot match net_null_test1 vdev\n"); 111 goto fail; 112 } 113 114 dev = get_matching_vdev("name=unexistant"); 115 if (dev != NULL) { 116 printf("Unexistant vdev should not match\n"); 117 goto fail; 118 } 119 120 dev = get_matching_vdev(""); 121 if (dev == NULL || dev == dev1) { 122 printf("Cannot match any vdev with empty match string\n"); 123 goto fail; 124 } 125 126 dev = get_matching_vdev(NULL); 127 if (dev == NULL || dev == dev1) { 128 printf("Cannot match any vdev with NULL match string\n"); 129 goto fail; 130 } 131 132 /* iterate all vdevs, and ensure we find vdev0 and vdev1 */ 133 RTE_DEV_FOREACH(dev, "bus=vdev", &dev_iter) { 134 if (dev == dev0) 135 dev0 = NULL; 136 else if (dev == dev1) 137 dev1 = NULL; 138 } 139 if (dev0 != NULL) { 140 printf("dev0 was not iterated\n"); 141 goto fail; 142 } 143 if (dev1 != NULL) { 144 printf("dev1 was not iterated\n"); 145 goto fail; 146 } 147 148 rte_vdev_uninit("net_null_test0"); 149 rte_vdev_uninit("net_null_test1"); 150 151 return 0; 152 153 fail: 154 rte_vdev_uninit("net_null_test0"); 155 rte_vdev_uninit("net_null_test1"); 156 return -1; 157 } 158 159 static int 160 test_vdev(void) 161 { 162 printf("== test vdev bus ==\n"); 163 if (test_vdev_bus() < 0) 164 return -1; 165 return 0; 166 } 167 168 REGISTER_TEST_COMMAND(vdev_autotest, test_vdev); 169