From f9121622725523d4c650fdb28b85016cfb4a3e6b Mon Sep 17 00:00:00 2001 From: tobhe Date: Sat, 27 Feb 2021 17:07:04 +0000 Subject: [PATCH] Set RTF_GATEWAY for host route based on RTM_GET response. --- sbin/iked/vroute.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/sbin/iked/vroute.c b/sbin/iked/vroute.c index ebba6b91716..fe839fc4697 100644 --- a/sbin/iked/vroute.c +++ b/sbin/iked/vroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vroute.c,v 1.4 2021/02/26 21:06:02 tobhe Exp $ */ +/* $OpenBSD: vroute.c,v 1.5 2021/02/27 17:07:04 tobhe Exp $ */ /* * Copyright (c) 2021 Tobias Heider @@ -43,7 +43,7 @@ int vroute_setroute(struct iked *, uint8_t, struct sockaddr *, uint8_t, struct sockaddr *, int); int vroute_doroute(struct iked *, int, int, int, uint8_t, struct sockaddr *, - struct sockaddr *, struct sockaddr *); + struct sockaddr *, struct sockaddr *, int *); int vroute_doaddr(struct iked *, char *, struct sockaddr *, struct sockaddr *, int); struct iked_vroute_sc { @@ -60,7 +60,7 @@ struct vroute_msg { }; int vroute_process(struct iked *, int msglen, struct vroute_msg *, - struct sockaddr *, struct sockaddr *, struct sockaddr *); + struct sockaddr *, struct sockaddr *, struct sockaddr *, int *); void vroute_init(struct iked *env) @@ -273,7 +273,7 @@ vroute_getroute(struct iked *env, struct imsg *imsg) } return (vroute_doroute(env, flags, addrs, rdomain, type, - dest, mask, addr)); + dest, mask, addr, NULL)); } int @@ -288,6 +288,7 @@ vroute_getcloneroute(struct iked *env, struct imsg *imsg) uint8_t rdomain; int flags; int addrs; + int need_gw; ptr = (uint8_t *)imsg->data; left = IMSG_DATA_SIZE(imsg); @@ -315,18 +316,21 @@ vroute_getcloneroute(struct iked *env, struct imsg *imsg) flags = RTF_UP | RTF_HOST | RTF_STATIC; if (vroute_doroute(env, flags, RTA_DST, rdomain, RTM_GET, (struct sockaddr *)&dest, (struct sockaddr *)&mask, - (struct sockaddr *)&addr)) + (struct sockaddr *)&addr, &need_gw)) return (-1); + if (need_gw) + flags |= RTF_GATEWAY; + /* Set explicit route to peer with gateway addr*/ addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; return (vroute_doroute(env, flags, addrs, rdomain, RTM_ADD, - dst, (struct sockaddr *)&mask, (struct sockaddr *)&addr)); + dst, (struct sockaddr *)&mask, (struct sockaddr *)&addr, NULL)); } int vroute_doroute(struct iked *env, int flags, int addrs, int rdomain, uint8_t type, - struct sockaddr *dest, struct sockaddr *mask, struct sockaddr *addr) + struct sockaddr *dest, struct sockaddr *mask, struct sockaddr *addr, int *need_gw) { struct vroute_msg m_rtmsg; struct iovec iov[7]; @@ -399,7 +403,7 @@ vroute_doroute(struct iked *env, int flags, int addrs, int rdomain, uint8_t type if ((type == RTM_ADD && errno != EEXIST) || (type == RTM_DELETE && errno != ESRCH)) { log_warn("%s: write %d", __func__, rtm.rtm_errno); - return (-1); + return (0); } } @@ -408,7 +412,7 @@ vroute_doroute(struct iked *env, int flags, int addrs, int rdomain, uint8_t type len = read(ivr->ivr_rtsock, &m_rtmsg, sizeof(m_rtmsg)); } while(len > 0 && (rtm.rtm_version != RTM_VERSION || rtm.rtm_seq != ivr->ivr_rtseq || rtm.rtm_pid != ivr->ivr_pid)); - return (vroute_process(env, len, &m_rtmsg, dest, mask, addr)); + return (vroute_process(env, len, &m_rtmsg, dest, mask, addr, need_gw)); } #undef rtm @@ -417,7 +421,7 @@ vroute_doroute(struct iked *env, int flags, int addrs, int rdomain, uint8_t type int vroute_process(struct iked *env, int msglen, struct vroute_msg *m_rtmsg, - struct sockaddr *dest, struct sockaddr *mask, struct sockaddr *addr) + struct sockaddr *dest, struct sockaddr *mask, struct sockaddr *addr, int *need_gw) { struct sockaddr *sa; char *cp; @@ -440,6 +444,7 @@ vroute_process(struct iked *env, int msglen, struct vroute_msg *m_rtmsg, return (-1); } cp = m_rtmsg->vm_space; + *need_gw = rtm.rtm_flags & RTF_GATEWAY; if(rtm.rtm_addrs) { for (i = 1; i; i <<= 1) { if (i & rtm.rtm_addrs) { @@ -508,7 +513,6 @@ vroute_doaddr(struct iked *env, char *ifname, struct sockaddr *addr, memcpy(&req6.ifra_prefixmask, mask, sizeof(req6.ifra_prefixmask)); - inet_ntop(af, &((struct sockaddr_in6 *)addr)->sin6_addr, addr_buf, sizeof(addr_buf)); inet_ntop(af, &((struct sockaddr_in6 *)mask)->sin6_addr, -- 2.20.1