]> Git Repo - linux.git/blob - net/core/dev_addr_lists_test.c
fs: Allow listmount() in foreign mount namespace
[linux.git] / 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
8 static const struct net_device_ops dummy_netdev_ops = {
9 };
10
11 struct dev_addr_test_priv {
12         u32 addr_seen;
13 };
14
15 static 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
24 static 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
34 static 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
55 static 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
63 static 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
81 static 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
110 static 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
152 static 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
172 static 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
204 static 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
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),
235         {}
236 };
237
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,
243 };
244 kunit_test_suite(dev_addr_test_suite);
245
246 MODULE_DESCRIPTION("KUnit tests for struct netdev_hw_addr_list");
247 MODULE_LICENSE("GPL");
This page took 0.039365 seconds and 4 git commands to generate.