1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/net/net_if.h>
7 #include <zephyr/net/dummy.h>
8 #include <zephyr/net/conn_mgr_connectivity_impl.h>
9 #include <zephyr/net/ethernet.h>
10 #include "test_ifaces.h"
11
12 /* Create test ifaces */
13
14 /* Generic iface initializer, shared by all test ifaces */
test_iface_init(struct net_if * iface)15 static void test_iface_init(struct net_if *iface)
16 {
17 /* Fake link layer address is needed to silence assertions inside the net core */
18 static uint8_t fake_lladdr[] = { 0x01 };
19
20 net_if_set_link_addr(iface, fake_lladdr, sizeof(fake_lladdr), NET_LINK_DUMMY);
21
22 /* Do not automatically start the iface */
23 net_if_flag_set(iface, NET_IF_NO_AUTO_START);
24 }
25
26 /* Mandatory stub for NET_DEVICE_INIT */
test_iface_netdev_init(const struct device * dev)27 static int test_iface_netdev_init(const struct device *dev)
28 {
29 return 0;
30 }
31
32 /* This is needed specifically for IPv6 DAD.
33 * DAD tries to send a packet, and the test will hang if send is not implemented.
34 */
test_iface_send(const struct device * dev,struct net_pkt * pkt)35 static int test_iface_send(const struct device *dev, struct net_pkt *pkt)
36 {
37 return 0;
38 }
39
40 static struct dummy_api test_iface_api = {
41 .iface_api.init = test_iface_init,
42 .send = test_iface_send,
43 };
44
45 static struct ethernet_api dummy_eth_api = {
46 .iface_api.init = test_iface_init,
47 };
48
49 NET_DEVICE_INIT(test_if_simple_a,
50 "test_if_simple_a",
51 test_iface_netdev_init,
52 NULL,
53 NULL,
54 NULL,
55 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
56 &test_iface_api,
57 DUMMY_L2,
58 NET_L2_GET_CTX_TYPE(DUMMY_L2),
59 127);
60
61 NET_DEVICE_INIT(test_if_simple_b,
62 "test_if_simple_b",
63 test_iface_netdev_init,
64 NULL,
65 NULL,
66 NULL,
67 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
68 &test_iface_api,
69 DUMMY_L2,
70 NET_L2_GET_CTX_TYPE(DUMMY_L2),
71 127);
72
73 NET_DEVICE_INIT(test_if_connected_a,
74 "test_if_connected_a",
75 test_iface_netdev_init,
76 NULL,
77 NULL,
78 NULL,
79 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
80 &test_iface_api,
81 DUMMY_L2,
82 NET_L2_GET_CTX_TYPE(DUMMY_L2),
83 127);
84
85 NET_DEVICE_INIT(test_if_connected_b,
86 "test_if_connected_b",
87 test_iface_netdev_init,
88 NULL,
89 NULL,
90 NULL,
91 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
92 &test_iface_api,
93 DUMMY_L2,
94 NET_L2_GET_CTX_TYPE(DUMMY_L2),
95 127);
96
97 /* A dummy ETHERNET_L2 iface so that we can test L2 ignore.
98 * This iface is not properly defined, do not attempt to use it.
99 */
100 NET_DEVICE_INIT(test_if_dummy_eth,
101 "test_if_dummy_eth",
102 test_iface_netdev_init,
103 NULL,
104 NULL,
105 NULL,
106 CONFIG_ETH_INIT_PRIORITY,
107 &dummy_eth_api,
108 ETHERNET_L2,
109 NET_L2_GET_CTX_TYPE(ETHERNET_L2),
110 127);
111
112
test_conn_api_init(struct conn_mgr_conn_binding * const binding)113 static void test_conn_api_init(struct conn_mgr_conn_binding *const binding)
114 {
115 /* Mark the iface dormant (disconnected) on initialization */
116 net_if_dormant_on(binding->iface);
117 }
118
test_conn_api_connect(struct conn_mgr_conn_binding * const binding)119 static int test_conn_api_connect(struct conn_mgr_conn_binding *const binding)
120 {
121 /* Mark iface as connected */
122 net_if_dormant_off(binding->iface);
123 return 0;
124 }
125
test_conn_api_disconnect(struct conn_mgr_conn_binding * const binding)126 static int test_conn_api_disconnect(struct conn_mgr_conn_binding *const binding)
127 {
128 /* Mark iface as dormant (disconnected) */
129 net_if_dormant_on(binding->iface);
130 return 0;
131 }
132
133 static struct conn_mgr_conn_api test_conn_api = {
134 .init = test_conn_api_init,
135 .connect = test_conn_api_connect,
136 .disconnect = test_conn_api_disconnect,
137 };
138
139 /* Dummy struct */
140 struct test_conn_data {
141 };
142
143 #define TEST_CONN_IMPL_CTX_TYPE struct test_conn_data
144 CONN_MGR_CONN_DEFINE(TEST_CONN_IMPL, &test_conn_api);
145
146 /* Bind connectivity implementation to ifaces */
147 CONN_MGR_BIND_CONN(test_if_connected_a, TEST_CONN_IMPL);
148 CONN_MGR_BIND_CONN(test_if_connected_b, TEST_CONN_IMPL);
149
150
151 struct net_if *if_simp_a = NET_IF_GET(test_if_simple_a, 0);
152 struct net_if *if_simp_b = NET_IF_GET(test_if_simple_b, 0);
153 struct net_if *if_conn_a = NET_IF_GET(test_if_connected_a, 0);
154 struct net_if *if_conn_b = NET_IF_GET(test_if_connected_b, 0);
155 struct net_if *if_dummy_eth = NET_IF_GET(test_if_dummy_eth, 0);
156