summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/rad/frontend.c83
-rw-r--r--usr.sbin/rad/rad.c15
-rw-r--r--usr.sbin/rad/rad.h3
3 files changed, 95 insertions, 6 deletions
diff --git a/usr.sbin/rad/frontend.c b/usr.sbin/rad/frontend.c
index 536822bd439..713b6c203e0 100644
--- a/usr.sbin/rad/frontend.c
+++ b/usr.sbin/rad/frontend.c
@@ -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)
+{
+}
diff --git a/usr.sbin/rad/rad.c b/usr.sbin/rad/rad.c
index 96aa5532989..59b3c073a07 100644
--- a/usr.sbin/rad/rad.c
+++ b/usr.sbin/rad/rad.c
@@ -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);
diff --git a/usr.sbin/rad/rad.h b/usr.sbin/rad/rad.h
index 388437afe5c..8faa2ee5d2c 100644
--- a/usr.sbin/rad/rad.h
+++ b/usr.sbin/rad/rad.h
@@ -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,