1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
  25  */
  26 #ifndef _LIBIPADM_H
  27 #define _LIBIPADM_H
  28 
  29 #ifdef  __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/socket.h>
  36 #include <net/if.h>
  37 #include <netdb.h>
  38 #include <ifaddrs.h>
  39 #include <libnvpair.h>
  40 #include <netinet/tcp.h>
  41 #include <sys/stropts.h>
  42 #include <sys/list.h>
  43 #include <stddef.h>
  44 
  45 #define IPADM_AOBJ_USTRSIZ      32
  46 #define IPADM_AOBJSIZ           (LIFNAMSIZ + IPADM_AOBJ_USTRSIZ)
  47 #define MAXPROPVALLEN           512
  48 #define LOOPBACK_IF             "lo0"
  49 
  50 /* special timeout values for dhcp operations */
  51 #define IPADM_DHCP_WAIT_DEFAULT (-1)
  52 #define IPADM_DHCP_WAIT_FOREVER (-2)
  53 
  54 /*
  55  * Specifies that the string passed to ipadm_str2nvlist() is a string of comma
  56  * separated names and that each name does not have values associated with it.
  57  */
  58 #define IPADM_NORVAL            0x00000001
  59 
  60 /* error codes */
  61 typedef enum {
  62         IPADM_SUCCESS,          /* No error occurred */
  63         IPADM_FAILURE,          /* Generic failure */
  64         IPADM_EAUTH,            /* Insufficient user authorizations */
  65         IPADM_EPERM,            /* Permission denied */
  66         IPADM_NO_BUFS,          /* No Buffer space available */
  67         IPADM_NO_MEMORY,        /* Insufficient memory */
  68         IPADM_BAD_ADDR,         /* Invalid address */
  69         IPADM_BAD_PROTOCOL,     /* Wrong protocol family for operation */
  70         IPADM_DAD_FOUND,        /* Duplicate address detected */
  71         IPADM_EXISTS,           /* Already exists */
  72         IPADM_IF_EXISTS,        /* Interface already exists */
  73         IPADM_ADDROBJ_EXISTS,   /* Address object already exists */
  74         IPADM_ADDRCONF_EXISTS,  /* Addrconf already in progress */
  75         IPADM_ENXIO,            /* Interface does not exist */
  76         IPADM_GRP_NOTEMPTY,     /* IPMP Group non-empty on unplumb */
  77         IPADM_INVALID_ARG,      /* Invalid argument */
  78         IPADM_INVALID_NAME,     /* Invalid name */
  79         IPADM_DLPI_FAILURE,     /* Could not open DLPI link */
  80         IPADM_DLADM_FAILURE,    /* DLADM error encountered */
  81         IPADM_PROP_UNKNOWN,     /* Unknown property */
  82         IPADM_ERANGE,           /* Value is outside the allowed range */
  83         IPADM_ESRCH,            /* Value does not exist */
  84         IPADM_EOVERFLOW,        /* Number of values exceed the allowed limit */
  85         IPADM_NOTFOUND,         /* Object not found */
  86         IPADM_IF_INUSE,         /* Interface already in use */
  87         IPADM_ADDR_INUSE,       /* Address alrelady in use */
  88         IPADM_BAD_HOSTNAME,     /* hostname maps to multiple IP addresses */
  89         IPADM_ADDR_NOTAVAIL,    /* Can't assign requested address */
  90         IPADM_ALL_ADDRS_NOT_ENABLED, /* All addresses could not be enabled */
  91         IPADM_NDPD_NOT_RUNNING, /* in.ndpd not running */
  92         IPADM_DHCP_START_ERROR, /* Cannot start dhcpagent */
  93         IPADM_DHCP_IPC_ERROR,   /* Cannot communicate with dhcpagent */
  94         IPADM_DHCP_IPC_TIMEOUT, /* Communication with dhcpagent timed out */
  95         IPADM_TEMPORARY_OBJ,    /* Permanent operation on temporary object */
  96         IPADM_IPC_ERROR,        /* Cannot communicate with ipmgmtd */
  97         IPADM_OP_DISABLE_OBJ,   /* Operation on disable object */
  98         IPADM_NOTSUP,           /* Operation not supported */
  99         IPADM_EBADE,            /* Invalid data exchange with ipmgmtd */
 100         IPADM_GZ_PERM           /* Operation not permitted on from-gz intf */
 101 } ipadm_status_t;
 102 
 103 /*
 104  * option flags taken by the libipadm functions
 105  *
 106  *  - IPADM_OPT_PERSIST:
 107  *      For all the create/delete/up/down/set/get functions,
 108  *      requests to persist the configuration so that it can be
 109  *      re-enabled or re-applied on boot.
 110  *
 111  *  - IPADM_OPT_ACTIVE:
 112  *      Requests to apply configuration without persisting it and
 113  *      used by show-* subcommands to retrieve current values.
 114  *
 115  *  - IPADM_OPT_DEFAULT:
 116  *      retrieves the default value for a given property
 117  *
 118  *  - IPADM_OPT_PERM
 119  *      retrieves the permission for a given property
 120  *
 121  *  - IPADM_OPT_POSSIBLE
 122  *      retrieves the range of values for a given property
 123  *
 124  *  - IPADM_OPT_APPEND
 125  *      for multi-valued properties, appends a new value.
 126  *
 127  *  - IPADM_OPT_REMOVE
 128  *      for multi-valued properties, removes the specified value
 129  *
 130  *  - IPADM_OPT_IPMP
 131  *      Used in ipadm_create_if() to plumb ipmp interfaces.
 132  *
 133  *  - IPADM_OPT_GENPPA
 134  *      Used in ipadm_create_if() to generate a ppa for the given interface.
 135  *
 136  *  - IPADM_OPT_ZEROADDR
 137  *      return :: or INADDR_ANY
 138  *
 139  *  - IPADM_OPT_RELEASE
 140  *      Used to release the lease on a dhcp address object
 141  *
 142  *  - IPADM_OPT_INFORM
 143  *      Used to perform DHCP_INFORM on a specified static address object
 144  *
 145  *  - IPADM_OPT_UP
 146  *      Used to bring up a static address on creation
 147  *
 148  *  - IPADM_OPT_V46
 149  *      Used to plumb both IPv4 and IPv6 interfaces by ipadm_create_addr()
 150  *
 151  *  - IPADM_OPT_SET_PROPS
 152  *      Used to indicate the update changes the running configuration of
 153  *      "props" data on the object. The props are cached there on the parent,
 154  *      but the PROPS_ONLY change does not affect the ACTIVE/PERSIST state of
 155  *      the parent.
 156  *
 157  *  - IPADM_OPT_PERSIST_PROPS
 158  *      Used when IPADM_OPT_SET_PROPS is active to indicate the update changes
 159  *  the persistent configuration of the "props" data on the object.
 160  */
 161 #define IPADM_OPT_PERSIST       0x00000001
 162 #define IPADM_OPT_ACTIVE        0x00000002
 163 #define IPADM_OPT_DEFAULT       0x00000004
 164 #define IPADM_OPT_PERM          0x00000008
 165 #define IPADM_OPT_POSSIBLE      0x00000010
 166 #define IPADM_OPT_APPEND        0x00000020
 167 #define IPADM_OPT_REMOVE        0x00000040
 168 #define IPADM_OPT_IPMP          0x00000080
 169 #define IPADM_OPT_GENPPA        0x00000100
 170 #define IPADM_OPT_ZEROADDR      0x00000200
 171 #define IPADM_OPT_RELEASE       0x00000400
 172 #define IPADM_OPT_INFORM        0x00000800
 173 #define IPADM_OPT_UP            0x00001000
 174 #define IPADM_OPT_V46           0x00002000
 175 #define IPADM_OPT_SET_PROPS     0x00004000
 176 #define IPADM_OPT_PERSIST_PROPS         0x00008000
 177 
 178 /* IPADM property class */
 179 #define IPADMPROP_CLASS_MODULE  0x00000001      /* on 'protocol' only */
 180 #define IPADMPROP_CLASS_IF      0x00000002      /* on 'IP interface' only */
 181 #define IPADMPROP_CLASS_ADDR    0x00000004      /* on 'IP address' only */
 182 /* protocol property that can be applied on interface too */
 183 #define IPADMPROP_CLASS_MODIF   (IPADMPROP_CLASS_MODULE | IPADMPROP_CLASS_IF)
 184 
 185 /* opaque ipadm handle to libipadm functions */
 186 struct ipadm_handle;
 187 typedef struct ipadm_handle     *ipadm_handle_t;
 188 
 189 /* ipadm_handle flags */
 190 #define IPH_VRRP                0x00000001      /* Caller is VRRP */
 191 #define IPH_LEGACY              0x00000002      /* Caller is legacy app */
 192 #define IPH_IPMGMTD             0x00000004      /* Caller is ipmgmtd itself */
 193 /*
 194  * Indicates that the operation being invoked is in 'init' context. This is
 195  * a library private flag.
 196  */
 197 #define IPH_INIT                0x10000000
 198 
 199 /* opaque address object structure */
 200 typedef struct ipadm_addrobj_s  *ipadm_addrobj_t;
 201 
 202 /* ipadm_if_info_t states */
 203 typedef enum {
 204         IFIS_OK,                /* Interface is usable */
 205         IFIS_DOWN,              /* Interface has no UP addresses */
 206         IFIS_FAILED,            /* Interface has failed. */
 207         IFIS_OFFLINE,           /* Interface has been offlined */
 208         IFIS_DISABLED           /* Interface has been disabled. */
 209 } ipadm_if_state_t;
 210 
 211 typedef list_t ipadm_ipmp_members_t;
 212 
 213 typedef struct {
 214     list_node_t node;
 215     char if_name[LIFNAMSIZ];
 216 } ipadm_ipmp_member_t;
 217 
 218 typedef enum {
 219     IPADM_IF_CLASS_REGULAR,
 220     IPADM_IF_CLASS_IPMP,
 221     IPADM_IF_CLASS_VIRTUAL,
 222     IPADM_IF_CLASS_UNKNOWN
 223 } ipadm_if_class_t;
 224 
 225 typedef struct ipadm_if_info_s {
 226         struct ipadm_if_info_s  *ifi_next;
 227         char                    ifi_name[LIFNAMSIZ];    /* interface name */
 228         ipadm_if_class_t        ifi_class;              /* interface class */
 229         ipadm_if_state_t        ifi_state;              /* see above */
 230         uint_t                  ifi_cflags;             /* current flags */
 231         uint_t                  ifi_pflags;             /* persistent flags */
 232         ipadm_ipmp_members_t    ifi_ipmp_cmembers; /* current IPMP members */
 233         ipadm_ipmp_members_t    ifi_ipmp_pmembers; /* persistent IPMP members */
 234 } ipadm_if_info_t;
 235 
 236 /* ipadm_if_info_t flags */
 237 #define IFIF_BROADCAST          0x00000001
 238 #define IFIF_MULTICAST          0x00000002
 239 #define IFIF_POINTOPOINT        0x00000004
 240 #define IFIF_VIRTUAL            0x00000008
 241 #define IFIF_IPMP               0x00000010
 242 #define IFIF_STANDBY            0x00000020
 243 #define IFIF_INACTIVE           0x00000040
 244 #define IFIF_VRRP               0x00000080
 245 #define IFIF_NOACCEPT           0x00000100
 246 #define IFIF_IPV4               0x00000200
 247 #define IFIF_IPV6               0x00000400
 248 #define IFIF_L3PROTECT          0x00000800
 249 
 250 /* ipadm_addr_info_t state */
 251 typedef enum {
 252         IFA_DISABLED,           /* Address not in active configuration. */
 253         IFA_DUPLICATE,          /* DAD failed. */
 254         IFA_DOWN,               /* Address is not IFF_UP */
 255         IFA_TENTATIVE,          /* DAD verification initiated */
 256         IFA_OK,                 /* Address is usable */
 257         IFA_INACCESSIBLE        /* Interface has failed */
 258 } ipadm_addr_state_t;
 259 
 260 /* possible address types */
 261 typedef enum  {
 262         IPADM_ADDR_NONE,
 263         IPADM_ADDR_STATIC,
 264         IPADM_ADDR_IPV6_ADDRCONF,
 265         IPADM_ADDR_DHCP
 266 } ipadm_addr_type_t;
 267 
 268 typedef struct ipadm_addr_info_s {
 269         struct ifaddrs          ia_ifa;         /* list of addresses */
 270         char                    ia_sname[NI_MAXHOST];   /* local hostname */
 271         char                    ia_dname[NI_MAXHOST];   /* remote hostname */
 272         char                    ia_aobjname[IPADM_AOBJSIZ];
 273         uint_t                  ia_cflags;      /* active flags */
 274         uint_t                  ia_pflags;      /* persistent flags */
 275         ipadm_addr_type_t       ia_atype;       /* see above */
 276         ipadm_addr_state_t      ia_state;       /* see above */
 277 } ipadm_addr_info_t;
 278 #define IA_NEXT(ia)             ((ipadm_addr_info_t *)(ia->ia_ifa.ifa_next))
 279 
 280 /* ipadm_addr_info_t flags */
 281 #define IA_UP                   0x00000001
 282 #define IA_UNNUMBERED           0x00000002
 283 #define IA_PRIVATE              0x00000004
 284 #define IA_TEMPORARY            0x00000008
 285 #define IA_DEPRECATED           0x00000010
 286 
 287 /* open/close libipadm handle */
 288 extern ipadm_status_t   ipadm_open(ipadm_handle_t *, uint32_t);
 289 extern void             ipadm_close(ipadm_handle_t);
 290 
 291 /* Check authorization for network configuration */
 292 extern boolean_t        ipadm_check_auth(void);
 293 /*
 294  * Interface management functions
 295  */
 296 extern ipadm_status_t   ipadm_create_if(ipadm_handle_t, char *, sa_family_t,
 297                             uint32_t);
 298 extern ipadm_status_t   ipadm_disable_if(ipadm_handle_t, const char *,
 299                             uint32_t);
 300 extern ipadm_status_t   ipadm_enable_if(ipadm_handle_t, const char *, uint32_t);
 301 extern ipadm_status_t   ipadm_if_info(ipadm_handle_t, const char *,
 302                             ipadm_if_info_t **, uint32_t, int64_t);
 303 extern void             ipadm_free_if_info(ipadm_if_info_t *);
 304 extern ipadm_status_t   ipadm_delete_if(ipadm_handle_t, const char *,
 305                             sa_family_t, uint32_t);
 306 extern void             ipadm_if_move(ipadm_handle_t, const char *);
 307 extern ipadm_status_t ipadm_add_ipmp_member(ipadm_handle_t, const char *,
 308             const char *, uint32_t);
 309 extern ipadm_status_t ipadm_remove_ipmp_member(ipadm_handle_t, const char *,
 310             const char *, uint32_t);
 311 
 312 /*
 313  * Address management functions
 314  */
 315 extern ipadm_status_t   ipadm_create_addr(ipadm_handle_t, ipadm_addrobj_t,
 316                             uint32_t);
 317 extern ipadm_status_t   ipadm_disable_addr(ipadm_handle_t, const char *,
 318                             uint32_t);
 319 extern ipadm_status_t   ipadm_enable_addr(ipadm_handle_t, const char *,
 320                             uint32_t);
 321 extern ipadm_status_t   ipadm_addr_info(ipadm_handle_t, const char *,
 322                             ipadm_addr_info_t **, uint32_t, int64_t);
 323 extern void             ipadm_free_addr_info(ipadm_addr_info_t *);
 324 extern ipadm_status_t   ipadm_up_addr(ipadm_handle_t, const char *,
 325                             uint32_t);
 326 extern ipadm_status_t   ipadm_down_addr(ipadm_handle_t, const char *,
 327                             uint32_t);
 328 extern ipadm_status_t   ipadm_refresh_addr(ipadm_handle_t, const char *,
 329                             uint32_t);
 330 extern ipadm_status_t   ipadm_delete_addr(ipadm_handle_t, const char *,
 331                             uint32_t);
 332 
 333 /* Functions related to creating/deleting/modifying opaque address object */
 334 extern ipadm_status_t   ipadm_create_addrobj(ipadm_addr_type_t, const char *,
 335                             ipadm_addrobj_t *);
 336 extern void             ipadm_destroy_addrobj(ipadm_addrobj_t);
 337 extern ipadm_status_t   ipadm_get_aobjname(const ipadm_addrobj_t, char *,
 338                             size_t);
 339 
 340 /* Functions to set fields in addrobj for static addresses */
 341 extern ipadm_status_t   ipadm_set_addr(ipadm_addrobj_t, const char *,
 342                             sa_family_t);
 343 extern ipadm_status_t   ipadm_set_dst_addr(ipadm_addrobj_t, const char *,
 344                             sa_family_t);
 345 extern ipadm_status_t   ipadm_get_addr(const ipadm_addrobj_t,
 346                             struct sockaddr_storage *);
 347 
 348 /* Functions to set fields in addrobj for IPv6 addrconf */
 349 extern ipadm_status_t   ipadm_set_interface_id(ipadm_addrobj_t, const char *);
 350 extern ipadm_status_t   ipadm_set_stateless(ipadm_addrobj_t, boolean_t);
 351 extern ipadm_status_t   ipadm_set_stateful(ipadm_addrobj_t, boolean_t);
 352 
 353 /* Functions to set fields in addrobj for DHCP */
 354 extern ipadm_status_t   ipadm_set_primary(ipadm_addrobj_t, boolean_t);
 355 extern ipadm_status_t   ipadm_set_wait_time(ipadm_addrobj_t, int32_t);
 356 extern ipadm_status_t   ipadm_set_reqhost(ipadm_addrobj_t, const char *);
 357 
 358 /*
 359  * Property management functions
 360  */
 361 /* call back function for the property walker */
 362 typedef boolean_t       ipadm_prop_wfunc_t(void *, const char *, uint_t);
 363 extern ipadm_status_t   ipadm_walk_proptbl(uint_t, uint_t, ipadm_prop_wfunc_t *,
 364                             void *);
 365 extern ipadm_status_t   ipadm_walk_prop(const char *, uint_t, uint_t,
 366                             ipadm_prop_wfunc_t *, void *);
 367 
 368 /* Interface property management - set, reset and get */
 369 extern ipadm_status_t   ipadm_set_ifprop(ipadm_handle_t, const char *,
 370                             const char *, const char *, uint_t, uint_t);
 371 extern ipadm_status_t   ipadm_get_ifprop(ipadm_handle_t, const char *,
 372                             const char *, char *, uint_t *, uint_t, uint_t);
 373 
 374 /* Address property management - set, reset and get */
 375 extern ipadm_status_t   ipadm_set_addrprop(ipadm_handle_t, const char *,
 376                             const char *, const char *, uint_t);
 377 extern ipadm_status_t   ipadm_get_addrprop(ipadm_handle_t, const char *, char *,
 378                             uint_t *, const char *, uint_t);
 379 
 380 /* Protoocl property management - set, reset and get */
 381 extern ipadm_status_t   ipadm_set_prop(ipadm_handle_t, const char *,
 382                             const char *, uint_t, uint_t);
 383 extern ipadm_status_t   ipadm_get_prop(ipadm_handle_t, const char *, char *,
 384                             uint_t *, uint_t, uint_t);
 385 
 386 /*
 387  * miscellaneous helper functions.
 388  */
 389 extern const char       *ipadm_status2str(ipadm_status_t);
 390 extern int              ipadm_str2nvlist(const char *, nvlist_t **, uint_t);
 391 extern size_t           ipadm_nvlist2str(nvlist_t *, char *, size_t);
 392 extern char             *ipadm_proto2str(uint_t);
 393 extern uint_t           ipadm_str2proto(const char *);
 394 extern ipadm_status_t   ipadm_open_arp_on_udp(const char *, int *);
 395 extern int              ipadm_legacy2new_propname(const char *, char *,
 396                             uint_t, uint_t *);
 397 extern int              ipadm_new2legacy_propname(const char *, char *,
 398                             uint_t, uint_t);
 399 extern boolean_t        ipadm_is_valid_hostname(const char *hostname);
 400 extern boolean_t        ipadm_is_nil_hostname(const char *hostname);
 401 
 402 #ifdef  __cplusplus
 403 }
 404 #endif
 405 
 406 #endif  /* _LIBIPADM_H */