summaryrefslogtreecommitdiff
path: root/usr.sbin/relayd/pfe_route.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2011-05-19 08:56:50 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2011-05-19 08:56:50 +0000
commit31b1bbafe11da6e0dead1dd433eff2ab64ae8bb6 (patch)
tree911cab636cae40f30bbaab5a11769d79cf7f41b2 /usr.sbin/relayd/pfe_route.c
parent1e687a712e695c6cf93da2be7c3d01ef04f587cb (diff)
Fix reload support in relayd(8) by reimplementing large parts of the
daemon infrastructure. The previous design made it fairly hard to reload the complex data structures, especially relays and protocols. One of the reasons was that the privsep'd relayd processes had two ways of getting their configuration: 1) from memory after forking from the parent process and 2) and (partially) via imsgs after reload. The new implementation first forks the privsep'd children before the parents loads the configuration and sends it via imsgs to them; so it is only like 2) before. It is based on an approach that I first implemented for iked(8) and I also fixed many bugs in the code. Thanks to many testers including dlg@ sthen@ phessler@ ok pyr@ dlg@ sthen@
Diffstat (limited to 'usr.sbin/relayd/pfe_route.c')
-rw-r--r--usr.sbin/relayd/pfe_route.c51
1 files changed, 22 insertions, 29 deletions
diff --git a/usr.sbin/relayd/pfe_route.c b/usr.sbin/relayd/pfe_route.c
index 0fae0dfd0a0..e0b5066eb40 100644
--- a/usr.sbin/relayd/pfe_route.c
+++ b/usr.sbin/relayd/pfe_route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfe_route.c,v 1.4 2011/05/09 12:08:47 reyk Exp $ */
+/* $OpenBSD: pfe_route.c,v 1.5 2011/05/19 08:56:49 reyk Exp $ */
/*
* Copyright (c) 2009 Reyk Floeter <reyk@openbsd.org>
@@ -96,9 +96,10 @@ sync_routes(struct relayd *env, struct router *rt)
HOST_ISUP(host->up) ? "up" : "down",
host->conf.priority);
- crt.id = nr->nr_conf.id;
- crt.hostid = host->conf.id;
crt.up = host->up;
+ memcpy(&crt.nr, &nr->nr_conf, sizeof(nr->nr_conf));
+ memcpy(&crt.host, &host->conf, sizeof(host->conf));
+ memcpy(&crt.rt, &rt->rt_conf, sizeof(rt->rt_conf));
proc_compose_imsg(env->sc_ps, PROC_PARENT, -1,
IMSG_RTMSG, -1, &crt, sizeof(crt));
@@ -115,19 +116,11 @@ pfe_route(struct relayd *env, struct ctl_netroute *crt)
struct sockaddr_in *s4;
struct sockaddr_in6 *s6;
size_t len = 0;
- struct netroute *nr;
- struct host *host;
char *gwname;
int i = 0;
- if ((nr = route_find(env, crt->id)) == NULL ||
- (host = host_find(env, crt->hostid)) == NULL) {
- log_debug("%s: invalid host or route id", __func__);
- return (-1);
- }
-
- gw = &host->conf.ss;
- gwname = host->conf.name;
+ gw = &crt->host.ss;
+ gwname = crt->host.name;
bzero(&rm, sizeof(rm));
bzero(&sr, sizeof(sr));
@@ -138,18 +131,18 @@ pfe_route(struct relayd *env, struct ctl_netroute *crt)
rm.rm_hdr.rtm_flags = RTF_STATIC | RTF_GATEWAY | RTF_MPATH;
rm.rm_hdr.rtm_seq = env->sc_rtseq++;
rm.rm_hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
- rm.rm_hdr.rtm_tableid = nr->nr_router->rt_conf.rtable;
- rm.rm_hdr.rtm_priority = host->conf.priority;
+ rm.rm_hdr.rtm_tableid = crt->rt.rtable;
+ rm.rm_hdr.rtm_priority = crt->host.priority;
- if (strlen(nr->nr_router->rt_conf.label)) {
+ if (strlen(crt->rt.label)) {
rm.rm_hdr.rtm_addrs |= RTA_LABEL;
sr.sr_len = sizeof(sr);
if (snprintf(sr.sr_label, sizeof(sr.sr_label),
- "%s", nr->nr_router->rt_conf.label) == -1)
+ "%s", crt->rt.label) == -1)
goto bad;
}
- if (nr->nr_conf.ss.ss_family == AF_INET) {
+ if (crt->nr.ss.ss_family == AF_INET) {
rm.rm_hdr.rtm_msglen = len =
sizeof(rm.rm_hdr) + sizeof(rm.rm_u.u4);
@@ -159,7 +152,7 @@ pfe_route(struct relayd *env, struct ctl_netroute *crt)
s4->sin_family = AF_INET;
s4->sin_len = sizeof(rm.rm_u.u4.rm_dst);
s4->sin_addr.s_addr =
- ((struct sockaddr_in *)&nr->nr_conf.ss)->sin_addr.s_addr;
+ ((struct sockaddr_in *)&crt->nr.ss)->sin_addr.s_addr;
s4 = &rm.rm_u.u4.rm_gateway;
s4->sin_family = AF_INET;
@@ -171,19 +164,19 @@ pfe_route(struct relayd *env, struct ctl_netroute *crt)
s4 = &rm.rm_u.u4.rm_netmask;
s4->sin_family = AF_INET;
s4->sin_len = sizeof(rm.rm_u.u4.rm_netmask);
- if (nr->nr_conf.prefixlen)
+ if (crt->nr.prefixlen)
s4->sin_addr.s_addr =
- htonl(0xffffffff << (32 - nr->nr_conf.prefixlen));
- else if (nr->nr_conf.prefixlen < 0)
+ htonl(0xffffffff << (32 - crt->nr.prefixlen));
+ else if (crt->nr.prefixlen < 0)
rm.rm_hdr.rtm_flags |= RTF_HOST;
- } else if (nr->nr_conf.ss.ss_family == AF_INET6) {
+ } else if (crt->nr.ss.ss_family == AF_INET6) {
rm.rm_hdr.rtm_msglen = len =
sizeof(rm.rm_hdr) + sizeof(rm.rm_u.u6);
bcopy(&sr, &rm.rm_u.u6.rm_label, sizeof(sr));
s6 = &rm.rm_u.u6.rm_dst;
- bcopy(((struct sockaddr_in6 *)&nr->nr_conf.ss),
+ bcopy(((struct sockaddr_in6 *)&crt->nr.ss),
s6, sizeof(*s6));
s6->sin6_family = AF_INET6;
s6->sin6_len = sizeof(*s6);
@@ -197,14 +190,14 @@ pfe_route(struct relayd *env, struct ctl_netroute *crt)
s6 = &rm.rm_u.u6.rm_netmask;
s6->sin6_family = AF_INET6;
s6->sin6_len = sizeof(*s6);
- if (nr->nr_conf.prefixlen) {
- for (i = 0; i < nr->nr_conf.prefixlen / 8; i++)
+ if (crt->nr.prefixlen) {
+ for (i = 0; i < crt->nr.prefixlen / 8; i++)
s6->sin6_addr.s6_addr[i] = 0xff;
- i = nr->nr_conf.prefixlen % 8;
+ i = crt->nr.prefixlen % 8;
if (i)
- s6->sin6_addr.s6_addr[nr->nr_conf.prefixlen
+ s6->sin6_addr.s6_addr[crt->nr.prefixlen
/ 8] = 0xff00 >> i;
- } else if (nr->nr_conf.prefixlen < 0)
+ } else if (crt->nr.prefixlen < 0)
rm.rm_hdr.rtm_flags |= RTF_HOST;
} else
fatal("pfe_route: invalid address family");