summaryrefslogtreecommitdiff
path: root/sbin/slaacd
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2018-02-10 05:58:00 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2018-02-10 05:58:00 +0000
commit040fcac5496fcb05243ae57288d3169ddfb1dbc1 (patch)
tree0cec2851feb146098fa4f08a5912fc6f0b57ab9c /sbin/slaacd
parentdc78b166bf4558328cfbe1dcab7c6cf45914c4c6 (diff)
RFC 7217 support for slaacd
OK naddy, sthen
Diffstat (limited to 'sbin/slaacd')
-rw-r--r--sbin/slaacd/engine.c76
-rw-r--r--sbin/slaacd/frontend.c3
-rw-r--r--sbin/slaacd/slaacd.c20
-rw-r--r--sbin/slaacd/slaacd.h7
4 files changed, 87 insertions, 19 deletions
diff --git a/sbin/slaacd/engine.c b/sbin/slaacd/engine.c
index 23ff8ec3534..f2424c392f2 100644
--- a/sbin/slaacd/engine.c
+++ b/sbin/slaacd/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.19 2017/11/04 17:23:05 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.20 2018/02/10 05:57:59 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -64,6 +64,8 @@
#include <netinet6/nd6.h>
#include <netinet/icmp6.h>
+#include <crypto/sha2.h>
+
#include <errno.h>
#include <event.h>
#include <imsg.h>
@@ -179,6 +181,7 @@ struct address_proposal {
uint8_t prefix_len;
uint32_t vltime;
uint32_t pltime;
+ uint8_t soiikey[SLAACD_SOIIKEY_LEN];
};
struct dfr_proposal {
@@ -204,8 +207,10 @@ struct slaacd_iface {
uint32_t if_index;
int running;
int autoconfprivacy;
+ int soii;
struct ether_addr hw_address;
struct sockaddr_in6 ll_address;
+ uint8_t soiikey[SLAACD_SOIIKEY_LEN];
LIST_HEAD(, radv) radvs;
LIST_HEAD(, address_proposal) addr_proposals;
LIST_HEAD(, dfr_proposal) dfr_proposals;
@@ -618,12 +623,15 @@ engine_dispatch_main(int fd, short event, void *bula)
iface->state = IF_DOWN;
iface->autoconfprivacy =
imsg_ifinfo.autoconfprivacy;
+ iface->soii = imsg_ifinfo.soii;
memcpy(&iface->hw_address,
&imsg_ifinfo.hw_address,
sizeof(struct ether_addr));
memcpy(&iface->ll_address,
&imsg_ifinfo.ll_address,
sizeof(struct sockaddr_in6));
+ memcpy(iface->soiikey, imsg_ifinfo.soiikey,
+ sizeof(iface->soiikey));
LIST_INIT(&iface->radvs);
LIST_INSERT_HEAD(&slaacd_interfaces,
iface, entries);
@@ -638,6 +646,14 @@ engine_dispatch_main(int fd, short event, void *bula)
imsg_ifinfo.autoconfprivacy;
need_refresh = 1;
}
+
+ if (iface->soii !=
+ imsg_ifinfo.soii) {
+ iface->soii =
+ imsg_ifinfo.soii;
+ need_refresh = 1;
+ }
+
if (memcmp(&iface->hw_address,
&imsg_ifinfo.hw_address,
sizeof(struct ether_addr)) != 0) {
@@ -646,6 +662,14 @@ engine_dispatch_main(int fd, short event, void *bula)
sizeof(struct ether_addr));
need_refresh = 1;
}
+ if (memcmp(iface->soiikey,
+ imsg_ifinfo.soiikey,
+ sizeof(iface->soiikey)) != 0) {
+ memcpy(iface->soiikey,
+ imsg_ifinfo.soiikey,
+ sizeof(iface->soiikey));
+ need_refresh = 1;
+ }
if (iface->state != IF_DOWN &&
imsg_ifinfo.running && need_refresh)
@@ -763,6 +787,7 @@ send_interface_info(struct slaacd_iface *iface, pid_t pid)
cei.if_index = iface->if_index;
cei.running = iface->running;
cei.autoconfprivacy = iface->autoconfprivacy;
+ cei.soii = iface->soii;
memcpy(&cei.hw_address, &iface->hw_address, sizeof(struct ether_addr));
memcpy(&cei.ll_address, &iface->ll_address,
sizeof(struct sockaddr_in6));
@@ -1209,7 +1234,10 @@ void
gen_addr(struct slaacd_iface *iface, struct radv_prefix *prefix, struct
address_proposal *addr_proposal, int privacy)
{
+ SHA2_CTX ctx;
struct in6_addr priv_in6;
+ int dad_counter = 0; /* XXX not used */
+ u_int8_t digest[SHA512_DIGEST_LENGTH];
/* from in6_ifadd() in nd6_rtr.c */
/* XXX from in6.h, guarded by #ifdef _KERNEL XXX nonstandard */
@@ -1256,20 +1284,33 @@ gen_addr(struct slaacd_iface *iface, struct radv_prefix *prefix, struct
addr_proposal->addr.sin6_addr.s6_addr32[3] |=
(priv_in6.s6_addr32[3] & ~addr_proposal->mask.s6_addr32[3]);
} else {
- addr_proposal->addr.sin6_addr.s6_addr32[0] |=
- (iface->ll_address.sin6_addr.s6_addr32[0] &
- ~addr_proposal->mask.s6_addr32[0]);
- addr_proposal->addr.sin6_addr.s6_addr32[1] |=
- (iface->ll_address.sin6_addr.s6_addr32[1] &
- ~addr_proposal->mask.s6_addr32[1]);
- addr_proposal->addr.sin6_addr.s6_addr32[2] |=
- (iface->ll_address.sin6_addr.s6_addr32[2] &
- ~addr_proposal->mask.s6_addr32[2]);
- addr_proposal->addr.sin6_addr.s6_addr32[3] |=
- (iface->ll_address.sin6_addr.s6_addr32[3] &
- ~addr_proposal->mask.s6_addr32[3]);
+ if (iface->soii) {
+ SHA512Init(&ctx);
+ SHA512Update(&ctx, &prefix->prefix,
+ sizeof(prefix->prefix));
+ SHA512Update(&ctx, &iface->hw_address,
+ sizeof(iface->hw_address));
+ SHA512Update(&ctx, &dad_counter, sizeof(dad_counter));
+ SHA512Update(&ctx, addr_proposal->soiikey,
+ sizeof(addr_proposal->soiikey));
+ SHA512Final(digest, &ctx);
+ memcpy(&addr_proposal->addr.sin6_addr.s6_addr[8],
+ digest, 8);
+ } else {
+ addr_proposal->addr.sin6_addr.s6_addr32[0] |=
+ (iface->ll_address.sin6_addr.s6_addr32[0] &
+ ~addr_proposal->mask.s6_addr32[0]);
+ addr_proposal->addr.sin6_addr.s6_addr32[1] |=
+ (iface->ll_address.sin6_addr.s6_addr32[1] &
+ ~addr_proposal->mask.s6_addr32[1]);
+ addr_proposal->addr.sin6_addr.s6_addr32[2] |=
+ (iface->ll_address.sin6_addr.s6_addr32[2] &
+ ~addr_proposal->mask.s6_addr32[2]);
+ addr_proposal->addr.sin6_addr.s6_addr32[3] |=
+ (iface->ll_address.sin6_addr.s6_addr32[3] &
+ ~addr_proposal->mask.s6_addr32[3]);
+ }
}
-
#undef s6_addr32
}
@@ -1650,6 +1691,11 @@ void update_iface_ra(struct slaacd_iface *iface, struct radv *ra)
sizeof(addr_proposal->hw_address)) != 0)
continue;
+ if (memcmp(&addr_proposal->soiikey,
+ &iface->soiikey,
+ sizeof(addr_proposal->soiikey)) != 0)
+ continue;
+
if (addr_proposal->privacy) {
/*
* create new privacy address if old
@@ -1797,6 +1843,8 @@ gen_address_proposal(struct slaacd_iface *iface, struct radv *ra, struct
addr_proposal->if_index = iface->if_index;
memcpy(&addr_proposal->hw_address, &iface->hw_address,
sizeof(addr_proposal->hw_address));
+ memcpy(&addr_proposal->soiikey, &iface->soiikey,
+ sizeof(addr_proposal->soiikey));
addr_proposal->privacy = privacy;
memcpy(&addr_proposal->prefix, &prefix->prefix,
sizeof(addr_proposal->prefix));
diff --git a/sbin/slaacd/frontend.c b/sbin/slaacd/frontend.c
index 3a193e2a00f..171cfe251b0 100644
--- a/sbin/slaacd/frontend.c
+++ b/sbin/slaacd/frontend.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frontend.c,v 1.10 2017/12/10 10:07:54 florian Exp $ */
+/* $OpenBSD: frontend.c,v 1.11 2018/02/10 05:57:59 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -490,6 +490,7 @@ update_iface(uint32_t if_index, char* if_name)
imsg_ifinfo.running = (flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP |
IFF_RUNNING);
imsg_ifinfo.autoconfprivacy = !(xflags & IFXF_INET6_NOPRIVACY);
+ imsg_ifinfo.soii = !(xflags & IFXF_INET6_NOSOII);
get_lladdr(if_name, &imsg_ifinfo.hw_address, &imsg_ifinfo.ll_address);
memcpy(&nd_opt_source_link_addr, &imsg_ifinfo.hw_address,
diff --git a/sbin/slaacd/slaacd.c b/sbin/slaacd/slaacd.c
index 628031f9049..fe895f906b0 100644
--- a/sbin/slaacd/slaacd.c
+++ b/sbin/slaacd/slaacd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.c,v 1.14 2017/12/10 17:34:05 stsp Exp $ */
+/* $OpenBSD: slaacd.c,v 1.15 2018/02/10 05:57:59 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -23,6 +23,7 @@
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/syslog.h>
+#include <sys/sysctl.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -100,6 +101,7 @@ void configure_interface(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 *);
+int get_soiikey(uint8_t *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
int main_imsg_compose_frontend(int, pid_t, void *, uint16_t);
@@ -470,8 +472,11 @@ main_dispatch_frontend(int fd, short event, void *bula)
fatal("%s: IMSG_UPDATE_IF wrong length: %d",
__func__, imsg.hdr.len);
memcpy(&imsg_ifinfo, imsg.data, sizeof(imsg_ifinfo));
- main_imsg_compose_engine(IMSG_UPDATE_IF, 0,
- &imsg_ifinfo, sizeof(imsg_ifinfo));
+ if (get_soiikey(imsg_ifinfo.soiikey) == -1)
+ log_warn("get_soiikey");
+ else
+ main_imsg_compose_engine(IMSG_UPDATE_IF, 0,
+ &imsg_ifinfo, sizeof(imsg_ifinfo));
break;
default:
log_debug("%s: error handling imsg %d", __func__,
@@ -885,3 +890,12 @@ sin6_to_str(struct sockaddr_in6 *sin6)
return hbuf;
}
#endif /* SMALL */
+
+int
+get_soiikey(uint8_t *key)
+{
+ int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY};
+ size_t size = SLAACD_SOIIKEY_LEN;
+
+ return sysctl(mib, sizeof(mib) / sizeof(mib[0]), key, &size, NULL, 0);
+}
diff --git a/sbin/slaacd/slaacd.h b/sbin/slaacd/slaacd.h
index 9e2fe0fc5b8..f824411da32 100644
--- a/sbin/slaacd/slaacd.h
+++ b/sbin/slaacd/slaacd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: slaacd.h,v 1.11 2017/12/10 10:07:54 florian Exp $ */
+/* $OpenBSD: slaacd.h,v 1.12 2018/02/10 05:57:59 florian Exp $ */
/*
* Copyright (c) 2017 Florian Obser <florian@openbsd.org>
@@ -21,6 +21,8 @@
#define SLAACD_SOCKET "/dev/slaacd.sock"
#define SLAACD_USER "_slaacd"
+#define SLAACD_SOIIKEY_LEN 16
+
/* MAXDNAME from arpa/namesr.h */
#define SLAACD_MAX_DNSSL 1025
@@ -90,6 +92,7 @@ struct ctl_engine_info {
uint32_t if_index;
int running;
int autoconfprivacy;
+ int soii;
struct ether_addr hw_address;
struct sockaddr_in6 ll_address;
};
@@ -169,8 +172,10 @@ struct imsg_ifinfo {
uint32_t if_index;
int running;
int autoconfprivacy;
+ int soii;
struct ether_addr hw_address;
struct sockaddr_in6 ll_address;
+ uint8_t soiikey[SLAACD_SOIIKEY_LEN];
};
struct imsg_del_addr {