bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 1/2] Add new RPC for pfinet network routes


From: Damien Zammit
Subject: [PATCH v2 1/2] Add new RPC for pfinet network routes
Date: Fri, 02 Sep 2022 09:06:33 +0000

I had to add some code to linux-src
(otherwise reimplement tons of structs).

---
 hurd/pfinet.defs                      |  9 +++
 pfinet/iioctl-ops.c                   |  1 +
 pfinet/linux-src/include/net/ip_fib.h |  2 +
 pfinet/linux-src/net/ipv4/fib_hash.c  | 84 +++++++++++++++++++++++++++
 pfinet/pfinet-ops.c                   | 84 ++++++++++++++++++++++++++-
 pfinet/pfinet.h                       |  5 +-
 pfinet/route.h                        | 26 +++++++++
 7 files changed, 207 insertions(+), 4 deletions(-)
 create mode 100644 pfinet/route.h

diff --git a/hurd/pfinet.defs b/hurd/pfinet.defs
index ec0b03e34..81f7c1945 100644
--- a/hurd/pfinet.defs
+++ b/hurd/pfinet.defs
@@ -37,3 +37,12 @@ routine pfinet_siocgifconf (
        amount: vm_size_t;
        out buf: data_t, dealloc
 );
+
+/* Return the routing table as a sequence of ifrtreq_t structs.
+   The maximum number of routes returned can be given in AMOUNT.
+   But if AMOUNT is -1, all routes will be returned up to MAX_ROUTES.  */
+routine pfinet_getroutes (
+       port: io_t;
+       amount: vm_size_t;
+       out routes: data_t, dealloc[]
+);
diff --git a/pfinet/iioctl-ops.c b/pfinet/iioctl-ops.c
index b128242bb..adf7bd82b 100644
--- a/pfinet/iioctl-ops.c
+++ b/pfinet/iioctl-ops.c
@@ -104,6 +104,7 @@ prepare_rt_req(struct rt_req *req, struct device *dev, 
in_addr_t dst, in_addr_t
   req->rtm.rtm_type = RTN_UNICAST;
   req->rtm.rtm_protocol = RTPROT_BOOT;
   req->rtm.rtm_dst_len = inet_mask_len(mask);
+  req->rtm.rtm_table = RT_TABLE_MAIN;

   return 0;
 }
diff --git a/pfinet/linux-src/include/net/ip_fib.h 
b/pfinet/linux-src/include/net/ip_fib.h
index 60338945f..faf13c649 100644
--- a/pfinet/linux-src/include/net/ip_fib.h
+++ b/pfinet/linux-src/include/net/ip_fib.h
@@ -17,6 +17,7 @@
 #define _NET_IP_FIB_H

 #include <linux/config.h>
+#include "route.h"

 struct kern_rta
 {
@@ -223,6 +224,7 @@ extern u32  __fib_res_prefsrc(struct fib_result *res);

 /* Exported by fib_hash.c */
 extern struct fib_table *fib_hash_init(int id);
+int fn_hash_get_routes(struct fib_table *tb, ifrtreq_t *routes, int first, int 
count);

 #ifdef CONFIG_IP_MULTIPLE_TABLES
 /* Exported by fib_rules.c */
diff --git a/pfinet/linux-src/net/ipv4/fib_hash.c 
b/pfinet/linux-src/net/ipv4/fib_hash.c
index 074a36876..ca25377c9 100644
--- a/pfinet/linux-src/net/ipv4/fib_hash.c
+++ b/pfinet/linux-src/net/ipv4/fib_hash.c
@@ -883,3 +883,87 @@ __initfunc(struct fib_table * fib_hash_init(int id))
        memset(tb->tb_data, 0, sizeof(struct fn_hash));
        return tb;
 }
+
+/* DZ: Could not fit this anywhere else, due to excessive struct defs in .c 
file */
+
+static void
+fib_node_get_route(int type, int dead, struct fib_info *fi, u32 prefix, u32 
mask, ifrtreq_t *r)
+{
+  int len;
+  static unsigned type2flags[RTN_MAX+1] = {
+    0, 0, 0, 0, 0, 0, 0, RTF_REJECT, RTF_REJECT, 0, 0, 0
+  };
+  unsigned flags = type2flags[type];
+
+  if (fi && fi->fib_nh->nh_gw)
+    flags |= RTF_GATEWAY;
+  if (mask == 0xFFFFFFFF)
+    flags |= RTF_HOST;
+  if (!dead)
+    flags |= RTF_UP;
+
+
+  if (fi && fi->fib_dev)
+    sprintf (r->ifname, "%s", fi->fib_dev->name);
+  else
+    {
+      r->ifname[0] = '*';
+      r->ifname[1] = '\0';
+    }
+
+  r->rt_dest = prefix;
+  r->rt_flags = flags;
+  r->rt_mask = mask;
+
+  if (fi)
+    {
+      r->rt_gateway = fi->fib_nh->nh_gw;
+      r->rt_metric = fi->fib_priority;
+      r->rt_mtu = fi->fib_mtu;
+      r->rt_window = fi->fib_window;
+      r->rt_irtt = fi->fib_rtt;
+    }
+}
+
+int
+fn_hash_get_routes(struct fib_table *tb, ifrtreq_t *routes, int first, int 
count)
+{
+  struct fn_hash *table = (struct fn_hash*)tb->tb_data;
+  struct fn_zone *fz;
+  int pos = 0;
+  int n = 0;
+
+  for (fz=table->fn_zone_list; fz; fz = fz->fz_next)
+    {
+      int i;
+      struct fib_node *f;
+      int maxslot = fz->fz_divisor;
+      struct fib_node **fp = fz->fz_hash;
+
+      if (fz->fz_nent == 0)
+        continue;
+
+      if (pos + fz->fz_nent <= first) {
+          pos += fz->fz_nent;
+          continue;
+      }
+
+      for (i=0; i < maxslot; i++, fp++)
+        {
+          for (f = *fp; f; f = f->fn_next)
+           {
+              if (++pos <= first)
+                continue;
+              fib_node_get_route(f->fn_type,
+                                 f->fn_state & FN_S_ZOMBIE,
+                                 FIB_INFO(f),
+                                 fz_prefix(f->fn_key, fz),
+                                 FZ_MASK(fz), routes);
+             routes++;
+              if (++n >= count)
+                return n;
+            }
+        }
+    }
+  return n;
+}
diff --git a/pfinet/pfinet-ops.c b/pfinet/pfinet-ops.c
index 5db669783..621721898 100644
--- a/pfinet/pfinet-ops.c
+++ b/pfinet/pfinet-ops.c
@@ -22,6 +22,13 @@

 #include <linux/netdevice.h>
 #include <linux/notifier.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.h>
+#include <net/route.h>
+#include <net/sock.h>
+#include <net/ip_fib.h>
+#include <net/addrconf.h>

 #include "pfinet_S.h"
 #include <netinet/in.h>
@@ -32,7 +39,8 @@
 #include <sys/mman.h>

 #include <sys/ioctl.h>
-#include <net/if.h>
+
+#define MAX_ROUTES     255

 extern int dev_ifconf(char *arg);

@@ -91,3 +99,77 @@ S_pfinet_siocgifconf (io_t port,
   pthread_mutex_unlock (&global_lock);
   return err;
 }
+
+int
+get_routing_table(int start, int count, ifrtreq_t *routes)
+{
+  struct fib_table *tb;
+
+  if (!routes)
+    return 0;
+
+  if ((tb = fib_get_table(RT_TABLE_MAIN)) == NULL)
+    return 0;
+
+  return fn_hash_get_routes(tb, routes, start, count);
+}
+
+
+/* Return the routing table as a series of ifrtreq_t structs
+   in routes, but don't return more then AMOUNT number of them.
+   If AMOUNT is -1, we get the full table. */
+error_t
+S_pfinet_getroutes (io_t port,
+                   vm_size_t amount,
+                   data_t *routes,
+                   mach_msg_type_number_t *len,
+                   boolean_t *dealloc_data)
+{
+  error_t err = 0;
+  ifrtreq_t rs[MAX_ROUTES];
+  int n;
+  ifrtreq_t *rtable;
+
+  pthread_mutex_lock (&global_lock);
+
+  if (dealloc_data)
+    *dealloc_data = FALSE;
+
+  if (amount == (vm_size_t) -1)
+    {
+      /* Get all of them, and return the number we got.  */
+      n = get_routing_table (0, MAX_ROUTES, rs);
+      amount = n;
+    }
+  else
+    n = amount;
+
+  if (amount > 0)
+    {
+      /* Possibly allocate a new buffer. */
+      if (*len < amount * sizeof(ifrtreq_t))
+       rtable = (ifrtreq_t *) mmap (0, amount * sizeof(ifrtreq_t), 
PROT_READ|PROT_WRITE,
+                                    MAP_ANON, 0, 0);
+      else
+       rtable = (ifrtreq_t *)*routes;
+
+      memset(rtable, 0, n * sizeof(ifrtreq_t));
+      n = get_routing_table (0, n, rtable);
+    }
+
+  if (rtable == MAP_FAILED)
+    {
+      err = ENOMEM;
+      *len = 0;
+      if ((char *)rtable != *routes)
+       munmap (rtable, amount * sizeof(ifrtreq_t));
+    }
+  else
+    {
+      *len = n * sizeof(ifrtreq_t);
+      *routes = (char *)rtable;
+    }
+
+  pthread_mutex_unlock (&global_lock);
+  return err;
+}
diff --git a/pfinet/pfinet.h b/pfinet/pfinet.h
index d08779bff..f8a1dd8dc 100644
--- a/pfinet/pfinet.h
+++ b/pfinet/pfinet.h
@@ -29,6 +29,7 @@
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <pthread.h>
+#include "route.h"

 extern pthread_mutex_t global_lock;
 extern pthread_mutex_t net_bh_lock;
@@ -77,9 +78,7 @@ error_t make_sockaddr_port (struct socket *, int,
 void init_devices (void);
 void *net_bh_worker (void *);
 void init_time (void);
-void ip_rt_add (short, u_long, u_long, u_long, struct device *,
-               u_short, u_long);
-void ip_rt_del (u_long, struct device *);
+int get_routing_table(int start, int count, ifrtreq_t *routes);
 struct sock;
 error_t tcp_tiocinq (struct sock *sk, mach_msg_type_number_t *amount);

diff --git a/pfinet/route.h b/pfinet/route.h
new file mode 100644
index 000000000..8cb1b8a3f
--- /dev/null
+++ b/pfinet/route.h
@@ -0,0 +1,26 @@
+#ifndef ROUTE_H_
+#define ROUTE_H_
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+typedef struct ifrtreq {
+  char ifname[IFNAMSIZ];
+  in_addr_t rt_dest;
+  in_addr_t rt_mask;
+  in_addr_t rt_gateway;
+  int rt_flags;
+  int rt_metric;
+  int rt_mtu;
+  int rt_window;
+  int rt_irtt;
+  int rt_tos;
+  int rt_class;
+} ifrtreq_t;
+
+#endif
--
2.34.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]