summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpamela <pamela@openbsd.org>2019-08-30 17:25:37 +0000
committerpamela <pamela@openbsd.org>2019-08-30 17:25:37 +0000
commitb64c4682bb880132c8db3fe68f3cc1f3caec8fe0 (patch)
tree206455ae703e81d3648d553c0a17b849bdb9bfaf
parentrevert r1.175 which added unveil to relayd; "check script" needs access to the (diff)
downloadwireguard-openbsd-b64c4682bb880132c8db3fe68f3cc1f3caec8fe0.tar.xz
wireguard-openbsd-b64c4682bb880132c8db3fe68f3cc1f3caec8fe0.zip
Remove configured IPv6 addresses remaining when slaacd(8) detects a
link-state change and no new router advertisement is obtained (in accordance with RFC 6059). This should improve IPv6 -> legacy-IP-only transitions, preventing applications from believing IPv6 connectivity is available when it is not, potentially resulting in long timeouts. suggestion, input and OK florian@ phessler@
-rw-r--r--sbin/slaacd/engine.c57
-rw-r--r--sbin/slaacd/slaacd.c37
-rw-r--r--sbin/slaacd/slaacd.h3
3 files changed, 89 insertions, 8 deletions
diff --git a/sbin/slaacd/engine.c b/sbin/slaacd/engine.c
index f4d08df9c9b..aac8f7e1b8d 100644
--- a/sbin/slaacd/engine.c
+++ b/sbin/slaacd/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.38 2019/08/26 18:50:04 pamela Exp $ */
+/* $OpenBSD: engine.c,v 1.39 2019/08/30 17:25:37 pamela Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -91,6 +91,7 @@ enum if_state {
IF_DELAY,
IF_PROBE,
IF_IDLE,
+ IF_DEAD,
};
const char* if_state_name[] = {
@@ -98,6 +99,7 @@ const char* if_state_name[] = {
"IF_DELAY",
"IF_PROBE",
"IF_IDLE",
+ "IF_DEAD",
};
enum proposal_state {
@@ -107,6 +109,7 @@ enum proposal_state {
PROPOSAL_NEARLY_EXPIRED,
PROPOSAL_WITHDRAWN,
PROPOSAL_DUPLICATED,
+ PROPOSAL_STALE,
};
const char* proposal_state_name[] = {
@@ -116,6 +119,7 @@ const char* proposal_state_name[] = {
"NEARLY_EXPIRED",
"WITHDRAWN",
"DUPLICATED",
+ "STALE",
};
const char* rpref_name[] = {
@@ -245,6 +249,7 @@ void gen_addr(struct slaacd_iface *, struct radv_prefix *,
void gen_address_proposal(struct slaacd_iface *, struct
radv *, struct radv_prefix *, int);
void free_address_proposal(struct address_proposal *);
+void withdraw_addr(struct address_proposal *);
void timeout_from_lifetime(struct address_proposal *);
void configure_address(struct address_proposal *);
void in6_prefixlen2mask(struct in6_addr *, int len);
@@ -1996,10 +2001,31 @@ free_address_proposal(struct address_proposal *addr_proposal)
LIST_REMOVE(addr_proposal, entries);
evtimer_del(&addr_proposal->timer);
+ switch (addr_proposal->state) {
+ case PROPOSAL_STALE:
+ withdraw_addr(addr_proposal);
+ break;
+ default:
+ break;
+ }
free(addr_proposal);
}
void
+withdraw_addr(struct address_proposal *addr_proposal)
+{
+ struct imsg_configure_address address;
+
+ log_debug("%s: %d", __func__, addr_proposal->if_index);
+ memset(&address, 0, sizeof(address));
+ address.if_index = addr_proposal->if_index;
+ memcpy(&address.addr, &addr_proposal->addr, sizeof(address.addr));
+
+ engine_imsg_compose_main(IMSG_WITHDRAW_ADDRESS, 0, &address,
+ sizeof(address));
+}
+
+void
gen_dfr_proposal(struct slaacd_iface *iface, struct radv *ra)
{
struct dfr_proposal *dfr_proposal;
@@ -2095,6 +2121,7 @@ free_dfr_proposal(struct dfr_proposal *dfr_proposal)
switch (dfr_proposal->state) {
case PROPOSAL_CONFIGURED:
case PROPOSAL_NEARLY_EXPIRED:
+ case PROPOSAL_STALE:
withdraw_dfr(dfr_proposal);
break;
default:
@@ -2235,6 +2262,8 @@ address_proposal_timeout(int fd, short events, void *arg)
log_debug("%s: address duplicated",
__func__);
break;
+ case PROPOSAL_STALE:
+ break;
default:
log_debug("%s: unhandled state: %s", __func__,
proposal_state_name[addr_proposal->state]);
@@ -2327,6 +2356,8 @@ iface_timeout(int fd, short events, void *arg)
{
struct slaacd_iface *iface = (struct slaacd_iface *)arg;
struct timeval tv;
+ struct address_proposal *addr_proposal;
+ struct dfr_proposal *dfr_proposal;
log_debug("%s[%d]: %s", __func__, iface->if_index,
if_state_name[iface->state]);
@@ -2338,12 +2369,26 @@ iface_timeout(int fd, short events, void *arg)
engine_imsg_compose_frontend(
IMSG_CTL_SEND_SOLICITATION, 0, &iface->if_index,
sizeof(iface->if_index));
- if (++iface->probes >= MAX_RTR_SOLICITATIONS)
- iface->state = IF_IDLE;
- else {
+ if (++iface->probes >= MAX_RTR_SOLICITATIONS) {
+ iface->state = IF_DEAD;
+ tv.tv_sec = 0;
+ } else
tv.tv_sec = RTR_SOLICITATION_INTERVAL;
- tv.tv_usec = arc4random_uniform(1000000);
- evtimer_add(&iface->timer, &tv);
+ tv.tv_usec = arc4random_uniform(1000000);
+ evtimer_add(&iface->timer, &tv);
+ break;
+ case IF_DEAD:
+ while(!LIST_EMPTY(&iface->addr_proposals)) {
+ addr_proposal =
+ LIST_FIRST(&iface->addr_proposals);
+ addr_proposal->state = PROPOSAL_STALE;
+ free_address_proposal(addr_proposal);
+ }
+ while(!LIST_EMPTY(&iface->dfr_proposals)) {
+ dfr_proposal =
+ LIST_FIRST(&iface->dfr_proposals);
+ dfr_proposal->state = PROPOSAL_STALE;
+ free_dfr_proposal(dfr_proposal);
}
break;
case IF_DOWN:
diff --git a/sbin/slaacd/slaacd.c b/sbin/slaacd/slaacd.c
index 5d4eda9421f..26a2e33493c 100644
--- a/sbin/slaacd/slaacd.c
+++ b/sbin/slaacd/slaacd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.c,v 1.38 2019/06/28 13:32:46 deraadt Exp $ */
+/* $OpenBSD: slaacd.c,v 1.39 2019/08/30 17:25:37 pamela Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -65,6 +65,7 @@ void main_dispatch_frontend(int, short, void *);
void main_dispatch_engine(int, short, void *);
void handle_proposal(struct imsg_proposal *);
void configure_interface(struct imsg_configure_address *);
+void delete_address(struct imsg_configure_address *);
void configure_gateway(struct imsg_configure_dfr *, uint8_t);
void add_gateway(struct imsg_configure_dfr *);
void delete_gateway(struct imsg_configure_dfr *);
@@ -519,6 +520,14 @@ main_dispatch_engine(int fd, short event, void *bula)
memcpy(&address, imsg.data, sizeof(address));
configure_interface(&address);
break;
+ case IMSG_WITHDRAW_ADDRESS:
+ if (IMSG_DATA_SIZE(imsg) != sizeof(address))
+ fatalx("%s: IMSG_WITHDRAW_ADDRESS wrong "
+ "length: %lu", __func__,
+ IMSG_DATA_SIZE(imsg));
+ memcpy(&address, imsg.data, sizeof(address));
+ delete_address(&address);
+ break;
case IMSG_CONFIGURE_DFR:
if (IMSG_DATA_SIZE(imsg) != sizeof(dfr))
fatalx("%s: IMSG_CONFIGURE_DFR wrong "
@@ -771,6 +780,32 @@ configure_interface(struct imsg_configure_address *address)
}
void
+delete_address(struct imsg_configure_address *address)
+{
+
+ struct in6_ifreq in6_ridreq;
+ char *if_name;
+
+ memset(&in6_ridreq, 0, sizeof(in6_ridreq));
+
+ if_name = if_indextoname(address->if_index, in6_ridreq.ifr_name);
+ if (if_name == NULL) {
+ log_warnx("%s: cannot find interface %d", __func__,
+ address->if_index);
+ return;
+ }
+
+ memcpy(&in6_ridreq.ifr_ifru, &address->addr,
+ sizeof(in6_ridreq.ifr_ifru));
+
+ log_debug("%s: %s", __func__, if_name);
+
+ if (ioctl(ioctl_sock, SIOCDIFADDR_IN6, &in6_ridreq) == -1)
+ log_warn("%s: cannot remove address", __func__);
+
+}
+
+void
configure_gateway(struct imsg_configure_dfr *dfr, uint8_t rtm_type)
{
struct rt_msghdr rtm;
diff --git a/sbin/slaacd/slaacd.h b/sbin/slaacd/slaacd.h
index eea0d906516..c82b35d92e8 100644
--- a/sbin/slaacd/slaacd.h
+++ b/sbin/slaacd/slaacd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.h,v 1.21 2019/03/02 05:34:59 pamela Exp $ */
+/* $OpenBSD: slaacd.h,v 1.22 2019/08/30 17:25:37 pamela Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -72,6 +72,7 @@ enum imsg_type {
IMSG_PROPOSAL,
IMSG_PROPOSAL_ACK,
IMSG_CONFIGURE_ADDRESS,
+ IMSG_WITHDRAW_ADDRESS,
IMSG_DEL_ADDRESS,
IMSG_DEL_ROUTE,
IMSG_FAKE_ACK,