Download raw body.
remove net.inet6.ip6.soiikey sysctl
RFC 7217 - "A Method for Generating Semantically Opaque Interface
Identifiers with IPv6 Stateless Address Autoconfiguration (SLAAC)"
applies to global addresses as well as to link-local address.
However, shortly after implementing it we found out that there are a
bunch of hosting providers that
a) hand out IPv6 addresses via slaac
b) know which mac-address their rental servers have
c) calculate an expect link-local address from the known mac-address
d) only route to the expect link-local address.
Implementing 7217 makes things not work, so we quickly disabled it for
link-local addresses. But that also means we no longer need the soiikey
in the kernel. This diff rips it all out and makes slaacd(8) read
/etc/soii.key file.
I can think of two behavioural changes, both are not important.
1. previously one could set a new key using sysctl, down & up the
interface and slaacd would calculate a new IPv6 address and configure
it. With the diff slaacd only reads soii.key on startup. A restart of
slaacd would get the old behaviour back. I consider this an
implementation detail.
2. The installer no longer sees soii.key during upgrade. So slaacd will
create an IPv6 address with a soii.key of all zero. It did so before and
*additionally* create a 2nd IPv6 address with the soii.key read from
/mnt/etc/soii.key. I don't think anyone could have dependent on this,
given the complicated IPv6 source address selection, picking the
"correct" address would be dumb luck.
It's probably best to first commit userland and then a week later or so
the kernel bits. I've successfully built a release with the full diff.
OK?
diff --git distrib/miniroot/install.sub distrib/miniroot/install.sub
index c7eea4df0ff..b2a6844b297 100644
--- distrib/miniroot/install.sub
+++ distrib/miniroot/install.sub
@@ -2653,9 +2653,6 @@ enable_network() {
echo "127.0.0.1\tlocalhost" >/tmp/i/hosts
echo "::1\t\tlocalhost" >>/tmp/i/hosts
- _f=/mnt/etc/soii.key
- [[ -f $_f ]] && sysctl "net.inet6.ip6.soiikey=$(<$_f)"
-
enable_ifs
}
diff --git distrib/special/sysctl/sysctl.c distrib/special/sysctl/sysctl.c
index 41d19856120..074b1d2b5f1 100644
--- distrib/special/sysctl/sysctl.c
+++ distrib/special/sysctl/sysctl.c
@@ -33,8 +33,6 @@
#include <machine/cpu.h>
-#define SOIIKEY_LEN 16
-
struct var {
char *name;
int (*print)(struct var *);
@@ -103,39 +101,6 @@ pstring(struct var *v)
return (1);
}
-int
-parse_hex_char(char ch)
-{
- if (ch >= '0' && ch <= '9')
- return (ch - '0');
-
- ch = tolower((unsigned char)ch);
- if (ch >= 'a' && ch <= 'f')
- return (ch - 'a' + 10);
-
- return (-1);
-}
-
-int
-set_soii_key(char *src)
-{
- uint8_t key[SOIIKEY_LEN];
- int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY};
- int i, c;
-
- for(i = 0; i < SOIIKEY_LEN; i++) {
- if ((c = parse_hex_char(src[2 * i])) == -1)
- return (-1);
- key[i] = c << 4;
- if ((c = parse_hex_char(src[2 * i + 1])) == -1)
- return (-1);
- key[i] |= c;
- }
-
- return sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, NULL, key,
- SOIIKEY_LEN);
-}
-
int
main(int argc, char *argv[])
{
@@ -163,17 +128,6 @@ main(int argc, char *argv[])
while (argc--) {
name = *argv++;
- /*
- * strlen("net.inet6.ip6.soiikey="
- * "00000000000000000000000000000000") == 54
- * strlen("net.inet6.ip6.soiikey=") == 22
- */
- if (strlen(name) == 54 && strncmp(name,
- "net.inet6.ip6.soiikey=", 22) == 0) {
- set_soii_key(name + 22);
- continue;
- }
-
for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
if (strcmp(name, vars[i].name) == 0) {
(vars[i].print)(&vars[i]);
diff --git etc/netstart etc/netstart
index af4866f909e..105d5a977cf 100644
--- etc/netstart
+++ etc/netstart
@@ -360,13 +360,6 @@ if ifconfig lo0 inet6 >/dev/null 2>&1; then
IP6KERNEL=true
fi
-# Load key material for the generation of IPv6 Semantically Opaque Interface
-# Identifiers (SOII) used for SLAAC addresses.
-if $IP6KERNEL && ! $PRINT_ONLY; then
- [[ -f /etc/soii.key ]] &&
- sysctl -q "net.inet6.ip6.soiikey=$(</etc/soii.key)"
-fi
-
# If we were invoked with a list of interface names, just reconfigure these
# interfaces (or bridges), add default routes and return.
# Create virtual interfaces upfront to make ifconfig commands depending on
diff --git etc/rc etc/rc
index 13de0c06603..e3061b2b5d0 100644
--- etc/rc
+++ etc/rc
@@ -163,9 +163,7 @@ make_keys() {
(read sz fp comm type && echo "sshd: $type $fp")
if [[ ! -f /etc/soii.key ]]; then
- openssl rand -hex 16 > /etc/soii.key &&
- chmod 600 /etc/soii.key && sysctl -q \
- "net.inet6.ip6.soiikey=$(</etc/soii.key)"
+ openssl rand -hex 16 > /etc/soii.key && chmod 600 /etc/soii.key
fi
}
diff --git lib/libc/sys/sysctl.2 lib/libc/sys/sysctl.2
index 596b603b7b8..2e030bd9a32 100644
--- lib/libc/sys/sysctl.2
+++ lib/libc/sys/sysctl.2
@@ -1859,7 +1859,6 @@ The currently defined protocols and names are:
.It ip6 Ta multipath Ta integer Ta yes
.It ip6 Ta neighborgcthresh Ta integer Ta yes
.It ip6 Ta redirect Ta integer Ta yes
-.It ip6 Ta soiikey Ta uint8_t[IP6_SOIIKEY_LEN] Ta yes
.It ip6 Ta use_deprecated Ta integer Ta yes
.El
.Pp
@@ -2030,14 +2029,6 @@ Returns 1 when ICMPv6 redirects may be sent by the node.
This option is ignored unless the node is routing IP packets,
and should normally be enabled on all systems.
.Pp
-.It Li ip6.soii Pq Va net.inet6.ip6.soiikey
-This variable configures the secret key for the RFC 7217 algorithm to
-calculate a persistent Semantically Opaque Interface Identifier (SOII)
-for IPv6 Stateless Address Autoconfiguration (SLAAC) addresses.
-It must be
-.Dv IP6_SOIIKEY_LEN
-bytes long.
-.Pp
.It Li ip6.use_deprecated Pq Va net.inet6.ip6.use_deprecated
This variable controls the use of deprecated addresses, specified in
RFC 4862 5.5.4.
diff --git sbin/slaacd/slaacd.c sbin/slaacd/slaacd.c
index 9e81a3994d8..e6b65d45876 100644
--- sbin/slaacd/slaacd.c
+++ sbin/slaacd/slaacd.c
@@ -34,6 +34,7 @@
#include <netinet6/in6_var.h>
#include <netinet/icmp6.h>
+#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -76,7 +77,9 @@ void configure_gateway(struct imsg_configure_dfr *, uint8_t);
void add_gateway(struct imsg_configure_dfr *);
void delete_gateway(struct imsg_configure_dfr *);
void send_rdns_proposal(struct imsg_propose_rdns *);
-int get_soiikey(uint8_t *);
+void read_soiikey(void);
+int parse_hex_char(char);
+ssize_t parse_hex_string(unsigned char *, size_t, const char *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *, struct imsgbuf *);
int main_imsg_compose_frontend(int, int, void *, uint16_t);
@@ -89,6 +92,7 @@ pid_t frontend_pid;
pid_t engine_pid;
int routesock, ioctl_sock, rtm_seq = 0;
+uint8_t soiikey[SLAACD_SOIIKEY_LEN];
void
main_sig_handler(int sig, short event, void *arg)
@@ -274,6 +278,8 @@ main(int argc, char *argv[])
#ifndef SMALL
if ((control_fd = control_init(csock)) == -1)
warnx("control socket setup failed");
+
+ read_soiikey();
#endif /* SMALL */
if (pledge("stdio inet sendfd wroute", NULL) == -1)
@@ -439,11 +445,10 @@ main_dispatch_frontend(int fd, short event, void *bula)
sizeof(imsg_ifinfo)) == -1)
fatalx("%s: invalid %s", __func__, i2s(type));
- 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));
+ memcpy(imsg_ifinfo.soiikey, soiikey,
+ SLAACD_SOIIKEY_LEN);
+ main_imsg_compose_engine(IMSG_UPDATE_IF, 0,
+ &imsg_ifinfo, sizeof(imsg_ifinfo));
break;
default:
log_debug("%s: error handling imsg %d", __func__, type);
@@ -874,17 +879,76 @@ sin6_to_str(struct sockaddr_in6 *sin6)
}
return hbuf;
}
-#endif /* SMALL */
int
-get_soiikey(uint8_t *key)
+parse_hex_char(char ch)
{
- int mib[4] = {CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_SOIIKEY};
- size_t size = SLAACD_SOIIKEY_LEN;
+ if (ch >= '0' && ch <= '9')
+ return (ch - '0');
- return sysctl(mib, sizeof(mib) / sizeof(mib[0]), key, &size, NULL, 0);
+ ch = tolower((unsigned char)ch);
+ if (ch >= 'a' && ch <= 'f')
+ return (ch - 'a' + 10);
+
+ return (-1);
}
+ssize_t
+parse_hex_string(unsigned char *dst, size_t dstlen, const char *src)
+{
+ size_t len = 0;
+ int digit;
+
+ while (len < dstlen) {
+ if (*src == '\0')
+ return (len);
+
+ digit = parse_hex_char(*src++);
+ if (digit == -1)
+ return (-1);
+ dst[len] = digit << 4;
+
+ digit = parse_hex_char(*src++);
+ if (digit == -1)
+ return (-1);
+
+ dst[len] |= digit;
+ len++;
+ }
+
+ while (*src != '\0') {
+ if (parse_hex_char(*src++) == -1 ||
+ parse_hex_char(*src++) == -1)
+ return (-1);
+
+ len++;
+ }
+
+ return (len);
+}
+
+void
+read_soiikey(void)
+{
+ int fd = -1;
+ char buf[33];
+
+ if ((fd = open("/etc/soii.key", O_RDONLY)) == -1)
+ goto err;
+ memset(buf, 0, sizeof(buf));
+ if (read(fd, buf, sizeof(buf) - 1) == -1)
+ goto err;
+ if (parse_hex_string(soiikey, sizeof(soiikey), buf) == -1)
+ goto err;
+ return;
+ err:
+ memset(soiikey, 0, sizeof(soiikey));
+ if (fd != -1)
+ close(fd);
+}
+
+#endif /* SMALL */
+
void
open_icmp6sock(int rdomain)
{
diff --git sbin/sysctl/sysctl.c sbin/sysctl/sysctl.c
index b2dd40151e7..70d5bfe5390 100644
--- sbin/sysctl/sysctl.c
+++ sbin/sysctl/sysctl.c
@@ -693,10 +693,6 @@ parse(char *string, int flags)
if (len < 0)
return;
- if (mib[2] == IPPROTO_IPV6 &&
- mib[3] == IPV6CTL_SOIIKEY)
- special |= HEX;
-
if ((mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_MRTMFC) ||
(mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_MRTMIF)) {
if (flags == 0)
diff --git sys/kern/kern_pledge.c sys/kern/kern_pledge.c
index a418aca22b3..375920ad357 100644
--- sys/kern/kern_pledge.c
+++ sys/kern/kern_pledge.c
@@ -832,13 +832,6 @@ pledge_sysctl(struct proc *p, int miblen, int *mib, void *new)
return (0);
}
- if ((pledge & PLEDGE_WROUTE)) {
- if (miblen == 4 &&
- mib[0] == CTL_NET && mib[1] == PF_INET6 &&
- mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_SOIIKEY)
- return (0);
- }
-
if (pledge & (PLEDGE_PS | PLEDGE_VMINFO)) {
if (miblen == 2 && /* kern.fscale */
mib[0] == CTL_KERN && mib[1] == KERN_FSCALE)
diff --git sys/netinet6/in6.h sys/netinet6/in6.h
index 8a997b563ba..074fde1f792 100644
--- sys/netinet6/in6.h
+++ sys/netinet6/in6.h
@@ -597,8 +597,7 @@ ifatoia6(struct ifaddr *ifa)
#define IPV6CTL_IFQUEUE 51
#define IPV6CTL_MRTMIF 52
#define IPV6CTL_MRTMFC 53
-#define IPV6CTL_SOIIKEY 54
-#define IPV6CTL_MAXID 55
+#define IPV6CTL_MAXID 54
/* New entries should be added here from current IPV6CTL_MAXID value. */
/* to define items, should talk with KAME guys first, for *BSD compatibility */
@@ -658,7 +657,6 @@ ifatoia6(struct ifaddr *ifa)
{ "ifq", CTLTYPE_NODE }, \
{ "mrtmif", CTLTYPE_STRUCT }, \
{ "mrtmfc", CTLTYPE_STRUCT }, \
- { "soiikey", CTLTYPE_STRING }, /* binary string */ \
}
__BEGIN_DECLS
diff --git sys/netinet6/ip6_input.c sys/netinet6/ip6_input.c
index e6a5fbc0404..6e042a797ff 100644
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -109,14 +109,11 @@ struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IPQ_MAXLEN, NETISR_IPV6);
struct cpumem *ip6counters;
-uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
-
int ip6_ours(struct mbuf **, int *, int, int, int, struct netstack *);
int ip6_check_rh0hdr(struct mbuf *, int *);
int ip6_hbhchcheck(struct mbuf **, int *, int *, int);
int ip6_hopopts_input(struct mbuf **, int *, u_int32_t *, u_int32_t *);
struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
-int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
static struct mbuf_queue ip6send_mq;
@@ -1481,32 +1478,6 @@ ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void *newp)
}
#endif /* SMALL_KERNEL */
-int
-ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
-{
- uint8_t soiikey[sizeof(ip6_soiikey)];
- int error;
-
- error = suser(curproc);
- if (error != 0)
- return (error);
-
- rw_enter_read(&sysctl_lock);
- memcpy(soiikey, ip6_soiikey, sizeof(ip6_soiikey));
- rw_exit_read(&sysctl_lock);
-
- error = sysctl_struct(oldp, oldlenp, newp, newlen, soiikey,
- sizeof(soiikey));
-
- if (error == 0 && newp) {
- rw_enter_write(&sysctl_lock);
- memcpy(ip6_soiikey, soiikey, sizeof(soiikey));
- rw_exit_write(&sysctl_lock);
- }
-
- return (error);
-}
-
int
ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen)
@@ -1516,8 +1487,6 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
return (ENOTDIR);
switch (name[0]) {
- case IPV6CTL_SOIIKEY:
- return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen));
#ifndef SMALL_KERNEL
case IPV6CTL_STATS:
return (ip6_sysctl_ip6stat(oldp, oldlenp, newp));
diff --git sys/netinet6/ip6_var.h sys/netinet6/ip6_var.h
index e5353caa50c..c9ad11832bb 100644
--- sys/netinet6/ip6_var.h
+++ sys/netinet6/ip6_var.h
@@ -298,9 +298,6 @@ extern int ip6_dad_pending; /* number of currently running DADs */
extern int ip6_auto_flowlabel;
-#define IP6_SOIIKEY_LEN 16
-extern uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
-
extern const struct pr_usrreqs rip6_usrreqs;
struct inpcb;
--
In my defence, I have been left unsupervised.
remove net.inet6.ip6.soiikey sysctl