The branch main has been updated by kib:

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

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

    ifconfig: Use SIOCGIFCAPNV if supported
    
    Reviewed by:    hselasky, jhb, kp (previous version)
    Sponsored by:   NVIDIA Networking
    MFC after:      3 weeks
    Differential revision:  https://reviews.freebsd.org/D32551
---
 sbin/ifconfig/ifconfig.c | 65 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 6 deletions(-)

diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 2ed7d43ac50c..4a0c3522c8e5 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1425,8 +1425,12 @@ status(const struct afswtch *afp, const struct 
sockaddr_dl *sdl,
        struct ifaddrs *ifa)
 {
        struct ifaddrs *ift;
-       int allfamilies, s;
        struct ifstat ifs;
+       nvlist_t *nvcap;
+       const char *nvname;
+       void *buf, *cookie;
+       int allfamilies, s, type;
+       bool first, val;
 
        if (afp == NULL) {
                allfamilies = 1;
@@ -1471,13 +1475,62 @@ status(const struct afswtch *afp, const struct 
sockaddr_dl *sdl,
        }
 
        if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) {
-               if (ifr.ifr_curcap != 0) {
+               if ((ifr.ifr_curcap & IFCAP_NV) != 0) {
+                       buf = malloc(IFR_CAP_NV_MAXBUFSIZE);
+                       if (buf == NULL)
+                               Perror("malloc");
+                       ifr.ifr_cap_nv.buffer = buf;
+                       ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE;
+                       if (ioctl(s, SIOCGIFCAPNV, (caddr_t)&ifr) != 0)
+                               Perror("ioctl (SIOCGIFCAPNV)");
+                       nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer,
+                           ifr.ifr_cap_nv.length, 0);
+                       if (nvcap == NULL)
+                               Perror("nvlist_unpack");
+                       printf("\toptions");
+                       cookie = NULL;
+                       for (first = true;; first = false) {
+                               nvname = nvlist_next(nvcap, &type, &cookie);
+                               if (nvname == NULL) {
+                                       printf("\n");
+                                       break;
+                               }
+                               if (type == NV_TYPE_BOOL) {
+                                       val = nvlist_get_bool(nvcap, nvname);
+                                       if (val) {
+                                               printf("%c%s",
+                                                   first ? ' ' : ',', nvname);
+                                       }
+                               }
+                       }
+                       if (supmedia) {
+                               printf("\tcapabilities");
+                               cookie = NULL;
+                               for (first = true;; first = false) {
+                                       nvname = nvlist_next(nvcap, &type,
+                                           &cookie);
+                                       if (nvname == NULL) {
+                                               printf("\n");
+                                               break;
+                                       }
+                                       if (type == NV_TYPE_BOOL)
+                                               printf("%c%s", first ? ' ' :
+                                                   ',', nvname);
+                               }
+                       }
+                       nvlist_destroy(nvcap);
+                       free(buf);
+
+                       if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0)
+                               Perror("ioctl (SIOCGIFCAP)");
+               } else if (ifr.ifr_curcap != 0) {
                        printb("\toptions", ifr.ifr_curcap, IFCAPBITS);
                        putchar('\n');
-               }
-               if (supmedia && ifr.ifr_reqcap != 0) {
-                       printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS);
-                       putchar('\n');
+                       if (supmedia && ifr.ifr_reqcap != 0) {
+                               printb("\tcapabilities", ifr.ifr_reqcap,
+                                   IFCAPBITS);
+                               putchar('\n');
+                       }
                }
        }
 

Reply via email to