You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2024/05/14 13:05:47 UTC
(nuttx) 03/04: net/netlink: Add RTM preifx notify support
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 4702a095387f5c93428cf183a9f113556552ad9c
Author: meijian <me...@xiaomi.com>
AuthorDate: Fri Apr 19 16:47:34 2024 +0800
net/netlink: Add RTM preifx notify support
Signed-off-by: meijian <me...@xiaomi.com>
---
include/netpacket/netlink.h | 30 +++++++++++++
net/icmpv6/icmpv6_input.c | 3 ++
net/netlink/Kconfig | 6 +++
net/netlink/netlink.h | 17 ++++++++
net/netlink/netlink_route.c | 104 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 160 insertions(+)
diff --git a/include/netpacket/netlink.h b/include/netpacket/netlink.h
index da4e13e165..31daae56a1 100644
--- a/include/netpacket/netlink.h
+++ b/include/netpacket/netlink.h
@@ -704,6 +704,36 @@ struct rtmsg
uint32_t rtm_flags;
};
+/* Structures used in prefix information. */
+
+struct prefixmsg
+{
+ uint8_t prefix_family;
+ uint8_t prefix_pad1;
+ uint16_t prefix_pad2;
+ int32_t prefix_ifindex;
+ uint8_t prefix_type;
+ uint8_t prefix_len;
+ uint8_t prefix_flags;
+ uint8_t prefix_pad3;
+};
+
+enum
+{
+ PREFIX_UNSPEC,
+ PREFIX_ADDRESS,
+ PREFIX_CACHEINFO,
+ __PREFIX_MAX
+};
+
+#define PREFIX_MAX (__PREFIX_MAX - 1)
+
+struct prefix_cacheinfo
+{
+ uint32_t preferred_time;
+ uint32_t valid_time;
+};
+
/* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
* +---------------------+- - -+- - - - - - - - - -+- - -+
* | Header | Pad | Payload | Pad |
diff --git a/net/icmpv6/icmpv6_input.c b/net/icmpv6/icmpv6_input.c
index 17d9137b54..e2be6241ac 100644
--- a/net/icmpv6/icmpv6_input.c
+++ b/net/icmpv6/icmpv6_input.c
@@ -36,6 +36,7 @@
#include <nuttx/net/dns.h>
#include "devif/devif.h"
+#include "netlink/netlink.h"
#include "neighbor/neighbor.h"
#include "utils/utils.h"
#include "icmpv6/icmpv6.h"
@@ -450,6 +451,8 @@ void icmpv6_input(FAR struct net_driver_s *dev, unsigned int iplen)
{
icmpv6_setaddresses(dev, ipv6->srcipaddr,
prefixopt->prefix, prefixopt->preflen);
+ netlink_ipv6_prefix_notify(dev, RTM_NEWPREFIX,
+ prefixopt);
}
/* Notify any waiting threads */
diff --git a/net/netlink/Kconfig b/net/netlink/Kconfig
index 71d60885fd..dd788e6006 100644
--- a/net/netlink/Kconfig
+++ b/net/netlink/Kconfig
@@ -116,6 +116,12 @@ config NETLINK_VALIDATE_POLICY
VALIDATE_POLICY is used to make sure the parameters
you pass in are valid.
+config NETLINK_DISABLE_NEWPREFIX
+ bool "Disable RTM_NEWPREFIX support"
+ default n
+ ---help---
+ RTM_NEWPREFIX is used to set netdev prefix.
+
endif # NETLINK_ROUTE
config NETLINK_NETFILTER
diff --git a/net/netlink/netlink.h b/net/netlink/netlink.h
index fd1f81e4b3..9932a9635f 100644
--- a/net/netlink/netlink.h
+++ b/net/netlink/netlink.h
@@ -32,6 +32,7 @@
#include <netpacket/netlink.h>
#include <nuttx/queue.h>
+#include <nuttx/net/icmpv6.h>
#include <nuttx/net/netlink.h>
#include <nuttx/semaphore.h>
#include <nuttx/wqueue.h>
@@ -48,6 +49,7 @@
# define netlink_device_notify_ipaddr(dev, type, domain, addr, preflen)
# define netlink_route_notify(route, type, domain)
# define netlink_neigh_notify(neigh, type, domain)
+# define netlink_ipv6_prefix_notify(dev, type, pinfo)
#endif
#ifdef CONFIG_NET_NETLINK
@@ -552,6 +554,21 @@ void netlink_route_notify(FAR const void *route, int type, int domain);
void netlink_neigh_notify(FAR const void *neigh, int type, int domain);
#endif
+/****************************************************************************
+ * Name: netlink_ipv6_prefix_notify()
+ *
+ * Description:
+ * Perform the RA prefix for the NETLINK_ROUTE protocol.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NETLINK_DISABLE_NEWPREFIX) || !defined(CONFIG_NET_IPV6)
+# define netlink_ipv6_prefix_notify(dev, type, pinfo)
+#else
+void netlink_ipv6_prefix_notify(FAR struct net_driver_s *dev, int type,
+ FAR const struct icmpv6_prefixinfo_s *pinfo);
+#endif
+
/****************************************************************************
* Name: nla_next
*
diff --git a/net/netlink/netlink_route.c b/net/netlink/netlink_route.c
index 24ee4cddda..b4fecc769d 100644
--- a/net/netlink/netlink_route.c
+++ b/net/netlink/netlink_route.c
@@ -29,6 +29,7 @@
#include <assert.h>
#include <errno.h>
#include <debug.h>
+#include <arpa/inet.h>
#include <net/route.h>
#include <netpacket/netlink.h>
@@ -179,6 +180,32 @@ struct getaddr_recvfrom_rsplist_s
struct getaddr_recvfrom_response_s payload;
};
+struct getprefix_recvfrom_addr_s
+{
+ struct rtattr attr;
+ net_ipv6addr_t addr;
+};
+
+struct getprefix_recvfrom_cache_s
+{
+ struct rtattr attr;
+ struct prefix_cacheinfo pci;
+};
+
+struct getprefix_recvfrom_response_s
+{
+ struct nlmsghdr hdr;
+ struct prefixmsg pmsg;
+ struct getprefix_recvfrom_addr_s prefix;
+ struct getprefix_recvfrom_cache_s pci;
+};
+
+struct getprefix_recvfrom_rsplist_s
+{
+ sq_entry_t flink;
+ struct getprefix_recvfrom_response_s payload;
+};
+
/* netdev_foreach() callback */
struct nlroute_sendto_request_s
@@ -1249,6 +1276,58 @@ static int netlink_get_addr(NETLINK_HANDLE handle,
}
#endif
+#if !defined(CONFIG_NETLINK_DISABLE_NEWADDR) && defined(CONFIG_NET_IPV6)
+static FAR struct netlink_response_s *
+netlink_fill_ipv6prefix(FAR struct net_driver_s *dev, int type,
+ FAR const struct icmpv6_prefixinfo_s *pinfo)
+{
+ FAR struct getprefix_recvfrom_rsplist_s *alloc;
+ FAR struct getprefix_recvfrom_response_s *resp;
+
+ DEBUGASSERT(dev != NULL && pinfo != NULL);
+
+ alloc = kmm_zalloc(sizeof(struct getprefix_recvfrom_rsplist_s));
+ if (alloc == NULL)
+ {
+ nerr("ERROR: Failed to allocate response buffer.\n");
+ return NULL;
+ }
+
+ /* Initialize the response buffer */
+
+ resp = &alloc->payload;
+
+ resp->hdr.nlmsg_len = sizeof(struct getprefix_recvfrom_response_s);
+ resp->hdr.nlmsg_type = type;
+ resp->hdr.nlmsg_flags = 0;
+ resp->hdr.nlmsg_seq = 0;
+ resp->hdr.nlmsg_pid = 0;
+
+ resp->pmsg.prefix_family = AF_INET6;
+#ifdef CONFIG_NETDEV_IFINDEX
+ resp->pmsg.prefix_ifindex = dev->d_ifindex;
+#endif
+ resp->pmsg.prefix_len = pinfo->optlen;
+ resp->pmsg.prefix_type = pinfo->opttype;
+
+ resp->prefix.attr.rta_len = RTA_LENGTH(sizeof(net_ipv6addr_t));
+ resp->prefix.attr.rta_type = PREFIX_ADDRESS;
+ net_ipv6addr_copy(resp->prefix.addr, pinfo->prefix);
+
+ resp->pci.attr.rta_len = RTA_LENGTH(sizeof(struct prefix_cacheinfo));
+ resp->pci.attr.rta_type = PREFIX_CACHEINFO;
+
+ resp->pci.pci.preferred_time = NTOHS(pinfo->plifetime[0]) << 16;
+ resp->pci.pci.preferred_time |= NTOHS(pinfo->plifetime[1]);
+ resp->pci.pci.valid_time = NTOHS(pinfo->vlifetime[0]) << 16;
+ resp->pci.pci.valid_time |= NTOHS(pinfo->vlifetime[1]);
+
+ /* Finally, return the response */
+
+ return (FAR struct netlink_response_s *)alloc;
+}
+#endif
+
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -1582,4 +1661,29 @@ void netlink_neigh_notify(FAR const void *neigh, int type, int domain)
}
#endif
+/****************************************************************************
+ * Name: netlink_ipv6_prefix_notify()
+ *
+ * Description:
+ * Perform the RA prefix for the NETLINK_ROUTE protocol.
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_NETLINK_DISABLE_NEWADDR) && defined(CONFIG_NET_IPV6)
+void netlink_ipv6_prefix_notify(FAR struct net_driver_s *dev, int type,
+ FAR const struct icmpv6_prefixinfo_s *pinfo)
+{
+ FAR struct netlink_response_s *resp;
+
+ resp = netlink_fill_ipv6prefix(dev, type, pinfo);
+ if (resp == NULL)
+ {
+ return;
+ }
+
+ netlink_add_broadcast(RTNLGRP_IPV6_PREFIX, resp);
+ netlink_add_terminator(NULL, NULL, RTNLGRP_IPV6_PREFIX);
+}
+#endif
+
#endif /* CONFIG_NETLINK_ROUTE */