Line data Source code
1 1 : /** @file
2 : * @brief Virtual Network Interface
3 : */
4 :
5 : /*
6 : * Copyright (c) 2021 Intel Corporation
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : */
10 :
11 : #ifndef ZEPHYR_INCLUDE_NET_VIRTUAL_H_
12 : #define ZEPHYR_INCLUDE_NET_VIRTUAL_H_
13 :
14 : #include <zephyr/kernel.h>
15 : #include <zephyr/types.h>
16 : #include <stdbool.h>
17 : #include <zephyr/sys/atomic.h>
18 :
19 : #include <zephyr/net/net_ip.h>
20 : #include <zephyr/net/net_pkt.h>
21 :
22 : #include <zephyr/sys/util.h>
23 : #include <zephyr/net/net_if.h>
24 :
25 : #ifdef __cplusplus
26 : extern "C" {
27 : #endif
28 :
29 : /**
30 : * @brief Virtual network interface support functions
31 : * @defgroup virtual Virtual Network Interface Support Functions
32 : * @since 2.6
33 : * @version 0.8.0
34 : * @ingroup networking
35 : * @{
36 : */
37 :
38 : /** Virtual interface capabilities */
39 1 : enum virtual_interface_caps {
40 : /** IPIP tunnel */
41 : VIRTUAL_INTERFACE_IPIP = BIT(1),
42 :
43 : /** Virtual LAN interface (VLAN) */
44 : VIRTUAL_INTERFACE_VLAN = BIT(2),
45 :
46 : /** Virtual Ethernet bridge interface. */
47 : VIRTUAL_INTERFACE_BRIDGE = BIT(3),
48 :
49 : /** VPN interface */
50 : VIRTUAL_INTERFACE_VPN = BIT(4),
51 :
52 : /** @cond INTERNAL_HIDDEN */
53 : /* Marker for capabilities - must be at the end of the enum.
54 : * It is here because the capability list cannot be empty.
55 : */
56 : VIRTUAL_INTERFACE_NUM_CAPS
57 : /** @endcond */
58 : };
59 :
60 : /** @cond INTERNAL_HIDDEN */
61 :
62 : enum virtual_interface_config_type {
63 : VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS,
64 : VIRTUAL_INTERFACE_CONFIG_TYPE_MTU,
65 : VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE,
66 : VIRTUAL_INTERFACE_CONFIG_TYPE_PRIVATE_KEY,
67 : VIRTUAL_INTERFACE_CONFIG_TYPE_PUBLIC_KEY,
68 : };
69 :
70 : struct virtual_interface_link_types {
71 : int count;
72 : uint16_t type[COND_CODE_1(CONFIG_NET_CAPTURE_COOKED_MODE,
73 : (CONFIG_NET_CAPTURE_COOKED_MODE_MAX_LINK_TYPES),
74 : (1))];
75 : };
76 :
77 : #if !defined(NET_VIRTUAL_MAX_PUBLIC_KEY_LEN)
78 : #define NET_VIRTUAL_MAX_PUBLIC_KEY_LEN 32U
79 : #endif
80 :
81 : struct virtual_interface_config {
82 : sa_family_t family;
83 : union {
84 : struct in_addr peer4addr;
85 : struct in6_addr peer6addr;
86 : int mtu;
87 : struct virtual_interface_link_types link_types;
88 : struct {
89 : size_t len;
90 : uint8_t *data;
91 : } private_key;
92 : struct {
93 : size_t len;
94 : uint8_t data[NET_VIRTUAL_MAX_PUBLIC_KEY_LEN];
95 : } public_key;
96 : };
97 : };
98 :
99 : #if defined(CONFIG_NET_L2_VIRTUAL)
100 : #define VIRTUAL_MAX_NAME_LEN CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN
101 : #else
102 : #define VIRTUAL_MAX_NAME_LEN 0
103 : #endif
104 : /** @endcond */
105 :
106 : /** Virtual L2 API operations. */
107 1 : struct virtual_interface_api {
108 : /**
109 : * The net_if_api must be placed in first position in this
110 : * struct so that we are compatible with network interface API.
111 : */
112 1 : struct net_if_api iface_api;
113 :
114 : /** Get the virtual interface capabilities */
115 : enum virtual_interface_caps (*get_capabilities)(struct net_if *iface);
116 :
117 : /** Start the device */
118 1 : int (*start)(const struct device *dev);
119 :
120 : /** Stop the device */
121 1 : int (*stop)(const struct device *dev);
122 :
123 : /** Send a network packet */
124 1 : int (*send)(struct net_if *iface, struct net_pkt *pkt);
125 :
126 : /**
127 : * Receive a network packet.
128 : * The callback returns NET_OK if this interface will accept the
129 : * packet and pass it upper layers, NET_DROP if the packet is to be
130 : * dropped and NET_CONTINUE to pass it to next interface.
131 : */
132 : enum net_verdict (*recv)(struct net_if *iface, struct net_pkt *pkt);
133 :
134 : /** Pass the attachment information to virtual interface */
135 1 : int (*attach)(struct net_if *virtual_iface, struct net_if *iface);
136 :
137 : /** Set specific L2 configuration */
138 1 : int (*set_config)(struct net_if *iface,
139 : enum virtual_interface_config_type type,
140 : const struct virtual_interface_config *config);
141 :
142 : /** Get specific L2 configuration */
143 1 : int (*get_config)(struct net_if *iface,
144 : enum virtual_interface_config_type type,
145 : struct virtual_interface_config *config);
146 : };
147 :
148 : /* Make sure that the network interface API is properly setup inside
149 : * Virtual API struct (it is the first one).
150 : */
151 : BUILD_ASSERT(offsetof(struct virtual_interface_api, iface_api) == 0);
152 :
153 : /** Virtual L2 context that is needed to binding to the real network interface
154 : */
155 1 : struct virtual_interface_context {
156 : /** @cond INTERNAL_HIDDEN */
157 : /* Keep track of contexts */
158 : sys_snode_t node;
159 :
160 : /* My virtual network interface */
161 : struct net_if *virtual_iface;
162 : /** @endcond */
163 :
164 : /**
165 : * Other network interface this virtual network interface is
166 : * attached to. These values can be chained so virtual network
167 : * interfaces can run on top of other virtual interfaces.
168 : */
169 1 : struct net_if *iface;
170 :
171 : /**
172 : * This tells what L2 features does virtual support.
173 : */
174 1 : enum net_l2_flags virtual_l2_flags;
175 :
176 : /** Is this context already initialized */
177 1 : bool is_init;
178 :
179 : /** Link address for this network interface */
180 1 : struct net_linkaddr lladdr;
181 :
182 : /** User friendly name of this L2 layer. */
183 1 : char name[VIRTUAL_MAX_NAME_LEN];
184 : };
185 :
186 : /**
187 : * @brief Attach virtual network interface to the given network interface.
188 : *
189 : * @param virtual_iface Virtual network interface.
190 : * @param iface Network interface we are attached to. This can be NULL,
191 : * if we want to detach.
192 : *
193 : * @return 0 if ok, <0 if attaching failed
194 : */
195 1 : int net_virtual_interface_attach(struct net_if *virtual_iface,
196 : struct net_if *iface);
197 :
198 : /**
199 : * @brief Return network interface related to this virtual network interface.
200 : * The returned network interface is below this virtual network interface.
201 : *
202 : * @param iface Virtual network interface.
203 : *
204 : * @return Network interface related to this virtual interface or
205 : * NULL if no such interface exists.
206 : */
207 1 : struct net_if *net_virtual_get_iface(struct net_if *iface);
208 :
209 : /**
210 : * @brief Return the name of the virtual network interface L2.
211 : *
212 : * @param iface Virtual network interface.
213 : * @param buf Buffer to store the name
214 : * @param len Max buffer length
215 : *
216 : * @return Name of the virtual network interface.
217 : */
218 1 : char *net_virtual_get_name(struct net_if *iface, char *buf, size_t len);
219 :
220 : /**
221 : * @brief Set the name of the virtual network interface L2.
222 : *
223 : * @param iface Virtual network interface.
224 : * @param name Name of the virtual L2 layer.
225 : */
226 1 : void net_virtual_set_name(struct net_if *iface, const char *name);
227 :
228 : /**
229 : * @brief Set the L2 flags of the virtual network interface.
230 : *
231 : * @param iface Virtual network interface.
232 : * @param flags L2 flags to set.
233 : *
234 : * @return Previous flags that were set.
235 : */
236 1 : enum net_l2_flags net_virtual_set_flags(struct net_if *iface,
237 : enum net_l2_flags flags);
238 :
239 : /**
240 : * @brief Feed the IP pkt to stack if tunneling is enabled.
241 : *
242 : * @param input_iface Network interface receiving the pkt.
243 : * @param remote_addr IP address of the sender.
244 : * @param pkt Network packet.
245 : *
246 : * @return Verdict what to do with the packet.
247 : */
248 1 : enum net_verdict net_virtual_input(struct net_if *input_iface,
249 : struct net_addr *remote_addr,
250 : struct net_pkt *pkt);
251 :
252 : /** @cond INTERNAL_HIDDEN */
253 :
254 : /**
255 : * @brief Initialize the network interface so that a virtual
256 : * interface can be attached to it.
257 : *
258 : * @param iface Network interface
259 : */
260 : #if defined(CONFIG_NET_L2_VIRTUAL)
261 : void net_virtual_init(struct net_if *iface);
262 : #else
263 : static inline void net_virtual_init(struct net_if *iface)
264 : {
265 : ARG_UNUSED(iface);
266 : }
267 : #endif
268 :
269 : /**
270 : * @brief Update the carrier state of the virtual network interface.
271 : * This is called if the underlying interface is going down.
272 : *
273 : * @param iface Network interface
274 : */
275 : #if defined(CONFIG_NET_L2_VIRTUAL)
276 : void net_virtual_disable(struct net_if *iface);
277 : #else
278 : static inline void net_virtual_disable(struct net_if *iface)
279 : {
280 : ARG_UNUSED(iface);
281 : }
282 : #endif
283 :
284 : /**
285 : * @brief Update the carrier state of the virtual network interface.
286 : * This is called if the underlying interface is going up.
287 : *
288 : * @param iface Network interface
289 : */
290 : #if defined(CONFIG_NET_L2_VIRTUAL)
291 : void net_virtual_enable(struct net_if *iface);
292 : #else
293 : static inline void net_virtual_enable(struct net_if *iface)
294 : {
295 : ARG_UNUSED(iface);
296 : }
297 : #endif
298 :
299 : #define VIRTUAL_L2_CTX_TYPE struct virtual_interface_context
300 :
301 : /**
302 : * @brief Return virtual device hardware capability information.
303 : *
304 : * @param iface Network interface
305 : *
306 : * @return Hardware capabilities
307 : */
308 : static inline enum virtual_interface_caps
309 : net_virtual_get_iface_capabilities(struct net_if *iface)
310 : {
311 : const struct virtual_interface_api *virt =
312 : (struct virtual_interface_api *)net_if_get_device(iface)->api;
313 :
314 : if (!virt->get_capabilities) {
315 : return (enum virtual_interface_caps)0;
316 : }
317 :
318 : return virt->get_capabilities(iface);
319 : }
320 :
321 : #define Z_NET_VIRTUAL_INTERFACE_INIT(node_id, dev_id, name, init_fn, \
322 : pm, data, config, prio, api, mtu) \
323 : Z_NET_DEVICE_INIT(node_id, dev_id, name, init_fn, pm, data, \
324 : config, prio, api, VIRTUAL_L2, \
325 : NET_L2_GET_CTX_TYPE(VIRTUAL_L2), mtu)
326 :
327 : #define Z_NET_VIRTUAL_INTERFACE_INIT_INSTANCE(node_id, dev_id, name, \
328 : inst, init_fn, pm, data, \
329 : config, prio, api, mtu) \
330 : Z_NET_DEVICE_INIT_INSTANCE(node_id, dev_id, name, inst, \
331 : init_fn, pm, data, \
332 : config, prio, api, VIRTUAL_L2, \
333 : NET_L2_GET_CTX_TYPE(VIRTUAL_L2), mtu)
334 : /** @endcond */
335 :
336 : /**
337 : * @brief Create a virtual network interface. Binding to another interface
338 : * is done at runtime by calling net_virtual_interface_attach().
339 : * The attaching is done automatically when setting up tunneling
340 : * when peer IP address is set in IP tunneling driver.
341 : *
342 : * @param dev_id Network device id.
343 : * @param name The name this instance of the driver exposes to
344 : * the system.
345 : * @param init_fn Address to the init function of the driver.
346 : * @param pm Reference to struct pm_device associated with the device.
347 : * (optional).
348 : * @param data Pointer to the device's private data.
349 : * @param config The address to the structure containing the
350 : * configuration information for this instance of the driver.
351 : * @param prio The initialization level at which configuration occurs.
352 : * @param api Provides an initial pointer to the API function struct
353 : * used by the driver. Can be NULL.
354 : * @param mtu Maximum transfer unit in bytes for this network interface.
355 : * This is the default value and its value can be tweaked at runtime.
356 : */
357 : #define NET_VIRTUAL_INTERFACE_INIT(dev_id, name, init_fn, pm, data, \
358 1 : config, prio, api, mtu) \
359 : Z_NET_VIRTUAL_INTERFACE_INIT(DT_INVALID_NODE, dev_id, name, \
360 : init_fn, pm, data, config, prio, \
361 : api, mtu)
362 :
363 : /**
364 : * @brief Create a virtual network interface. Binding to another interface
365 : * is done at runtime by calling net_virtual_interface_attach().
366 : * The attaching is done automatically when setting up tunneling
367 : * when peer IP address is set in IP tunneling driver.
368 : *
369 : * @param dev_id Network device id.
370 : * @param name The name this instance of the driver exposes to
371 : * the system.
372 : * @param inst instance number
373 : * @param init_fn Address to the init function of the driver.
374 : * @param pm Reference to struct pm_device associated with the device.
375 : * (optional).
376 : * @param data Pointer to the device's private data.
377 : * @param config The address to the structure containing the
378 : * configuration information for this instance of the driver.
379 : * @param prio The initialization level at which configuration occurs.
380 : * @param api Provides an initial pointer to the API function struct
381 : * used by the driver. Can be NULL.
382 : * @param mtu Maximum transfer unit in bytes for this network interface.
383 : * This is the default value and its value can be tweaked at runtime.
384 : */
385 : #define NET_VIRTUAL_INTERFACE_INIT_INSTANCE(dev_id, name, inst, \
386 : init_fn, pm, data, \
387 1 : config, prio, api, mtu) \
388 : Z_NET_VIRTUAL_INTERFACE_INIT_INSTANCE(DT_INVALID_NODE, dev_id, \
389 : name, inst, \
390 : init_fn, pm, data, config, \
391 : prio, api, mtu)
392 :
393 : /**
394 : * @}
395 : */
396 :
397 : #ifdef __cplusplus
398 : }
399 : #endif
400 :
401 : #endif /* ZEPHYR_INCLUDE_NET_VIRTUAL_H_ */
|