LCOV - code coverage report
Current view: top level - zephyr/net - virtual.h Hit Total Coverage
Test: new.info Lines: 24 24 100.0 %
Date: 2024-12-22 00:14:23

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

Generated by: LCOV version 1.14