pass in route socket from main; stub out handling for now
authorflorian <florian@openbsd.org>
Fri, 13 Jul 2018 08:31:34 +0000 (08:31 +0000)
committerflorian <florian@openbsd.org>
Fri, 13 Jul 2018 08:31:34 +0000 (08:31 +0000)
usr.sbin/rad/frontend.c
usr.sbin/rad/rad.c
usr.sbin/rad/rad.h

index 536822b..713b6c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frontend.c,v 1.5 2018/07/11 19:05:25 florian Exp $    */
+/*     $OpenBSD: frontend.c,v 1.6 2018/07/13 08:31:34 florian Exp $    */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -86,7 +86,8 @@
 #include "frontend.h"
 #include "control.h"
 
-#define        RA_MAX_SIZE     1500
+#define        RA_MAX_SIZE             1500
+#define        ROUTE_SOCKET_BUF_SIZE   16384
 
 struct icmp6_ev {
        struct event             ev;
@@ -131,10 +132,16 @@ void                       get_interface_prefixes(struct ra_iface *,
 void                    build_package(struct ra_iface *);
 void                    build_leaving_package(struct ra_iface *);
 void                    ra_output(struct ra_iface *, struct sockaddr_in6 *);
+void                    get_rtaddrs(int, struct sockaddr *,
+                            struct sockaddr **);
+void                    route_receive(int, short, void *);
+void                    handle_route_message(struct rt_msghdr *,
+                            struct sockaddr **);
 
 struct rad_conf        *frontend_conf;
 struct imsgev          *iev_main;
 struct imsgev          *iev_engine;
+struct event            ev_route;
 int                     icmp6sock = -1, ioctlsock = -1;
 struct ipv6_mreq        all_routers;
 struct sockaddr_in6     all_nodes;
@@ -406,6 +413,14 @@ frontend_dispatch_main(int fd, short event, void *bula)
                                    __func__);
                        event_set(&icmp6ev.ev, icmp6sock, EV_READ | EV_PERSIST,
                            icmp6_receive, NULL);
+               case IMSG_ROUTESOCK:
+                       if ((fd = imsg.fd) == -1)
+                               fatalx("%s: expected to receive imsg "
+                                   "routesocket fd but didn't receive any",
+                                   __func__);
+                       event_set(&ev_route, fd, EV_READ | EV_PERSIST,
+                           route_receive, NULL);
+                       break;
                case IMSG_STARTUP:
                        if (pledge("stdio inet unix route mcast", NULL) == -1)
                                fatal("pledge");
@@ -503,13 +518,11 @@ frontend_dispatch_engine(int fd, short event, void *bula)
 void
 frontend_startup(void)
 {
-#if 0
        if (!event_initialized(&ev_route))
                fatalx("%s: did not receive a route socket from the main "
                    "process", __func__);
 
        event_add(&ev_route, NULL);
-#endif
 
        if (!event_initialized(&icmp6ev.ev))
                fatalx("%s: did not receive a icmp6 socket fd from the main "
@@ -969,3 +982,65 @@ ra_output(struct ra_iface *ra_iface, struct sockaddr_in6 *to)
                log_warn("sendmsg on %s", ra_iface->name);
 
 }
+
+#define ROUNDUP(a) \
+       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
+void
+get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
+{
+       int     i;
+
+       for (i = 0; i < RTAX_MAX; i++) {
+               if (addrs & (1 << i)) {
+                       rti_info[i] = sa;
+                       sa = (struct sockaddr *)((char *)(sa) +
+                           ROUNDUP(sa->sa_len));
+               } else
+                       rti_info[i] = NULL;
+       }
+}
+
+void
+route_receive(int fd, short events, void *arg)
+{
+       static uint8_t                   *buf;
+
+       struct rt_msghdr                *rtm;
+       struct sockaddr                 *sa, *rti_info[RTAX_MAX];
+       ssize_t                          n;
+
+       if (buf == NULL) {
+               buf = malloc(ROUTE_SOCKET_BUF_SIZE);
+               if (buf == NULL)
+                       fatal("malloc");
+       }
+       rtm = (struct rt_msghdr *)buf;
+       if ((n = read(fd, buf, ROUTE_SOCKET_BUF_SIZE)) == -1) {
+               if (errno == EAGAIN || errno == EINTR)
+                       return;
+               log_warn("dispatch_rtmsg: read error");
+               return;
+       }
+
+       if (n == 0)
+               fatal("routing socket closed");
+
+       if (n < (ssize_t)sizeof(rtm->rtm_msglen) || n < rtm->rtm_msglen) {
+               log_warnx("partial rtm of %zd in buffer", n);
+               return;
+       }
+
+       if (rtm->rtm_version != RTM_VERSION)
+               return;
+
+       sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen);
+       get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+
+       handle_route_message(rtm, rti_info);
+}
+
+void
+handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info)
+{
+}
index 96aa553..59b3c07 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rad.c,v 1.4 2018/07/11 19:05:25 florian Exp $ */
+/*     $OpenBSD: rad.c,v 1.5 2018/07/13 08:31:34 florian Exp $ */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -27,6 +27,7 @@
 
 #include <netinet/in.h>
 #include <net/if.h>
+#include <net/route.h>
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 #include <netinet6/in6_var.h>
@@ -129,6 +130,7 @@ main(int argc, char *argv[])
        int                      pipe_main2frontend[2];
        int                      pipe_main2engine[2];
        int                      icmp6sock, on = 1;
+       int                      frontend_routesock, rtfilter;
 
        conffile = CONF_FILE;
        csock = RAD_SOCKET;
@@ -280,7 +282,18 @@ main(int argc, char *argv[])
            sizeof(filt)) == -1)
                fatal("ICMP6_FILTER");
 
+       if ((frontend_routesock = socket(PF_ROUTE, SOCK_RAW | SOCK_CLOEXEC,
+           AF_INET6)) < 0)
+               fatal("route socket");
+
+       rtfilter = ROUTE_FILTER(RTM_IFINFO) | ROUTE_FILTER(RTM_NEWADDR) |
+           ROUTE_FILTER(RTM_DELADDR);
+       if (setsockopt(frontend_routesock, PF_ROUTE, ROUTE_MSGFILTER,
+           &rtfilter, sizeof(rtfilter)) < 0)
+               fatal("setsockopt(ROUTE_MSGFILTER)");
+
        main_imsg_compose_frontend_fd(IMSG_ICMP6SOCK, 0, icmp6sock);
+       main_imsg_compose_frontend_fd(IMSG_ROUTESOCK, 0, frontend_routesock);
 
        main_imsg_send_config(main_conf);
 
index 388437a..8faa2ee 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rad.h,v 1.7 2018/07/12 08:18:10 florian Exp $ */
+/*     $OpenBSD: rad.h,v 1.8 2018/07/13 08:31:34 florian Exp $ */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -57,6 +57,7 @@ enum imsg_type {
        IMSG_RECONF_RA_PREFIX,
        IMSG_RECONF_END,
        IMSG_ICMP6SOCK,
+       IMSG_ROUTESOCK,
        IMSG_STARTUP,
        IMSG_STARTUP_DONE,
        IMSG_RA_RS,