The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6ca418e4816a9d1db18f2ce55dcab6c04757be27

commit 6ca418e4816a9d1db18f2ce55dcab6c04757be27
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2021-12-15 03:05:18 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2022-05-24 20:59:33 +0000

    ifconfig: add setifcapnv()
    
    which uses SIOCSIFCAPNV to set arbitrary string-named interface
    capability.
    
    Reviewed by:    hselasky, jhb, kp
    Sponsored by:   NVIDIA Networking
    MFC after:      3 weeks
    Differential revision:  https://reviews.freebsd.org/D32551
---
 sbin/ifconfig/ifconfig.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 sbin/ifconfig/ifconfig.h |  2 ++
 2 files changed, 45 insertions(+)

diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 37ce0fb18943..9ee86b2a5169 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -44,6 +44,7 @@ static const char rcsid[] =
 #include <sys/ioctl.h>
 #include <sys/module.h>
 #include <sys/linker.h>
+#include <sys/nv.h>
 #include <sys/queue.h>
 #include <sys/socket.h>
 #include <sys/time.h>
@@ -1253,6 +1254,48 @@ setifcap(const char *vname, int value, int s, const 
struct afswtch *afp)
                Perror(vname);
 }
 
+void
+setifcapnv(const char *vname, const char *arg, int s, const struct afswtch 
*afp)
+{
+       nvlist_t *nvcap;
+       void *buf;
+       char *marg, *mopt;
+       size_t nvbuflen;
+       bool neg;
+
+       if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0)
+               Perror("ioctl (SIOCGIFCAP)");
+       if ((ifr.ifr_curcap & IFCAP_NV) == 0) {
+               warnx("IFCAP_NV not supported");
+               return; /* Not exit() */
+       }
+
+       marg = strdup(arg);
+       if (marg == NULL)
+               Perror("strdup");
+       nvcap = nvlist_create(0);
+       if (nvcap == NULL)
+               Perror("nvlist_create");
+       while ((mopt = strsep(&marg, ",")) != NULL) {
+               neg = *mopt == '-';
+               if (neg)
+                       mopt++;
+               nvlist_add_bool(nvcap, mopt, !neg);
+       }
+       buf = nvlist_pack(nvcap, &nvbuflen);
+       if (buf == NULL) {
+               errx(1, "nvlist_pack error");
+               exit(1);
+       }
+       ifr.ifr_cap_nv.buf_length = ifr.ifr_cap_nv.length = nvbuflen;
+       ifr.ifr_cap_nv.buffer = buf;
+       if (ioctl(s, SIOCSIFCAPNV, (caddr_t)&ifr) < 0)
+               Perror(vname);
+       free(buf);
+       nvlist_destroy(nvcap);
+       free(marg);
+}
+
 static void
 setifmetric(const char *val, int dummy __unused, int s, 
     const struct afswtch *afp)
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 4a9fb380fbab..26f68d67cec2 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -202,6 +202,8 @@ extern      int printifname;
 extern int exit_code;
 
 void   setifcap(const char *, int value, int s, const struct afswtch *);
+void   setifcapnv(const char *vname, const char *arg, int s,
+           const struct afswtch *afp);
 
 void   Perror(const char *cmd);
 void   printb(const char *s, unsigned value, const char *bits);

Reply via email to