1 /*
2 * SPDX-FileCopyrightText: Copyright 2025 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_bridge_sample, CONFIG_NET_L2_ETHERNET_LOG_LEVEL);
9
10 #include <zephyr/net/ethernet_bridge.h>
11
12 struct ud {
13 struct net_if *bridge;
14 struct net_if *iface[CONFIG_NET_ETHERNET_BRIDGE_ETH_INTERFACE_COUNT];
15 #if defined(CONFIG_NET_MGMT_EVENT) && defined(CONFIG_NET_DHCPV4)
16 struct net_mgmt_event_callback mgmt_cb;
17 #endif
18 };
19
20 struct ud g_user_data = {0};
21
bridge_find_cb(struct eth_bridge_iface_context * br,void * user_data)22 static void bridge_find_cb(struct eth_bridge_iface_context *br, void *user_data)
23 {
24 struct ud *u = user_data;
25
26 if (u->bridge == NULL) {
27 u->bridge = br->iface;
28 LOG_INF("Find bridge iface %d.", net_if_get_by_iface(br->iface));
29 }
30 }
31
bridge_add_iface_cb(struct net_if * iface,void * user_data)32 static void bridge_add_iface_cb(struct net_if *iface, void *user_data)
33 {
34 #if defined(CONFIG_NET_DSA) && !defined(CONFIG_NET_DSA_DEPRECATED)
35 struct ethernet_context *eth_ctx;
36 #endif
37 struct ud *u = user_data;
38 int i;
39
40 for (i = 0; i < CONFIG_NET_ETHERNET_BRIDGE_ETH_INTERFACE_COUNT; i++) {
41 if (u->iface[i] == NULL) {
42 break;
43 }
44 }
45
46 if (i == CONFIG_NET_ETHERNET_BRIDGE_ETH_INTERFACE_COUNT) {
47 return;
48 }
49
50 if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
51 return;
52 }
53
54 #if defined(CONFIG_NET_DSA) && !defined(CONFIG_NET_DSA_DEPRECATED)
55 eth_ctx = net_if_l2_data(iface);
56
57 if (eth_ctx->dsa_port == DSA_USER_PORT || eth_ctx->dsa_port == NON_DSA_PORT) {
58 u->iface[i] = iface;
59 }
60 #else
61 u->iface[i] = iface;
62 #endif
63 eth_bridge_iface_add(u->bridge, iface);
64 LOG_INF("Find iface %d. Add into bridge.", net_if_get_by_iface(iface));
65 }
66
67 #if defined(CONFIG_NET_MGMT_EVENT) && defined(CONFIG_NET_DHCPV4)
event_handler(struct net_mgmt_event_callback * cb,uint64_t mgmt_event,struct net_if * iface)68 static void event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event,
69 struct net_if *iface)
70 {
71 struct ethernet_context *eth_ctx;
72
73 ARG_UNUSED(cb);
74
75 if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
76 return;
77 }
78
79 eth_ctx = net_if_l2_data(iface);
80
81 if (net_eth_iface_is_bridged(eth_ctx) && mgmt_event == NET_EVENT_IF_UP) {
82 net_dhcpv4_restart(net_eth_get_bridge(eth_ctx));
83 return;
84 }
85 }
86 #endif
87
main(void)88 int main(void)
89 {
90 struct ud *u = &g_user_data;
91
92 net_eth_bridge_foreach(bridge_find_cb, u);
93 net_if_foreach(bridge_add_iface_cb, u);
94 net_if_up(u->bridge);
95 #if defined(CONFIG_NET_MGMT_EVENT) && defined(CONFIG_NET_DHCPV4)
96 net_mgmt_init_event_callback(&u->mgmt_cb, event_handler, NET_EVENT_IF_UP);
97 net_mgmt_add_event_callback(&u->mgmt_cb);
98 #endif
99 return 0;
100 }
101