1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <kunit/test.h>
4 #include <linux/etherdevice.h>
5 #include <linux/netdevice.h>
6 #include <linux/rtnetlink.h>
8 static const struct net_device_ops dummy_netdev_ops
= {
11 struct dev_addr_test_priv
{
15 static int dev_addr_test_sync(struct net_device
*netdev
, const unsigned char *a
)
17 struct dev_addr_test_priv
*datp
= netdev_priv(netdev
);
19 if (a
[0] < 31 && !memchr_inv(a
, a
[0], ETH_ALEN
))
20 datp
->addr_seen
|= 1 << a
[0];
24 static int dev_addr_test_unsync(struct net_device
*netdev
,
25 const unsigned char *a
)
27 struct dev_addr_test_priv
*datp
= netdev_priv(netdev
);
29 if (a
[0] < 31 && !memchr_inv(a
, a
[0], ETH_ALEN
))
30 datp
->addr_seen
&= ~(1 << a
[0]);
34 static int dev_addr_test_init(struct kunit
*test
)
36 struct dev_addr_test_priv
*datp
;
37 struct net_device
*netdev
;
40 netdev
= alloc_etherdev(sizeof(*datp
));
41 KUNIT_ASSERT_TRUE(test
, !!netdev
);
44 netdev
->netdev_ops
= &dummy_netdev_ops
;
46 err
= register_netdev(netdev
);
49 KUNIT_FAIL(test
, "Can't register netdev %d", err
);
55 static void dev_addr_test_exit(struct kunit
*test
)
57 struct net_device
*netdev
= test
->priv
;
59 unregister_netdev(netdev
);
63 static void dev_addr_test_basic(struct kunit
*test
)
65 struct net_device
*netdev
= test
->priv
;
69 KUNIT_EXPECT_TRUE(test
, !!netdev
->dev_addr
);
71 memset(addr
, 2, sizeof(addr
));
72 eth_hw_addr_set(netdev
, addr
);
73 KUNIT_EXPECT_MEMEQ(test
, netdev
->dev_addr
, addr
, sizeof(addr
));
75 memset(addr
, 3, sizeof(addr
));
76 dev_addr_set(netdev
, addr
);
77 KUNIT_EXPECT_MEMEQ(test
, netdev
->dev_addr
, addr
, sizeof(addr
));
81 static void dev_addr_test_sync_one(struct kunit
*test
)
83 struct net_device
*netdev
= test
->priv
;
84 struct dev_addr_test_priv
*datp
;
87 datp
= netdev_priv(netdev
);
90 memset(addr
, 1, sizeof(addr
));
91 eth_hw_addr_set(netdev
, addr
);
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
);
97 memset(addr
, 2, sizeof(addr
));
98 eth_hw_addr_set(netdev
, addr
);
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.
106 KUNIT_EXPECT_EQ(test
, 0, datp
->addr_seen
);
110 static void dev_addr_test_add_del(struct kunit
*test
)
112 struct net_device
*netdev
= test
->priv
;
113 struct dev_addr_test_priv
*datp
;
117 datp
= netdev_priv(netdev
);
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
));
126 KUNIT_EXPECT_EQ(test
, 0, dev_addr_add(netdev
, addr
,
127 NETDEV_HW_ADDR_T_LAN
));
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
);
133 KUNIT_EXPECT_EQ(test
, 0, dev_addr_del(netdev
, addr
,
134 NETDEV_HW_ADDR_T_LAN
));
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
);
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
));
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
);
152 static void dev_addr_test_del_main(struct kunit
*test
)
154 struct net_device
*netdev
= test
->priv
;
158 memset(addr
, 1, sizeof(addr
));
159 eth_hw_addr_set(netdev
, addr
);
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
));
172 static void dev_addr_test_add_set(struct kunit
*test
)
174 struct net_device
*netdev
= test
->priv
;
175 struct dev_addr_test_priv
*datp
;
179 datp
= netdev_priv(netdev
);
182 /* There is no external API like dev_addr_add_excl(),
183 * so shuffle the tree a little bit and exploit aliasing.
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
));
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
);
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
);
204 static void dev_addr_test_add_excl(struct kunit
*test
)
206 struct net_device
*netdev
= test
->priv
;
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
));
215 KUNIT_EXPECT_EQ(test
, -EEXIST
, dev_uc_add_excl(netdev
, addr
));
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
));
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
));
228 static 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
),
238 static 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
,
244 kunit_test_suite(dev_addr_test_suite
);
246 MODULE_DESCRIPTION("KUnit tests for struct netdev_hw_addr_list");
247 MODULE_LICENSE("GPL");