FILE
dev_addr_lists_test.c
File preview with syntax highlighting.
linux-6.19.14/net/core/dev_addr_lists_test.c
1// SPDX-License-Identifier: GPL-2.0-or-later 2 3#include <kunit/test.h> 4#include <linux/etherdevice.h> 5#include <linux/netdevice.h> 6#include <linux/rtnetlink.h> 7 8static const struct net_device_ops dummy_netdev_ops = { 9}; 10 11struct dev_addr_test_priv { 12 u32 addr_seen; 13}; 14 15static int dev_addr_test_sync(struct net_device *netdev, const unsigned char *a) 16{ 17 struct dev_addr_test_priv *datp = netdev_priv(netdev); 18 19 if (a[0] < 31 && !memchr_inv(a, a[0], ETH_ALEN)) 20 datp->addr_seen |= 1 << a[0]; 21 return 0; 22} 23 24static int dev_addr_test_unsync(struct net_device *netdev, 25 const unsigned char *a) 26{ 27 struct dev_addr_test_priv *datp = netdev_priv(netdev); 28 29 if (a[0] < 31 && !memchr_inv(a, a[0], ETH_ALEN)) 30 datp->addr_seen &= ~(1 << a[0]); 31 return 0; 32} 33 34static int dev_addr_test_init(struct kunit *test) 35{ 36 struct dev_addr_test_priv *datp; 37 struct net_device *netdev; 38 int err; 39 40 netdev = alloc_etherdev(sizeof(*datp)); 41 KUNIT_ASSERT_TRUE(test, !!netdev); 42 43 test->priv = netdev; 44 netdev->netdev_ops = &dummy_netdev_ops; 45 46 err = register_netdev(netdev); 47 if (err) { 48 free_netdev(netdev); 49 KUNIT_FAIL(test, "Can't register netdev %d", err); 50 } 51 52 return 0; 53} 54 55static void dev_addr_test_exit(struct kunit *test) 56{ 57 struct net_device *netdev = test->priv; 58 59 unregister_netdev(netdev); 60 free_netdev(netdev); 61} 62 63static void dev_addr_test_basic(struct kunit *test) 64{ 65 struct net_device *netdev = test->priv; 66 u8 addr[ETH_ALEN]; 67 68 rtnl_lock(); 69 KUNIT_EXPECT_TRUE(test, !!netdev->dev_addr); 70 71 memset(addr, 2, sizeof(addr)); 72 eth_hw_addr_set(netdev, addr); 73 KUNIT_EXPECT_MEMEQ(test, netdev->dev_addr, addr, sizeof(addr)); 74 75 memset(addr, 3, sizeof(addr)); 76 dev_addr_set(netdev, addr); 77 KUNIT_EXPECT_MEMEQ(test, netdev->dev_addr, addr, sizeof(addr)); 78 rtnl_unlock(); 79} 80 81static void dev_addr_test_sync_one(struct kunit *test) 82{ 83 struct net_device *netdev = test->priv; 84 struct dev_addr_test_priv *datp; 85 u8 addr[ETH_ALEN]; 86 87 datp = netdev_priv(netdev); 88 89 rtnl_lock(); 90 memset(addr, 1, sizeof(addr)); 91 eth_hw_addr_set(netdev, addr); 92 93 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 94 dev_addr_test_unsync); 95 KUNIT_EXPECT_EQ(test, 2, datp->addr_seen); 96 97 memset(addr, 2, sizeof(addr)); 98 eth_hw_addr_set(netdev, addr); 99 100 datp->addr_seen = 0; 101 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 102 dev_addr_test_unsync); 103 /* It's not going to sync anything because the main address is 104 * considered synced and we overwrite in place. 105 */ 106 KUNIT_EXPECT_EQ(test, 0, datp->addr_seen); 107 rtnl_unlock(); 108} 109 110static void dev_addr_test_add_del(struct kunit *test) 111{ 112 struct net_device *netdev = test->priv; 113 struct dev_addr_test_priv *datp; 114 u8 addr[ETH_ALEN]; 115 int i; 116 117 datp = netdev_priv(netdev); 118 119 rtnl_lock(); 120 for (i = 1; i < 4; i++) { 121 memset(addr, i, sizeof(addr)); 122 KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr, 123 NETDEV_HW_ADDR_T_LAN)); 124 } 125 /* Add 3 again */ 126 KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr, 127 NETDEV_HW_ADDR_T_LAN)); 128 129 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 130 dev_addr_test_unsync); 131 KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen); 132 133 KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr, 134 NETDEV_HW_ADDR_T_LAN)); 135 136 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 137 dev_addr_test_unsync); 138 KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen); 139 140 for (i = 1; i < 4; i++) { 141 memset(addr, i, sizeof(addr)); 142 KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr, 143 NETDEV_HW_ADDR_T_LAN)); 144 } 145 146 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 147 dev_addr_test_unsync); 148 KUNIT_EXPECT_EQ(test, 1, datp->addr_seen); 149 rtnl_unlock(); 150} 151 152static void dev_addr_test_del_main(struct kunit *test) 153{ 154 struct net_device *netdev = test->priv; 155 u8 addr[ETH_ALEN]; 156 157 rtnl_lock(); 158 memset(addr, 1, sizeof(addr)); 159 eth_hw_addr_set(netdev, addr); 160 161 KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr, 162 NETDEV_HW_ADDR_T_LAN)); 163 KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr, 164 NETDEV_HW_ADDR_T_LAN)); 165 KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr, 166 NETDEV_HW_ADDR_T_LAN)); 167 KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr, 168 NETDEV_HW_ADDR_T_LAN)); 169 rtnl_unlock(); 170} 171 172static void dev_addr_test_add_set(struct kunit *test) 173{ 174 struct net_device *netdev = test->priv; 175 struct dev_addr_test_priv *datp; 176 u8 addr[ETH_ALEN]; 177 int i; 178 179 datp = netdev_priv(netdev); 180 181 rtnl_lock(); 182 /* There is no external API like dev_addr_add_excl(), 183 * so shuffle the tree a little bit and exploit aliasing. 184 */ 185 for (i = 1; i < 16; i++) { 186 memset(addr, i, sizeof(addr)); 187 KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr, 188 NETDEV_HW_ADDR_T_LAN)); 189 } 190 191 memset(addr, i, sizeof(addr)); 192 eth_hw_addr_set(netdev, addr); 193 KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr, 194 NETDEV_HW_ADDR_T_LAN)); 195 memset(addr, 0, sizeof(addr)); 196 eth_hw_addr_set(netdev, addr); 197 198 __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync, 199 dev_addr_test_unsync); 200 KUNIT_EXPECT_EQ(test, 0xffff, datp->addr_seen); 201 rtnl_unlock(); 202} 203 204static void dev_addr_test_add_excl(struct kunit *test) 205{ 206 struct net_device *netdev = test->priv; 207 u8 addr[ETH_ALEN]; 208 int i; 209 210 rtnl_lock(); 211 for (i = 0; i < 10; i++) { 212 memset(addr, i, sizeof(addr)); 213 KUNIT_EXPECT_EQ(test, 0, dev_uc_add_excl(netdev, addr)); 214 } 215 KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr)); 216 217 for (i = 0; i < 10; i += 2) { 218 memset(addr, i, sizeof(addr)); 219 KUNIT_EXPECT_EQ(test, 0, dev_uc_del(netdev, addr)); 220 } 221 for (i = 1; i < 10; i += 2) { 222 memset(addr, i, sizeof(addr)); 223 KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr)); 224 } 225 rtnl_unlock(); 226} 227 228static struct kunit_case dev_addr_test_cases[] = { 229 KUNIT_CASE(dev_addr_test_basic), 230 KUNIT_CASE(dev_addr_test_sync_one), 231 KUNIT_CASE(dev_addr_test_add_del), 232 KUNIT_CASE(dev_addr_test_del_main), 233 KUNIT_CASE(dev_addr_test_add_set), 234 KUNIT_CASE(dev_addr_test_add_excl), 235 {} 236}; 237 238static struct kunit_suite dev_addr_test_suite = { 239 .name = "dev-addr-list-test", 240 .test_cases = dev_addr_test_cases, 241 .init = dev_addr_test_init, 242 .exit = dev_addr_test_exit, 243}; 244kunit_test_suite(dev_addr_test_suite); 245 246MODULE_DESCRIPTION("KUnit tests for struct netdev_hw_addr_list"); 247MODULE_LICENSE("GPL");
~/
Read-only file preview.