| /** @file |
| * @brief Ethernet Bridge public header file |
| * |
| * Ethernet Bridges connect two or more Ethernet networks together and |
| * transparently forward packets from one network to the others as if |
| * they were part of the same network. |
| */ |
| |
| /* |
| * Copyright (c) 2021 BayLibre SAS |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ |
| #define ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ |
| |
| #include <sys/slist.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * @brief Ethernet Bridging API |
| * @defgroup eth_bridge Ethernet Bridging API |
| * @ingroup networking |
| * @{ |
| */ |
| |
| /** @cond INTERNAL_HIDDEN */ |
| |
| struct eth_bridge { |
| struct k_mutex lock; |
| sys_slist_t interfaces; |
| sys_slist_t listeners; |
| }; |
| |
| #define ETH_BRIDGE_INITIALIZER(obj) \ |
| { \ |
| .lock = { }, \ |
| .interfaces = SYS_SLIST_STATIC_INIT(&obj.interfaces), \ |
| .listeners = SYS_SLIST_STATIC_INIT(&obj.listeners), \ |
| } |
| |
| /** @endcond */ |
| |
| /** |
| * @brief Statically define and initialize a bridge instance. |
| * |
| * @param name Name of the bridge object |
| */ |
| #define ETH_BRIDGE_INIT(name) \ |
| STRUCT_SECTION_ITERABLE(eth_bridge, name) = \ |
| ETH_BRIDGE_INITIALIZER(name) |
| |
| struct eth_bridge_iface_context { |
| sys_snode_t node; |
| struct eth_bridge *instance; |
| bool allow_tx; |
| }; |
| |
| struct eth_bridge_listener { |
| sys_snode_t node; |
| struct k_fifo pkt_queue; |
| }; |
| |
| /** |
| * @brief Add an Ethernet network interface to a bridge |
| * |
| * This adds a network interface to a bridge. The interface is then put |
| * into promiscuous mode, all packets received by this interface are sent |
| * to the bridge, and any other packets sent to the bridge (with some |
| * exceptions) are transmitted via this interface. |
| * |
| * For transmission from the bridge to occur via this interface, it is |
| * necessary to enable TX mode with eth_bridge_iface_tx(). TX mode is |
| * initially disabled. |
| * |
| * Once an interface is added to a bridge, all its incoming traffic is |
| * diverted to the bridge. However, packets sent out with net_if_queue_tx() |
| * via this interface are not subjected to the bridge. |
| * |
| * @param br A pointer to an initialized bridge object |
| * @param iface Interface to add |
| * |
| * @return 0 if OK, negative error code otherwise. |
| */ |
| int eth_bridge_iface_add(struct eth_bridge *br, struct net_if *iface); |
| |
| /** |
| * @brief Remove an Ethernet network interface from a bridge |
| * |
| * @param br A pointer to an initialized bridge object |
| * @param iface Interface to remove |
| * |
| * @return 0 if OK, negative error code otherwise. |
| */ |
| int eth_bridge_iface_remove(struct eth_bridge *br, struct net_if *iface); |
| |
| /** |
| * @brief Enable/disable transmission mode for a bridged interface |
| * |
| * When TX mode is off, the interface may receive packets and send them to |
| * the bridge but no packets coming from the bridge will be sent through this |
| * interface. When TX mode is on, both incoming and outgoing packets are |
| * allowed. |
| * |
| * @param iface Interface to configure |
| * @param allow true to activate TX mode, false otherwise |
| * |
| * @return 0 if OK, negative error code otherwise. |
| */ |
| int eth_bridge_iface_allow_tx(struct net_if *iface, bool allow); |
| |
| /** |
| * @brief Add (register) a listener to the bridge |
| * |
| * This lets a software listener register a pointer to a provided FIFO for |
| * receiving packets sent to the bridge. The listener is responsible for |
| * emptying the FIFO with k_fifo_get() which will return a struct net_pkt |
| * pointer, and releasing the packet with net_pkt_unref() when done with it. |
| * |
| * The listener wishing not to receive any more packets should simply |
| * unregister itself with eth_bridge_listener_remove(). |
| * |
| * @param br A pointer to an initialized bridge object |
| * @param l A pointer to an initialized listener instance. |
| * |
| * @return 0 if OK, negative error code otherwise. |
| */ |
| int eth_bridge_listener_add(struct eth_bridge *br, struct eth_bridge_listener *l); |
| |
| /** |
| * @brief Remove (unregister) a listener from the bridge |
| * |
| * @param br A pointer to an initialized bridge object |
| * @param l A pointer to the listener instance to be removed. |
| * |
| * @return 0 if OK, negative error code otherwise. |
| */ |
| int eth_bridge_listener_remove(struct eth_bridge *br, struct eth_bridge_listener *l); |
| |
| /** |
| * @brief Get bridge index according to pointer |
| * |
| * @param br Pointer to bridge instance |
| * |
| * @return Bridge index |
| */ |
| int eth_bridge_get_index(struct eth_bridge *br); |
| |
| /** |
| * @brief Get bridge instance according to index |
| * |
| * @param index Bridge instance index |
| * |
| * @return Pointer to bridge instance or NULL if not found. |
| */ |
| struct eth_bridge *eth_bridge_get_by_index(int index); |
| |
| /** |
| * @typedef eth_bridge_cb_t |
| * @brief Callback used while iterating over bridge instances |
| * |
| * @param br Pointer to bridge instance |
| * @param user_data User supplied data |
| */ |
| typedef void (*eth_bridge_cb_t)(struct eth_bridge *br, void *user_data); |
| |
| /** |
| * @brief Go through all the bridge instances in order to get |
| * information about them. This is mainly useful in |
| * net-shell to print data about currently active bridges. |
| * |
| * @param cb Callback to call for each bridge instance |
| * @param user_data User supplied data |
| */ |
| void net_eth_bridge_foreach(eth_bridge_cb_t cb, void *user_data); |
| |
| /** |
| * @} |
| */ |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ */ |