This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 035faaccc76d7ef3f43a03afa72288c142ed0550 Author: Ludovic Vanasse <[email protected]> AuthorDate: Sun Oct 20 12:39:28 2024 -0400 Doc: Migrate IPv6 Migrate https://cwiki.apache.org/confluence/display/NUTTX/IPv6 to official wiki Signed-off-by: Ludovic Vanasse <[email protected]> --- Documentation/guides/index.rst | 3 +- Documentation/guides/ipv6.rst | 348 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 350 insertions(+), 1 deletion(-) diff --git a/Documentation/guides/index.rst b/Documentation/guides/index.rst index 3ff5697012..07bd86d7ac 100644 --- a/Documentation/guides/index.rst +++ b/Documentation/guides/index.rst @@ -44,4 +44,5 @@ Guides specialstuff_in_nuttxheaderfiles.rst kernel_threads_with_custom_stacks.rst versioning_and_task_names.rst - logging_rambuffer.rst \ No newline at end of file + logging_rambuffer.rst + ipv6.rst \ No newline at end of file diff --git a/Documentation/guides/ipv6.rst b/Documentation/guides/ipv6.rst new file mode 100644 index 0000000000..d67c30c518 --- /dev/null +++ b/Documentation/guides/ipv6.rst @@ -0,0 +1,348 @@ +==== +IPv6 +==== + +.. warning:: + Migrated from: https://cwiki.apache.org/confluence/display/NUTTX/IPv6 + +NuttX has supported the Internet Protocol Version 4 (IPv4) for many years. +There have been fragments of IPv6 in the code base for many years as well, +but these fragments were not more than place markers and not functional. + +But recently, post NuttX-7.6, I have focused some effort into completing the +IPv6 implementation. This Wiki page contains notes from that integration +effort and will, hopefully, evolve to provide full documentation for NuttX +IPv6 support. + +Current status: Basic functionality is complete and verified. That includes +ICMPPv6 Neighbor Discover Protocol, IPCMPv6 Echo Request/Response +(for ``ping6``), TCP/IPv6, and UDP/IPv6. It has also been proven that you +can support a platform with `both` IPv4 and IPv6 enabled. + +Ethernet Driver Requirements +============================ + +Basic Driver Requirements +------------------------- + +In order to support IPv6, Ethernet drivers must do the following: + +* They must recognize IPv6 packets and call ``ipv6_input`` in order to pass the + packets into the network stack. This is equivalent to calling ``ipv4_input`` + when an IPv4 pack is received. +* When sending an IPv6, the drivers must call ``neighbor_out()`` in order to add + the MAC address of the destination into the link layer header. IPv6's + `ICMPv6 Neighbor Discovery Protocol` is the moral equivalent of the + `Address Resolution Protocol` (ARP) used with IPv6. And the IPv6 + ``neighbor_out()`` performs a similar function to the IPv4 ``arp_out()`` + function. +* Ethernet drivers must also support some additional address filtering. + For IPv4 support, most Ethernet drivers are configured to accept only + Ethernet packets with matching MAC addresses and broadcast packets (or + selected multicast packets if IGMP support is enabled). Additional + filtering support is needed to support IPv6. + +All existing NuttX Ethernet drivers have already been modified to support +the requirements of the first two bullets. However, additional logic must +be added to most of the existing Ethernet drivers to support the final +requirement. + +Multicast Address Filtering +--------------------------- + +Each Ethernet device connects to the Ethernet wire via a PHY and so +potentially has access to every packet that passes on the wire. In +`promiscuous` mode, that is the behavior that is desired but normally +it is not: The amount of traffic that appears on the wire would swamp +most modest MCUs in promiscuous mode. So instead, the Ethernet MAC +hardware will support address filtering. That is, the hardware will +look at the Ethernet header at the beginning of each packet and will +ignore packets that do not have the desired information in the Ethernet +header. The software will see only those filtered packets that are desired. + +Typically, the Ethernet MAC is set-up for `unicast` address filtering: The +hardware is programmed so that that only packets whose destination Ethernet +MAC address matches the MAC address programmed into the hardware are accepted. +In addition, special `broadcast` Ethernet addresses will also be accepted. +In this way, the volume of Ethernet data received by the MCU is greatly +reduced. + +`Multicast` addresses are a little different. Unlike broadcast addresses, +there are many possible multicast addresses and so the Ethernet MAC hardware +must support some special capability to match the destination Ethernet +address in an incoming packet with a variety of multicast addresses. +Usually this involves `hashing` the Ethernet address and performing a `hash +table lookup` to check for an address match. + +Each Ethernet driver uses a common interface that is defined in +``nuttx/include/nuttx/net/netdev.h``. That interface defines, among other +things, a set of calls into the Ethernet driver to perform a variety of +functions. One of those functions is multicast address filtering: + +.. code-block:: c + + #ifdef CONFIG_NET_IGMP + int (*d_addmac)(FAR struct net_driver_s *dev, FAR const uint8_t *mac); + int (*d_rmmac)(FAR struct net_driver_s *dev, FAR const uint8_t *mac); + #endif + +The ``d_addmac()`` interface adds a multicast address to the hash +table; ``d_rmmac()`` removes a multicast address from the hash table. + +These interface is only required if IGMP is supported, but the underlying +ability to program multicast address filtered is required for full IPv6 +support. This interface exists in all Ethernet drivers but most are +currently place holders and are `to-be-provided`. At present, only the +STMicro STM32, the TI Tiva TM4C, and the Atmel SAM3/4 and SAMA5D3/4 +Ethernet drivers support multicast hash tables. This capability will +have to be added to any additional Ethernet drivers that are modified +to support IPv6. + +ICMPv6 Neighbor Discovery Protocol +---------------------------------- + +The ICMPv6 Neighbor Discover protocol is the reason for this additional +address filtering. The ICMPv6 Neighbor Discovery Protocol is the +replacement for IPv4's ARP. It different from ARP in the it is +implemented not at the Ethernet link layer, but within the IPv6 layer. +In order to receive broadcast packets to ICMPv6, the IPv6 Multicast +address of 33.33.ff.xx.xx.xx is used, where the xx.xx.xx part derives +from the IPv6 address. The Ethernet driver filtering logic must be modified +so that it accepts packets directed to the that MAC address. + +At present, this additional support is only implemented for the TI Tiva +TM4C129X Ethernet driver. Below is a snippet of code from that drier +showing how this is implemented: + +.. code-block:: c + + /* Set the MAC address */ + + tiva_macaddress(priv); + + #ifdef CONFIG_NET_ICMPv6 + /* Set up the IPv6 multicast address */ + + tiva_ipv6multicast(priv); + #endif + +Where `tiva_macaddress()` sets up the normal MAC address filtering and +`tiva_ipv6multicast()` sets up the special filtering needed by IPv6: + +.. code-block:: c + + /**************************************************************************** + * Function: tiva_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + ***************************************************************************/ + + #ifdef CONFIG_NET_ICMPv6 + static void tiva_ipv6multicast(FAR struct tiva_ethmac_s *priv) + { + struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + nvdbg("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)tiva_addmac(dev, mac); + + #ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)tiva_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + + #endif /* CONFIG_NET_ICMPv6_AUTOCONF */ + #ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)tiva_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + + #endif /* CONFIG_NET_ICMPv6_ROUTER */ + } + #endif /* CONFIG_NET_ICMPv6 */ + + +The following Ethernet drivers are complete and IPv6 ready. All others +Ethernet drivers have all required IPv6 support `except` that they are +missing (1) the required ICMPv6 addressing filtering described above +and/or (2) support for multi-cast address filtering. + +* STMicro STM32 +* TI Tiva TM4C +* Atmel SAMA5D4 +* NXP LPC17xx + + +Board Configurations +==================== + +At present, there are three board configuration that are pre-configured to +use IPv6: ``nuttx/boards/arm/tiva/dk-tm4c129x/configs/ipv6``, +``nuttx/boards/arm/stm32/stm32f4discovery/ipv6``, and +``nuttx/boards/arm/tiva/tm4c1294-launchpad/configs/ipv6``. These default +configurations have only IPv6 enabled. But the `README` files at in those +board directories describes how to enable `both` IPv4 and IPv6 simultaneously. + +Ping +==== + +Ping from Host PC +----------------- + +Ping from Windows cmd Terminal +`````````````````````````````` + +.. code-block:: bash + + ping -6 fc00::2 + +Ping From Linux shell +````````````````````` + +.. code-block:: bash + + ping6 fc00::2 + +Ping from the NuttShell (NSH) +----------------------------- + +.. code-block:: bash + + nsh> ping6 fc00::2 + +NSH ifconfig +============ + +IPv4 Only +--------- + +``CONFIG_NET_IPv4=y`` and ``CONFIG_NET_IPv6=n`` + +.. code-block:: bash + + nsh> ifconfig + eth0 Link encap: Ethernet HWaddr 00:1a:b6:02:81:14 at UP + inet addr:10.0.0.2 DRaddr:10.0.0.1 Mask:255.255.255.0 + + IPv4 TCP UDP ICMP + Received 003b 001c 0000 0004 + Dropped 001b 0000 0000 0000 + IPv4 VHL: 0000 Frg: 0000 + Checksum 0000 0000 0000 ---- + TCP ACK: 0000 SYN: 0000 + RST: 0000 0000 + Type 0000 ---- ---- 0000 + Sent 0031 002d 0000 0004 + Rexmit ---- ---- 0000 ---- + +NOTE: The detailed packet statistics only appear if +``CONFIG_NET_STATISTICS`` is enabled. + +IPv6 Only +--------- + +``CONFIG_NET_IPv4=n`` and ``CONFIG_NET_IPv6=y`` + +.. code-block:: bash + + nsh> ifconfig + eth0 Link encap: Ethernet HWaddr 00:1a:b6:02:81:14 at UP + inet6 addr:fc00::2 + inet6 DRaddr:fc00::1 + inet6 Mask:ffff:ffff:ffff::ffff:ffff:ffff:ff80 + + IPv6 TCP UDP ICMPv6 + Received 0007 0000 0000 0007 + Dropped 0000 0000 0000 0000 + IPv6 VHL: 0000 + Checksum ---- 0000 0000 ---- + TCP ACK: 0000 SYN: 0000 + RST: 0000 0000 + Type 0000 ---- ---- 0000 + Sent 0011 0000 0000 0011 + Rexmit ---- ---- 0000 ---- + +Both IPv4 and IPv6 +------------------ + +``CONFIG_NET_IPv4=y`` and ``CONFIG_NET_IPv6=y`` + +.. code-block:: bash + + nsh> ifconfig + eth0 Link encap: Ethernet HWaddr 00:1a:b6:02:81:14 at UP + inet addr:10.0.0.2 DRaddr:10.0.0.1 Mask:255.255.255.0 + inet6 addr:fc00::2 + inet6 DRaddr:fc00::1 + inet6 Mask:ffff:ffff:ffff::ffff:ffff:ffff:ff80 + + IPv4 IPv6 TCP UDP ICMP ICMPv6 + Received 0047 000a 001c 0000 0004 000a + Dropped 0027 0000 0000 0000 0000 0000 + IPv4 VHL: 0000 Frg: 0000 + IPv6 VHL: 0000 + Checksum 0000 ---- 0000 0000 ---- ---- + TCP ACK: 0000 SYN: 0000 + RST: 0000 0000 + Type 0000 0000 ---- ---- 0000 0000 + Sent 0033 000a 002f 0000 0004 000a + Rexmit ---- ---- ---- 0000 ---- ---- + +Tests, Applications, and Network Utilities +========================================== + +In addition to the core RTOS support IPv6, changes are also required to +networking tests, to networking aware applications, and, of course, to all of +the network utils (``netutils``). + +* NuttShell (NSH): IPv6 support is partially available. NSH is capable of + initializing the IPv6 domain and some of the NSH commands have been adapted + to support IPv6. A ping6 command has been added. But there are many commands + that still require updating. +* Tests: There are several networking tests in ``apps/examples``. The + ``nettest`` test and the ``udp`` test have been adapted to work in the IPv6 + domain, but none of the others have yet been adapted. +* Netutils: The network utilities in ``apps/netutils`` have been adapted to + work with IPv6: DHCP, FTP, TFTP, Telnet, etc. Support for managing IPv6 + address have been included in the ``netlib``, but nothing else has yet been + updated. \ No newline at end of file
