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

*** 36,45 **** --- 36,47 ---- #include <libdladm.h> #include <libdliptun.h> #include <libdllink.h> #include <libinetutil.h> #include <libipadm.h> + #include <ipmp.h> + #include <ipmp_admin.h> #include <locale.h> #include <netdb.h> #include <netinet/in.h> #include <ofmt.h> #include <stdarg.h>
*** 49,72 **** #include <string.h> #include <strings.h> #include <sys/stat.h> #include <sys/types.h> #include <zone.h> #define STR_UNKNOWN_VAL "?" #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\ LIFC_UNDER_IPMP) typedef void cmdfunc_t(int, char **, const char *); ! static cmdfunc_t do_create_if, do_delete_if, do_enable_if, do_disable_if; ! static cmdfunc_t do_show_if; ! static cmdfunc_t do_set_prop, do_show_prop, do_set_ifprop; ! static cmdfunc_t do_show_ifprop, do_reset_ifprop, do_reset_prop; ! static cmdfunc_t do_show_addrprop, do_set_addrprop, do_reset_addrprop; ! static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr; ! static cmdfunc_t do_enable_addr, do_disable_addr; ! static cmdfunc_t do_up_addr, do_down_addr, do_refresh_addr; static void warn(const char *, ...); static void die(const char *, ...); typedef struct cmd { --- 51,78 ---- #include <string.h> #include <strings.h> #include <sys/stat.h> #include <sys/types.h> #include <zone.h> + #include <sys/list.h> + #include <stddef.h> #define STR_UNKNOWN_VAL "?" #define LIFC_DEFAULT (LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES |\ LIFC_UNDER_IPMP) + static void do_create_ip_common(int, char **, const char *, uint32_t); + typedef void cmdfunc_t(int, char **, const char *); ! static cmdfunc_t do_create_ip, do_delete_ip; ! static cmdfunc_t do_create_ipmp, do_add_ipmp, do_remove_ipmp; ! static cmdfunc_t do_disable_if, do_enable_if, do_show_if; ! static cmdfunc_t do_set_ifprop, do_reset_ifprop, do_show_ifprop; ! static cmdfunc_t do_create_addr, do_delete_addr, do_show_addr, do_refresh_addr; ! static cmdfunc_t do_disable_addr, do_enable_addr, do_down_addr, do_up_addr; ! static cmdfunc_t do_set_addrprop, do_reset_addrprop, do_show_addrprop; ! static cmdfunc_t do_set_prop, do_reset_prop, do_show_prop; static void warn(const char *, ...); static void die(const char *, ...); typedef struct cmd {
*** 75,90 **** const char *c_usage; } cmd_t; static cmd_t cmds[] = { /* interface management related sub-commands */ ! { "create-if", do_create_if, "\tcreate-if\t[-t] <interface>" }, { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" }, { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" }, - { "delete-if", do_delete_if, "\tdelete-if\t<interface>" }, { "show-if", do_show_if, "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" }, { "set-ifprop", do_set_ifprop, "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> " "<interface>" }, { "reset-ifprop", do_reset_ifprop, "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" }, --- 81,111 ---- const char *c_usage; } cmd_t; static cmd_t cmds[] = { /* interface management related sub-commands */ ! { "create-ip", do_create_ip, "\tcreate-ip\t[-t] <interface>" }, ! { "create-if", do_create_ip, NULL }, ! { "delete-ip", do_delete_ip, "\tdelete-ip\t<interface>\n" }, ! { "delete-if", do_delete_ip, NULL }, ! ! { "create-ipmp", do_create_ipmp, ! "\tcreate-ipmp\t[-t] <ipmp-interface>" }, ! { "delete-ipmp", do_delete_ip, ! "\tdelete-ipmp\t<ipmp-interface>" }, ! { "add-ipmp", do_add_ipmp, ! "\tadd-ipmp\t[-t] -i <interface> ... " ! "<ipmp-interface>" }, ! { "remove-ipmp", do_remove_ipmp, ! "\tremove-ipmp\t[-t] -i <interface> ... " ! "<ipmp-interface>\n" }, ! { "disable-if", do_disable_if, "\tdisable-if\t-t <interface>" }, { "enable-if", do_enable_if, "\tenable-if\t-t <interface>" }, { "show-if", do_show_if, "\tshow-if\t\t[[-p] -o <field>,...] [<interface>]\n" }, + { "set-ifprop", do_set_ifprop, "\tset-ifprop\t[-t] -p <prop>=<value[,...]> -m <protocol> " "<interface>" }, { "reset-ifprop", do_reset_ifprop, "\treset-ifprop\t[-t] -p <prop> -m <protocol> <interface>" },
*** 98,115 **** "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n" "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever]\n" "\t\t\t[-1] [-h <hostname>] <addrobj>\n" "\tcreate-addr\t[-t] -T addrconf [-i interface-id]\n" "\t\t\t[-p {stateful|stateless}={yes|no}] <addrobj>" }, { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>" }, { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>" }, { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" }, ! { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>" }, ! { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" }, ! { "delete-addr", do_delete_addr, "\tdelete-addr\t[-r] <addrobj>" }, ! { "show-addr", do_show_addr, ! "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]\n" }, { "set-addrprop", do_set_addrprop, "\tset-addrprop\t[-t] -p <prop>=<value[,...]> <addrobj>" }, { "reset-addrprop", do_reset_addrprop, "\treset-addrprop\t[-t] -p <prop> <addrobj>" }, { "show-addrprop", do_show_addrprop, --- 119,137 ---- "-a{local|remote}=addr[/prefixlen]\n\t\t\t<addrobj>\n" "\tcreate-addr\t[-t] -T dhcp [-w <seconds> | forever]\n" "\t\t\t[-1] [-h <hostname>] <addrobj>\n" "\tcreate-addr\t[-t] -T addrconf [-i interface-id]\n" "\t\t\t[-p {stateful|stateless}={yes|no}] <addrobj>" }, + { "delete-addr", do_delete_addr, "\tdelete-addr\t[-r] <addrobj>" }, + { "show-addr", do_show_addr, + "\tshow-addr\t[[-p] -o <field>,...] [<addrobj>]" }, + { "refresh-addr", do_refresh_addr, "\trefresh-addr\t[-i] <addrobj>" }, { "down-addr", do_down_addr, "\tdown-addr\t[-t] <addrobj>" }, { "up-addr", do_up_addr, "\tup-addr\t\t[-t] <addrobj>" }, { "disable-addr", do_disable_addr, "\tdisable-addr\t-t <addrobj>" }, ! { "enable-addr", do_enable_addr, "\tenable-addr\t-t <addrobj>\n" }, ! { "set-addrprop", do_set_addrprop, "\tset-addrprop\t[-t] -p <prop>=<value[,...]> <addrobj>" }, { "reset-addrprop", do_reset_addrprop, "\treset-addrprop\t[-t] -p <prop> <addrobj>" }, { "show-addrprop", do_show_addrprop,
*** 293,302 **** --- 315,325 ---- SA_ADDR } sa_field_index_t; typedef enum { SI_IFNAME, + SI_IFCLASS, SI_STATE, SI_CURRENT, SI_PERSISTENT } si_field_index_t;
*** 312,321 **** --- 335,345 ---- }; static ofmt_field_t show_if_fields[] = { /* name, field width, id, callback */ { "IFNAME", 11, SI_IFNAME, print_si_cb}, + { "CLASS", 10, SI_IFCLASS, print_si_cb}, { "STATE", 9, SI_STATE, print_si_cb}, { "CURRENT", 13, SI_CURRENT, print_si_cb}, { "PERSISTENT", 11, SI_PERSISTENT, print_si_cb}, { NULL, 0, 0, NULL} };
*** 325,334 **** --- 349,363 ---- char *name; uint64_t bits; uint64_t mask; } fmask_t; + typedef enum { + IPMP_ADD_MEMBER, + IPMP_REMOVE_MEMBER + } ipmp_action_t; + /* * Handle to libipadm. Opened in main() before the sub-command specific * function is called and is closed before the program exits. */ ipadm_handle_t iph = NULL;
*** 344,353 **** --- 373,383 ---- static void die_opterr(int, int, const char *); static void warn_ipadmerr(ipadm_status_t, const char *, ...); static void ipadm_check_propstr(const char *, boolean_t, const char *); static void process_misc_addrargs(int, char **, const char *, int *, uint32_t *); + static void do_action_ipmp(int, char **, const char *, ipmp_action_t); static void usage(void) { int i;
*** 406,428 **** return (0); } /* ! * Create an IP interface for which no saved configuration exists in the ! * persistent store. */ static void ! do_create_if(int argc, char *argv[], const char *use) { ipadm_status_t status; int option; - uint32_t flags = IPADM_OPT_PERSIST|IPADM_OPT_ACTIVE; opterr = 0; ! while ((option = getopt_long(argc, argv, ":t", if_longopts, ! NULL)) != -1) { switch (option) { case 't': /* * "ifconfig" mode - plumb interface, but do not * restore settings that may exist in db. --- 436,456 ---- return (0); } /* ! * Create regular IP interface or IPMP group interface */ static void ! do_create_ip_common(int argc, char *argv[], const char *use, uint32_t flags) { ipadm_status_t status; int option; opterr = 0; ! while ((option = getopt_long(argc, argv, ! ":t", if_longopts, NULL)) != -1) { switch (option) { case 't': /* * "ifconfig" mode - plumb interface, but do not * restore settings that may exist in db.
*** 431,450 **** break; default: die_opterr(optopt, option, use); } } ! if (optind != (argc - 1)) ! die("Usage: %s", use); status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags); if (status != IPADM_SUCCESS) { die("Could not create %s : %s", argv[optind], ipadm_status2str(status)); } } /* * Enable an IP interface based on the persistent configuration for * that interface. */ static void do_enable_if(int argc, char *argv[], const char *use) --- 459,600 ---- break; default: die_opterr(optopt, option, use); } } ! if (optind != (argc - 1)) { ! if (use != NULL) ! die("usage: %s", use); ! else ! die(NULL); ! } status = ipadm_create_if(iph, argv[optind], AF_UNSPEC, flags); if (status != IPADM_SUCCESS) { die("Could not create %s : %s", argv[optind], ipadm_status2str(status)); } } /* + * Create an IPMP group interface for which no saved configuration + * exists in the persistent store. + */ + static void + do_create_ipmp(int argc, char *argv[], const char *use) + { + ipmp_handle_t ipmp_handle; + int retval; + uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE | IPADM_OPT_IPMP; + + retval = ipmp_open(&ipmp_handle); + if (retval != IPMP_SUCCESS) { + die("Could not create IPMP handle: %s", + ipadm_status2str(retval)); + } + + retval = ipmp_ping_daemon(ipmp_handle); + ipmp_close(ipmp_handle); + + if (retval != IPMP_SUCCESS) { + die("Cannot ping in.mpathd: %s", ipmp_errmsg(retval)); + } + + do_create_ip_common(argc, argv, use, flags); + } + + static void + do_add_ipmp(int argc, char *argv[], const char *use) + { + do_action_ipmp(argc, argv, use, IPMP_ADD_MEMBER); + } + + static void + do_remove_ipmp(int argc, char *argv[], const char *use) + { + do_action_ipmp(argc, argv, use, IPMP_REMOVE_MEMBER); + } + + static void + do_action_ipmp(int argc, char *argv[], const char *use, + ipmp_action_t action) + { + int option; + ipadm_status_t status; + ipadm_ipmp_members_t members; + ipadm_ipmp_member_t *ipmp_member; + uint32_t flags = IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE; + + list_create(&members, sizeof (ipadm_ipmp_member_t), + offsetof(ipadm_ipmp_member_t, node)); + + opterr = 0; + while ((option = getopt_long(argc, argv, + ":ti:", if_longopts, NULL)) != -1) { + switch (option) { + case 't': + flags &= ~IPADM_OPT_PERSIST; + break; + case 'i': + if ((ipmp_member = calloc(1, + sizeof (ipadm_ipmp_member_t))) == NULL) + die("insufficient memory"); + + if (strlcpy(ipmp_member->if_name, + optarg, sizeof (ipmp_member->if_name)) >= LIFNAMSIZ) + die("Incorrect length of interface" + "name: %s", optarg); + + list_insert_tail(&members, ipmp_member); + break; + default: + die_opterr(optopt, option, use); + } + } + + if (optind != (argc - 1)) + die("Usage: %s", use); + + while ((ipmp_member = list_remove_head(&members)) != NULL) { + switch (action) { + case IPMP_ADD_MEMBER: + if ((status = ipadm_add_ipmp_member(iph, + argv[optind], ipmp_member->if_name, flags)) + != IPADM_SUCCESS) + die("Cannot add interface '%s' to " + "IPMP interface '%s': %s", + ipmp_member->if_name, argv[optind], + ipadm_status2str(status)); + break; + case IPMP_REMOVE_MEMBER: + if ((status = ipadm_remove_ipmp_member(iph, + argv[optind], ipmp_member->if_name, flags)) + != IPADM_SUCCESS) + die("Cannot remove interface '%s' from " + "IPMP interface '%s': %s", + ipmp_member->if_name, argv[optind], + ipadm_status2str(status)); + break; + } + + free(ipmp_member); + } + + list_destroy(&members); + } + + /* + * Create an IP interface for which no saved configuration exists in the + * persistent store. + */ + static void + do_create_ip(int argc, char *argv[], const char *use) + { + do_create_ip_common(argc, argv, use, + IPADM_OPT_PERSIST | IPADM_OPT_ACTIVE); + } + + /* * Enable an IP interface based on the persistent configuration for * that interface. */ static void do_enable_if(int argc, char *argv[], const char *use)
*** 467,477 **** /* * Remove an IP interface from both active and persistent configuration. */ static void ! do_delete_if(int argc, char *argv[], const char *use) { ipadm_status_t status; uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; if (argc != 2) --- 617,627 ---- /* * Remove an IP interface from both active and persistent configuration. */ static void ! do_delete_ip(int argc, char *argv[], const char *use) { ipadm_status_t status; uint32_t flags = IPADM_OPT_ACTIVE|IPADM_OPT_PERSIST; if (argc != 2)
*** 1042,1059 **** --- 1192,1211 ---- static void die(const char *format, ...) { va_list alist; + if (format != NULL) { format = gettext(format); (void) fprintf(stderr, "%s: ", progname); va_start(alist, format); (void) vfprintf(stderr, format, alist); va_end(alist); (void) putchar('\n'); + } ipadm_destroy_addrobj(ipaddr); ipadm_close(iph); exit(EXIT_FAILURE); }
*** 1919,1934 **** --- 2071,2097 ---- { "Z", IFIF_L3PROTECT, IFIF_L3PROTECT }, { "4", IFIF_IPV4, IFIF_IPV4 }, { "6", IFIF_IPV6, IFIF_IPV6 }, { NULL, 0, 0 } }; + fmask_t intf_class[] = { + { "IP", IPADM_IF_CLASS_REGULAR, IPADM_ALL_BITS}, + { "IPMP", IPADM_IF_CLASS_IPMP, IPADM_ALL_BITS}, + { "VIRTUAL", IPADM_IF_CLASS_VIRTUAL, IPADM_ALL_BITS}, + { "UNKNOWN", IPADM_IF_CLASS_UNKNOWN, IPADM_ALL_BITS}, + { NULL, 0, 0} + }; buf[0] = '\0'; switch (ofarg->ofmt_id) { case SI_IFNAME: (void) snprintf(buf, bufsize, "%s", ifname); break; + case SI_IFCLASS: + flags2str(ifinfo->ifi_class, intf_class, _B_FALSE, + buf, bufsize); + break; case SI_STATE: flags2str(ifinfo->ifi_state, intf_state, _B_FALSE, buf, bufsize); break; case SI_CURRENT: