summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2017-05-30 19:27:16 +0000
committerflorian <florian@openbsd.org>2017-05-30 19:27:16 +0000
commit0e74924deb6684cd40a34b00d528c4783a3bfda9 (patch)
tree987ed42e84d43e4fc7c043111d958cbf0694955b
parentAdd missing KERNEL_LOCKs to a few error paths. (diff)
downloadwireguard-openbsd-0e74924deb6684cd40a34b00d528c4783a3bfda9.tar.xz
wireguard-openbsd-0e74924deb6684cd40a34b00d528c4783a3bfda9.zip
Send a source link-layer address option with our solicitations.
Servers following RFC 7772 may then send us unicast router advertisments and thus reduce multicast traffic which might increase the battery life of other devices using the same shared media.
-rw-r--r--usr.sbin/slaacd/frontend.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/usr.sbin/slaacd/frontend.c b/usr.sbin/slaacd/frontend.c
index 03ebe29bc44..173c95635ce 100644
--- a/usr.sbin/slaacd/frontend.c
+++ b/usr.sbin/slaacd/frontend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frontend.c,v 1.14 2017/05/30 18:18:08 deraadt Exp $ */
+/* $OpenBSD: frontend.c,v 1.15 2017/05/30 19:27:16 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -74,8 +74,10 @@ struct imsgev *iev_main;
struct imsgev *iev_engine;
struct event ev_route;
struct msghdr sndmhdr;
-struct iovec sndiov[2];
+struct iovec sndiov[4];
struct nd_router_solicit rs;
+struct nd_opt_hdr nd_opt_hdr;
+struct ether_addr nd_opt_source_link_addr;
struct sockaddr_in6 dst;
int icmp6sock, routesock, xflagssock;
@@ -228,6 +230,9 @@ frontend(int debug, int verbose, char *sockname)
rs.nd_rs_cksum = 0;
rs.nd_rs_reserved = 0;
+ nd_opt_hdr.nd_opt_type = ND_OPT_SOURCE_LINKADDR;
+ nd_opt_hdr.nd_opt_len = 1;
+
memset(&dst, 0, sizeof(dst));
dst.sin6_family = AF_INET6;
if (inet_pton(AF_INET6, ALLROUTER, &dst.sin6_addr.s6_addr) != 1)
@@ -235,13 +240,17 @@ frontend(int debug, int verbose, char *sockname)
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
sndmhdr.msg_iov = sndiov;
- sndmhdr.msg_iovlen = 1;
+ sndmhdr.msg_iovlen = 3;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
sndmhdr.msg_controllen = sndcmsglen;
sndmhdr.msg_name = (caddr_t)&dst;
sndmhdr.msg_iov[0].iov_base = (caddr_t)&rs;
sndmhdr.msg_iov[0].iov_len = sizeof(rs);
+ sndmhdr.msg_iov[1].iov_base = (caddr_t)&nd_opt_hdr;
+ sndmhdr.msg_iov[1].iov_len = sizeof(nd_opt_hdr);
+ sndmhdr.msg_iov[2].iov_base = (caddr_t)&nd_opt_source_link_addr;
+ sndmhdr.msg_iov[2].iov_len = sizeof(nd_opt_source_link_addr);
cm = CMSG_FIRSTHDR(&sndmhdr);
@@ -501,6 +510,9 @@ update_iface(uint32_t if_index, char* if_name)
imsg_ifinfo.autoconfprivacy = !(xflags & IFXF_INET6_NOPRIVACY);
get_lladdr(if_name, &imsg_ifinfo.hw_address, &imsg_ifinfo.ll_address);
+ memcpy(&nd_opt_source_link_addr, &imsg_ifinfo.hw_address,
+ sizeof(nd_opt_source_link_addr));
+
frontend_imsg_compose_engine(IMSG_UPDATE_IF, 0, 0, &imsg_ifinfo,
sizeof(imsg_ifinfo));
}
@@ -820,6 +832,7 @@ send_solicitation(uint32_t if_index)
pi = (struct in6_pktinfo *)CMSG_DATA(cm);
pi->ipi6_ifindex = if_index;
- if (sendmsg(icmp6sock, &sndmhdr, 0) != sizeof(rs))
+ if (sendmsg(icmp6sock, &sndmhdr, 0) != sizeof(rs) +
+ sizeof(nd_opt_hdr) + sizeof(nd_opt_source_link_addr))
log_warn("sendmsg");
}