Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions subsys/net/l2/openthread/openthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,12 @@ static int openthread_l2_init(struct net_if *iface)
ot_l2_context->iface = iface;

if (!IS_ENABLED(CONFIG_OPENTHREAD_COPROCESSOR)) {
net_mgmt_init_event_callback(&ip6_addr_cb, ipv6_addr_event_handler,
NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_MADDR_ADD);
net_mgmt_add_event_callback(&ip6_addr_cb);
if (!IS_ENABLED(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER)) {
net_mgmt_init_event_callback(&ip6_addr_cb, ipv6_addr_event_handler,
NET_EVENT_IPV6_ADDR_ADD |
NET_EVENT_IPV6_MADDR_ADD);
net_mgmt_add_event_callback(&ip6_addr_cb);
}
net_if_dormant_on(iface);

openthread_set_receive_cb(ot_receive_handler, (void *)ot_l2_context);
Expand Down
79 changes: 74 additions & 5 deletions subsys/net/l2/openthread/openthread_border_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <ipv6.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/openthread.h>
#include <zephyr/sys/util.h>

#include <inttypes.h>
#include <stdarg.h>
Expand All @@ -38,6 +39,7 @@ static struct net_mgmt_event_callback ail_net_event_ipv4_addr_add_cb;
#endif /* CONFIG_NET_IPV4 */
static uint32_t ail_iface_index;
static struct net_if *ail_iface_ptr;
static struct net_if *ot_iface_ptr;
static bool is_border_router_started;
char otbr_vendor_name[] = OTBR_VENDOR_NAME;
char otbr_base_service_instance_name[] = OTBR_BASE_SERVICE_INSTANCE_NAME;
Expand All @@ -53,6 +55,7 @@ K_MEM_SLAB_DEFINE_STATIC(border_router_messages_slab, sizeof(struct otbr_msg_ctx
CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER_MSG_POOL_NUM, sizeof(void *));

static const char *create_base_name(otInstance *ot_instance, char *base_name);
static void openthread_border_router_add_route_to_multicast_groups(void);

#if defined(CONFIG_NET_IPV4)
static void openthread_border_router_check_for_dhcpv4_addr(struct net_if *iface,
Expand All @@ -66,8 +69,12 @@ int openthread_start_border_router_services(struct net_if *ot_iface, struct net_
otInstance *instance = openthread_get_default_instance();
ail_iface_index = (uint32_t)net_if_get_by_iface(ail_iface);
ail_iface_ptr = ail_iface;
ot_iface_ptr = ot_iface;

net_if_flag_set(ot_iface, NET_IF_FORWARD_MULTICASTS);
net_if_flag_set(ail_iface, NET_IF_FORWARD_MULTICASTS);

openthread_border_router_add_route_to_multicast_groups();

openthread_mutex_lock();

Expand Down Expand Up @@ -266,19 +273,43 @@ static void ot_bbr_multicast_listener_handler(void *context,
otBackboneRouterMulticastListenerEvent event,
const otIp6Address *address)
{
struct openthread_context *ot_context = context;
struct in6_addr mcast_prefix = {0};
struct openthread_context *ot_context = (struct openthread_context *)context;
struct in6_addr recv_addr = {0};
struct net_if_mcast_addr *mcast_addr = NULL;
struct net_route_entry_mcast *entry = NULL;

memcpy(mcast_prefix.s6_addr, address->mFields.m32, sizeof(otIp6Address));
memcpy(recv_addr.s6_addr, address->mFields.m32, sizeof(otIp6Address));

if (event == OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED) {
net_route_mcast_add((struct net_if *)ot_context->iface, &mcast_prefix, 16);
entry = net_route_mcast_lookup(&recv_addr);
if (entry == NULL) {
entry = net_route_mcast_add(ot_context->iface, &recv_addr,
NUM_BITS(struct in6_addr));
}
if (entry != NULL) {
/*
* No need to perform mcast_lookup explicitly as it's already done in
* net_if_ipv6_maddr_add call. If it's found, NULL will be returned
* and maddr_join will not be performed.
*/
mcast_addr = net_if_ipv6_maddr_add(ot_context->iface,
(const struct in6_addr *)&recv_addr);
if (mcast_addr != NULL) {
net_if_ipv6_maddr_join(ot_context->iface, mcast_addr);
}
}
} else {
struct net_route_entry_mcast *route_to_del = net_route_mcast_lookup(&mcast_prefix);
struct net_route_entry_mcast *route_to_del = net_route_mcast_lookup(&recv_addr);
struct net_if_mcast_addr *addr_to_del;

addr_to_del = net_if_ipv6_maddr_lookup(&recv_addr, &(ot_context->iface));
if (route_to_del != NULL) {
net_route_mcast_del(route_to_del);
}

if (addr_to_del != NULL && net_if_ipv6_maddr_is_joined(addr_to_del)) {
net_if_ipv6_maddr_leave(ot_context->iface, addr_to_del);
}
}
}

Expand Down Expand Up @@ -479,6 +510,18 @@ static bool openthread_border_router_check_unicast_packet_forwarding_policy(stru
return false;
}

/*
* This is the case when a packet from OpenThread stack is sent via UDP platform.
* Packet will be eventually returned to OpenThread interface, but it won't have
* orig_iface set, an indication that the packet was not forwarded from another interface.
* In this case, this function should not check and let the packet be handled by
* 15.4 layer.
*/

if (net_pkt_orig_iface(pkt) != ail_iface_ptr && net_pkt_iface(pkt) == ot_iface_ptr) {
return true;
}

/* An IPv6 packet with a link-local source address or a link-local destination address
* is never forwarded.
*/
Expand Down Expand Up @@ -536,3 +579,29 @@ bool openthread_border_router_check_packet_forwarding_rules(struct net_pkt *pkt)

return true;
}

static void openthread_border_router_add_route_to_multicast_groups(void)
{
static uint8_t mcast_group_idx[] = {
0x04, /** Admin-Local scope multicast address */
0x05, /** Site-Local scope multicast address */
0x08, /** Organization-Local scope multicast address */
0x0e, /** Global scope multicast address */
Comment on lines +586 to +589
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately we need to have one more round. If you use this style, then the comment needs to be written with < so like this

		0x04, /**< Admin-Local scope multicast address */
		0x05, /**< Site-Local scope multicast address */
		0x08, /**< Organization-Local scope multicast address */
		0x0e, /**< Global scope multicast address */

otherwise the comment in documentation refers to the next line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this even parsed for documentation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, very good point. In that case we could just say /* xxxx */ without doxygen comment. If we keep doxygen comment, and want to document this, then we should do /**< xxxx */.
Anyway, as this is in .c file, it does not matter much, I was a bit too pedantic here.

};
struct in6_addr addr = {0};
struct net_if_mcast_addr *mcast_addr = NULL;
struct net_route_entry_mcast *entry = NULL;

ARRAY_FOR_EACH(mcast_group_idx, i) {

net_ipv6_addr_create(&addr, (0xff << 8) | mcast_group_idx[i], 0, 0, 0, 0, 0, 0, 1);
entry = net_route_mcast_add(ail_iface_ptr, &addr, NUM_BITS(struct in6_addr));
if (entry != NULL) {
mcast_addr = net_if_ipv6_maddr_add(ail_iface_ptr,
(const struct in6_addr *)&addr);
if (mcast_addr != NULL) {
net_if_ipv6_maddr_join(ail_iface_ptr, mcast_addr);
}
}
}
}