net: ethernet: bridging support
This adds the ability to create Ethernet bridges for connecting separate Ethernet segments together to appear as a single Ethernet network. This mimics the Linux functionality of the same name. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
d3f6b54f8e
commit
89482f0119
11 changed files with 519 additions and 3 deletions
|
@ -30,6 +30,7 @@ LOG_MODULE_REGISTER(net_ethernet, CONFIG_NET_L2_ETHERNET_LOG_LEVEL);
|
|||
#include "net_private.h"
|
||||
#include "ipv6.h"
|
||||
#include "ipv4_autoconf_internal.h"
|
||||
#include "bridge.h"
|
||||
|
||||
#define NET_BUF_TIMEOUT K_MSEC(100)
|
||||
|
||||
|
@ -187,6 +188,19 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
|
|||
goto drop;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE) &&
|
||||
net_eth_iface_is_bridged(ctx)) {
|
||||
net_pkt_set_l2_bridged(pkt, true);
|
||||
net_pkt_lladdr_src(pkt)->addr = hdr->src.addr;
|
||||
net_pkt_lladdr_src(pkt)->len = sizeof(struct net_eth_addr);
|
||||
net_pkt_lladdr_src(pkt)->type = NET_LINK_ETHERNET;
|
||||
net_pkt_lladdr_dst(pkt)->addr = hdr->dst.addr;
|
||||
net_pkt_lladdr_dst(pkt)->len = sizeof(struct net_eth_addr);
|
||||
net_pkt_lladdr_dst(pkt)->type = NET_LINK_ETHERNET;
|
||||
ethernet_update_rx_stats(iface, pkt, net_pkt_get_len(pkt));
|
||||
return net_eth_bridge_input(ctx, pkt);
|
||||
}
|
||||
|
||||
type = ntohs(hdr->type);
|
||||
|
||||
if (net_eth_is_vlan_enabled(ctx, iface) &&
|
||||
|
@ -578,7 +592,19 @@ static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4) &&
|
||||
if (IS_ENABLED(CONFIG_NET_ETHERNET_BRIDGE) &&
|
||||
net_pkt_is_l2_bridged(pkt)) {
|
||||
net_pkt_cursor_init(pkt);
|
||||
ret = net_l2_send(api->send, net_if_get_device(iface), iface, pkt);
|
||||
if (ret != 0) {
|
||||
eth_stats_update_errors_tx(iface);
|
||||
goto error;
|
||||
}
|
||||
ethernet_update_tx_stats(iface, pkt);
|
||||
ret = net_pkt_get_len(pkt);
|
||||
net_pkt_unref(pkt);
|
||||
return ret;
|
||||
} else if (IS_ENABLED(CONFIG_NET_IPV4) &&
|
||||
net_pkt_family(pkt) == AF_INET) {
|
||||
struct net_pkt *tmp;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue