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