diff options
author | Damien Zammit <damien@zamaudio.com> | 2022-09-09 09:42:48 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-09-11 19:10:14 +0200 |
commit | b43d6d6f4617cf045ef1a5443568360df6cef328 (patch) | |
tree | 5a83d5debdcc9e665eab196675108cc3db3d183f /pfinet/linux-src | |
parent | da8d2ba4b61a7d6b25f5b2215447795f2b9badf9 (diff) | |
download | hurd-b43d6d6f4617cf045ef1a5443568360df6cef328.tar.gz hurd-b43d6d6f4617cf045ef1a5443568360df6cef328.tar.bz2 hurd-b43d6d6f4617cf045ef1a5443568360df6cef328.zip |
Add new RPC for pfinet network routes
Message-Id: <20220909094234.517165-1-damien@zamaudio.com>
Diffstat (limited to 'pfinet/linux-src')
-rw-r--r-- | pfinet/linux-src/include/net/ip_fib.h | 2 | ||||
-rw-r--r-- | pfinet/linux-src/net/ipv4/fib_hash.c | 80 |
2 files changed, 82 insertions, 0 deletions
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; +} |