LCOV - code coverage report
Current view: top level - zephyr/net - virtual.h Coverage Total Hit
Test: new.info Lines: 100.0 % 24 24
Test Date: 2025-09-05 22:20:39

            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_ */
        

Generated by: LCOV version 2.0-1