I didn't not hear any objections to RFC 7217 support, so I guess it's
time to get this thing in to get some operational experience with it
before 6.2 is cut.
Also the big diff gets a bit unwieldy, further improvement can happen
in-tree.
This is the sysctl part for "net.inet6.ip6.soiikey", written by dlg
with a few tweaks by me. Therefore he should commit it.
This is OK florian@, anyone else?
diff --git sbin/sysctl/sysctl.c sbin/sysctl/sysctl.c
index 94f78c0d673..cbacaca19d2 100644
--- sbin/sysctl/sysctl.c
+++ sbin/sysctl/sysctl.c
@@ -212,7 +212,7 @@ int sysctl_chipset(char *, char **, int *, int, int *);
#endif
void vfsinit(void);
-char *equ = "=";
+const char *equ = "=";
int
main(int argc, char *argv[])
@@ -286,6 +286,53 @@ listall(char *prefix, struct list *lp)
}
}
+int
+parse_hex_char(char ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return (ch - '0');
+ if (ch >= 'a' && ch <= 'f')
+ return (ch - 'a' + 10);
+ 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)
+{
+ ssize_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);
+}
+
/*
* Parse a name into a MIB entry.
* Lookup and print out the MIB entry if it exists.
@@ -302,6 +349,7 @@ parse(char *string, int flags)
struct list *lp;
int mib[CTL_MAXNAME];
char *cp, *bufp, buf[SYSCTL_BUFSIZ];
+ unsigned char hex[SYSCTL_BUFSIZ];
(void)strlcpy(buf, string, sizeof(buf));
bufp = buf;
@@ -566,6 +614,9 @@ parse(char *string, int flags)
len = sysctl_inet6(string, &bufp, mib, flags, &type);
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) ||
@@ -717,6 +768,27 @@ parse(char *string, int flags)
newval = &quadval;
newsize = sizeof(quadval);
break;
+ case CTLTYPE_STRING:
+ if (special & HEX) {
+ ssize_t len;
+
+ len = parse_hex_string(hex, sizeof(hex),
+ newval);
+ if (len == -1) {
+ warnx("%s: hex string %s: invalid",
+ string, newval);
+ return;
+ }
+ if (len > sizeof(hex)) {
+ warnx("%s: hex string %s: too long",
+ string, newval);
+ return;
+ }
+
+ newval = hex;
+ newsize = len;
+ }
+ break;
}
}
size = (special & SMALLBUF) ? 512 : SYSCTL_BUFSIZ;
@@ -936,13 +1008,30 @@ parse(char *string, int flags)
if (newval == NULL) {
if (!nflag)
(void)printf("%s%s", string, equ);
- (void)puts(buf);
- } else {
- if (!qflag) {
- if (!nflag)
- (void)printf("%s: %s -> ", string, buf);
- (void)puts((char *)newval);
+ if (special & HEX) {
+ size_t i;
+ for (i = 0; i < size; i++) {
+ (void)printf("%02x",
+ (unsigned char)buf[i]);
+ }
+ (void)printf("\n");
+ } else
+ (void)puts(buf);
+ } else if (!qflag) {
+ if (!nflag) {
+ (void)printf("%s: ", string);
+ if (special & HEX) {
+ size_t i;
+ for (i = 0; i < size; i++) {
+ (void)printf("%02x",
+ (unsigned char)buf[i]);
+ }
+ } else
+ (void)printf("%s", cp);
+
+ (void)printf(" -> ");
}
+ (void)puts(cp);
}
return;
diff --git sys/netinet6/in6.h sys/netinet6/in6.h
index ac0120e4217..549cf0c5159 100644
--- sys/netinet6/in6.h
+++ sys/netinet6/in6.h
@@ -590,7 +590,8 @@ ifatoia6(struct ifaddr *ifa)
#define IPV6CTL_IFQUEUE 51
#define IPV6CTL_MRTMIF 52
#define IPV6CTL_MRTMFC 53
-#define IPV6CTL_MAXID 54
+#define IPV6CTL_SOIIKEY 54
+#define IPV6CTL_MAXID 55
/* New entries should be added here from current IPV6CTL_MAXID value. */
/* to define items, should talk with KAME guys first, for *BSD compatibility */
@@ -650,6 +651,7 @@ ifatoia6(struct ifaddr *ifa)
{ "ifq", CTLTYPE_NODE }, \
{ "mrtmif", CTLTYPE_STRUCT }, \
{ "mrtmfc", CTLTYPE_STRUCT }, \
+ { "soiikey", CTLTYPE_STRING }, /* binary string */ \
}
#define IPV6CTL_VARS { \
diff --git sys/netinet6/ip6_input.c sys/netinet6/ip6_input.c
index ed8702fa71a..4aaf8cee6d6 100644
--- sys/netinet6/ip6_input.c
+++ sys/netinet6/ip6_input.c
@@ -118,6 +118,8 @@ struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IFQ_MAXLEN,
NETISR_IPV6);
struct cpumem *ip6counters;
+uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
+
int ip6_ours(struct mbuf **, int *, int, int);
int ip6_local(struct mbuf **, int *, int, int);
int ip6_check_rh0hdr(struct mbuf *, int *);
@@ -1376,6 +1378,21 @@ ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void
*newp)
}
int
+ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
+{
+ int error;
+
+ error = suser(curproc, 0);
+ if (error != 0)
+ return (error);
+
+ error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey,
+ sizeof(ip6_soiikey));
+
+ return (error);
+}
+
+int
ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen)
{
@@ -1429,6 +1446,8 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t
*oldlenp,
case IPV6CTL_IFQUEUE:
return (sysctl_niq(name + 1, namelen - 1,
oldp, oldlenp, newp, newlen, &ip6intrq));
+ case IPV6CTL_SOIIKEY:
+ return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen));
default:
if (name[0] < IPV6CTL_MAXID)
return (sysctl_int_arr(ipv6ctl_vars, name, namelen,
diff --git sys/netinet6/ip6_var.h sys/netinet6/ip6_var.h
index 2b9f86cab2f..f1ae3680b81 100644
--- sys/netinet6/ip6_var.h
+++ sys/netinet6/ip6_var.h
@@ -294,6 +294,9 @@ extern int ip6_dad_pending; /* number of currently
running DADs */
extern int ip6_auto_flowlabel;
extern int ip6_auto_linklocal;
+#define IP6_SOIIKEY_LEN 16
+extern uint8_t ip6_soiikey[IP6_SOIIKEY_LEN];
+
struct in6pcb;
struct inpcb;
--
2.13.0
--
I'm not entirely sure you are real.