Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 
0003 #include <kunit/test.h>
0004 #include <linux/etherdevice.h>
0005 #include <linux/netdevice.h>
0006 #include <linux/rtnetlink.h>
0007 
0008 static const struct net_device_ops dummy_netdev_ops = {
0009 };
0010 
0011 struct dev_addr_test_priv {
0012     u32 addr_seen;
0013 };
0014 
0015 static int dev_addr_test_sync(struct net_device *netdev, const unsigned char *a)
0016 {
0017     struct dev_addr_test_priv *datp = netdev_priv(netdev);
0018 
0019     if (a[0] < 31 && !memchr_inv(a, a[0], ETH_ALEN))
0020         datp->addr_seen |= 1 << a[0];
0021     return 0;
0022 }
0023 
0024 static int dev_addr_test_unsync(struct net_device *netdev,
0025                 const unsigned char *a)
0026 {
0027     struct dev_addr_test_priv *datp = netdev_priv(netdev);
0028 
0029     if (a[0] < 31 && !memchr_inv(a, a[0], ETH_ALEN))
0030         datp->addr_seen &= ~(1 << a[0]);
0031     return 0;
0032 }
0033 
0034 static int dev_addr_test_init(struct kunit *test)
0035 {
0036     struct dev_addr_test_priv *datp;
0037     struct net_device *netdev;
0038     int err;
0039 
0040     netdev = alloc_etherdev(sizeof(*datp));
0041     KUNIT_ASSERT_TRUE(test, !!netdev);
0042 
0043     test->priv = netdev;
0044     netdev->netdev_ops = &dummy_netdev_ops;
0045 
0046     err = register_netdev(netdev);
0047     if (err) {
0048         free_netdev(netdev);
0049         KUNIT_FAIL(test, "Can't register netdev %d", err);
0050     }
0051 
0052     rtnl_lock();
0053     return 0;
0054 }
0055 
0056 static void dev_addr_test_exit(struct kunit *test)
0057 {
0058     struct net_device *netdev = test->priv;
0059 
0060     rtnl_unlock();
0061     unregister_netdev(netdev);
0062     free_netdev(netdev);
0063 }
0064 
0065 static void dev_addr_test_basic(struct kunit *test)
0066 {
0067     struct net_device *netdev = test->priv;
0068     u8 addr[ETH_ALEN];
0069 
0070     KUNIT_EXPECT_TRUE(test, !!netdev->dev_addr);
0071 
0072     memset(addr, 2, sizeof(addr));
0073     eth_hw_addr_set(netdev, addr);
0074     KUNIT_EXPECT_EQ(test, 0, memcmp(netdev->dev_addr, addr, sizeof(addr)));
0075 
0076     memset(addr, 3, sizeof(addr));
0077     dev_addr_set(netdev, addr);
0078     KUNIT_EXPECT_EQ(test, 0, memcmp(netdev->dev_addr, addr, sizeof(addr)));
0079 }
0080 
0081 static void dev_addr_test_sync_one(struct kunit *test)
0082 {
0083     struct net_device *netdev = test->priv;
0084     struct dev_addr_test_priv *datp;
0085     u8 addr[ETH_ALEN];
0086 
0087     datp = netdev_priv(netdev);
0088 
0089     memset(addr, 1, sizeof(addr));
0090     eth_hw_addr_set(netdev, addr);
0091 
0092     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0093                dev_addr_test_unsync);
0094     KUNIT_EXPECT_EQ(test, 2, datp->addr_seen);
0095 
0096     memset(addr, 2, sizeof(addr));
0097     eth_hw_addr_set(netdev, addr);
0098 
0099     datp->addr_seen = 0;
0100     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0101                dev_addr_test_unsync);
0102     /* It's not going to sync anything because the main address is
0103      * considered synced and we overwrite in place.
0104      */
0105     KUNIT_EXPECT_EQ(test, 0, datp->addr_seen);
0106 }
0107 
0108 static void dev_addr_test_add_del(struct kunit *test)
0109 {
0110     struct net_device *netdev = test->priv;
0111     struct dev_addr_test_priv *datp;
0112     u8 addr[ETH_ALEN];
0113     int i;
0114 
0115     datp = netdev_priv(netdev);
0116 
0117     for (i = 1; i < 4; i++) {
0118         memset(addr, i, sizeof(addr));
0119         KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
0120                               NETDEV_HW_ADDR_T_LAN));
0121     }
0122     /* Add 3 again */
0123     KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
0124                           NETDEV_HW_ADDR_T_LAN));
0125 
0126     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0127                dev_addr_test_unsync);
0128     KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen);
0129 
0130     KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
0131                           NETDEV_HW_ADDR_T_LAN));
0132 
0133     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0134                dev_addr_test_unsync);
0135     KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen);
0136 
0137     for (i = 1; i < 4; i++) {
0138         memset(addr, i, sizeof(addr));
0139         KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
0140                               NETDEV_HW_ADDR_T_LAN));
0141     }
0142 
0143     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0144                dev_addr_test_unsync);
0145     KUNIT_EXPECT_EQ(test, 1, datp->addr_seen);
0146 }
0147 
0148 static void dev_addr_test_del_main(struct kunit *test)
0149 {
0150     struct net_device *netdev = test->priv;
0151     u8 addr[ETH_ALEN];
0152 
0153     memset(addr, 1, sizeof(addr));
0154     eth_hw_addr_set(netdev, addr);
0155 
0156     KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr,
0157                             NETDEV_HW_ADDR_T_LAN));
0158     KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
0159                           NETDEV_HW_ADDR_T_LAN));
0160     KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
0161                           NETDEV_HW_ADDR_T_LAN));
0162     KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr,
0163                             NETDEV_HW_ADDR_T_LAN));
0164 }
0165 
0166 static void dev_addr_test_add_set(struct kunit *test)
0167 {
0168     struct net_device *netdev = test->priv;
0169     struct dev_addr_test_priv *datp;
0170     u8 addr[ETH_ALEN];
0171     int i;
0172 
0173     datp = netdev_priv(netdev);
0174 
0175     /* There is no external API like dev_addr_add_excl(),
0176      * so shuffle the tree a little bit and exploit aliasing.
0177      */
0178     for (i = 1; i < 16; i++) {
0179         memset(addr, i, sizeof(addr));
0180         KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
0181                               NETDEV_HW_ADDR_T_LAN));
0182     }
0183 
0184     memset(addr, i, sizeof(addr));
0185     eth_hw_addr_set(netdev, addr);
0186     KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
0187                           NETDEV_HW_ADDR_T_LAN));
0188     memset(addr, 0, sizeof(addr));
0189     eth_hw_addr_set(netdev, addr);
0190 
0191     __hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
0192                dev_addr_test_unsync);
0193     KUNIT_EXPECT_EQ(test, 0xffff, datp->addr_seen);
0194 }
0195 
0196 static void dev_addr_test_add_excl(struct kunit *test)
0197 {
0198     struct net_device *netdev = test->priv;
0199     u8 addr[ETH_ALEN];
0200     int i;
0201 
0202     for (i = 0; i < 10; i++) {
0203         memset(addr, i, sizeof(addr));
0204         KUNIT_EXPECT_EQ(test, 0, dev_uc_add_excl(netdev, addr));
0205     }
0206     KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr));
0207 
0208     for (i = 0; i < 10; i += 2) {
0209         memset(addr, i, sizeof(addr));
0210         KUNIT_EXPECT_EQ(test, 0, dev_uc_del(netdev, addr));
0211     }
0212     for (i = 1; i < 10; i += 2) {
0213         memset(addr, i, sizeof(addr));
0214         KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr));
0215     }
0216 }
0217 
0218 static struct kunit_case dev_addr_test_cases[] = {
0219     KUNIT_CASE(dev_addr_test_basic),
0220     KUNIT_CASE(dev_addr_test_sync_one),
0221     KUNIT_CASE(dev_addr_test_add_del),
0222     KUNIT_CASE(dev_addr_test_del_main),
0223     KUNIT_CASE(dev_addr_test_add_set),
0224     KUNIT_CASE(dev_addr_test_add_excl),
0225     {}
0226 };
0227 
0228 static struct kunit_suite dev_addr_test_suite = {
0229     .name = "dev-addr-list-test",
0230     .test_cases = dev_addr_test_cases,
0231     .init = dev_addr_test_init,
0232     .exit = dev_addr_test_exit,
0233 };
0234 kunit_test_suite(dev_addr_test_suite);
0235 
0236 MODULE_LICENSE("GPL");