summaryrefslogtreecommitdiff
path: root/sbin/iked/vroute.c
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2023-02-10 19:51:09 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2023-02-10 19:51:09 +0000
commit0a8634c4115e371893d1b8b9df63ada1f646ffb0 (patch)
tree9af72c99c79e9194d7ae7059d231ba19763ce0a5 /sbin/iked/vroute.c
parent05ea373e6aa6e3cf10b2114aaa604b02274e6a10 (diff)
Add support for configuring multiple name servers as roadwarrior
client. This allows us to have a fallback in case one connection fails. Tested by Ryan Kavanagh ok patrick@
Diffstat (limited to 'sbin/iked/vroute.c')
-rw-r--r--sbin/iked/vroute.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/sbin/iked/vroute.c b/sbin/iked/vroute.c
index 89a7f01cc5e..7f900e771e3 100644
--- a/sbin/iked/vroute.c
+++ b/sbin/iked/vroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vroute.c,v 1.17 2022/07/18 19:32:16 tobhe Exp $ */
+/* $OpenBSD: vroute.c,v 1.18 2023/02/10 19:51:08 tobhe Exp $ */
/*
* Copyright (c) 2021 Tobias Heider <tobhe@openbsd.org>
@@ -76,12 +76,14 @@ TAILQ_HEAD(vroute_routes, vroute_route);
struct vroute_dns {
struct sockaddr_storage vd_addr;
int vd_ifidx;
+ TAILQ_ENTRY(vroute_dns) vd_entry;
};
+TAILQ_HEAD(vroute_dnss, vroute_dns);
struct iked_vroute_sc {
struct vroute_addrs ivr_addrs;
struct vroute_routes ivr_routes;
- struct vroute_dns *ivr_dns;
+ struct vroute_dnss ivr_dnss;
struct event ivr_routeev;
int ivr_iosock;
int ivr_iosock6;
@@ -103,6 +105,7 @@ vroute_rtmsg_cb(int fd, short events, void *arg)
{
struct iked *env = (struct iked *) arg;
struct iked_vroute_sc *ivr = env->sc_vroute;
+ struct vroute_dns *dns;
static uint8_t *buf;
struct rt_msghdr *rtm;
ssize_t n;
@@ -133,11 +136,12 @@ vroute_rtmsg_cb(int fd, short events, void *arg)
switch(rtm->rtm_type) {
case RTM_PROPOSAL:
- if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT &&
- ivr->ivr_dns) {
- log_debug("%s: got solicit", __func__);
- vroute_dodns(env, (struct sockaddr *)&ivr->ivr_dns->vd_addr, 1,
- ivr->ivr_dns->vd_ifidx);
+ if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT) {
+ TAILQ_FOREACH(dns, &ivr->ivr_dnss, vd_entry) {
+ log_debug("%s: got solicit", __func__);
+ vroute_dodns(env, (struct sockaddr *) &dns->vd_addr,
+ 1, dns->vd_ifidx);
+ }
}
break;
default:
@@ -171,6 +175,7 @@ vroute_init(struct iked *env)
fatal("%s: setsockopt(ROUTE_MSGFILTER)", __func__);
TAILQ_INIT(&ivr->ivr_addrs);
+ TAILQ_INIT(&ivr->ivr_dnss);
TAILQ_INIT(&ivr->ivr_routes);
ivr->ivr_pid = getpid();
@@ -189,6 +194,7 @@ vroute_cleanup(struct iked *env)
struct iked_vroute_sc *ivr = env->sc_vroute;
struct vroute_addr *addr;
struct vroute_route *route;
+ struct vroute_dns *dns;
while ((addr = TAILQ_FIRST(&ivr->ivr_addrs))) {
if_indextoname(addr->va_ifidx, ifname);
@@ -209,10 +215,11 @@ vroute_cleanup(struct iked *env)
free(route);
}
- if (ivr->ivr_dns) {
- vroute_dodns(env, (struct sockaddr *)&ivr->ivr_dns->vd_addr, 0,
- ivr->ivr_dns->vd_ifidx);
- free(ivr->ivr_dns);
+ while ((dns = TAILQ_FIRST(&ivr->ivr_dnss))) {
+ vroute_dodns(env, (struct sockaddr *)&dns->vd_addr, 0,
+ dns->vd_ifidx);
+ TAILQ_REMOVE(&ivr->ivr_dnss, dns, vd_entry);
+ free(dns);
}
}
@@ -334,7 +341,6 @@ vroute_setdns(struct iked *env, int add, struct sockaddr *addr,
int
vroute_getdns(struct iked *env, struct imsg *imsg)
{
- struct iked_vroute_sc *ivr = env->sc_vroute;
struct sockaddr *dns;
uint8_t *ptr;
size_t left;
@@ -361,12 +367,8 @@ vroute_getdns(struct iked *env, struct imsg *imsg)
add = (imsg->hdr.type == IMSG_VDNS_ADD);
if (add) {
- if (ivr->ivr_dns != NULL)
- return (0);
vroute_insertdns(env, ifidx, dns);
} else {
- if (ivr->ivr_dns == NULL)
- return (0);
vroute_removedns(env, ifidx, dns);
}
@@ -432,19 +434,23 @@ vroute_insertdns(struct iked *env, int ifidx, struct sockaddr *addr)
memcpy(&dns->vd_addr, addr, addr->sa_len);
dns->vd_ifidx = ifidx;
- ivr->ivr_dns = dns;
+ TAILQ_INSERT_TAIL(&ivr->ivr_dnss, dns, vd_entry);
}
void
vroute_removedns(struct iked *env, int ifidx, struct sockaddr *addr)
{
struct iked_vroute_sc *ivr = env->sc_vroute;
+ struct vroute_dns *dns, *tdns;
+
+ TAILQ_FOREACH_SAFE(dns, &ivr->ivr_dnss, vd_entry, tdns) {
+ if (ifidx != dns->vd_ifidx)
+ continue;
+ if (sockaddr_cmp(addr, (struct sockaddr *) &dns->vd_addr, -1))
+ continue;
- if (ifidx == ivr->ivr_dns->vd_ifidx &&
- sockaddr_cmp(addr, (struct sockaddr *)
- &ivr->ivr_dns->vd_addr, -1) == 0) {
- free(ivr->ivr_dns);
- ivr->ivr_dns = NULL;
+ TAILQ_REMOVE(&ivr->ivr_dnss, dns, vd_entry);
+ free(dns);
}
}