1 /** @file 2 * @brief Ethernet Bridge public header file 3 * 4 * Ethernet Bridges connect two or more Ethernet networks together and 5 * transparently forward packets from one network to the others as if 6 * they were part of the same network. 7 */ 8 9 /* 10 * Copyright (c) 2021 BayLibre SAS 11 * 12 * SPDX-License-Identifier: Apache-2.0 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ 16 #define ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ 17 18 #include <sys/slist.h> 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 /** 25 * @brief Ethernet Bridging API 26 * @defgroup eth_bridge Ethernet Bridging API 27 * @ingroup networking 28 * @{ 29 */ 30 31 /** @cond INTERNAL_HIDDEN */ 32 33 struct eth_bridge { 34 struct k_mutex lock; 35 sys_slist_t interfaces; 36 sys_slist_t listeners; 37 }; 38 39 #define ETH_BRIDGE_INITIALIZER(obj) \ 40 { \ 41 .lock = { }, \ 42 .interfaces = SYS_SLIST_STATIC_INIT(&obj.interfaces), \ 43 .listeners = SYS_SLIST_STATIC_INIT(&obj.listeners), \ 44 } 45 46 /** @endcond */ 47 48 /** 49 * @brief Statically define and initialize a bridge instance. 50 * 51 * @param name Name of the bridge object 52 */ 53 #define ETH_BRIDGE_INIT(name) \ 54 STRUCT_SECTION_ITERABLE(eth_bridge, name) = \ 55 ETH_BRIDGE_INITIALIZER(name) 56 57 struct eth_bridge_iface_context { 58 sys_snode_t node; 59 struct eth_bridge *instance; 60 bool allow_tx; 61 }; 62 63 struct eth_bridge_listener { 64 sys_snode_t node; 65 struct k_fifo pkt_queue; 66 }; 67 68 /** 69 * @brief Add an Ethernet network interface to a bridge 70 * 71 * This adds a network interface to a bridge. The interface is then put 72 * into promiscuous mode, all packets received by this interface are sent 73 * to the bridge, and any other packets sent to the bridge (with some 74 * exceptions) are transmitted via this interface. 75 * 76 * For transmission from the bridge to occur via this interface, it is 77 * necessary to enable TX mode with eth_bridge_iface_tx(). TX mode is 78 * initially disabled. 79 * 80 * Once an interface is added to a bridge, all its incoming traffic is 81 * diverted to the bridge. However, packets sent out with net_if_queue_tx() 82 * via this interface are not subjected to the bridge. 83 * 84 * @param br A pointer to an initialized bridge object 85 * @param iface Interface to add 86 * 87 * @return 0 if OK, negative error code otherwise. 88 */ 89 int eth_bridge_iface_add(struct eth_bridge *br, struct net_if *iface); 90 91 /** 92 * @brief Remove an Ethernet network interface from a bridge 93 * 94 * @param br A pointer to an initialized bridge object 95 * @param iface Interface to remove 96 * 97 * @return 0 if OK, negative error code otherwise. 98 */ 99 int eth_bridge_iface_remove(struct eth_bridge *br, struct net_if *iface); 100 101 /** 102 * @brief Enable/disable transmission mode for a bridged interface 103 * 104 * When TX mode is off, the interface may receive packets and send them to 105 * the bridge but no packets coming from the bridge will be sent through this 106 * interface. When TX mode is on, both incoming and outgoing packets are 107 * allowed. 108 * 109 * @param iface Interface to configure 110 * @param allow true to activate TX mode, false otherwise 111 * 112 * @return 0 if OK, negative error code otherwise. 113 */ 114 int eth_bridge_iface_allow_tx(struct net_if *iface, bool allow); 115 116 /** 117 * @brief Add (register) a listener to the bridge 118 * 119 * This lets a software listener register a pointer to a provided FIFO for 120 * receiving packets sent to the bridge. The listener is responsible for 121 * emptying the FIFO with k_fifo_get() which will return a struct net_pkt 122 * pointer, and releasing the packet with net_pkt_unref() when done with it. 123 * 124 * The listener wishing not to receive any more packets should simply 125 * unregister itself with eth_bridge_listener_remove(). 126 * 127 * @param br A pointer to an initialized bridge object 128 * @param l A pointer to an initialized listener instance. 129 * 130 * @return 0 if OK, negative error code otherwise. 131 */ 132 int eth_bridge_listener_add(struct eth_bridge *br, struct eth_bridge_listener *l); 133 134 /** 135 * @brief Remove (unregister) a listener from the bridge 136 * 137 * @param br A pointer to an initialized bridge object 138 * @param l A pointer to the listener instance to be removed. 139 * 140 * @return 0 if OK, negative error code otherwise. 141 */ 142 int eth_bridge_listener_remove(struct eth_bridge *br, struct eth_bridge_listener *l); 143 144 /** 145 * @brief Get bridge index according to pointer 146 * 147 * @param br Pointer to bridge instance 148 * 149 * @return Bridge index 150 */ 151 int eth_bridge_get_index(struct eth_bridge *br); 152 153 /** 154 * @brief Get bridge instance according to index 155 * 156 * @param index Bridge instance index 157 * 158 * @return Pointer to bridge instance or NULL if not found. 159 */ 160 struct eth_bridge *eth_bridge_get_by_index(int index); 161 162 /** 163 * @typedef eth_bridge_cb_t 164 * @brief Callback used while iterating over bridge instances 165 * 166 * @param br Pointer to bridge instance 167 * @param user_data User supplied data 168 */ 169 typedef void (*eth_bridge_cb_t)(struct eth_bridge *br, void *user_data); 170 171 /** 172 * @brief Go through all the bridge instances in order to get 173 * information about them. This is mainly useful in 174 * net-shell to print data about currently active bridges. 175 * 176 * @param cb Callback to call for each bridge instance 177 * @param user_data User supplied data 178 */ 179 void net_eth_bridge_foreach(eth_bridge_cb_t cb, void *user_data); 180 181 /** 182 * @} 183 */ 184 185 #ifdef __cplusplus 186 } 187 #endif 188 189 #endif /* ZEPHYR_INCLUDE_NET_ETHERNET_BRIDGE_H_ */ 190