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