=============== Network Devices =============== - ``include/nuttx/net/netdev.h``. All structures and APIs needed to work with network drivers are provided in this header file. The structure ``struct net_driver_s`` defines the interface and is passed to the network via ``netdev_register()``. - ``include/nuttx/net/netdev_lowerhalf.h``. (Recommended for new drivers, see :ref:`Network Drivers `) This header file defines the interface between the network device and the network stack. The network device is a lower-half driver that provides the network stack with the ability to send and receive packets. IP Addresses ============ The structure ``struct net_driver_s`` now supports one IPv4 address and multiple IPv6 addresses. Multiple IPv6 addresses is common in modern network devices. For example, a network device may have a link-local address and a global address. The link-local address is used for neighbor discovery protocol and the global address is used for communication with the Internet. Configuration Options --------------------- ``CONFIG_NETDEV_MULTIPLE_IPv6`` Enable support for multiple IPv6 addresses per network device. Depends on ``CONFIG_NET_IPv6``. ``CONFIG_NETDEV_MAX_IPv6_ADDR`` Maximum number of IPv6 addresses that can be assigned to a single network device. Normally a link-local address and a global address are needed. IPv4 Interfaces --------------- Now we only support one IPv4 address per network device, and directly use the :c:member:`d_ipaddr`, :c:member:`d_draddr` and :c:member:`d_netmask` in :c:struct:`net_driver_s`. .. c:struct:: net_driver_s .. code-block:: c struct net_driver_s { #ifdef CONFIG_NET_IPv4 in_addr_t d_ipaddr; /* Host IPv4 address assigned to the network interface */ in_addr_t d_draddr; /* Default router IP address */ in_addr_t d_netmask; /* Network subnet mask */ #endif }; IPv6 Interfaces --------------- Now we support multiple IPv6 addresses per network device, and use the :c:member:`d_ipv6` in :c:struct:`net_driver_s` to store the IPv6 addresses. For historical reason, we keep the old name :c:member:`d_ipv6addr` and :c:member:`d_ipv6netmask` for backward compatibility. Please use :c:member:`d_ipv6` for new drivers. .. c:struct:: net_driver_s .. code-block:: c struct net_driver_s { #ifdef CONFIG_NET_IPv6 struct netdev_ifaddr6_s d_ipv6[CONFIG_NETDEV_MAX_IPv6_ADDR]; #endif }; Managing the IPv6 addresses by provided APIs would be more flexible: - :c:func:`netdev_ipv6_add()` - :c:func:`netdev_ipv6_del()` - :c:func:`netdev_ipv6_srcaddr()` - :c:func:`netdev_ipv6_lladdr()` - :c:func:`netdev_ipv6_lookup()` - :c:func:`netdev_ipv6_foreach()` .. c:function:: int netdev_ipv6_add(FAR struct net_driver_s *dev, const net_ipv6addr_t addr, \ unsigned int preflen); .. c:function:: int netdev_ipv6_del(FAR struct net_driver_s *dev, const net_ipv6addr_t addr, \ unsigned int preflen); Add or delete an IPv6 address on the network device :return: Zero is returned if the operation is successfully applied on the device; A negated errno value is returned if failed. .. c:function:: FAR const uint16_t *netdev_ipv6_srcaddr(FAR struct net_driver_s *dev, \ const net_ipv6addr_t dst); Get the source IPv6 address (RFC6724). :return: A pointer to the IPv6 address is returned on success. It will never be NULL, but can be an address containing g_ipv6_unspecaddr. .. c:function:: FAR const uint16_t *netdev_ipv6_lladdr(FAR struct net_driver_s *dev); Get the link-local address of the network device. :return: A pointer to the link-local address is returned on success. NULL is returned if the address is not found on the device. .. c:function:: FAR struct netdev_ifaddr6_s *netdev_ipv6_lookup(FAR struct net_driver_s *dev, \ const net_ipv6addr_t addr, bool maskcmp); Look up an IPv6 address in the network device's IPv6 addresses :return: A pointer to the matching IPv6 address entry is returned on success. NULL is returned if the IPv6 address is not found in the device. .. c:function:: int netdev_ipv6_foreach(FAR struct net_driver_s *dev, \ devif_ipv6_callback_t callback, FAR void *arg); Enumerate each IPv6 address on a network device. This function will terminate when either (1) all addresses have been enumerated or (2) when a callback returns any non-zero value. :return: Zero is returned if the enumeration is successfully completed; Non-zero value is returned if enumeration is terminated early by callback. Ioctls for IP Addresses ----------------------- - :c:macro:`SIOCGIFADDR` - :c:macro:`SIOCSIFADDR` - :c:macro:`SIOCDIFADDR` - :c:macro:`SIOCGLIFADDR` - :c:macro:`SIOCSLIFADDR` - :c:macro:`SIOCGIFNETMASK` - :c:macro:`SIOCSIFNETMASK` - :c:macro:`SIOCGLIFNETMASK` - :c:macro:`SIOCSLIFNETMASK` .. c:macro:: SIOCGIFADDR .. c:macro:: SIOCSIFADDR .. c:macro:: SIOCDIFADDR We just follow the Linux convention[1]: Get, set, or delete the address of the device using :c:member:`ifr_addr`, or :c:member:`ifr6_addr` with :c:member:`ifr6_prefixlen`. For compatibility, :c:macro:`SIOCGIFADDR` returns only :c:macro:`AF_INET` addresses, :c:macro:`SIOCSIFADDR` accepts :c:macro:`AF_INET` and :c:macro:`AF_INET6` addresses, and :c:macro:`SIOCDIFADDR` deletes only :c:macro:`AF_INET6` addresses. A :c:macro:`AF_INET` address can be deleted by setting it to zero via :c:macro:`SIOCSIFADDR`. Note: Unlike Linux, the maximum number of IPv6 addresses is limited on NuttX. If you add more IPv6 addresses when we have already reached the limit, the new addresses will replace addresses with same scope. [1]: https://man7.org/linux/man-pages/man7/netdevice.7.html .. c:macro:: SIOCGLIFADDR .. c:macro:: SIOCSLIFADDR Get or set the IPv6 address of the device using :c:member:`lifr_addr`. We follow the Linux convention[1] to allow interface name to be :[2], to keep working with multiple IPv6 addresses. Note: Recommend to use :c:macro:`SIOCSIFADDR` and :c:macro:`SIOCDIFADDR` to manage IPv6 addresses, by which you don't need to care about the slot it stored. [1]: https://man7.org/linux/man-pages/man7/netdevice.7.html [2]: e.g. 'eth0:0' stands for the secondary address on eth0 .. c:macro:: SIOCGIFNETMASK .. c:macro:: SIOCSIFNETMASK Get or set the IPv4 network mask for a device using :c:member:`ifr_netmask`. .. c:macro:: SIOCGLIFNETMASK .. c:macro:: SIOCSLIFNETMASK Get or set the IPv6 network mask for a device using :c:member:`lifr_netmask`. We follow the Linux convention to allow interface name to be :, to keep working with multiple IPv6 addresses. Note: Recommend to use :c:macro:`SIOCSIFADDR` and :c:macro:`SIOCDIFADDR` to manage IPv6 addresses, by which you don't need to care about the slot it stored.