You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/04/16 17:47:05 UTC
[incubator-nuttx] 02/04: netlink: add netlink route notify support
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch pr807
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit f49bba8678a65ff42998d81f68e29efed40902a4
Author: chao.an <an...@xiaomi.com>
AuthorDate: Mon Apr 13 16:10:30 2020 +0800
netlink: add netlink route notify support
Change-Id: I9b7585ce5c9b67c606b118ccd72d496ecb219eeb
Signed-off-by: chao.an <an...@xiaomi.com>
---
net/netlink/netlink.h | 18 ++++++
net/netlink/netlink_route.c | 131 +++++++++++++++++++++++++++++++-------------
2 files changed, 111 insertions(+), 38 deletions(-)
diff --git a/net/netlink/netlink.h b/net/netlink/netlink.h
index 19381dc..d11d8a8 100644
--- a/net/netlink/netlink.h
+++ b/net/netlink/netlink.h
@@ -53,6 +53,14 @@
#include "devif/devif.h"
#include "socket/socket.h"
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_NETLINK_ROUTE
+ #define netlink_device_notify(dev)
+#endif
+
#ifdef CONFIG_NET_NETLINK
/****************************************************************************
@@ -277,6 +285,16 @@ ssize_t netlink_route_sendto(NETLINK_HANDLE handle,
size_t len, int flags,
FAR const struct sockaddr_nl *to,
socklen_t tolen);
+
+/****************************************************************************
+ * Name: netlink_device_notify()
+ *
+ * Description:
+ * Perform the route broadcast for the NETLINK_ROUTE protocol.
+ *
+ ****************************************************************************/
+
+void netlink_device_notify(FAR struct net_driver_s *dev);
#endif
#undef EXTERN
diff --git a/net/netlink/netlink_route.c b/net/netlink/netlink_route.c
index 955e3da..3a46391 100644
--- a/net/netlink/netlink_route.c
+++ b/net/netlink/netlink_route.c
@@ -184,32 +184,21 @@ struct nlroute_info_s
****************************************************************************/
/****************************************************************************
- * Name: netlink_device_callback
+ * Name: netlink_get_device
*
* Description:
- * Handle one device.
+ * Generate one device response.
*
****************************************************************************/
#ifndef CONFIG_NETLINK_DISABLE_GETLINK
-static int netlink_device_callback(FAR struct net_driver_s *dev,
- FAR void *arg)
+static FAR struct netlink_response_s *
+netlink_get_device(FAR struct net_driver_s *dev,
+ FAR const struct nlroute_sendto_request_s *req)
{
FAR struct getlink_recvfrom_rsplist_s *alloc;
FAR struct getlink_recvfrom_response_s *resp;
- FAR struct nlroute_info_s *info = arg;
-
- DEBUGASSERT(dev != NULL && arg != NULL);
- DEBUGASSERT(info->handle != NULL && info->req != NULL);
-
- /* Check if the link is in the UP state */
-
- if ((dev->d_flags & IFF_UP) == 0)
- {
- /* No.. skip this device */
-
- return 0;
- }
+ int up = IFF_IS_UP(dev->d_flags);
/* Allocate the response buffer */
@@ -218,7 +207,7 @@ static int netlink_device_callback(FAR struct net_driver_s *dev,
if (alloc == NULL)
{
nerr("ERROR: Failed to allocate response buffer.\n");
- return -ENOMEM;
+ return NULL;
}
/* Initialize the response buffer */
@@ -226,12 +215,12 @@ static int netlink_device_callback(FAR struct net_driver_s *dev,
resp = &alloc->payload;
resp->hdr.nlmsg_len = sizeof(struct getlink_recvfrom_response_s);
- resp->hdr.nlmsg_type = RTM_NEWLINK;
- resp->hdr.nlmsg_flags = info->req->hdr.nlmsg_flags;
- resp->hdr.nlmsg_seq = info->req->hdr.nlmsg_seq;
- resp->hdr.nlmsg_pid = info->req->hdr.nlmsg_pid;
+ resp->hdr.nlmsg_type = up ? RTM_NEWLINK : RTM_DELLINK;
+ resp->hdr.nlmsg_flags = req ? req->hdr.nlmsg_flags : 0;
+ resp->hdr.nlmsg_seq = req ? req->hdr.nlmsg_seq : 0;
+ resp->hdr.nlmsg_pid = req ? req->hdr.nlmsg_pid : 0;
- resp->iface.ifi_family = info->req->gen.rtgen_family;
+ resp->iface.ifi_family = req ? req->gen.rtgen_family : AF_PACKET;
resp->iface.ifi_type = dev->d_lltype;
#ifdef CONFIG_NETDEV_IFINDEX
resp->iface.ifi_index = dev->d_ifindex;
@@ -244,23 +233,22 @@ static int netlink_device_callback(FAR struct net_driver_s *dev,
strncpy((FAR char *)resp->data, dev->d_ifname, IFNAMSIZ);
- /* Finally, add the data to the list of pending responses */
+ /* Finally, return the response */
- netlink_add_response(info->handle, (FAR struct netlink_response_s *)alloc);
- return OK;
+ return (FAR struct netlink_response_s *)alloc;
}
#endif
/****************************************************************************
- * Name: netlink_response_terminator
+ * Name: netlink_get_terminator
*
* Description:
- * Dump a list of all network devices of the specified type.
+ * Generate one NLMSG_DONE response.
*
****************************************************************************/
-static int netlink_response_terminator(NETLINK_HANDLE handle,
- FAR const struct nlroute_sendto_request_s *req)
+static FAR struct netlink_response_s *
+netlink_get_terminator(FAR const struct nlroute_sendto_request_s *req)
{
FAR struct netlink_response_s *resp;
FAR struct nlmsghdr *hdr;
@@ -271,7 +259,7 @@ static int netlink_response_terminator(NETLINK_HANDLE handle,
if (resp == NULL)
{
nerr("ERROR: Failed to allocate response terminator.\n");
- return -ENOMEM;
+ return NULL;
}
/* Initialize and send the list terminator */
@@ -279,11 +267,33 @@ static int netlink_response_terminator(NETLINK_HANDLE handle,
hdr = &resp->msg;
hdr->nlmsg_len = sizeof(struct nlmsghdr);
hdr->nlmsg_type = NLMSG_DONE;
- hdr->nlmsg_flags = req->hdr.nlmsg_flags;
- hdr->nlmsg_seq = req->hdr.nlmsg_seq;
- hdr->nlmsg_pid = req->hdr.nlmsg_pid;
+ hdr->nlmsg_flags = req ? req->hdr.nlmsg_flags : 0;
+ hdr->nlmsg_seq = req ? req->hdr.nlmsg_seq : 0;
+ hdr->nlmsg_pid = req ? req->hdr.nlmsg_pid : 0;
- /* Finally, add the response to the list of pending responses */
+ /* Finally, return the response */
+
+ return resp;
+}
+
+/****************************************************************************
+ * Name: netlink_add_terminator
+ *
+ * Description:
+ * Add one NLMSG_DONE response to handle.
+ *
+ ****************************************************************************/
+
+static int netlink_add_terminator(NETLINK_HANDLE handle,
+ FAR const struct nlroute_sendto_request_s *req)
+{
+ FAR struct netlink_response_s * resp;
+
+ resp = netlink_get_terminator(req);
+ if (resp == NULL)
+ {
+ return -ENOMEM;
+ }
netlink_add_response(handle, resp);
return OK;
@@ -298,6 +308,22 @@ static int netlink_response_terminator(NETLINK_HANDLE handle,
****************************************************************************/
#ifndef CONFIG_NETLINK_DISABLE_GETLINK
+static int netlink_device_callback(FAR struct net_driver_s *dev,
+ FAR void *arg)
+{
+ FAR struct nlroute_info_s *info = arg;
+ FAR struct netlink_response_s * resp;
+
+ resp = netlink_get_device(dev, info->req);
+ if (resp == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ netlink_add_response(info->handle, resp);
+ return OK;
+}
+
static int netlink_get_devlist(NETLINK_HANDLE handle,
FAR const struct nlroute_sendto_request_s *req)
{
@@ -317,7 +343,7 @@ static int netlink_get_devlist(NETLINK_HANDLE handle,
return ret;
}
- return netlink_response_terminator(handle, req);
+ return netlink_add_terminator(handle, req);
}
#endif
@@ -576,7 +602,7 @@ static int netlink_get_ipv4route(NETLINK_HANDLE handle,
/* Terminate the routing table */
- return netlink_response_terminator(handle, req);
+ return netlink_add_terminator(handle, req);
}
#endif
@@ -669,7 +695,7 @@ static int netlink_get_ip6vroute(NETLINK_HANDLE handle,
/* Terminate the routing table */
- return netlink_response_terminator(handle, req);
+ return netlink_add_terminator(handle, req);
}
#endif
@@ -784,4 +810,33 @@ ssize_t netlink_route_sendto(NETLINK_HANDLE handle,
return ret;
}
+/****************************************************************************
+ * Name: netlink_device_notify()
+ *
+ * Description:
+ * Perform the route broadcast for the NETLINK_ROUTE protocol.
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_NETLINK_DISABLE_GETLINK
+void netlink_device_notify(FAR struct net_driver_s *dev)
+{
+ FAR struct netlink_response_s *resp;
+
+ DEBUGASSERT(dev != NULL);
+
+ resp = netlink_get_device(dev, NULL);
+ if (resp != NULL)
+ {
+ netlink_add_broadcast(RTNLGRP_LINK, resp);
+
+ resp = netlink_get_terminator(NULL);
+ if (resp != NULL)
+ {
+ netlink_add_broadcast(RTNLGRP_LINK, resp);
+ }
+ }
+}
+#endif
+
#endif /* CONFIG_NETLINK_ROUTE */