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 34aeeb024c9b59b22c8a57d63aaaae2c56460319
Author: meijian <[email protected]>
AuthorDate: Tue Apr 9 21:07:57 2024 +0800

    net/netlink: Add RTM route support
    
    Signed-off-by: meijian <[email protected]>
---
 net/netlink/netlink.h         |  20 +++++
 net/netlink/netlink_route.c   | 167 ++++++++++++++++++++++++++++++++++--------
 net/route/net_add_fileroute.c |   5 ++
 net/route/net_add_ramroute.c  |   5 ++
 net/route/net_del_fileroute.c |   5 ++
 net/route/net_del_ramroute.c  |  20 +++--
 6 files changed, 183 insertions(+), 39 deletions(-)

diff --git a/net/netlink/netlink.h b/net/netlink/netlink.h
index 9e8fc9e584..474a898c16 100644
--- a/net/netlink/netlink.h
+++ b/net/netlink/netlink.h
@@ -46,6 +46,7 @@
 #ifndef CONFIG_NETLINK_ROUTE
 #  define netlink_device_notify(dev)
 #  define netlink_device_notify_ipaddr(dev, type, domain, addr, preflen)
+#  define netlink_route_notify(route, type, domain)
 #endif
 
 #ifdef CONFIG_NET_NETLINK
@@ -512,6 +513,25 @@ void netlink_device_notify_ipaddr(FAR struct net_driver_s 
*dev,
                                   int type, int domain,
                                   FAR const void *addr, uint8_t preflen);
 
+/****************************************************************************
+ * Name: netlink_route_notify
+ *
+ * Description:
+ *   Perform the route broadcast for the NETLINK_NETFILTER protocol.
+ *
+ * Input Parameters:
+ *   route  - The route entry
+ *   type   - The type of the message, RTM_*ROUTE
+ *   domain - The domain of the message
+ *
+ ****************************************************************************/
+
+#if defined CONFIG_NETLINK_DISABLE_GETROUTE
+# define netlink_route_notify(route, type, domain)
+#else
+void netlink_route_notify(FAR const void *route, int type, int domain);
+#endif
+
 /****************************************************************************
  * Name: nla_next
  *
diff --git a/net/netlink/netlink_route.c b/net/netlink/netlink_route.c
index 0f4bdc2e18..e91241a1d0 100644
--- a/net/netlink/netlink_route.c
+++ b/net/netlink/netlink_route.c
@@ -663,15 +663,14 @@ static int netlink_get_nbtable(NETLINK_HANDLE handle,
  ****************************************************************************/
 
 #if defined(CONFIG_NET_IPv4) && !defined(CONFIG_NETLINK_DISABLE_GETROUTE)
-static int netlink_ipv4_route(FAR struct net_route_ipv4_s *route,
-                              FAR void *arg)
+static FAR struct netlink_response_s *
+netlink_get_ipv4_route(FAR const struct net_route_ipv4_s *route, int type,
+                       FAR const struct nlroute_sendto_request_s *req)
 {
   FAR struct getroute_recvfrom_ipv4resplist_s *alloc;
   FAR struct getroute_recvfrom_ipv4response_s *resp;
-  FAR struct nlroute_info_s *info;
 
-  DEBUGASSERT(route != NULL && arg != NULL);
-  info = (FAR struct nlroute_info_s *)arg;
+  DEBUGASSERT(route != NULL);
 
   /* Allocate the response */
 
@@ -679,19 +678,19 @@ static int netlink_ipv4_route(FAR struct net_route_ipv4_s 
*route,
     kmm_zalloc(sizeof(struct getroute_recvfrom_ipv4resplist_s));
   if (alloc == NULL)
     {
-      return -ENOMEM;
+      return NULL;
     }
 
   /* Format the response */
 
   resp                  = &alloc->payload;
   resp->hdr.nlmsg_len   = sizeof(struct getroute_recvfrom_ipv4response_s);
-  resp->hdr.nlmsg_type  = RTM_NEWROUTE;
-  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  = type;
+  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->rte.rtm_family   = info->req->gen.rtgen_family;
+  resp->rte.rtm_family   = AF_INET;
   resp->rte.rtm_table    = RT_TABLE_MAIN;
   resp->rte.rtm_protocol = RTPROT_STATIC;
   resp->rte.rtm_scope    = RT_SCOPE_SITE;
@@ -708,15 +707,39 @@ static int netlink_ipv4_route(FAR struct net_route_ipv4_s 
*route,
   resp->gateway.attr.rta_type = RTA_GATEWAY;
   resp->gateway.addr          = route->router;
 
+  return (FAR struct netlink_response_s *)alloc;
+}
+
+/****************************************************************************
+ * Name: netlink_ipv4route_callback
+ *
+ * Input Parameters:
+ *   route - The entry of IPV4 routing table.
+ *   arg   - The netlink info of request.
+ *
+ ****************************************************************************/
+
+static int netlink_ipv4route_callback(FAR struct net_route_ipv4_s *route,
+                                      FAR void *arg)
+{
+  FAR struct nlroute_info_s *info = arg;
+  FAR struct netlink_response_s *resp;
+
+  resp = netlink_get_ipv4_route(route, RTM_NEWROUTE, info->req);
+  if (resp == NULL)
+    {
+      return -ENOENT;
+    }
+
   /* Finally, add the response to the list of pending responses */
 
-  netlink_add_response(info->handle, (FAR struct netlink_response_s *)alloc);
+  netlink_add_response(info->handle, resp);
   return OK;
 }
 #endif
 
 /****************************************************************************
- * Name: netlink_get_ipv4route
+ * Name: netlink_list_ipv4_route
  *
  * Description:
  *   Dump a list of all network devices of the specified type.
@@ -724,7 +747,7 @@ static int netlink_ipv4_route(FAR struct net_route_ipv4_s 
*route,
  ****************************************************************************/
 
 #if defined(CONFIG_NET_IPv4) && !defined(CONFIG_NETLINK_DISABLE_GETROUTE)
-static int netlink_get_ipv4route(NETLINK_HANDLE handle,
+static int netlink_list_ipv4_route(NETLINK_HANDLE handle,
                               FAR const struct nlroute_sendto_request_s *req)
 {
   struct nlroute_info_s info;
@@ -735,7 +758,7 @@ static int netlink_get_ipv4route(NETLINK_HANDLE handle,
   info.handle = handle;
   info.req    = req;
 
-  ret = net_foreachroute_ipv4(netlink_ipv4_route, &info);
+  ret = net_foreachroute_ipv4(netlink_ipv4route_callback, &info);
   if (ret < 0)
     {
       return ret;
@@ -748,7 +771,7 @@ static int netlink_get_ipv4route(NETLINK_HANDLE handle,
 #endif
 
 /****************************************************************************
- * Name: netlink_ipv6_route
+ * Name: netlink_get_ipv6_route
  *
  * Description:
  *   Dump a list of all network devices of the specified type.
@@ -756,15 +779,14 @@ static int netlink_get_ipv4route(NETLINK_HANDLE handle,
  ****************************************************************************/
 
 #if defined(CONFIG_NET_IPv6) && !defined(CONFIG_NETLINK_DISABLE_GETROUTE)
-static int netlink_ipv6_route(FAR struct net_route_ipv6_s *route,
-                              FAR void *arg)
+static FAR struct netlink_response_s *
+netlink_get_ipv6_route(FAR const struct net_route_ipv6_s *route, int type,
+                       FAR const struct nlroute_sendto_request_s *req)
 {
   FAR struct getroute_recvfrom_ipv6resplist_s *alloc;
   FAR struct getroute_recvfrom_ipv6response_s *resp;
-  FAR struct nlroute_info_s *info;
 
-  DEBUGASSERT(route != NULL && arg != NULL);
-  info = (FAR struct nlroute_info_s *)arg;
+  DEBUGASSERT(route != NULL);
 
   /* Allocate the response */
 
@@ -772,19 +794,19 @@ static int netlink_ipv6_route(FAR struct net_route_ipv6_s 
*route,
     kmm_zalloc(sizeof(struct getroute_recvfrom_ipv6resplist_s));
   if (alloc == NULL)
     {
-      return -ENOMEM;
+      return NULL;
     }
 
   /* Format the response */
 
   resp                  = &alloc->payload;
   resp->hdr.nlmsg_len   = sizeof(struct getroute_recvfrom_ipv6response_s);
-  resp->hdr.nlmsg_type  = RTM_NEWROUTE;
-  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  = type;
+  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->rte.rtm_family   = info->req->gen.rtgen_family;
+  resp->rte.rtm_family   = AF_INET6;
   resp->rte.rtm_table    = RT_TABLE_MAIN;
   resp->rte.rtm_protocol = RTPROT_STATIC;
   resp->rte.rtm_scope    = RT_SCOPE_SITE;
@@ -801,9 +823,37 @@ static int netlink_ipv6_route(FAR struct net_route_ipv6_s 
*route,
   resp->gateway.attr.rta_type = RTA_GATEWAY;
   net_ipv6addr_copy(resp->gateway.addr, route->router);
 
+  return (FAR struct netlink_response_s *)alloc;
+}
+
+/****************************************************************************
+ * Name: netlink_ipv6route_callback
+ *
+ * Description:
+ *   Response netlink message from ipv6 route list.
+ *
+ * Input Parameters:
+ *   route - The entry of IPV6 routing table.
+ *   arg   - The netlink info of request.
+ *
+ ****************************************************************************/
+
+static int netlink_ipv6route_callback(FAR struct net_route_ipv6_s *route,
+                                      FAR void *arg)
+{
+  FAR struct nlroute_info_s *info = arg;
+  FAR struct netlink_response_s *resp;
+
+  resp = netlink_get_ipv6_route(route, RTM_NEWROUTE, info->req);
+  if (resp == NULL)
+    {
+      return -ENOENT;
+    }
+
   /* Finally, add the response to the list of pending responses */
 
-  netlink_add_response(info->handle, (FAR struct netlink_response_s *)alloc);
+  netlink_add_response(info->handle, resp);
+
   return OK;
 }
 #endif
@@ -817,7 +867,7 @@ static int netlink_ipv6_route(FAR struct net_route_ipv6_s 
*route,
  ****************************************************************************/
 
 #if defined(CONFIG_NET_IPv6) && !defined(CONFIG_NETLINK_DISABLE_GETROUTE)
-static int netlink_get_ipv6route(NETLINK_HANDLE handle,
+static int netlink_list_ipv6_route(NETLINK_HANDLE handle,
                               FAR const struct nlroute_sendto_request_s *req)
 {
   struct nlroute_info_s info;
@@ -828,7 +878,7 @@ static int netlink_get_ipv6route(NETLINK_HANDLE handle,
   info.handle = handle;
   info.req    = req;
 
-  ret = net_foreachroute_ipv6(netlink_ipv6_route, &info);
+  ret = net_foreachroute_ipv6(netlink_ipv6route_callback, &info);
   if (ret < 0)
     {
       return ret;
@@ -1211,14 +1261,14 @@ ssize_t netlink_route_sendto(NETLINK_HANDLE handle,
 #ifdef CONFIG_NET_IPv4
         if (req->gen.rtgen_family == AF_INET)
           {
-            ret = netlink_get_ipv4route(handle, req);
+            ret = netlink_list_ipv4_route(handle, req);
           }
         else
 #endif
 #ifdef CONFIG_NET_IPv6
         if (req->gen.rtgen_family == AF_INET6)
           {
-            ret = netlink_get_ipv6route(handle, req);
+            ret = netlink_list_ipv6_route(handle, req);
           }
         else
 #endif
@@ -1388,4 +1438,57 @@ void netlink_device_notify_ipaddr(FAR struct 
net_driver_s *dev,
 }
 #endif
 
+/****************************************************************************
+ * Name: netlink_route_notify
+ *
+ * Description:
+ *   Perform the route broadcast for the NETLINK_NETFILTER protocol.
+ *
+ * Input Parameters:
+ *   route  - The route entry
+ *   type   - The type of the message, RTM_*ROUTE
+ *   domain - The domain of the message
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_NETLINK_DISABLE_GETROUTE
+void netlink_route_notify(FAR const void *route, int type, int domain)
+{
+  FAR struct netlink_response_s *resp;
+  int group;
+
+  DEBUGASSERT(route != NULL);
+
+#ifdef CONFIG_NET_IPv4
+  if (domain == AF_INET)
+    {
+      resp = netlink_get_ipv4_route((FAR struct net_route_ipv4_s *)route,
+                                    type, NULL);
+      group = RTNLGRP_IPV4_ROUTE;
+    }
+  else
+#endif
+#ifdef CONFIG_NET_IPv6
+  if (domain == AF_INET6)
+    {
+      resp = netlink_get_ipv6_route((FAR struct net_route_ipv6_s *)route,
+                                    type, NULL);
+      group = RTNLGRP_IPV6_ROUTE;
+    }
+    else
+#endif
+    {
+      nwarn("netlink_route_notify unknown type %d domain %d\n",
+            type, domain);
+      return;
+    }
+
+  if (resp != NULL)
+    {
+      netlink_add_broadcast(group, resp);
+      netlink_add_terminator(NULL, NULL, group);
+    }
+}
+#endif
+
 #endif /* CONFIG_NETLINK_ROUTE */
diff --git a/net/route/net_add_fileroute.c b/net/route/net_add_fileroute.c
index 6c846c6c6f..51593ac47a 100644
--- a/net/route/net_add_fileroute.c
+++ b/net/route/net_add_fileroute.c
@@ -33,6 +33,7 @@
 #include <nuttx/fs/fs.h>
 #include <nuttx/net/ip.h>
 
+#include "netlink/netlink.h"
 #include "route/fileroute.h"
 #include "route/route.h"
 
@@ -84,6 +85,8 @@ int net_addroute_ipv4(in_addr_t target, in_addr_t netmask, 
in_addr_t router)
   nwritten = net_writeroute_ipv4(&fshandle, &route);
 
   net_closeroute_ipv4(&fshandle);
+
+  netlink_route_notify(&route, RTM_NEWROUTE, AF_INET);
   return nwritten >= 0 ? 0 : (int)nwritten;
 }
 #endif
@@ -118,6 +121,8 @@ int net_addroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t 
netmask,
   nwritten = net_writeroute_ipv6(&fshandle, &route);
 
   net_closeroute_ipv6(&fshandle);
+
+  netlink_route_notify(&route, RTM_NEWROUTE, AF_INET6);
   return nwritten >= 0 ? 0 : (int)nwritten;
 }
 #endif
diff --git a/net/route/net_add_ramroute.c b/net/route/net_add_ramroute.c
index 05adde4625..5f1907839d 100644
--- a/net/route/net_add_ramroute.c
+++ b/net/route/net_add_ramroute.c
@@ -34,6 +34,7 @@
 
 #include <arch/irq.h>
 
+#include "netlink/netlink.h"
 #include "route/ramroute.h"
 #include "route/route.h"
 
@@ -86,6 +87,8 @@ int net_addroute_ipv4(in_addr_t target, in_addr_t netmask, 
in_addr_t router)
   ramroute_ipv4_addlast((FAR struct net_route_ipv4_entry_s *)route,
                         &g_ipv4_routes);
   net_unlock();
+
+  netlink_route_notify(route, RTM_NEWROUTE, AF_INET);
   return OK;
 }
 #endif
@@ -121,6 +124,8 @@ int net_addroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t 
netmask,
   ramroute_ipv6_addlast((FAR struct net_route_ipv6_entry_s *)route,
                         &g_ipv6_routes);
   net_unlock();
+
+  netlink_route_notify(route, RTM_NEWROUTE, AF_INET6);
   return OK;
 }
 #endif
diff --git a/net/route/net_del_fileroute.c b/net/route/net_del_fileroute.c
index dff88fe7df..5c232ec030 100644
--- a/net/route/net_del_fileroute.c
+++ b/net/route/net_del_fileroute.c
@@ -36,6 +36,7 @@
 #include <nuttx/fs/fs.h>
 #include <nuttx/net/ip.h>
 
+#include "netlink/netlink.h"
 #include "route/fileroute.h"
 #include "route/cacheroute.h"
 #include "route/route.h"
@@ -313,6 +314,8 @@ int net_delroute_ipv4(in_addr_t target, in_addr_t netmask)
   filesize = (nentries - 1) * sizeof(struct net_route_ipv4_s);
   ret = file_truncate(&fshandle, filesize);
 
+  netlink_route_notify(&match, RTM_DELROUTE, AF_INET);
+
 errout_with_fshandle:
   net_closeroute_ipv4(&fshandle);
 
@@ -464,6 +467,8 @@ int net_delroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t 
netmask)
   filesize = (nentries - 1) * sizeof(struct net_route_ipv6_s);
   ret = file_truncate(&fshandle, filesize);
 
+  netlink_route_notify(&match, RTM_DELROUTE, AF_INET6);
+
 errout_with_fshandle:
   net_closeroute_ipv6(&fshandle);
 
diff --git a/net/route/net_del_ramroute.c b/net/route/net_del_ramroute.c
index 5914dd46d2..71e8b067b7 100644
--- a/net/route/net_del_ramroute.c
+++ b/net/route/net_del_ramroute.c
@@ -32,6 +32,7 @@
 #include <arpa/inet.h>
 #include <nuttx/net/ip.h>
 
+#include "netlink/netlink.h"
 #include "route/ramroute.h"
 #include "route/route.h"
 
@@ -64,10 +65,10 @@ struct route_match_ipv6_s
  ****************************************************************************/
 
 /****************************************************************************
- * Name: net_match_ipv4
+ * Name: net_del_ipv4route
  *
  * Description:
- *   Return 1 if the route is available
+ *   Return 1 if the route is available, and delete the match route
  *
  * Input Parameters:
  *   route - The next route to examine
@@ -79,7 +80,8 @@ struct route_match_ipv6_s
  ****************************************************************************/
 
 #ifdef CONFIG_ROUTE_IPv4_RAMROUTE
-static int net_match_ipv4(FAR struct net_route_ipv4_s *route, FAR void *arg)
+static int net_del_ipv4route(FAR struct net_route_ipv4_s *route,
+                             FAR void *arg)
 {
   FAR struct route_match_ipv4_s *match =
                     (FAR struct route_match_ipv4_s *)arg;
@@ -109,6 +111,8 @@ static int net_match_ipv4(FAR struct net_route_ipv4_s 
*route, FAR void *arg)
           ramroute_ipv4_remfirst(&g_ipv4_routes);
         }
 
+      netlink_route_notify(route, RTM_DELROUTE, AF_INET);
+
       /* And free the routing table entry by adding it to the free list */
 
       net_freeroute_ipv4(route);
@@ -126,8 +130,8 @@ static int net_match_ipv4(FAR struct net_route_ipv4_s 
*route, FAR void *arg)
 #endif
 
 #ifdef CONFIG_ROUTE_IPv6_RAMROUTE
-static int net_match_ipv6(
-               FAR struct net_route_ipv6_s *route, FAR void *arg)
+static int net_del_ipv6route(FAR struct net_route_ipv6_s *route,
+                             FAR void *arg)
 {
   FAR struct route_match_ipv6_s *match =
                      (FAR struct route_match_ipv6_s *)arg;
@@ -165,6 +169,8 @@ static int net_match_ipv6(
           ramroute_ipv6_remfirst(&g_ipv6_routes);
         }
 
+      netlink_route_notify(route, RTM_DELROUTE, AF_INET6);
+
       /* And free the routing table entry by adding it to the free list */
 
       net_freeroute_ipv6(route);
@@ -211,7 +217,7 @@ int net_delroute_ipv4(in_addr_t target, in_addr_t netmask)
 
   /* Then remove the entry from the routing table */
 
-  return net_foreachroute_ipv4(net_match_ipv4, &match) ? OK : -ENOENT;
+  return net_foreachroute_ipv4(net_del_ipv4route, &match) ? OK : -ENOENT;
 }
 #endif
 
@@ -228,7 +234,7 @@ int net_delroute_ipv6(net_ipv6addr_t target, net_ipv6addr_t 
netmask)
 
   /* Then remove the entry from the routing table */
 
-  return net_foreachroute_ipv6(net_match_ipv6, &match) ? OK : -ENOENT;
+  return net_foreachroute_ipv6(net_del_ipv6route, &match) ? OK : -ENOENT;
 }
 #endif
 

Reply via email to