cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dev_addr_lists_test.c (6102B)


      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	rtnl_lock();
     53	return 0;
     54}
     55
     56static void dev_addr_test_exit(struct kunit *test)
     57{
     58	struct net_device *netdev = test->priv;
     59
     60	rtnl_unlock();
     61	unregister_netdev(netdev);
     62	free_netdev(netdev);
     63}
     64
     65static void dev_addr_test_basic(struct kunit *test)
     66{
     67	struct net_device *netdev = test->priv;
     68	u8 addr[ETH_ALEN];
     69
     70	KUNIT_EXPECT_TRUE(test, !!netdev->dev_addr);
     71
     72	memset(addr, 2, sizeof(addr));
     73	eth_hw_addr_set(netdev, addr);
     74	KUNIT_EXPECT_EQ(test, 0, memcmp(netdev->dev_addr, addr, sizeof(addr)));
     75
     76	memset(addr, 3, sizeof(addr));
     77	dev_addr_set(netdev, addr);
     78	KUNIT_EXPECT_EQ(test, 0, memcmp(netdev->dev_addr, addr, sizeof(addr)));
     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	memset(addr, 1, sizeof(addr));
     90	eth_hw_addr_set(netdev, addr);
     91
     92	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
     93			   dev_addr_test_unsync);
     94	KUNIT_EXPECT_EQ(test, 2, datp->addr_seen);
     95
     96	memset(addr, 2, sizeof(addr));
     97	eth_hw_addr_set(netdev, addr);
     98
     99	datp->addr_seen = 0;
    100	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
    101			   dev_addr_test_unsync);
    102	/* It's not going to sync anything because the main address is
    103	 * considered synced and we overwrite in place.
    104	 */
    105	KUNIT_EXPECT_EQ(test, 0, datp->addr_seen);
    106}
    107
    108static void dev_addr_test_add_del(struct kunit *test)
    109{
    110	struct net_device *netdev = test->priv;
    111	struct dev_addr_test_priv *datp;
    112	u8 addr[ETH_ALEN];
    113	int i;
    114
    115	datp = netdev_priv(netdev);
    116
    117	for (i = 1; i < 4; i++) {
    118		memset(addr, i, sizeof(addr));
    119		KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
    120						      NETDEV_HW_ADDR_T_LAN));
    121	}
    122	/* Add 3 again */
    123	KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
    124					      NETDEV_HW_ADDR_T_LAN));
    125
    126	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
    127			   dev_addr_test_unsync);
    128	KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen);
    129
    130	KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
    131					      NETDEV_HW_ADDR_T_LAN));
    132
    133	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
    134			   dev_addr_test_unsync);
    135	KUNIT_EXPECT_EQ(test, 0xf, datp->addr_seen);
    136
    137	for (i = 1; i < 4; i++) {
    138		memset(addr, i, sizeof(addr));
    139		KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
    140						      NETDEV_HW_ADDR_T_LAN));
    141	}
    142
    143	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
    144			   dev_addr_test_unsync);
    145	KUNIT_EXPECT_EQ(test, 1, datp->addr_seen);
    146}
    147
    148static void dev_addr_test_del_main(struct kunit *test)
    149{
    150	struct net_device *netdev = test->priv;
    151	u8 addr[ETH_ALEN];
    152
    153	memset(addr, 1, sizeof(addr));
    154	eth_hw_addr_set(netdev, addr);
    155
    156	KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr,
    157						    NETDEV_HW_ADDR_T_LAN));
    158	KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
    159					      NETDEV_HW_ADDR_T_LAN));
    160	KUNIT_EXPECT_EQ(test, 0, dev_addr_del(netdev, addr,
    161					      NETDEV_HW_ADDR_T_LAN));
    162	KUNIT_EXPECT_EQ(test, -ENOENT, dev_addr_del(netdev, addr,
    163						    NETDEV_HW_ADDR_T_LAN));
    164}
    165
    166static void dev_addr_test_add_set(struct kunit *test)
    167{
    168	struct net_device *netdev = test->priv;
    169	struct dev_addr_test_priv *datp;
    170	u8 addr[ETH_ALEN];
    171	int i;
    172
    173	datp = netdev_priv(netdev);
    174
    175	/* There is no external API like dev_addr_add_excl(),
    176	 * so shuffle the tree a little bit and exploit aliasing.
    177	 */
    178	for (i = 1; i < 16; i++) {
    179		memset(addr, i, sizeof(addr));
    180		KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
    181						      NETDEV_HW_ADDR_T_LAN));
    182	}
    183
    184	memset(addr, i, sizeof(addr));
    185	eth_hw_addr_set(netdev, addr);
    186	KUNIT_EXPECT_EQ(test, 0, dev_addr_add(netdev, addr,
    187					      NETDEV_HW_ADDR_T_LAN));
    188	memset(addr, 0, sizeof(addr));
    189	eth_hw_addr_set(netdev, addr);
    190
    191	__hw_addr_sync_dev(&netdev->dev_addrs, netdev, dev_addr_test_sync,
    192			   dev_addr_test_unsync);
    193	KUNIT_EXPECT_EQ(test, 0xffff, datp->addr_seen);
    194}
    195
    196static void dev_addr_test_add_excl(struct kunit *test)
    197{
    198	struct net_device *netdev = test->priv;
    199	u8 addr[ETH_ALEN];
    200	int i;
    201
    202	for (i = 0; i < 10; i++) {
    203		memset(addr, i, sizeof(addr));
    204		KUNIT_EXPECT_EQ(test, 0, dev_uc_add_excl(netdev, addr));
    205	}
    206	KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr));
    207
    208	for (i = 0; i < 10; i += 2) {
    209		memset(addr, i, sizeof(addr));
    210		KUNIT_EXPECT_EQ(test, 0, dev_uc_del(netdev, addr));
    211	}
    212	for (i = 1; i < 10; i += 2) {
    213		memset(addr, i, sizeof(addr));
    214		KUNIT_EXPECT_EQ(test, -EEXIST, dev_uc_add_excl(netdev, addr));
    215	}
    216}
    217
    218static struct kunit_case dev_addr_test_cases[] = {
    219	KUNIT_CASE(dev_addr_test_basic),
    220	KUNIT_CASE(dev_addr_test_sync_one),
    221	KUNIT_CASE(dev_addr_test_add_del),
    222	KUNIT_CASE(dev_addr_test_del_main),
    223	KUNIT_CASE(dev_addr_test_add_set),
    224	KUNIT_CASE(dev_addr_test_add_excl),
    225	{}
    226};
    227
    228static struct kunit_suite dev_addr_test_suite = {
    229	.name = "dev-addr-list-test",
    230	.test_cases = dev_addr_test_cases,
    231	.init = dev_addr_test_init,
    232	.exit = dev_addr_test_exit,
    233};
    234kunit_test_suite(dev_addr_test_suite);
    235
    236MODULE_LICENSE("GPL");