-/* $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 <tobhe@openbsd.org>
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 {
};
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)
}
return (vroute_doroute(env, flags, addrs, rdomain, type,
- dest, mask, addr));
+ dest, mask, addr, NULL));
}
int
uint8_t rdomain;
int flags;
int addrs;
+ int need_gw;
ptr = (uint8_t *)imsg->data;
left = IMSG_DATA_SIZE(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];
if ((type == RTM_ADD && errno != EEXIST) ||
(type == RTM_DELETE && errno != ESRCH)) {
log_warn("%s: write %d", __func__, rtm.rtm_errno);
- return (-1);
+ return (0);
}
}
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
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;
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) {
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,