Print this page
NEX-1785 Add IPMP related subcommands to ipadm(1M) man page
Reviewed by: Dan Fields <dan.fields@nexenta.com>
OS-161: Integrate IPMP changes

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
          +++ new/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c
↓ open down ↓ 30 lines elided ↑ open up ↑
  31   31  #include <errno.h>
  32   32  #include <getopt.h>
  33   33  #include <inet/ip.h>
  34   34  #include <inet/iptun.h>
  35   35  #include <inet/tunables.h>
  36   36  #include <libdladm.h>
  37   37  #include <libdliptun.h>
  38   38  #include <libdllink.h>
  39   39  #include <libinetutil.h>
  40   40  #include <libipadm.h>
       41 +#include <ipmp.h>
       42 +#include <ipmp_admin.h>
  41   43  #include <locale.h>
  42   44  #include <netdb.h>
  43   45  #include <netinet/in.h>
  44   46  #include <ofmt.h>
  45   47  #include <stdarg.h>
  46   48  #include <stddef.h>
  47   49  #include <stdio.h>
  48   50  #include <stdlib.h>
  49   51  #include <string.h>
  50   52  #include <strings.h>
  51   53  #include <sys/stat.h>
  52   54  #include <sys/types.h>
  53   55  #include <zone.h>
       56 +#include <sys/list.h>
       57 +#include <stddef.h>
  54   58  
  55   59  #define STR_UNKNOWN_VAL "?"
  56   60  #define LIFC_DEFAULT    (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\
  57   61                          LIFC_UNDER_IPMP)
  58   62  
       63 +static void do_create_ip_common(int, char **, const char *, uint32_t);
       64 +
  59   65  typedef void cmdfunc_t(int, char **, const char *);
  60      -static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if;
  61      -static cmdfunc_t do_show_if;
  62      -static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop;
  63      -static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop;
  64      -static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop;
  65      -static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr;
  66      -static cmdfunc_t do_enable_addr, do_disable_addr;
  67      -static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr;
       66 +static cmdfunc_t do_create_ip, do_delete_ip;
       67 +static cmdfunc_t do_create_ipmp, do_add_ipmp, do_remove_ipmp;
       68 +static cmdfunc_t do_disable_if, do_enable_if, do_show_if;
       69 +static cmdfunc_t do_set_ifprop, do_reset_ifprop, do_show_ifprop;
       70 +static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr, do_refresh_addr;
       71 +static cmdfunc_t do_disable_addr, do_enable_addr, do_down_addr, do_up_addr;
       72 +static cmdfunc_t do_set_addrprop, do_reset_addrprop, do_show_addrprop;
       73 +static cmdfunc_t do_set_prop, do_reset_prop, do_show_prop;
  68   74  
  69   75  static void warn(const char *, ...);
  70   76  static void die(const char *, ...);
  71   77  
  72   78  typedef struct  cmd {
  73   79          char            *c_name;
  74   80          cmdfunc_t       *c_fn;
  75   81          const char      *c_usage;
  76   82  } cmd_t;
  77   83  
  78   84  static cmd_t    cmds[] = {
  79   85          /* interface management related sub-commands */
  80      -        { "create-if",  do_create_if,   "\tcreate-if\t[-t] <interface>" },
  81      -        { "disable-if", do_disable_if,  "\tdisable-if\t-t <interface>"  },
  82      -        { "enable-if",  do_enable_if,   "\tenable-if\t-t <interface>"   },
  83      -        { "delete-if",  do_delete_if,   "\tdelete-if\t<interface>"      },
  84      -        { "show-if",    do_show_if,
       86 +        { "create-ip", do_create_ip, "\tcreate-ip\t[-t] <interface>"    },
       87 +        { "create-if", do_create_ip, NULL                               },
       88 +        { "delete-ip", do_delete_ip, "\tdelete-ip\t<interface>\n"       },
       89 +        { "delete-if", do_delete_ip, NULL                               },
       90 +
       91 +        { "create-ipmp", do_create_ipmp,
       92 +            "\tcreate-ipmp\t[-t] <ipmp-interface>"                      },
       93 +        { "delete-ipmp", do_delete_ip,
       94 +            "\tdelete-ipmp\t<ipmp-interface>"                           },
       95 +        { "add-ipmp", do_add_ipmp,
       96 +            "\tadd-ipmp\t[-t] -i <interface> ... "
       97 +            "<ipmp-interface>"                                          },
       98 +        { "remove-ipmp", do_remove_ipmp,
       99 +            "\tremove-ipmp\t[-t] -i <interface> ... "
      100 +            "<ipmp-interface>\n"                                        },
      101 +
      102 +        { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>"   },
      103 +        { "enable-if", do_enable_if, "\tenable-if\t-t <interface>"      },
      104 +        { "show-if", do_show_if,
  85  105              "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n"        },
      106 +
  86  107          { "set-ifprop", do_set_ifprop,
  87  108              "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> "
  88  109              "<interface>"                                               },
  89  110          { "reset-ifprop", do_reset_ifprop,
  90  111              "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>"  },
  91  112          { "show-ifprop", do_show_ifprop,
  92  113              "\tshow-ifprop\t[[-c] -o <field>,...] [-p <prop>,...]\n"
  93      -            "\t\t\t[-m <protocol>] [interface]\n"                       },
      114 +            "\t\t\t[-m <protocol>] [interface]\n"                       },
  94  115  
  95  116          /* address management related sub-commands */
  96  117          { "create-addr", do_create_addr,
  97  118              "\tcreate-addr\t[-t] -T static [-d] "
  98  119              "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n"
  99  120              "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever]\n"
 100  121              "\t\t\t[-1] [-h <hostname>] <addrobj>\n"
 101  122              "\tcreate-addr\t[-t] -T addrconf [-i interface-id]\n"
 102  123              "\t\t\t[-p {stateful|stateless}={yes|no}] <addrobj>" },
 103      -        { "down-addr",  do_down_addr,   "\tdown-addr\t[-t] <addrobj>"   },
 104      -        { "up-addr",    do_up_addr,     "\tup-addr\t\t[-t] <addrobj>"   },
 105      -        { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" },
 106      -        { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>"  },
 107      -        { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" },
 108  124          { "delete-addr", do_delete_addr, "\tdelete-addr\t[-r] <addrobj>" },
 109      -        { "show-addr",  do_show_addr,
 110      -            "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]\n"          },
      125 +        { "show-addr", do_show_addr,
      126 +            "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]"            },
      127 +        { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" },
      128 +        { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>"      },
      129 +        { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>"  },
      130 +        { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" },
      131 +        { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>\n" },
      132 +
 111  133          { "set-addrprop", do_set_addrprop,
 112  134              "\tset-addrprop\t[-t] -p <prop>=<value[,...]> <addrobj>"    },
 113  135          { "reset-addrprop", do_reset_addrprop,
 114  136              "\treset-addrprop\t[-t] -p <prop> <addrobj>"                },
 115  137          { "show-addrprop", do_show_addrprop,
 116  138              "\tshow-addrprop\t[[-c] -o <field>,...] [-p <prop>,...] "
 117  139              "<addrobj>\n"                                               },
 118  140  
 119  141          /* protocol properties related sub-commands */
 120      -        { "set-prop",   do_set_prop,
      142 +        { "set-prop", do_set_prop,
 121  143              "\tset-prop\t[-t] -p <prop>[+|-]=<value[,...]> <protocol>"  },
 122      -        { "reset-prop", do_reset_prop,
      144 +        { "reset-prop", do_reset_prop,
 123  145              "\treset-prop\t[-t] -p <prop> <protocol>"                   },
 124      -        { "show-prop",  do_show_prop,
      146 +        { "show-prop", do_show_prop,
 125  147              "\tshow-prop\t[[-c] -o <field>,...] [-p <prop>,...]"
 126  148              " [protocol]"                                               }
 127  149  };
 128  150  
 129  151  static const struct option if_longopts[] = {
 130  152          {"temporary",   no_argument,            0, 't'  },
 131  153          { 0, 0, 0, 0 }
 132  154  };
 133  155  
 134  156  static const struct option show_prop_longopts[] = {
↓ open down ↓ 153 lines elided ↑ open up ↑
 288  310          SA_ADDROBJ,
 289  311          SA_TYPE,
 290  312          SA_STATE,
 291  313          SA_CURRENT,
 292  314          SA_PERSISTENT,
 293  315          SA_ADDR
 294  316  } sa_field_index_t;
 295  317  
 296  318  typedef enum {
 297  319          SI_IFNAME,
      320 +        SI_IFCLASS,
 298  321          SI_STATE,
 299  322          SI_CURRENT,
 300  323          SI_PERSISTENT
 301  324  } si_field_index_t;
 302  325  
 303  326  static ofmt_field_t show_addr_fields[] = {
 304  327  /* name,        field width,    id,             callback */
 305  328  { "ADDROBJ",    18,             SA_ADDROBJ,     print_sa_cb},
 306  329  { "TYPE",       9,              SA_TYPE,        print_sa_cb},
 307  330  { "STATE",      13,             SA_STATE,       print_sa_cb},
 308  331  { "CURRENT",    8,              SA_CURRENT,     print_sa_cb},
 309  332  { "PERSISTENT", 11,             SA_PERSISTENT,  print_sa_cb},
 310  333  { "ADDR",       46,             SA_ADDR,        print_sa_cb},
 311  334  { NULL,         0,              0,              NULL}
 312  335  };
 313  336  
 314  337  static ofmt_field_t show_if_fields[] = {
 315  338  /* name,        field width,    id,             callback */
 316  339  { "IFNAME",     11,             SI_IFNAME,      print_si_cb},
      340 +{ "CLASS",      10,             SI_IFCLASS,     print_si_cb},
 317  341  { "STATE",      9,              SI_STATE,       print_si_cb},
 318  342  { "CURRENT",    13,             SI_CURRENT,     print_si_cb},
 319  343  { "PERSISTENT", 11,             SI_PERSISTENT,  print_si_cb},
 320  344  { NULL,         0,              0,              NULL}
 321  345  };
 322  346  
 323  347  #define IPADM_ALL_BITS  ((uint_t)-1)
 324  348  typedef struct intf_mask {
 325  349          char            *name;
 326  350          uint64_t        bits;
 327  351          uint64_t        mask;
 328  352  } fmask_t;
 329  353  
      354 +typedef enum {
      355 +    IPMP_ADD_MEMBER,
      356 +    IPMP_REMOVE_MEMBER
      357 +} ipmp_action_t;
      358 +
 330  359  /*
 331  360   * Handle to libipadm. Opened in main() before the sub-command specific
 332  361   * function is called and is closed before the program exits.
 333  362   */
 334  363  ipadm_handle_t  iph = NULL;
 335  364  
 336  365  /*
 337  366   * Opaque ipadm address object. Used by all the address management subcommands.
 338  367   */
 339  368  ipadm_addrobj_t ipaddr = NULL;
 340  369  
 341  370  static char *progname;
 342  371  
 343  372  static void     die(const char *, ...);
 344  373  static void     die_opterr(int, int, const char *);
 345  374  static void     warn_ipadmerr(ipadm_status_t, const char *, ...);
 346  375  static void     ipadm_check_propstr(const char *, boolean_t, const char *);
 347  376  static void     process_misc_addrargs(int, char **, const char *, int *,
 348  377                      uint32_t *);
      378 +static void     do_action_ipmp(int, char **, const char *, ipmp_action_t);
 349  379  
 350  380  static void
 351  381  usage(void)
 352  382  {
 353  383          int     i;
 354  384          cmd_t   *cmdp;
 355  385  
 356  386          (void) fprintf(stderr,
 357  387              gettext("usage:  ipadm <subcommand> <args> ...\n"));
 358  388          for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
↓ open down ↓ 42 lines elided ↑ open up ↑
 401  431          }
 402  432  
 403  433          (void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
 404  434              progname, argv[1]);
 405  435          usage();
 406  436  
 407  437          return (0);
 408  438  }
 409  439  
 410  440  /*
 411      - * Create an IP interface for which no saved configuration exists in the
 412      - * persistent store.
      441 + * Create regular IP interface or IPMP group interface
 413  442   */
 414  443  static void
 415      -do_create_if(int argc, char *argv[], const char *use)
      444 +do_create_ip_common(int argc, char *argv[], const char *use, uint32_t flags)
 416  445  {
 417  446          ipadm_status_t  status;
 418  447          int             option;
 419      -        uint32_t        flags = IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE;
 420  448  
 421  449          opterr = 0;
 422      -        while ((option = getopt_long(argc, argv, ":t", if_longopts,
 423      -            NULL)) != -1) {
      450 +        while ((option = getopt_long(argc, argv,
      451 +            ":t", if_longopts, NULL)) != -1) {
 424  452                  switch (option) {
 425  453                  case 't':
 426  454                          /*
 427  455                           * "ifconfig" mode - plumb interface, but do not
 428  456                           * restore settings that may exist in db.
 429  457                           */
 430  458                          flags &= ~IPADM_OPT_PERSIST;
 431  459                          break;
 432  460                  default:
 433  461                          die_opterr(optopt, option, use);
 434  462                  }
 435  463          }
 436      -        if (optind != (argc - 1))
 437      -                die("Usage: %s", use);
      464 +        if (optind != (argc - 1)) {
      465 +                if (use != NULL)
      466 +                        die("usage: %s", use);
      467 +                else
      468 +                        die(NULL);
      469 +        }
 438  470          status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags);
 439  471          if (status != IPADM_SUCCESS) {
 440  472                  die("Could not create %s : %s",
 441  473                      argv[optind], ipadm_status2str(status));
 442  474          }
 443  475  }
 444  476  
 445  477  /*
      478 + * Create an IPMP group interface for which no saved configuration
      479 + * exists in the persistent store.
      480 + */
      481 +static void
      482 +do_create_ipmp(int argc, char *argv[], const char *use)
      483 +{
      484 +        ipmp_handle_t ipmp_handle;
      485 +        int retval;
      486 +        uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE | IPADM_OPT_IPMP;
      487 +
      488 +        retval = ipmp_open(&ipmp_handle);
      489 +        if (retval != IPMP_SUCCESS) {
      490 +                die("Could not create IPMP handle: %s",
      491 +                    ipadm_status2str(retval));
      492 +        }
      493 +
      494 +        retval = ipmp_ping_daemon(ipmp_handle);
      495 +        ipmp_close(ipmp_handle);
      496 +
      497 +        if (retval != IPMP_SUCCESS) {
      498 +                die("Cannot ping in.mpathd: %s", ipmp_errmsg(retval));
      499 +        }
      500 +
      501 +        do_create_ip_common(argc, argv, use, flags);
      502 +}
      503 +
      504 +static void
      505 +do_add_ipmp(int argc, char *argv[], const char *use)
      506 +{
      507 +        do_action_ipmp(argc, argv, use, IPMP_ADD_MEMBER);
      508 +}
      509 +
      510 +static void
      511 +do_remove_ipmp(int argc, char *argv[], const char *use)
      512 +{
      513 +        do_action_ipmp(argc, argv, use, IPMP_REMOVE_MEMBER);
      514 +}
      515 +
      516 +static void
      517 +do_action_ipmp(int argc, char *argv[], const char *use,
      518 +    ipmp_action_t action)
      519 +{
      520 +        int     option;
      521 +        ipadm_status_t  status;
      522 +        ipadm_ipmp_members_t members;
      523 +        ipadm_ipmp_member_t *ipmp_member;
      524 +        uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE;
      525 +
      526 +        list_create(&members, sizeof (ipadm_ipmp_member_t),
      527 +            offsetof(ipadm_ipmp_member_t, node));
      528 +
      529 +        opterr = 0;
      530 +        while ((option = getopt_long(argc, argv,
      531 +            ":ti:", if_longopts, NULL)) != -1) {
      532 +                switch (option) {
      533 +                case 't':
      534 +                        flags &= ~IPADM_OPT_PERSIST;
      535 +                        break;
      536 +                case 'i':
      537 +                        if ((ipmp_member = calloc(1,
      538 +                            sizeof (ipadm_ipmp_member_t))) == NULL)
      539 +                                die("insufficient memory");
      540 +
      541 +                        if (strlcpy(ipmp_member->if_name,
      542 +                            optarg, sizeof (ipmp_member->if_name)) >= LIFNAMSIZ)
      543 +                                die("Incorrect length of interface"
      544 +                                    "name: %s", optarg);
      545 +
      546 +                        list_insert_tail(&members, ipmp_member);
      547 +                        break;
      548 +                default:
      549 +                        die_opterr(optopt, option, use);
      550 +                }
      551 +        }
      552 +
      553 +        if (optind != (argc - 1))
      554 +                die("Usage: %s", use);
      555 +
      556 +        while ((ipmp_member = list_remove_head(&members)) != NULL) {
      557 +                switch (action) {
      558 +                        case IPMP_ADD_MEMBER:
      559 +                                if ((status = ipadm_add_ipmp_member(iph,
      560 +                                    argv[optind], ipmp_member->if_name, flags))
      561 +                                    != IPADM_SUCCESS)
      562 +                                        die("Cannot add interface '%s' to "
      563 +                                            "IPMP interface '%s': %s",
      564 +                                            ipmp_member->if_name, argv[optind],
      565 +                                            ipadm_status2str(status));
      566 +                                break;
      567 +                        case IPMP_REMOVE_MEMBER:
      568 +                                if ((status = ipadm_remove_ipmp_member(iph,
      569 +                                    argv[optind], ipmp_member->if_name, flags))
      570 +                                    != IPADM_SUCCESS)
      571 +                                        die("Cannot remove interface '%s' from "
      572 +                                            "IPMP interface '%s': %s",
      573 +                                            ipmp_member->if_name, argv[optind],
      574 +                                            ipadm_status2str(status));
      575 +                                break;
      576 +                }
      577 +
      578 +                free(ipmp_member);
      579 +        }
      580 +
      581 +        list_destroy(&members);
      582 +}
      583 +
      584 +/*
      585 + * Create an IP interface for which no saved configuration exists in the
      586 + * persistent store.
      587 + */
      588 +static void
      589 +do_create_ip(int argc, char *argv[], const char *use)
      590 +{
      591 +        do_create_ip_common(argc, argv, use,
      592 +            IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE);
      593 +}
      594 +
      595 +/*
 446  596   * Enable an IP interface based on the persistent configuration for
 447  597   * that interface.
 448  598   */
 449  599  static void
 450  600  do_enable_if(int argc, char *argv[], const char *use)
 451  601  {
 452  602          ipadm_status_t  status;
 453  603          int             index;
 454  604          uint32_t        flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
 455  605  
↓ open down ↓ 6 lines elided ↑ open up ↑
 462  612          } else if (status != IPADM_SUCCESS) {
 463  613                  die("Could not enable %s : %s",
 464  614                      argv[optind], ipadm_status2str(status));
 465  615          }
 466  616  }
 467  617  
 468  618  /*
 469  619   * Remove an IP interface from both active and persistent configuration.
 470  620   */
 471  621  static void
 472      -do_delete_if(int argc, char *argv[], const char *use)
      622 +do_delete_ip(int argc, char *argv[], const char *use)
 473  623  {
 474  624          ipadm_status_t  status;
 475  625          uint32_t        flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST;
 476  626  
 477  627          if (argc != 2)
 478  628                  die("Usage: %s", use);
 479  629  
 480  630          status = ipadm_delete_if(iph, argv[1], AF_UNSPEC, flags);
 481  631          if (status != IPADM_SUCCESS) {
 482  632                  die("Could not delete %s: %s",
↓ open down ↓ 554 lines elided ↑ open up ↑
1037 1187  
1038 1188          (void) fprintf(stderr, "\n");
1039 1189  }
1040 1190  
1041 1191  /* PRINTFLIKE1 */
1042 1192  static void
1043 1193  die(const char *format, ...)
1044 1194  {
1045 1195          va_list alist;
1046 1196  
1047      -        format = gettext(format);
1048      -        (void) fprintf(stderr, "%s: ", progname);
     1197 +        if (format != NULL) {
     1198 +                format = gettext(format);
     1199 +                (void) fprintf(stderr, "%s: ", progname);
1049 1200  
1050      -        va_start(alist, format);
1051      -        (void) vfprintf(stderr, format, alist);
1052      -        va_end(alist);
     1201 +                va_start(alist, format);
     1202 +                (void) vfprintf(stderr, format, alist);
     1203 +                va_end(alist);
1053 1204  
1054      -        (void) putchar('\n');
     1205 +                (void) putchar('\n');
     1206 +        }
1055 1207  
1056 1208          ipadm_destroy_addrobj(ipaddr);
1057 1209          ipadm_close(iph);
1058 1210          exit(EXIT_FAILURE);
1059 1211  }
1060 1212  
1061 1213  static void
1062 1214  die_opterr(int opt, int opterr, const char *usage)
1063 1215  {
1064 1216          switch (opterr) {
↓ open down ↓ 849 lines elided ↑ open up ↑
1914 2066                  { "I",  IFIF_IPMP,              IFIF_IPMP       },
1915 2067                  { "s",  IFIF_STANDBY,           IFIF_STANDBY    },
1916 2068                  { "i",  IFIF_INACTIVE,          IFIF_INACTIVE   },
1917 2069                  { "V",  IFIF_VRRP,              IFIF_VRRP       },
1918 2070                  { "a",  IFIF_NOACCEPT,          IFIF_NOACCEPT   },
1919 2071                  { "Z",  IFIF_L3PROTECT,         IFIF_L3PROTECT  },
1920 2072                  { "4",  IFIF_IPV4,              IFIF_IPV4       },
1921 2073                  { "6",  IFIF_IPV6,              IFIF_IPV6       },
1922 2074                  { NULL, 0,                      0               }
1923 2075          };
     2076 +        fmask_t intf_class[] = {
     2077 +                { "IP",         IPADM_IF_CLASS_REGULAR, IPADM_ALL_BITS},
     2078 +                { "IPMP",       IPADM_IF_CLASS_IPMP,    IPADM_ALL_BITS},
     2079 +                { "VIRTUAL",    IPADM_IF_CLASS_VIRTUAL, IPADM_ALL_BITS},
     2080 +                { "UNKNOWN",    IPADM_IF_CLASS_UNKNOWN, IPADM_ALL_BITS},
     2081 +                { NULL, 0,      0}
     2082 +        };
1924 2083  
1925 2084          buf[0] = '\0';
1926 2085          switch (ofarg->ofmt_id) {
1927 2086          case SI_IFNAME:
1928 2087                  (void) snprintf(buf, bufsize, "%s", ifname);
1929 2088                  break;
     2089 +        case SI_IFCLASS:
     2090 +                flags2str(ifinfo->ifi_class, intf_class, _B_FALSE,
     2091 +                    buf, bufsize);
     2092 +                break;
1930 2093          case SI_STATE:
1931 2094                  flags2str(ifinfo->ifi_state, intf_state, _B_FALSE,
1932 2095                      buf, bufsize);
1933 2096                  break;
1934 2097          case SI_CURRENT:
1935 2098                  flags2str(ifinfo->ifi_cflags, intf_cflags, _B_TRUE,
1936 2099                      buf, bufsize);
1937 2100                  break;
1938 2101          case SI_PERSISTENT:
1939 2102                  flags2str(ifinfo->ifi_pflags, intf_pflags, _B_TRUE,
↓ open down ↓ 280 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX