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 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 	net_sa_family_t family;
83 	union {
84 		struct net_in_addr peer4addr;
85 		struct net_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 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 	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 	int (*start)(const struct device *dev);
119 
120 	/** Stop the device */
121 	int (*stop)(const struct device *dev);
122 
123 	/** Send a network packet */
124 	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 	int (*attach)(struct net_if *virtual_iface, struct net_if *iface);
136 
137 	/** Set specific L2 configuration */
138 	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 	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 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 	struct net_if *iface;
170 
171 	/**
172 	 * This tells what L2 features does virtual support.
173 	 */
174 	enum net_l2_flags virtual_l2_flags;
175 
176 	/** Is this context already initialized */
177 	bool is_init;
178 
179 	/** Link address for this network interface */
180 	struct net_linkaddr lladdr;
181 
182 	/** User friendly name of this L2 layer. */
183 	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 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 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 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 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 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 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
net_virtual_init(struct net_if * iface)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
net_virtual_disable(struct net_if * iface)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
net_virtual_enable(struct net_if * iface)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
net_virtual_get_iface_capabilities(struct net_if * iface)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 				   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 					    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_ */
402