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-2024 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.4.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/ndp_router_adv.h"
38 #include "debug.h"
39 
40 //Check TCP/IP stack configuration
41 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Initialize settings with default values
46  * @param[out] settings Structure that contains the RA service configuration variables
47  **/
48 
50 {
51  //Underlying network interface
52  settings->interface = netGetDefaultInterface();
53 
54  //The maximum time allowed between sending unsolicited multicast Router
55  //Advertisements from the interface
57 
58  //The minimum time allowed between sending unsolicited multicast Router
59  //Advertisements from the interface
61 
62  //The default value to be placed in the Cur Hop Limit field in the Router
63  //Advertisement messages sent by the router
64  settings->curHopLimit = 0;
65 
66  //The value to be placed in the Managed Address Configuration flag in the
67  //Router Advertisement
68  settings->managedFlag = FALSE;
69 
70  //The value to be placed in the Other Configuration flag in the Router
71  //Advertisement
72  settings->otherConfigFlag = FALSE;
73 
74  //The value to be placed in the Mobile IPv6 Home Agent flag in the Router
75  //Advertisement
76  settings->homeAgentFlag = FALSE;
77 
78  //The value to be placed in the Router Selection Preferences field in the
79  //Router Advertisement
81 
82  //The value to be placed in the Neighbor Discovery Proxy flag in the Router
83  //Advertisement
84  settings->proxyFlag = FALSE;
85 
86  //The value to be placed in the Router Lifetime field of Router
87  //Advertisements sent from the interface
88  settings->defaultLifetime = 3 * (NDP_MAX_RTR_ADVERT_INTERVAL / 1000);
89 
90  //The value to be placed in the Reachable Time field in the Router
91  //Advertisement messages sent by the router
92  settings->reachableTime = 0;
93 
94  //The value to be placed in the Retrans Timer field in the Router
95  //Advertisement messages sent by the router
96  settings->retransTimer = 0;
97 
98  //The value to be placed in the MTU option sent by the router
99  settings->linkMtu = 0;
100 
101  //A list of prefixes to be placed in Prefix Information options (PIO) in
102  //Router Advertisement messages sent from the interface
103  settings->prefixList = NULL;
104  settings->prefixListLength = 0;
105 
106  //A list of routes to be placed in Route Information options (RIO) in
107  //Router Advertisement messages sent from the interface
108  settings->routeList = NULL;
109  settings->routeListLength = 0;
110 
111  //A list of header compression contexts to be placed in the 6LoWPAN Context
112  //options (6CO) in Router Advertisement messages sent from the interface
113  settings->contextList = NULL;
114  settings->contextListLength = 0;
115 
116  //Add Router Advertisement options callback
117  settings->addOptionsCallback = NULL;
118 }
119 
120 
121 /**
122  * @brief RA service initialization
123  * @param[in] context Pointer to the RA service context
124  * @param[in] settings RA service configuration variables
125  * @return Error code
126  **/
127 
129  const NdpRouterAdvSettings *settings)
130 {
131  NetInterface *interface;
132 
133  //Debug message
134  TRACE_INFO("Initializing Router Advertisement service...\r\n");
135 
136  //Ensure the parameters are valid
137  if(!context || !settings)
139 
140  //Valid network interface?
141  if(!settings->interface)
143 
144  //Get exclusive access
146 
147  //Point to the underlying network interface
148  interface = settings->interface;
149 
150  //Clear the RA service context
151  osMemset(context, 0, sizeof(NdpRouterAdvContext));
152  //Save user settings
153  context->settings = *settings;
154 
155  //The RA service is currently disabled on the interface
156  context->running = FALSE;
157  //Attach the RA service context to the network interface
158  interface->ndpRouterAdvContext = context;
159 
160  //Release exclusive access
162 
163  //Successful initialization
164  return NO_ERROR;
165 }
166 
167 
168 /**
169  * @brief Start RA service
170  * @param[in] context Pointer to the RA service context
171  * @return Error code
172  **/
173 
175 {
176  error_t error;
177  NetInterface *interface;
178 
179  //Make sure the RA service context is valid
180  if(context == NULL)
182 
183  //Debug message
184  TRACE_INFO("Starting Router Advertisement service...\r\n");
185 
186  //Get exclusive access
188 
189  //Check whether the service is running
190  if(!context->running)
191  {
192  //Point to the underlying network interface
193  interface = context->settings.interface;
194 
195  //Join the All-Routers multicast address
196  error = ipv6JoinMulticastGroup(interface,
198 
199  //Successful membership registration?
200  if(!error)
201  {
202  //Reset variables
203  context->timestamp = osGetSystemTime();
204  context->timeout = 0;
205  context->routerAdvCount = 0;
206 
207  //Enable the router to forward packets to or from the interface
208  interface->ipv6Context.isRouter = TRUE;
209 
210  //Default Hop Limit value
211  if(context->settings.curHopLimit != 0)
212  {
213  interface->ipv6Context.curHopLimit = context->settings.curHopLimit;
214  }
215 
216  //The time a node assumes a neighbor is reachable
217  if(context->settings.reachableTime != 0)
218  {
219  interface->ndpContext.reachableTime = context->settings.reachableTime;
220  }
221 
222  //The time between retransmissions of NS messages
223  if(context->settings.retransTimer != 0)
224  {
225  interface->ndpContext.retransTimer = context->settings.retransTimer;
226  }
227 
228  //Start transmitting Router Advertisements
229  context->running = TRUE;
230  }
231  }
232  else
233  {
234  //The service is already running...
235  error = NO_ERROR;
236  }
237 
238  //Release exclusive access
240 
241  //Return status code
242  return error;
243 }
244 
245 
246 /**
247  * @brief Stop RA service
248  * @param[in] context Pointer to the RA service context
249  * @return Error code
250  **/
251 
253 {
254  error_t error;
255  NetInterface *interface;
256 
257  //Make sure the RA service context is valid
258  if(context == NULL)
260 
261  //Debug message
262  TRACE_INFO("Stopping Router Advertisement service...\r\n");
263 
264  //Get exclusive access
266 
267  //Check whether the service is running
268  if(context->running)
269  {
270  //Point to the underlying network interface
271  interface = context->settings.interface;
272 
273  //The router should transmit one or more final multicast Router
274  //Advertisements with a Router Lifetime field of zero
275  ndpSendRouterAdv(context, 0);
276 
277  //Leave the All-Routers multicast address
278  error = ipv6LeaveMulticastGroup(interface,
280 
281  //Restore default parameters
282  interface->ipv6Context.curHopLimit = interface->ipv6Context.defaultHopLimit;
283  interface->ndpContext.reachableTime = NDP_REACHABLE_TIME;
284  interface->ndpContext.retransTimer = NDP_RETRANS_TIMER;
285 
286  //Stop transmitting Router Advertisements
287  context->running = FALSE;
288  }
289  else
290  {
291  //The service is not running...
292  error = NO_ERROR;
293  }
294 
295  //Release exclusive access
297 
298  //Return status code
299  return error;
300 }
301 
302 #endif
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Leave an IPv6 multicast group.
Definition: ipv6.c:2145
const Ipv6Addr IPV6_LINK_LOCAL_ALL_ROUTERS_ADDR
Definition: ipv6.c:77
error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr)
Join an IPv6 multicast group.
Definition: ipv6.c:2035
@ NDP_ROUTER_SEL_PREFERENCE_MEDIUM
Definition: ndp.h:236
#define NDP_RETRANS_TIMER
Definition: ndp.h:186
#define NDP_MAX_RTR_ADVERT_INTERVAL
Definition: ndp.h:74
#define NDP_REACHABLE_TIME
Definition: ndp.h:179
error_t ndpRouterAdvInit(NdpRouterAdvContext *context, const NdpRouterAdvSettings *settings)
RA service initialization.
error_t ndpRouterAdvStart(NdpRouterAdvContext *context)
Start RA service.
void ndpRouterAdvGetDefaultSettings(NdpRouterAdvSettings *settings)
Initialize settings with default values.
error_t ndpRouterAdvStop(NdpRouterAdvContext *context)
Stop RA service.
Router advertisement service.
#define NdpRouterAdvContext
error_t ndpSendRouterAdv(NdpRouterAdvContext *context, uint16_t routerLifetime)
Send a Router Advertisement message.
Helper functions for router advertisement service.
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:470
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netMutex
Definition: net_legacy.h:195
#define osMemset(p, value, length)
Definition: os_port.h:135
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
systime_t osGetSystemTime(void)
Retrieve system time.
RA service settings.
systime_t maxRtrAdvInterval
Minimum time between unsolicited Router Advertisements.
uint32_t linkMtu
Recommended MTU for the link (MTU option)
uint16_t defaultLifetime
Value of the Router Lifetime field.
NdpRouterAdvContextInfo * contextList
List of compression contexts (6CO option)
uint_t prefixListLength
Number of prefixes in the list.
NdpRouterAdvPrefixInfo * prefixList
List of prefixes (PIO option)
bool_t proxyFlag
Value of the Neighbor Discovery Proxy flag.
uint_t routeListLength
Number of routes in the list.
NdpRouterAddOptionsCallback addOptionsCallback
Add Router Advertisement options callback.
uint8_t curHopLimit
Value of the Cur Hop Limit field.
bool_t managedFlag
Managed Address Configuration flag.
bool_t homeAgentFlag
Mobile IPv6 Home Agent flag.
uint32_t reachableTime
Value of the Reachable Time field.
uint32_t retransTimer
Value of the Retrans Timer field.
bool_t otherConfigFlag
Other Configuration flag.
systime_t minRtrAdvInterval
Maximum time between unsolicited Router Advertisements.
uint_t contextListLength
Number of compression contexts in the list.
uint8_t preference
Value of the Router Selection Preferences field.
NdpRouterAdvRouteInfo * routeList
List of routes (RIO option)
NetInterface * interface
Underlying network interface.