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