bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH v3 1/2] Add new RPC for pfinet network routes


From: Samuel Thibault
Subject: Re: [PATCH v3 1/2] Add new RPC for pfinet network routes
Date: Sun, 11 Sep 2022 19:13:26 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Damien Zammit, le ven. 09 sept. 2022 09:42:48 +0000, a ecrit:
> ---
>  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  | 80 ++++++++++++++++++++++++
>  pfinet/pfinet-ops.c                   | 88 ++++++++++++++++++++++++++-
>  pfinet/pfinet.h                       |  5 +-
>  pfinet/route.h                        | 42 +++++++++++++
>  7 files changed, 223 insertions(+), 4 deletions(-)
>  create mode 100644 pfinet/route.h
> 
> diff --git a/hurd/pfinet.defs b/hurd/pfinet.defs
> index ec0b03e3..81f7c194 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 b128242b..adf7bd82 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 60338945..faf13c64 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 074a3687..495f1682 100644
> --- a/pfinet/linux-src/net/ipv4/fib_hash.c
> +++ b/pfinet/linux-src/net/ipv4/fib_hash.c
> @@ -883,3 +883,83 @@ __initfunc(struct fib_table * fib_hash_init(int id))
>       memset(tb->tb_data, 0, sizeof(struct fn_hash));
>       return tb;
>  }
> +
> +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] = {
> +             [RTN_UNREACHABLE] = RTF_REJECT,
> +             [RTN_PROHIBIT] = RTF_REJECT
> +     };
> +     unsigned flags;
> +
> +     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) {
> +             snprintf (r->ifname, IFNAMSIZ, "%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 5db66978..9722e0e3 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,81 @@ 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);
> +       if (dealloc_data)
> +         *dealloc_data = TRUE;
> +     }
> +      else
> +     rtable = (ifrtreq_t *)*routes;
> +
> +      n = get_routing_table (0, n, rtable);
> +      if (amount > n)
> +        memset(&rtable[n], 0, (amount - n) * sizeof(ifrtreq_t));
> +    }
> +
> +  if (rtable == MAP_FAILED)
> +    {
> +      /* Should use errno here, but glue headers #undef errno */
> +      err = ENOMEM;
> +      *len = 0;
> +    }
> +  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 d08779bf..f8a1dd8d 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 00000000..00beb6c1
> --- /dev/null
> +++ b/pfinet/route.h
> @@ -0,0 +1,42 @@
> +/*
> +   Copyright (C) 2022  Free Software Foundation, Inc.
> +
> +   This file is part of the GNU Hurd.
> +
> +   The GNU Hurd is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License as
> +   published by the Free Software Foundation; either version 2, or (at
> +   your option) any later version.
> +
> +   The GNU Hurd is distributed in the hope that it will be useful, but
> +   WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
> +
> +#ifndef ROUTE_H_
> +#define ROUTE_H_
> +
> +#include <sys/socket.h>
> +#include <netinet/in.h>
> +#include <arpa/inet.h>
> +#include <net/if.h>
> +
> +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
> 
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

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