You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/11/07 16:20:26 UTC
(nuttx-apps) 01/02: netutils/netlib: Add support for add/del a single IPv6 address
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git
commit 2f9d98cab221a93bd9939ffb6ac637ebb684adc3
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Thu Oct 19 15:35:32 2023 +0800
netutils/netlib: Add support for add/del a single IPv6 address
Note:
The `SIOCSIFADDR` and `SIOCDIFADDR` uses different params for `AF_INET` and `AF_INET6` (`struct ifreq` vs `struct in6_ifreq`) as defined by https://man7.org/linux/man-pages/man7/netdevice.7.html
Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
include/netutils/netlib.h | 14 ++++++++
netutils/netlib/CMakeLists.txt | 1 +
netutils/netlib/Makefile | 1 +
.../{netlib_setipv4addr.c => netlib_addipv6addr.c} | 41 +++++++++++++---------
.../{netlib_setipv4addr.c => netlib_delipv6addr.c} | 41 +++++++++++++---------
netutils/netlib/netlib_setipv4addr.c | 2 +-
6 files changed, 67 insertions(+), 33 deletions(-)
diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h
index e99dafbde..8668a86a3 100644
--- a/include/netutils/netlib.h
+++ b/include/netutils/netlib.h
@@ -239,7 +239,21 @@ int netlib_get_ipv4netmask(FAR const char *ifname, FAR struct in_addr *addr);
int netlib_ipv4adaptor(in_addr_t destipaddr, FAR in_addr_t *srcipaddr);
#endif
+/* We support multiple IPv6 addresses on a single interface.
+ * Recommend to use netlib_add/del_ipv6addr to manage them, by which you
+ * don't need to care about the slot it stored.
+ *
+ * Previous interfaces can still work, the ifname can be <eth>:<num>,
+ * e.g. eth0:0 stands for managing the secondary address on eth0
+ */
+
#ifdef CONFIG_NET_IPv6
+# ifdef CONFIG_NETDEV_MULTIPLE_IPv6
+int netlib_add_ipv6addr(FAR const char *ifname,
+ FAR const struct in6_addr *addr, uint8_t preflen);
+int netlib_del_ipv6addr(FAR const char *ifname,
+ FAR const struct in6_addr *addr, uint8_t preflen);
+# endif
int netlib_get_ipv6addr(FAR const char *ifname, FAR struct in6_addr *addr);
int netlib_set_ipv6addr(FAR const char *ifname,
FAR const struct in6_addr *addr);
diff --git a/netutils/netlib/CMakeLists.txt b/netutils/netlib/CMakeLists.txt
index 5ae551d6f..fd039bc53 100644
--- a/netutils/netlib/CMakeLists.txt
+++ b/netutils/netlib/CMakeLists.txt
@@ -56,6 +56,7 @@ if(CONFIG_NETUTILS_NETLIB)
endif()
if(CONFIG_NET_IPv6)
+ list(APPEND SRCS netlib_addipv6addr.c netlib_delipv6addr.c)
list(APPEND SRCS netlib_setipv6addr.c netlib_getipv6addr.c)
list(APPEND SRCS netlib_setdripv6addr.c netlib_setipv6netmask.c)
list(APPEND SRCS netlib_prefix2ipv6netmask.c netlib_ipv6netmask2prefix.c)
diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile
index bd6673017..12aac379e 100644
--- a/netutils/netlib/Makefile
+++ b/netutils/netlib/Makefile
@@ -56,6 +56,7 @@ endif
endif
ifeq ($(CONFIG_NET_IPv6),y)
+CSRCS += netlib_addipv6addr.c netlib_delipv6addr.c
CSRCS += netlib_setipv6addr.c netlib_getipv6addr.c
CSRCS += netlib_setdripv6addr.c netlib_setipv6netmask.c
CSRCS += netlib_prefix2ipv6netmask.c netlib_ipv6netmask2prefix.c
diff --git a/netutils/netlib/netlib_setipv4addr.c b/netutils/netlib/netlib_addipv6addr.c
similarity index 67%
copy from netutils/netlib/netlib_setipv4addr.c
copy to netutils/netlib/netlib_addipv6addr.c
index dca8f09fb..142e3e1e3 100644
--- a/netutils/netlib/netlib_setipv4addr.c
+++ b/netutils/netlib/netlib_addipv6addr.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * apps/netutils/netlib/netlib_setipv4addr.c
+ * apps/netutils/netlib/netlib_addipv6addr.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -23,7 +23,7 @@
****************************************************************************/
#include <nuttx/config.h>
-#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NETDEV_MULTIPLE_IPv6
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -42,45 +42,54 @@
****************************************************************************/
/****************************************************************************
- * Name: netlib_set_ipv4addr
+ * Name: netlib_add_ipv6addr
*
* Description:
- * Set the network driver IPv4 address
+ * Add an IPv6 address to the network driver
*
* Parameters:
* ifname The name of the interface to use
- * ipaddr The address to set
+ * ipaddr The address to add
+ * preflen The prefix length of the address
*
* Return:
* 0 on success; -1 on failure
*
****************************************************************************/
-int netlib_set_ipv4addr(FAR const char *ifname,
- FAR const struct in_addr *addr)
+int netlib_add_ipv6addr(FAR const char *ifname,
+ FAR const struct in6_addr *addr, uint8_t preflen)
{
int ret = ERROR;
if (ifname && addr)
{
- int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
+ int sockfd = socket(AF_INET6, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
if (sockfd >= 0)
{
- FAR struct sockaddr_in *inaddr;
struct ifreq req;
+ struct in6_ifreq ifr6;
/* Add the device name to the request */
strlcpy(req.ifr_name, ifname, IFNAMSIZ);
- /* Add the INET address to the request */
+ /* Get interface index */
- inaddr = (FAR struct sockaddr_in *)&req.ifr_addr;
- inaddr->sin_family = AF_INET;
- inaddr->sin_port = 0;
- memcpy(&inaddr->sin_addr, addr, sizeof(struct in_addr));
+ ret = ioctl(sockfd, SIOCGIFINDEX,
+ ((unsigned long)(uintptr_t)&req));
+ if (ret == OK)
+ {
+ /* Add address to the interface. */
+
+ ifr6.ifr6_ifindex = req.ifr_ifindex;
+ ifr6.ifr6_prefixlen = preflen;
+ memcpy(&ifr6.ifr6_addr, addr, sizeof(struct in6_addr));
+
+ ret = ioctl(sockfd, SIOCSIFADDR,
+ ((unsigned long)(uintptr_t)&ifr6));
+ }
- ret = ioctl(sockfd, SIOCSIFADDR, (unsigned long)&req);
close(sockfd);
}
}
@@ -88,4 +97,4 @@ int netlib_set_ipv4addr(FAR const char *ifname,
return ret;
}
-#endif /* CONFIG_NET_IPv4 */
+#endif /* CONFIG_NETDEV_MULTIPLE_IPv6 */
diff --git a/netutils/netlib/netlib_setipv4addr.c b/netutils/netlib/netlib_delipv6addr.c
similarity index 66%
copy from netutils/netlib/netlib_setipv4addr.c
copy to netutils/netlib/netlib_delipv6addr.c
index dca8f09fb..d83ffa807 100644
--- a/netutils/netlib/netlib_setipv4addr.c
+++ b/netutils/netlib/netlib_delipv6addr.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * apps/netutils/netlib/netlib_setipv4addr.c
+ * apps/netutils/netlib/netlib_delipv6addr.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -23,7 +23,7 @@
****************************************************************************/
#include <nuttx/config.h>
-#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NETDEV_MULTIPLE_IPv6
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -42,45 +42,54 @@
****************************************************************************/
/****************************************************************************
- * Name: netlib_set_ipv4addr
+ * Name: netlib_del_ipv6addr
*
* Description:
- * Set the network driver IPv4 address
+ * Remove an IPv6 address from the network driver
*
* Parameters:
* ifname The name of the interface to use
- * ipaddr The address to set
+ * ipaddr The address to delete
+ * preflen The prefix length of the address
*
* Return:
* 0 on success; -1 on failure
*
****************************************************************************/
-int netlib_set_ipv4addr(FAR const char *ifname,
- FAR const struct in_addr *addr)
+int netlib_del_ipv6addr(FAR const char *ifname,
+ FAR const struct in6_addr *addr, uint8_t preflen)
{
int ret = ERROR;
if (ifname && addr)
{
- int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
+ int sockfd = socket(AF_INET6, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
if (sockfd >= 0)
{
- FAR struct sockaddr_in *inaddr;
struct ifreq req;
+ struct in6_ifreq ifr6;
/* Add the device name to the request */
strlcpy(req.ifr_name, ifname, IFNAMSIZ);
- /* Add the INET address to the request */
+ /* Get interface index */
- inaddr = (FAR struct sockaddr_in *)&req.ifr_addr;
- inaddr->sin_family = AF_INET;
- inaddr->sin_port = 0;
- memcpy(&inaddr->sin_addr, addr, sizeof(struct in_addr));
+ ret = ioctl(sockfd, SIOCGIFINDEX,
+ ((unsigned long)(uintptr_t)&req));
+ if (ret == OK)
+ {
+ /* Delete address from the interface. */
+
+ ifr6.ifr6_ifindex = req.ifr_ifindex;
+ ifr6.ifr6_prefixlen = preflen;
+ memcpy(&ifr6.ifr6_addr, addr, sizeof(struct in6_addr));
+
+ ret = ioctl(sockfd, SIOCDIFADDR,
+ ((unsigned long)(uintptr_t)&ifr6));
+ }
- ret = ioctl(sockfd, SIOCSIFADDR, (unsigned long)&req);
close(sockfd);
}
}
@@ -88,4 +97,4 @@ int netlib_set_ipv4addr(FAR const char *ifname,
return ret;
}
-#endif /* CONFIG_NET_IPv4 */
+#endif /* CONFIG_NETDEV_MULTIPLE_IPv6 */
diff --git a/netutils/netlib/netlib_setipv4addr.c b/netutils/netlib/netlib_setipv4addr.c
index dca8f09fb..8ada0e48a 100644
--- a/netutils/netlib/netlib_setipv4addr.c
+++ b/netutils/netlib/netlib_setipv4addr.c
@@ -63,7 +63,7 @@ int netlib_set_ipv4addr(FAR const char *ifname,
if (ifname && addr)
{
- int sockfd = socket(NET_SOCK_FAMILY, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
+ int sockfd = socket(AF_INET, NET_SOCK_TYPE, NET_SOCK_PROTOCOL);
if (sockfd >= 0)
{
FAR struct sockaddr_in *inaddr;