Skip to content

Commit f836a9e

Browse files
Cristib05fabiobaltieri
authored andcommitted
modules: openthread: platform: Add DHCP6_PD socket and DNS resolver
Implemented DHCP6_PD platform code required by OpenThread stack. Fixed some typos added at OpenThread stack rebase. Implemented DNS upstream resolver platform code. Signed-off-by: Cristian Bulacu <[email protected]>
1 parent 90286fc commit f836a9e

File tree

5 files changed

+399
-2
lines changed

5 files changed

+399
-2
lines changed

modules/openthread/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTER OT_BORDER_ROUTER "Enable Bo
5555
kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING OT_BORDER_ROUTING "Enable Border routing")
5656
kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_COUNTERS OT_BORDER_ROUTING_COUNTERS "Enable Border routing counters")
5757
kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD OT_BORDER_ROUTING_DHCP6_PD "DHCPv6-PD support in border routing")
58-
kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD_CLIENT OT_BORDER_ROUTING_DHCP6_PD_CLIENT, "DHCPv6-PD client support in border routing")
58+
kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD_CLIENT OT_BORDER_ROUTING_DHCP6_PD_CLIENT "DHCPv6-PD client support in border routing")
5959
kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MANAGER OT_CHANNEL_MANAGER "Enable channel manager support")
6060
kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MANAGER_CSL OT_CHANNEL_MANAGER_CSL "Channel manager for CSL channel")
6161
kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MONITOR OT_CHANNEL_MONITOR "Enable channel monitor support")
@@ -127,7 +127,7 @@ kconfig_to_ot_option(CONFIG_OPENTHREAD_SNTP_CLIENT OT_SNTP_CLIENT "Enable SNTP C
127127
kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_ADV_PROXY OT_SRP_ADV_PROXY "Enable SRP Server Advertising Proxy support")
128128
kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_CLIENT OT_SRP_CLIENT "Enable SRP Client support")
129129
kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_SERVER OT_SRP_SERVER "Enable SRP Server support")
130-
kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_SERVER_FAST_START OT_SRP_SERVER_FAST_START_MDOE "Enable SRP server fast start")
130+
kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_SERVER_FAST_START OT_SRP_SERVER_FAST_START_MODE "Enable SRP server fast start")
131131
kconfig_to_ot_option(CONFIG_OPENTHREAD_TCP_ENABLE OT_TCP "Enable TCP support")
132132
kconfig_to_ot_option(CONFIG_OPENTHREAD_TIME_SYNC OT_TIME_SYNC "Enable the time synchronization service feature")
133133
kconfig_to_ot_option(CONFIG_OPENTHREAD_TREL OT_TREL "Enable TREL radio link for Thread over Infrastructure feature")

modules/openthread/platform/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER udp.c)
3333
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER mdns_socket.c)
3434
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER border_agent.c)
3535
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER trel.c)
36+
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER dhcp6_pd.c)
37+
zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER dns_upstream_resolver.c)
3638

3739
zephyr_include_directories(.)
3840

3941
if(CONFIG_OPENTHREAD_ZEPHYR_BORDER_ROUTER)
4042
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
4143
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/lib/sockets)
4244
zephyr_include_directories(${ZEPHYR_BASE}/subsys/net/l2/openthread)
45+
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/lib/dns)
4346
endif()
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright 2025 NXP
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "openthread/instance.h"
8+
#include "openthread/ip6.h"
9+
#include "openthread_border_router.h"
10+
#include <common/code_utils.hpp>
11+
#include <openthread/platform/infra_if.h>
12+
#include <zephyr/posix/sys/socket.h>
13+
#include <zephyr/net/socket_service.h>
14+
#include <zephyr/net/net_if.h>
15+
#include <zephyr/net/net_ip.h>
16+
#include "sockets_internal.h"
17+
18+
#define DHCPV6_SERVER_PORT 547
19+
#define DHCPV6_CLIENT_PORT 546
20+
#define DHCPV6_PD_CLIENT_NUM_SERVICES 1
21+
22+
static struct zsock_pollfd sockfd_udp[DHCPV6_PD_CLIENT_NUM_SERVICES];
23+
static struct otInstance *ot_instance_ptr;
24+
static uint32_t ail_iface_idx;
25+
static int dhcpv6_pd_client_sock = -1;
26+
27+
static void dhcpv6_pd_client_receive_handler(struct net_socket_service_event *evt);
28+
static void process_dhcpv6_pd_client_message(struct otbr_msg_ctx *msg_ctx_ptr);
29+
static void dhcpv6_pd_client_socket_init(uint32_t infra_if_index);
30+
static void dhcpv6_pd_client_socket_deinit(uint32_t infra_if_index);
31+
32+
NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(dhcpv6_pd_client_udp_receive,
33+
dhcpv6_pd_client_receive_handler,
34+
DHCPV6_PD_CLIENT_NUM_SERVICES);
35+
36+
otError dhcpv6_pd_client_init(otInstance *ot_instance, uint32_t ail_iface_index)
37+
{
38+
ot_instance_ptr = ot_instance;
39+
ail_iface_idx = ail_iface_index;
40+
41+
sockfd_udp[0].fd = -1;
42+
43+
return OT_ERROR_NONE;
44+
}
45+
46+
void otPlatInfraIfDhcp6PdClientSetListeningEnabled(otInstance *aInstance, bool aEnable,
47+
uint32_t aInfraIfIndex)
48+
{
49+
if (aEnable) {
50+
dhcpv6_pd_client_socket_init(aInfraIfIndex);
51+
} else {
52+
dhcpv6_pd_client_socket_deinit(aInfraIfIndex);
53+
}
54+
}
55+
56+
void otPlatInfraIfDhcp6PdClientSend(otInstance *aInstance,
57+
otMessage *aMessage,
58+
otIp6Address *aDestAddress,
59+
uint32_t aInfraIfIndex)
60+
{
61+
struct otbr_msg_ctx *req = NULL;
62+
63+
VerifyOrExit(dhcpv6_pd_client_sock != -1 && aInfraIfIndex == ail_iface_idx);
64+
uint16_t length = otMessageGetLength(aMessage);
65+
struct sockaddr_in6 dest_sock_addr = {.sin6_family = AF_INET6,
66+
.sin6_port = htons(DHCPV6_SERVER_PORT),
67+
.sin6_addr = IN6ADDR_ANY_INIT,
68+
.sin6_scope_id = 0};
69+
70+
memcpy(&dest_sock_addr.sin6_addr, aDestAddress, sizeof(otIp6Address));
71+
72+
VerifyOrExit(length <= OTBR_MESSAGE_SIZE);
73+
VerifyOrExit(openthread_border_router_allocate_message((void **)&req) ==
74+
OT_ERROR_NONE);
75+
VerifyOrExit(otMessageRead(aMessage, 0, req->buffer, length) == length);
76+
77+
VerifyOrExit(zsock_sendto(dhcpv6_pd_client_sock, req->buffer, length, 0,
78+
(struct sockaddr *)&dest_sock_addr,
79+
sizeof(dest_sock_addr)) == length);
80+
81+
exit:
82+
otMessageFree(aMessage);
83+
if (req != NULL) {
84+
openthread_border_router_deallocate_message((void *)req);
85+
}
86+
}
87+
88+
static void dhcpv6_pd_client_receive_handler(struct net_socket_service_event *evt)
89+
{
90+
struct sockaddr_in6 addr = {0};
91+
socklen_t addrlen = sizeof(addr);
92+
ssize_t len = 0;
93+
struct otbr_msg_ctx *req = NULL;
94+
95+
VerifyOrExit(evt->event.revents & ZSOCK_POLLIN);
96+
VerifyOrExit(openthread_border_router_allocate_message((void **)&req) == OT_ERROR_NONE);
97+
memset(req, 0, sizeof(struct otbr_msg_ctx));
98+
99+
len = zsock_recvfrom(dhcpv6_pd_client_sock, req->buffer, sizeof(req->buffer), 0,
100+
(struct sockaddr *)&addr, &addrlen);
101+
VerifyOrExit(len > 0, openthread_border_router_deallocate_message((void *)req));
102+
103+
req->length = (uint16_t)len;
104+
req->sock_addr.mPort = ntohs(addr.sin6_port);
105+
req->cb = process_dhcpv6_pd_client_message;
106+
107+
openthread_border_router_post_message(req);
108+
exit:
109+
return;
110+
}
111+
112+
static void dhcpv6_pd_client_socket_init(uint32_t infra_if_index)
113+
{
114+
char name[CONFIG_NET_INTERFACE_NAME_LEN + 1] = {0};
115+
struct ifreq if_req = {0};
116+
int hop_limit = 255;
117+
int on = 1;
118+
struct sockaddr_in6 addr = {.sin6_family = AF_INET6,
119+
.sin6_port = htons(DHCPV6_CLIENT_PORT),
120+
.sin6_addr = IN6ADDR_ANY_INIT,
121+
.sin6_scope_id = 0};
122+
123+
dhcpv6_pd_client_sock = zsock_socket(AF_INET6, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
124+
VerifyOrExit(dhcpv6_pd_client_sock >= 0);
125+
126+
VerifyOrExit(zsock_bind(dhcpv6_pd_client_sock, (struct sockaddr *)&addr,
127+
sizeof(addr)) == 0);
128+
129+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, SOL_SOCKET, SO_REUSEADDR,
130+
&on, sizeof(on)) == 0);
131+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, SOL_SOCKET, SO_REUSEPORT,
132+
&on, sizeof(on)) == 0);
133+
134+
VerifyOrExit(net_if_get_name(net_if_get_by_index(infra_if_index), name,
135+
CONFIG_NET_INTERFACE_NAME_LEN) > 0);
136+
memcpy(if_req.ifr_name, name, MIN(sizeof(name) - 1, sizeof(if_req.ifr_name) - 1));
137+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, SOL_SOCKET, SO_BINDTODEVICE, &if_req,
138+
sizeof(if_req)) == 0);
139+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
140+
&hop_limit, sizeof(hop_limit)) == 0);
141+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
142+
&hop_limit, sizeof(hop_limit)) == 0);
143+
VerifyOrExit(zsock_setsockopt(dhcpv6_pd_client_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
144+
&infra_if_index, sizeof(infra_if_index)) == 0);
145+
146+
sockfd_udp[0].fd = dhcpv6_pd_client_sock;
147+
sockfd_udp[0].events = ZSOCK_POLLIN;
148+
149+
VerifyOrExit(net_socket_service_register(&dhcpv6_pd_client_udp_receive, sockfd_udp,
150+
ARRAY_SIZE(sockfd_udp), NULL) == 0);
151+
152+
exit:
153+
return;
154+
}
155+
156+
static void dhcpv6_pd_client_socket_deinit(uint32_t infra_if_index)
157+
{
158+
VerifyOrExit(dhcpv6_pd_client_sock != -1);
159+
VerifyOrExit(zsock_close(dhcpv6_pd_client_sock) == 0);
160+
161+
sockfd_udp[0].fd = -1;
162+
dhcpv6_pd_client_sock = -1;
163+
exit:
164+
return;
165+
}
166+
167+
static void process_dhcpv6_pd_client_message(struct otbr_msg_ctx *msg_ctx_ptr)
168+
{
169+
otMessage *ot_message = NULL;
170+
171+
ot_message = otIp6NewMessage(ot_instance_ptr, NULL);
172+
VerifyOrExit(ot_message);
173+
VerifyOrExit(otMessageAppend(ot_message, msg_ctx_ptr->buffer,
174+
msg_ctx_ptr->length) == OT_ERROR_NONE);
175+
176+
/* Ownership of the message is passed to OT stack, no need to free it here */
177+
otPlatInfraIfDhcp6PdClientHandleReceived(ot_instance_ptr, ot_message, ail_iface_idx);
178+
179+
exit:
180+
return;
181+
}

0 commit comments

Comments
 (0)