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: