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 */