ipv6_routing.c
Go to the documentation of this file.
1 /**
2  * @file ipv6_routing.c
3  * @brief IPv6 routing
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.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IPV6_TRACE_LEVEL
33 
34 //Dependencies
35 #include <limits.h>
36 #include "core/net.h"
37 #include "core/ip.h"
38 #include "ipv6/ipv6.h"
39 #include "ipv6/ipv6_misc.h"
40 #include "ipv6/ipv6_multicast.h"
41 #include "ipv6/ipv6_routing.h"
42 #include "ipv6/icmpv6.h"
43 #include "ipv6/ndp.h"
44 #include "debug.h"
45 
46 //Check TCP/IP stack configuration
47 #if (IPV6_SUPPORT == ENABLED && IPV6_ROUTING_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Initialize IPv6 routing table
52  * @param[in] context Pointer to the TCP/IP stack context
53  * @return Error code
54  **/
55 
57 {
58  uint_t i;
59 
60  //Clear the routing table
61  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
62  {
63  osMemset(&context->ipv6RoutingTable[i], 0, sizeof(Ipv6RoutingTableEntry));
64  }
65 
66  //Successful initialization
67  return NO_ERROR;
68 }
69 
70 
71 /**
72  * @brief Enable routing for the specified interface
73  * @param[in] interface Underlying network interface
74  * @param[in] enable When the flag is set to TRUE, routing is enabled on the
75  * interface and the router can forward packets to or from the interface
76  * @return Error code
77  **/
78 
80 {
81  //Check parameters
82  if(interface == NULL)
84 
85  //Get exclusive access
86  netLock(interface->netContext);
87  //Enable or disable routing
88  interface->ipv6Context.isRouter = enable;
89  //Release exclusive access
90  netUnlock(interface->netContext);
91 
92  //Successful processing
93  return NO_ERROR;
94 }
95 
96 
97 /**
98  * @brief Add a new entry in the IPv6 routing table
99  * @param[in] context Pointer to the TCP/IP stack context
100  * @param[in] prefix Network destination
101  * @param[in] prefixLen Length of the prefix, in bits
102  * @param[in] interface Network interface where to forward the packet
103  * @param[in] nextHop IPv6 address of the next hop
104  * @param[in] metric Metric value
105  * @return Error code
106  **/
107 
109  uint_t prefixLen, NetInterface *interface, const Ipv6Addr *nextHop,
110  uint_t metric)
111 {
112  error_t error;
113  uint_t i;
114  Ipv6RoutingTableEntry *entry;
115  Ipv6RoutingTableEntry *firstFreeEntry;
116 
117  //Check parameters
118  if(context == NULL || prefix == NULL || interface == NULL)
120 
121  //Keep track of the first free entry
122  firstFreeEntry = NULL;
123 
124  //Get exclusive access
125  netLock(context);
126 
127  //Loop through routing table entries
128  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
129  {
130  //Point to the current entry
131  entry = &context->ipv6RoutingTable[i];
132 
133  //Valid entry?
134  if(entry->valid)
135  {
136  //Check prefix length
137  if(entry->prefixLen == prefixLen)
138  {
139  //Check whether the current entry matches the specified destination
140  if(ipv6CompPrefix(&entry->prefix, prefix, prefixLen))
141  break;
142  }
143  }
144  else
145  {
146  //Keep track of the first free entry
147  if(firstFreeEntry == NULL)
148  {
149  firstFreeEntry = entry;
150  }
151  }
152  }
153 
154  //If the routing table does not contain the specified destination,
155  //then a new entry should be created
156  if(i >= IPV6_ROUTING_TABLE_SIZE)
157  {
158  entry = firstFreeEntry;
159  }
160 
161  //Check whether the routing table runs out of space
162  if(entry != NULL)
163  {
164  //Network destination
165  entry->prefix = *prefix;
166  entry->prefixLen = prefixLen;
167 
168  //Interface where to forward the packet
169  entry->interface = interface;
170 
171  //Address of the next hop
172  if(nextHop != NULL)
173  {
174  entry->nextHop = *nextHop;
175  }
176  else
177  {
179  }
180 
181  //Metric value
182  entry->metric = metric;
183  //The entry is now valid
184  entry->valid = TRUE;
185 
186  //Successful processing
187  error = NO_ERROR;
188  }
189  else
190  {
191  //The routing table is full
192  error = ERROR_FAILURE;
193  }
194 
195  //Release exclusive access
196  netUnlock(context);
197 
198  //Return status code
199  return error;
200 }
201 
202 
203 /**
204  * @brief Remove an entry from the IPv6 routing table
205  * @param[in] context Pointer to the TCP/IP stack context
206  * @param[in] prefix Network destination
207  * @param[in] prefixLen Length of the prefix, in bits
208  * @return Error code
209  **/
210 
213 {
214  error_t error;
215  uint_t i;
216  Ipv6RoutingTableEntry *entry;
217 
218  //Valid TCP/IP stack context?
219  if(context != NULL)
220  {
221  //Initialize status code
222  error = ERROR_NOT_FOUND;
223 
224  //Get exclusive access
225  netLock(context);
226 
227  //Loop through routing table entries
228  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
229  {
230  //Point to the current entry
231  entry = &context->ipv6RoutingTable[i];
232 
233  //Valid entry?
234  if(entry->valid)
235  {
236  //Check prefix length
237  if(entry->prefixLen == prefixLen)
238  {
239  //Check whether the current entry matches the specified destination
240  if(ipv6CompPrefix(&entry->prefix, prefix, prefixLen))
241  {
242  //Delete current entry
243  entry->valid = FALSE;
244  //The route was successfully deleted from the routing table
245  error = NO_ERROR;
246  }
247  }
248  }
249  }
250 
251  //Release exclusive access
252  netUnlock(context);
253  }
254  else
255  {
256  //Report an error
257  error = ERROR_INVALID_PARAMETER;
258  }
259 
260  //Return status code
261  return error;
262 }
263 
264 
265 /**
266  * @brief Delete all routes from the IPv6 routing table
267  * @param[in] context Pointer to the TCP/IP stack context
268  * @return Error code
269  **/
270 
272 {
273  error_t error;
274  uint_t i;
275 
276  //Valid TCP/IP stack context?
277  if(context != NULL)
278  {
279  //Get exclusive access
280  netLock(context);
281 
282  //Clear the routing table
283  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
284  {
285  osMemset(&context->ipv6RoutingTable[i], 0,
286  sizeof(Ipv6RoutingTableEntry));
287  }
288 
289  //Release exclusive access
290  netUnlock(context);
291 
292  //Successful processing
293  error = NO_ERROR;
294  }
295  else
296  {
297  //Report an error
298  error = ERROR_INVALID_PARAMETER;
299  }
300 
301  //Return status code
302  return error;
303 }
304 
305 
306 /**
307  * @brief Forward an IPv6 packet
308  * @param[in] srcInterface Network interface on which the packet was received
309  * @param[in] ipPacket Multi-part buffer that holds the IPv6 packet to forward
310  * @param[in] ipPacketOffset Offset to the first byte of the IPv6 packet
311  * @return Error code
312  **/
313 
315  size_t ipPacketOffset)
316 {
317  error_t error;
318  uint_t i;
319  uint_t metric;
321  bool_t match;
322  size_t length;
323  size_t destOffset;
324  NetContext *context;
325  NetInterface *destInterface;
326  NetBuffer *destBuffer;
327  Ipv6Header *ipHeader;
328  Ipv6RoutingTableEntry *entry;
330 #if (ETH_SUPPORT == ENABLED)
331  NetInterface *physicalInterface;
332 #endif
333 
334  //Point to the TCP/IP stack context
335  context = srcInterface->netContext;
336 
337  //If routing is not enabled on the interface, then the router cannot
338  //forward packets from the interface
339  if(!srcInterface->ipv6Context.isRouter)
340  return ERROR_FAILURE;
341 
342  //Silently drop any IP packets received on an interface that has
343  //not been assigned a valid link-local address
345  return ERROR_NOT_CONFIGURED;
346 
347  //Calculate the length of the IPv6 packet
348  length = netBufferGetLength(ipPacket) - ipPacketOffset;
349 
350  //Ensure the packet length is greater than 40 bytes
351  if(length < sizeof(Ipv6Header))
352  return ERROR_INVALID_LENGTH;
353 
354  //Point to the IPv6 header
355  ipHeader = netBufferAt(ipPacket, ipPacketOffset, sizeof(Ipv6Header));
356  //Malformed IPv6 packet?
357  if(ipHeader == NULL)
358  return ERROR_FAILURE;
359 
360  //An IPv6 packet with a source address of unspecified must never be
361  //forwarded by an IPv6 router (refer to RFC section 3513 2.5.2)
362  if(ipv6CompAddr(&ipHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR))
363  return ERROR_INVALID_ADDRESS;
364 
365  //The unspecified address must not be used as the destination address
366  //of IPv6 packets (refer to RFC section 3513 2.5.2)
367  if(ipv6CompAddr(&ipHeader->destAddr, &IPV6_UNSPECIFIED_ADDR))
368  return ERROR_INVALID_ADDRESS;
369 
370  //An IPv6 packet with a destination address of loopback must never be
371  //forwarded by an IPv6 router (refer to RFC 3513 section 2.5.3)
372  if(ipv6CompAddr(&ipHeader->destAddr, &IPV6_LOOPBACK_ADDR))
373  return ERROR_INVALID_ADDRESS;
374 
375  //Check whether the destination address is a link-local address
376  if(ipv6IsLinkLocalUnicastAddr(&ipHeader->destAddr))
377  {
378  //Forward the packet on the same network interface
379  destInterface = srcInterface;
380  //Next hop
381  destIpAddr = ipHeader->destAddr;
382  }
383  else
384  {
385  //Lowest metric value
386  metric = UINT_MAX;
387  //Longest prefix length
388  prefixLen = 0;
389  //Outgoing network interface
390  destInterface = NULL;
391 
392  //Route determination process
393  for(i = 0; i < IPV6_ROUTING_TABLE_SIZE; i++)
394  {
395  //Point to the current entry
396  entry = &context->ipv6RoutingTable[i];
397 
398  //Valid entry?
399  if(entry->valid && entry->interface != NULL)
400  {
401  //Clear flag
402  match = FALSE;
403 
404  //Do not forward any IP packets to an interface that has not
405  //been assigned a valid link-local address...
407  {
408  //If routing is enabled on the interface, then the router
409  //can forward packets to the interface
410  if(entry->interface->ipv6Context.isRouter)
411  {
412  //Compare the destination address with the current entry for a match
413  if(ipv6CompPrefix(&ipHeader->destAddr, &entry->prefix, entry->prefixLen))
414  {
415  //The longest matching route is the most specific route to the
416  //destination IPv6 address...
417  if(entry->prefixLen > prefixLen)
418  {
419  //Give the current route the higher precedence
420  match = TRUE;
421  }
422  else if(entry->prefixLen == prefixLen)
423  {
424  //If multiple entries with the longest match are found, the
425  //router uses the lowest metric to select the best route
426  if(entry->metric < metric)
427  {
428  //Give the current route the higher precedence
429  match = TRUE;
430  }
431  }
432  }
433  }
434  }
435 
436  //Matching entry?
437  if(match)
438  {
439  //Select the current route
440  metric = entry->metric;
441  prefixLen = entry->prefixLen;
442 
443  //Outgoing interface on which to forward the packet
444  destInterface = entry->interface;
445 
446  //Next hop
448  {
449  destIpAddr = entry->nextHop;
450  }
451  else
452  {
453  destIpAddr = ipHeader->destAddr;
454  }
455  }
456  }
457  }
458  }
459 
460  //No route to the destination?
461  if(destInterface == NULL)
462  {
463  //A Destination Unreachable message should be generated by a router
464  //in response to a packet that cannot be delivered
466  ICMPV6_CODE_NO_ROUTE_TO_DEST, 0, ipPacket, ipPacketOffset);
467 
468  //Exit immediately
469  return ERROR_NO_ROUTE;
470  }
471 
472  //Check whether the length of the IPv6 packet is larger than the link MTU
473  if(length > destInterface->ipv6Context.linkMtu)
474  {
475  //A Packet Too Big must be sent by a router in response to a packet
476  //that it cannot forward because the packet is larger than the MTU
477  //of the outgoing link
479  0, destInterface->ipv6Context.linkMtu, ipPacket, ipPacketOffset);
480 
481  //Exit immediately
482  return ERROR_INVALID_LENGTH;
483  }
484 
485  //Check whether the packet is explicitly addressed to the router itself
486  if(!ipv6CheckDestAddr(destInterface, &ipHeader->destAddr))
487  {
488  //Valid unicast address?
489  if(!ipv6IsMulticastAddr(&ipHeader->destAddr))
490  {
491  //Process IPv6 packet
492  //ipv6ProcessPacket(destInterface, ipPacket, ipPacketOffset);
493  //Exit immediately
494  return NO_ERROR;
495  }
496  }
497 
498  //Check whether the IPv6 packet is about to be sent out the interface
499  //on which it was received
500  if(destInterface == srcInterface)
501  {
502 #if (NDP_SUPPORT == ENABLED)
503  //A router should send a Redirect message whenever it forwards a packet
504  //that is not explicitly addressed to itself in which the source address
505  //identifies a neighbor, and
506  if(ipv6IsOnLink(srcInterface, &ipHeader->srcAddr))
507  {
508  //The router determines that a better first-hop node resides on the
509  //same link as the sending node for the destination address of the
510  //packet being forwarded, and
511  if(ipv6IsOnLink(destInterface, &destIpAddr))
512  {
513  //The destination address of the packet is not a multicast address
514  if(!ipv6IsMulticastAddr(&ipHeader->destAddr))
515  {
516  //Transmit a Redirect message
517  ndpSendRedirect(srcInterface, &destIpAddr, ipPacket, ipPacketOffset);
518  }
519  }
520  }
521 #endif
522  }
523  else
524  {
525  //Check whether the scope of the source address is smaller than the
526  //scope of the destination address
527  if(ipv6GetAddrScope(&ipHeader->srcAddr) < ipv6GetAddrScope(&ipHeader->destAddr))
528  {
529  //A Destination Unreachable message should be generated by a router
530  //in response to a packet that cannot be delivered without leaving
531  //the scope of the source address
533  ICMPV6_CODE_BEYOND_SCOPE_OF_SRC_ADDR, 0, ipPacket, ipPacketOffset);
534 
535  //Exit immediately
536  return ERROR_INVALID_ADDRESS;
537  }
538  }
539 
540  //Hop Limit exceeded in transit?
541  if(ipHeader->hopLimit <= 1)
542  {
543  //If a router receives a packet with a Hop Limit of zero, or if a router
544  //decrements a packet's Hop Limit to zero, it must discard the packet
545  //and originate an ICMPv6 Time Exceeded message
547  ICMPV6_CODE_HOP_LIMIT_EXCEEDED, 0, ipPacket, ipPacketOffset);
548 
549  //Exit immediately
550  return ERROR_FAILURE;
551  }
552 
553  //The Hop-by-Hop Options header, when present, must immediately follow
554  //the IPv6 header. Its presence is indicated by the value zero in the
555  //Next Header field of the IPv6 header
556  if(ipHeader->nextHeader == IPV6_HOP_BY_HOP_OPT_HEADER)
557  {
558  //Point to the extension header
559  size_t headerOffset = ipPacketOffset + sizeof(Ipv6Header);
560 
561  //Calculate the offset of the Next Header field
562  size_t nextHeaderOffset = ipPacketOffset +
563  &ipHeader->nextHeader - (uint8_t *) ipHeader;
564 
565  //The Hop-by-Hop Options header is used to carry optional information
566  //that must be examined by every node along a packet's delivery path
567  error = ipv6ParseHopByHopOptHeader(srcInterface,
568  ipPacket, ipPacketOffset, &headerOffset, &nextHeaderOffset);
569 
570  //Any error while processing the extension header?
571  if(error)
572  return error;
573  }
574 
575  //Allocate a buffer to hold the IPv6 packet
576  destBuffer = ethAllocBuffer(length, &destOffset);
577 
578  //Successful memory allocation?
579  if(destBuffer != NULL)
580  {
581  //Copy IPv6 packet
582  error = netBufferCopy(destBuffer, destOffset, ipPacket, ipPacketOffset,
583  length);
584 
585  //Check status code
586  if(!error)
587  {
588  //Point to the IPv6 header
589  ipHeader = netBufferAt(destBuffer, destOffset, 0);
590  //Every time a router forwards a packet, it decrements the Hop Limit field
591  ipHeader->hopLimit--;
592 
593 #if (ETH_SUPPORT == ENABLED)
594  //Point to the physical interface
595  physicalInterface = nicGetPhysicalInterface(destInterface);
596 
597  //Ethernet interface?
598  if(physicalInterface->nicDriver != NULL &&
599  physicalInterface->nicDriver->type == NIC_TYPE_ETHERNET)
600  {
601  MacAddr destMacAddr;
602  NetTxAncillary ancillary;
603 
604  //Additional options can be passed to the stack along with the packet
605  ancillary = NET_DEFAULT_TX_ANCILLARY;
606 
607  //Destination IPv6 address
609  destIpAddr = ipHeader->destAddr;
610 
611  //Check whether the destination IPv6 address is a multicast address?
613  {
614  //Map IPv6 multicast address to MAC-layer multicast address
615  error = ipv6MapMulticastAddrToMac(&destIpAddr, &destMacAddr);
616  }
617  else
618  {
619  //Resolve host address using Neighbor Discovery protocol
620  error = ndpResolve(destInterface, &destIpAddr, &destMacAddr);
621  }
622 
623  //Successful address resolution?
624  if(!error)
625  {
626  //Debug message
627  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
628  destInterface->name, length);
629  //Dump IP header contents for debugging purpose
630  ipv6DumpHeader(ipHeader);
631 
632  //Send Ethernet frame
633  error = ethSendFrame(destInterface, &destMacAddr, ETH_TYPE_IPV6,
634  destBuffer, destOffset, &ancillary);
635  }
636  //Address resolution in progress?
637  else if(error == ERROR_IN_PROGRESS)
638  {
639  //Debug message
640  TRACE_INFO("Enqueuing IPv6 packet (%" PRIuSIZE " bytes)...\r\n", length);
641  //Dump IP header contents for debugging purpose
642  ipv6DumpHeader(ipHeader);
643 
644  //Enqueue packets waiting for address resolution
645  error = ndpEnqueuePacket(srcInterface, destInterface, &destIpAddr,
646  destBuffer, destOffset, &ancillary);
647  }
648  //Address resolution failed?
649  else
650  {
651  //Debug message
652  TRACE_WARNING("Cannot map IPv6 address to Ethernet address!\r\n");
653  }
654  }
655  else
656 #endif
657 #if (PPP_SUPPORT == ENABLED)
658  //PPP interface?
659  if(destInterface->nicDriver != NULL &&
660  destInterface->nicDriver->type == NIC_TYPE_PPP)
661  {
662  //Debug message
663  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
664  destInterface->name, length);
665  //Dump IP header contents for debugging purpose
666  ipv6DumpHeader(ipHeader);
667 
668  //Send PPP frame
669  error = pppSendFrame(destInterface, destBuffer, destOffset,
671  }
672  else
673 #endif
674  //6LoWPAN interface?
675  if(destInterface->nicDriver != NULL &&
676  destInterface->nicDriver->type == NIC_TYPE_6LOWPAN)
677  {
678  NetTxAncillary ancillary;
679 
680  //Debug message
681  TRACE_INFO("Forwarding IPv6 packet to %s (%" PRIuSIZE " bytes)...\r\n",
682  destInterface->name, length);
683  //Dump IP header contents for debugging purpose
684  ipv6DumpHeader(ipHeader);
685 
686  //Additional options can be passed to the stack along with the packet
687  ancillary = NET_DEFAULT_TX_ANCILLARY;
688 
689  //Send the packet over the specified link
690  error = nicSendPacket(destInterface, destBuffer, destOffset,
691  &ancillary);
692  }
693  else
694  //Unknown interface type?
695  {
696  //Report an error
697  error = ERROR_INVALID_INTERFACE;
698  }
699  }
700 
701  //Free previously allocated memory
702  netBufferFree(destBuffer);
703  }
704  else
705  {
706  //Failed to allocate memory
707  error = ERROR_OUT_OF_MEMORY;
708  }
709 
710  //Return status code
711  return error;
712 }
713 
714 #endif
IPv6 (Internet Protocol Version 6)
@ ICMPV6_TYPE_PACKET_TOO_BIG
Definition: icmpv6.h:72
@ ICMPV6_TYPE_DEST_UNREACHABLE
Definition: icmpv6.h:71
void netUnlock(NetContext *context)
Release exclusive access to the core of the TCP/IP stack.
Definition: net.c:319
#define NetContext
Definition: net.h:36
int bool_t
Definition: compiler_port.h:63
@ ERROR_NOT_FOUND
Definition: error.h:148
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:70
@ ERROR_INVALID_INTERFACE
Invalid interface.
Definition: error.h:53
error_t nicSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet to the network controller.
Definition: nic.c:303
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
Ipv6Addr nextHop
Next hop.
Definition: ipv6_routing.h:68
error_t ndpSendRedirect(NetInterface *interface, const Ipv6Addr *targetAddr, const NetBuffer *ipPacket, size_t ipPacketOffset)
Send a Redirect message.
Definition: ndp.c:2089
#define TRUE
Definition: os_port.h:50
#define Ipv6Header
Definition: ipv6.h:36
error_t ethSendFrame(NetInterface *interface, const MacAddr *destAddr, uint16_t type, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send an Ethernet frame.
Definition: ethernet.c:406
Ipv6Addr
Definition: ipv6.h:282
#define IPV6_ROUTING_TABLE_SIZE
Definition: ipv6_routing.h:47
Routing table entry.
Definition: ipv6_routing.h:63
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
IPv6 routing.
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:136
@ ERROR_NOT_CONFIGURED
Definition: error.h:218
Ipv6Addr prefix
uint_t prefixLen
IPv6 prefix length.
Definition: ipv6_routing.h:66
uint8_t ipPacket[]
Definition: ndp.h:431
#define ipv6IsMulticastAddr(ipAddr)
Definition: ipv6.h:148
IPv6 multicast filtering.
@ ERROR_IN_PROGRESS
Definition: error.h:214
error_t icmpv6SendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code, uint32_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
Send an ICMPv6 Error message.
Definition: icmpv6.c:518
#define FALSE
Definition: os_port.h:46
ICMPv6 (Internet Control Message Protocol Version 6)
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:87
error_t
Error codes.
Definition: error.h:43
void ipv6DumpHeader(const Ipv6Header *ipHeader)
Dump IPv6 header for debugging purpose.
Definition: ipv6.c:2396
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t ipv6ForwardPacket(NetInterface *srcInterface, NetBuffer *ipPacket, size_t ipPacketOffset)
Forward an IPv6 packet.
Definition: ipv6_routing.c:314
#define NetInterface
Definition: net.h:40
error_t ipv6CheckDestAddr(NetInterface *interface, const Ipv6Addr *ipAddr)
Destination IPv6 address filtering.
Definition: ipv6_misc.c:814
uint_t ipv6GetAddrScope(const Ipv6Addr *ipAddr)
Retrieve the scope of an IPv6 address.
Definition: ipv6_misc.c:1270
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ICMPV6_CODE_HOP_LIMIT_EXCEEDED
Definition: icmpv6.h:109
Helper functions for IPv6.
@ IPV6_HOP_BY_HOP_OPT_HEADER
Definition: ipv6.h:208
error_t ipv6MapMulticastAddrToMac(const Ipv6Addr *ipAddr, MacAddr *macAddr)
Map an IPv6 multicast address to a MAC-layer multicast address.
#define NetTxAncillary
Definition: net_misc.h:36
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:65
const Ipv6Addr IPV6_LOOPBACK_ADDR
Definition: ipv6.c:69
error_t netBufferCopy(NetBuffer *dest, size_t destOffset, const NetBuffer *src, size_t srcOffset, size_t length)
Copy data between multi-part buffers.
Definition: net_mem.c:522
@ PPP_PROTOCOL_IPV6
Internet Protocol version 6.
Definition: ppp.h:200
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
NetInterface * interface
Outgoing network interface.
Definition: ipv6_routing.h:67
bool_t valid
Valid entry.
Definition: ipv6_routing.h:64
MacAddr
Definition: ethernet.h:197
#define ipv6IsLinkLocalUnicastAddr(ipAddr)
Definition: ipv6.h:140
@ ERROR_NO_ROUTE
Definition: error.h:221
error_t ipv6AddRoute(NetContext *context, const Ipv6Addr *prefix, uint_t prefixLen, NetInterface *interface, const Ipv6Addr *nextHop, uint_t metric)
Add a new entry in the IPv6 routing table.
Definition: ipv6_routing.c:108
NDP (Neighbor Discovery Protocol)
@ NIC_TYPE_PPP
PPP interface.
Definition: nic.h:84
#define TRACE_WARNING(...)
Definition: debug.h:93
uint8_t prefixLen
error_t ipv6InitRouting(NetContext *context)
Initialize IPv6 routing table.
Definition: ipv6_routing.c:56
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1034
@ ICMPV6_CODE_BEYOND_SCOPE_OF_SRC_ADDR
Definition: icmpv6.h:97
uint_t metric
Metric value.
Definition: ipv6_routing.h:69
IPv4 and IPv6 common routines.
Ipv6Addr prefix
Destination.
Definition: ipv6_routing.h:65
error_t ndpEnqueuePacket(NetInterface *srcInterface, NetInterface *destInterface, const Ipv6Addr *ipAddr, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Enqueue an IPv6 packet waiting for address resolution.
Definition: ndp.c:453
@ ETH_TYPE_IPV6
Definition: ethernet.h:168
Ipv6AddrState ipv6GetLinkLocalAddrState(NetInterface *interface)
Get the state of the link-local address.
Definition: ipv6.c:330
error_t ipv6EnableRouting(NetInterface *interface, bool_t enable)
Enable routing for the specified interface.
Definition: ipv6_routing.c:79
error_t ipv6DeleteAllRoutes(NetContext *context)
Delete all routes from the IPv6 routing table.
Definition: ipv6_routing.c:271
bool_t ipv6CompPrefix(const Ipv6Addr *ipAddr1, const Ipv6Addr *ipAddr2, size_t length)
Compare IPv6 address prefixes.
Definition: ipv6_misc.c:1225
error_t ipv6ParseHopByHopOptHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset)
Parse Hop-by-Hop Options header.
Definition: ipv6.c:1333
error_t ipv6DeleteRoute(NetContext *context, const Ipv6Addr *prefix, uint_t prefixLen)
Remove an entry from the IPv6 routing table.
Definition: ipv6_routing.c:211
void netLock(NetContext *context)
Get exclusive access to the core of the TCP/IP stack.
Definition: net.c:307
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
@ ICMPV6_CODE_NO_ROUTE_TO_DEST
Definition: icmpv6.h:95
error_t ndpResolve(NetInterface *interface, const Ipv6Addr *ipAddr, MacAddr *macAddr)
Address resolution using Neighbor Discovery protocol.
Definition: ndp.c:353
@ IPV6_ADDR_STATE_PREFERRED
An address assigned to an interface whose use is unrestricted.
Definition: ipv6.h:197
NetBuffer * ethAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an Ethernet frame.
Definition: ethernet.c:784
#define PRIuSIZE
@ NIC_TYPE_6LOWPAN
6LoWPAN interface
Definition: nic.h:87
unsigned int uint_t
Definition: compiler_port.h:57
#define osMemset(p, value, length)
Definition: os_port.h:141
TCP/IP stack core.
bool_t ipv6IsOnLink(NetInterface *interface, const Ipv6Addr *ipAddr)
Check whether an IPv6 address is on-link.
Definition: ipv6_misc.c:1048
@ NO_ERROR
Success.
Definition: error.h:44
@ ICMPV6_TYPE_TIME_EXCEEDED
Definition: icmpv6.h:73
Debugging facilities.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
Ipv4Addr destIpAddr
Definition: ipcp.h:80