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 (c) 2016, Chris Fraire <cfraire@me.com>.
24  * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
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 ipadm_status_t	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 */
407