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-2025 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.5.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 = netGetDefaultInterface();
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 || !settings)
140 
141  //Valid network interface?
142  if(!settings->interface)
144 
145  //Get exclusive access
147 
148  //Point to the underlying network interface
149  interface = settings->interface;
150 
151  //Clear the RA service context
152  osMemset(context, 0, sizeof(NdpRouterAdvContext));
153  //Save user settings
154  context->settings = *settings;
155 
156  //The RA service is currently disabled on the interface
157  context->running = FALSE;
158  //Attach the RA service context to the network interface
159  interface->ndpRouterAdvContext = context;
160 
161  //Release exclusive access
163 
164  //Successful initialization
165  return NO_ERROR;
166 }
167 
168 
169 /**
170  * @brief Start RA service
171  * @param[in] context Pointer to the RA service context
172  * @return Error code
173  **/
174 
176 {
177  error_t error;
178  NetInterface *interface;
179 
180  //Make sure the RA service context is valid
181  if(context == NULL)
183 
184  //Debug message
185  TRACE_INFO("Starting Router Advertisement service...\r\n");
186 
187  //Get exclusive access
189 
190  //Check whether the service is running
191  if(!context->running)
192  {
193  //Point to the underlying network interface
194  interface = context->settings.interface;
195 
196  //Join the All-Routers multicast address
197  error = ipv6JoinMulticastGroup(interface,
199 
200  //Successful membership registration?
201  if(!error)
202  {
203  //Reset variables
204  context->timestamp = osGetSystemTime();
205  context->timeout = 0;
206  context->routerAdvCount = 0;
207 
208  //Enable the router to forward packets to or from the interface
209  interface->ipv6Context.isRouter = TRUE;
210 
211  //Default Hop Limit value
212  if(context->settings.curHopLimit != 0)
213  {
214  interface->ipv6Context.curHopLimit = context->settings.curHopLimit;
215  }
216 
217  //The time a node assumes a neighbor is reachable
218  if(context->settings.reachableTime != 0)
219  {
220  interface->ndpContext.reachableTime = context->settings.reachableTime;
221  }
222 
223  //The time between retransmissions of NS messages
224  if(context->settings.retransTimer != 0)
225  {
226  interface->ndpContext.retransTimer = context->settings.retransTimer;
227  }
228 
229  //Start transmitting Router Advertisements
230  context->running = TRUE;
231  }
232  }
233  else
234  {
235  //The service is already running...
236  error = NO_ERROR;
237  }
238 
239  //Release exclusive access
241 
242  //Return status code
243  return error;
244 }
245 
246 
247 /**
248  * @brief Stop RA service
249  * @param[in] context Pointer to the RA service context
250  * @return Error code
251  **/
252 
254 {
255  error_t error;
256  NetInterface *interface;
257 
258  //Make sure the RA service context is valid
259  if(context == NULL)
261 
262  //Debug message
263  TRACE_INFO("Stopping Router Advertisement service...\r\n");
264 
265  //Get exclusive access
267 
268  //Check whether the service is running
269  if(context->running)
270  {
271  //Point to the underlying network interface
272  interface = context->settings.interface;
273 
274  //The router should transmit one or more final multicast Router
275  //Advertisements with a Router Lifetime field of zero
276  ndpSendRouterAdv(context, 0);
277 
278  //Leave the All-Routers multicast address
279  error = ipv6LeaveMulticastGroup(interface,
281 
282  //Restore default parameters
283  interface->ipv6Context.curHopLimit = interface->ipv6Context.defaultHopLimit;
284  interface->ndpContext.reachableTime = NDP_REACHABLE_TIME;
285  interface->ndpContext.retransTimer = NDP_RETRANS_TIMER;
286 
287  //Stop transmitting Router Advertisements
288  context->running = FALSE;
289  }
290  else
291  {
292  //The service is not running...
293  error = NO_ERROR;
294  }
295 
296  //Release exclusive access
298 
299  //Return status code
300  return error;
301 }
302 
303 #endif
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.
#define netMutex
Definition: net_legacy.h:195
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:36
error_t ndpRouterAdvInit(NdpRouterAdvContext *context, const NdpRouterAdvSettings *settings)
RA service initialization.
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:471
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:78
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
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.
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.