ndp_router_adv.c
Go to the documentation of this file.
1 /**
2  * @file ndp_router_adv.c
3  * @brief Router advertisement service
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NDP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ipv6/ipv6_multicast.h"
37 #include "ipv6/ndp_router_adv.h"
39 #include "debug.h"
40 
41 //Check TCP/IP stack configuration
42 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Initialize settings with default values
47  * @param[out] settings Structure that contains the RA service configuration variables
48  **/
49 
51 {
52  //Underlying network interface
53  settings->interface = NULL;
54 
55  //The maximum time allowed between sending unsolicited multicast Router
56  //Advertisements from the interface
58 
59  //The minimum time allowed between sending unsolicited multicast Router
60  //Advertisements from the interface
62 
63  //The default value to be placed in the Cur Hop Limit field in the Router
64  //Advertisement messages sent by the router
65  settings->curHopLimit = 0;
66 
67  //The value to be placed in the Managed Address Configuration flag in the
68  //Router Advertisement
69  settings->managedFlag = FALSE;
70 
71  //The value to be placed in the Other Configuration flag in the Router
72  //Advertisement
73  settings->otherConfigFlag = FALSE;
74 
75  //The value to be placed in the Mobile IPv6 Home Agent flag in the Router
76  //Advertisement
77  settings->homeAgentFlag = FALSE;
78 
79  //The value to be placed in the Router Selection Preferences field in the
80  //Router Advertisement
82 
83  //The value to be placed in the Neighbor Discovery Proxy flag in the Router
84  //Advertisement
85  settings->proxyFlag = FALSE;
86 
87  //The value to be placed in the Router Lifetime field of Router
88  //Advertisements sent from the interface
89  settings->defaultLifetime = 3 * (NDP_MAX_RTR_ADVERT_INTERVAL / 1000);
90 
91  //The value to be placed in the Reachable Time field in the Router
92  //Advertisement messages sent by the router
93  settings->reachableTime = 0;
94 
95  //The value to be placed in the Retrans Timer field in the Router
96  //Advertisement messages sent by the router
97  settings->retransTimer = 0;
98 
99  //The value to be placed in the MTU option sent by the router
100  settings->linkMtu = 0;
101 
102  //A list of prefixes to be placed in Prefix Information options (PIO) in
103  //Router Advertisement messages sent from the interface
104  settings->prefixList = NULL;
105  settings->prefixListLength = 0;
106 
107  //A list of routes to be placed in Route Information options (RIO) in
108  //Router Advertisement messages sent from the interface
109  settings->routeList = NULL;
110  settings->routeListLength = 0;
111 
112  //A list of header compression contexts to be placed in the 6LoWPAN Context
113  //options (6CO) in Router Advertisement messages sent from the interface
114  settings->contextList = NULL;
115  settings->contextListLength = 0;
116 
117  //Add Router Advertisement options callback
118  settings->addOptionsCallback = NULL;
119 }
120 
121 
122 /**
123  * @brief RA service initialization
124  * @param[in] context Pointer to the RA service context
125  * @param[in] settings RA service configuration variables
126  * @return Error code
127  **/
128 
130  const NdpRouterAdvSettings *settings)
131 {
132  NetInterface *interface;
133 
134  //Debug message
135  TRACE_INFO("Initializing Router Advertisement service...\r\n");
136 
137  //Ensure the parameters are valid
138  if(context == NULL || settings == NULL)
140 
141  //Invalid network interface?
142  if(settings->interface == NULL)
144 
145  //Point to the underlying network interface
146  interface = settings->interface;
147 
148  //Clear the RA service context
149  osMemset(context, 0, sizeof(NdpRouterAdvContext));
150 
151  //Attach TCP/IP stack context
152  context->netContext = settings->interface->netContext;
153 
154  //Save user settings
155  context->interface = settings->interface;
156  context->maxRtrAdvInterval = settings->maxRtrAdvInterval;
157  context->minRtrAdvInterval = settings->minRtrAdvInterval;
158  context->curHopLimit = settings->curHopLimit;
159  context->managedFlag = settings->managedFlag;
160  context->otherConfigFlag = settings->otherConfigFlag;
161  context->homeAgentFlag = settings->homeAgentFlag;
162  context->preference = settings->preference;
163  context->proxyFlag = settings->proxyFlag;
164  context->defaultLifetime = settings->defaultLifetime;
165  context->reachableTime = settings->reachableTime;
166  context->retransTimer = settings->retransTimer;
167  context->linkMtu = settings->linkMtu;
168  context->prefixList = settings->prefixList;
169  context->prefixListLength = settings->prefixListLength;
170  context->routeList = settings->routeList;
171  context->routeListLength = settings->routeListLength;
172  context->contextList = settings->contextList;
173  context->contextListLength = settings->contextListLength;
174  context->addOptionsCallback = settings->addOptionsCallback;
175 
176  //The RA service is currently disabled on the interface
177  context->running = FALSE;
178 
179  //Get exclusive access
180  netLock(context->netContext);
181  //Attach the RA service context to the network interface
182  interface->ndpRouterAdvContext = context;
183  //Release exclusive access
184  netUnlock(context->netContext);
185 
186  //Successful initialization
187  return NO_ERROR;
188 }
189 
190 
191 /**
192  * @brief Start RA service
193  * @param[in] context Pointer to the RA service context
194  * @return Error code
195  **/
196 
198 {
199  error_t error;
200  NetInterface *interface;
201 
202  //Make sure the RA service context is valid
203  if(context == NULL)
205 
206  //Debug message
207  TRACE_INFO("Starting Router Advertisement service...\r\n");
208 
209  //Get exclusive access
210  netLock(context->netContext);
211 
212  //Check whether the service is running
213  if(!context->running)
214  {
215  //Point to the underlying network interface
216  interface = context->interface;
217 
218  //Join the All-Routers multicast address
219  error = ipv6JoinMulticastGroup(interface,
221 
222  //Successful membership registration?
223  if(!error)
224  {
225  //Reset variables
226  context->timestamp = osGetSystemTime();
227  context->timeout = 0;
228  context->routerAdvCount = 0;
229 
230  //Enable the router to forward packets to or from the interface
231  interface->ipv6Context.isRouter = TRUE;
232 
233  //Default Hop Limit value
234  if(context->curHopLimit != 0)
235  {
236  interface->ipv6Context.curHopLimit = context->curHopLimit;
237  }
238 
239  //The time a node assumes a neighbor is reachable
240  if(context->reachableTime != 0)
241  {
242  interface->ndpContext.reachableTime = context->reachableTime;
243  }
244 
245  //The time between retransmissions of NS messages
246  if(context->retransTimer != 0)
247  {
248  interface->ndpContext.retransTimer = context->retransTimer;
249  }
250 
251  //Start transmitting Router Advertisements
252  context->running = TRUE;
253  }
254  }
255  else
256  {
257  //The service is already running...
258  error = NO_ERROR;
259  }
260 
261  //Release exclusive access
262  netUnlock(context->netContext);
263 
264  //Return status code
265  return error;
266 }
267 
268 
269 /**
270  * @brief Stop RA service
271  * @param[in] context Pointer to the RA service context
272  * @return Error code
273  **/
274 
276 {
277  error_t error;
278  NetInterface *interface;
279 
280  //Make sure the RA service context is valid
281  if(context == NULL)
283 
284  //Debug message
285  TRACE_INFO("Stopping Router Advertisement service...\r\n");
286 
287  //Get exclusive access
288  netLock(context->netContext);
289 
290  //Check whether the service is running
291  if(context->running)
292  {
293  //Point to the underlying network interface
294  interface = context->interface;
295 
296  //The router should transmit one or more final multicast Router
297  //Advertisements with a Router Lifetime field of zero
298  ndpSendRouterAdv(context, 0);
299 
300  //Leave the All-Routers multicast address
301  error = ipv6LeaveMulticastGroup(interface,
303 
304  //Restore default parameters
305  interface->ipv6Context.curHopLimit = interface->ipv6Context.defaultHopLimit;
306  interface->ndpContext.reachableTime = NDP_REACHABLE_TIME;
307  interface->ndpContext.retransTimer = NDP_RETRANS_TIMER;
308 
309  //Stop transmitting Router Advertisements
310  context->running = FALSE;
311  }
312  else
313  {
314  //The service is not running...
315  error = NO_ERROR;
316  }
317 
318  //Release exclusive access
319  netUnlock(context->netContext);
320 
321  //Return status code
322  return error;
323 }
324 
325 
326 /**
327  * @brief Release RA service
328  * @param[in] context Pointer to the RA service context
329  **/
330 
332 {
333  NetInterface *interface;
334 
335  //Make sure the RA service context is valid
336  if(context != NULL)
337  {
338  //Get exclusive access
339  netLock(context->netContext);
340 
341  //Point to the underlying network interface
342  interface = context->interface;
343  //Detach the RA service context from the network interface
344  interface->ndpRouterAdvContext = NULL;
345 
346  //Release exclusive access
347  netUnlock(context->netContext);
348 
349  //Clear RA service context
350  osMemset(context, 0, sizeof(NdpRouterAdvContext));
351  }
352 }
353 
354 #endif
void netUnlock(NetContext *context)
Release exclusive access to the core of the TCP/IP stack.
Definition: net.c:319
error_t ndpSendRouterAdv(NdpRouterAdvContext *context, uint16_t routerLifetime)
Send a Router Advertisement message.
@ NDP_ROUTER_SEL_PREFERENCE_MEDIUM
Definition: ndp.h:236
void ndpRouterAdvGetDefaultSettings(NdpRouterAdvSettings *settings)
Initialize settings with default values.
uint32_t reachableTime
Value of the Reachable Time field.
#define TRUE
Definition: os_port.h:50
uint8_t preference
Value of the Router Selection Preferences field.
bool_t homeAgentFlag
Mobile IPv6 Home Agent flag.
bool_t proxyFlag
Value of the Neighbor Discovery Proxy flag.
uint32_t linkMtu
Recommended MTU for the link (MTU option)
NdpRouterAdvRouteInfo * routeList
List of routes (RIO option)
Router advertisement service.
IPv6 multicast filtering.
#define FALSE
Definition: os_port.h:46
#define NdpRouterAdvContext
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint16_t defaultLifetime
Value of the Router Lifetime field.
error_t
Error codes.
Definition: error.h:43
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
bool_t managedFlag
Managed Address Configuration flag.
#define NDP_RETRANS_TIMER
Definition: ndp.h:186
#define NetInterface
Definition: net.h:40
error_t ndpRouterAdvInit(NdpRouterAdvContext *context, const NdpRouterAdvSettings *settings)
RA service initialization.
NdpRouterAddOptionsCallback addOptionsCallback
Add Router Advertisement options callback.
#define TRACE_INFO(...)
Definition: debug.h:105
NdpRouterAdvContextInfo * contextList
List of compression contexts (6CO option)
error_t ndpRouterAdvStart(NdpRouterAdvContext *context)
Start RA service.
uint32_t retransTimer
Value of the Retrans Timer field.
RA service settings.
systime_t minRtrAdvInterval
Maximum time between unsolicited Router Advertisements.
uint8_t curHopLimit
Value of the Cur Hop Limit field.
const Ipv6Addr IPV6_LINK_LOCAL_ALL_ROUTERS_ADDR
Definition: ipv6.c:77
void ndpRouterAdvDeinit(NdpRouterAdvContext *context)
Release RA service.
bool_t otherConfigFlag
Other Configuration flag.
uint_t routeListLength
Number of routes in the list.
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
NetInterface * interface
Underlying network interface.
uint_t contextListLength
Number of compression contexts in the list.
#define NDP_REACHABLE_TIME
Definition: ndp.h:179
#define NDP_MAX_RTR_ADVERT_INTERVAL
Definition: ndp.h:74
error_t ndpRouterAdvStop(NdpRouterAdvContext *context)
Stop RA service.
void netLock(NetContext *context)
Get exclusive access to the core of the TCP/IP stack.
Definition: net.c:307
uint_t prefixListLength
Number of prefixes in the list.
systime_t maxRtrAdvInterval
Minimum time between unsolicited Router Advertisements.
Helper functions for router advertisement service.
#define osMemset(p, value, length)
Definition: os_port.h:138
TCP/IP stack core.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
NdpRouterAdvPrefixInfo * prefixList
List of prefixes (PIO option)
systime_t osGetSystemTime(void)
Retrieve system time.