On Sat, Jul 15, 2017 at 05:05:52PM +0000, Florian Obser wrote:
> 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?
ok
>
> 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.
>