diff options
author | Damien Zammit <damien@zamaudio.com> | 2022-08-29 10:30:04 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-08-29 23:01:17 +0200 |
commit | 574bc98f0f236939c6ef5bc1fc61c919ee8b5d47 (patch) | |
tree | 308c207b2db56a9f8a644a389dd9187f065a9362 /pfinet/options.c | |
parent | 5adb4b834b1eba82b7f3eca6324bed0355cae0af (diff) | |
download | hurd-574bc98f0f236939c6ef5bc1fc61c919ee8b5d47.tar.gz hurd-574bc98f0f236939c6ef5bc1fc61c919ee8b5d47.tar.bz2 hurd-574bc98f0f236939c6ef5bc1fc61c919ee8b5d47.zip |
pfinet: Add SIOCADDRT and SIOCDELRT equivalent iioctls
Using a new client side <net/route.h>
I was able to clean up the existing options.c in pfinet
and add two new ioctls for adding/deleting network routes.
/* move to bits/ioctl.h */
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;
};
Message-Id: <20220829102952.369798-1-damien@zamaudio.com>
Diffstat (limited to 'pfinet/options.c')
-rw-r--r-- | pfinet/options.c | 120 |
1 files changed, 20 insertions, 100 deletions
diff --git a/pfinet/options.c b/pfinet/options.c index ae44759d..1e8c1c26 100644 --- a/pfinet/options.c +++ b/pfinet/options.c @@ -28,6 +28,7 @@ #include <error.h> #include <netinet/in.h> #include <arpa/inet.h> +#include <hurd/ioctl_types.h> #include "pfinet.h" @@ -60,6 +61,10 @@ extern struct inet6_dev *ipv6_find_idev (struct device *dev); extern int inet6_addr_add (int ifindex, struct in6_addr *pfx, int plen); extern int inet6_addr_del (int ifindex, struct in6_addr *pfx, int plen); +/* iioctl.c */ +extern error_t add_route (struct device *dev, struct srtentry *r); +extern error_t delete_route (struct device *dev, struct srtentry *r); + #ifdef CONFIG_IPV6 static struct rt6_info * ipv6_get_dflt_router (void); #endif @@ -504,62 +509,19 @@ parse_opt (int opt, char *arg, struct argp_state *state) #endif /* CONFIG_IPV6 */ } - /* Set the default gateway. This code is cobbled together from what - the SIOCADDRT ioctl code does, and from the apparent functionality - of the "netlink" layer from perusing a little. */ + /* Set the default gateway. */ + { - struct kern_rta rta; - struct - { - struct nlmsghdr nlh; - struct rtmsg rtm; - } req; - struct fib_table *tb; - - req.nlh.nlmsg_pid = 0; - req.nlh.nlmsg_seq = 0; - req.nlh.nlmsg_len = NLMSG_LENGTH (sizeof req.rtm); - - memset (&req.rtm, 0, sizeof req.rtm); - memset (&rta, 0, sizeof rta); - req.rtm.rtm_scope = RT_SCOPE_UNIVERSE; - req.rtm.rtm_type = RTN_UNICAST; - req.rtm.rtm_protocol = RTPROT_STATIC; - - if (!gw4_in) - { - /* Delete any existing default route on configured devices */ - for (in = h->interfaces; in < h->interfaces + h->num_interfaces; - in++) - { - req.nlh.nlmsg_type = RTM_DELROUTE; - req.nlh.nlmsg_flags = 0; - rta.rta_oif = &in->device->ifindex; - tb = fib_get_table (req.rtm.rtm_table); - if (tb) - { - err = - (*tb->tb_delete) - (tb, &req.rtm, &rta, &req.nlh, 0); - if (err && err != ESRCH) - { - pthread_mutex_unlock (&global_lock); - FAIL (err, 17, 0, - "cannot remove old default gateway"); - } - err = 0; - } - } - } - else + struct srtentry route = {0}; + route.rt_flags = RTF_GATEWAY; + route.rt_mask = INADDR_ANY; + route.rt_dest = INADDR_ANY; + route.rt_gateway = h->curint->gateway; + + if (gw4_in) { - /* Add a default route, replacing any existing one. */ - rta.rta_oif = &gw4_in->device->ifindex; - rta.rta_gw = &gw4_in->gateway; - req.nlh.nlmsg_type = RTM_NEWROUTE; - req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE; - tb = fib_new_table (req.rtm.rtm_table); - err = (!tb ? ENOBUFS - : - (*tb->tb_insert) (tb, &req.rtm, &rta, &req.nlh, 0)); + /* Add a default route */ + err = add_route (gw4_in->device, &route); if (err) { pthread_mutex_unlock (&global_lock); @@ -592,55 +554,13 @@ parse_opt (int opt, char *arg, struct argp_state *state) /* Setup the routing required for DHCP. */ for (in = h->interfaces; in < h->interfaces + h->num_interfaces; in++) { - struct kern_rta rta; - struct - { - struct nlmsghdr nlh; - struct rtmsg rtm; - } req; - struct fib_table *tb; - struct rtentry route; - struct sockaddr_in *dst; - struct device *dev; - if (!in->device) continue; + struct srtentry route = {0}; + route.rt_flags = 0; + route.rt_dest = INADDR_ANY; - dst = (struct sockaddr_in *) &route.rt_dst; - if (!in->device->name) - { - pthread_mutex_unlock (&global_lock); - FAIL (ENODEV, 17, 0, "unknown device"); - } - dev = dev_get (in->device->name); - if (!dev) - { - pthread_mutex_unlock (&global_lock); - FAIL (ENODEV, 17, 0, "unknown device"); - } - - /* Simulate the SIOCADDRT behavior. */ - memset (&route, 0, sizeof (struct rtentry)); - memset (&req.rtm, 0, sizeof req.rtm); - memset (&rta, 0, sizeof rta); - req.nlh.nlmsg_type = RTM_NEWROUTE; - - /* Append this routing for 0.0.0.0. By this way we can send always - dhcp messages (e.g dhcp renew). */ - req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE - | NLM_F_APPEND; - req.rtm.rtm_protocol = RTPROT_BOOT; - req.rtm.rtm_scope = RT_SCOPE_LINK; - req.rtm.rtm_type = RTN_UNICAST; - rta.rta_dst = &dst->sin_addr.s_addr; - rta.rta_oif = &dev->ifindex; - - tb = fib_new_table (req.rtm.rtm_table); - if (tb) - err = tb->tb_insert (tb, &req.rtm, &rta, &req.nlh, NULL); - else - err = ENOBUFS; - + err = add_route (in->device, &route); if (err) { pthread_mutex_unlock (&global_lock); |