xref: /freebsd/lib/libifconfig/libifconfig.h (revision a259b98fa211ed87bfee58c575de4e2de94ee0fa)
1 /*
2  * Copyright (c) 2016-2017, Marie Helene Kvello-Aune
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * thislist of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation and/or
13  * other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #pragma once
28 
29 #include <sys/types.h>
30 
31 #include <net/ethernet.h>
32 #include <net/if.h>
33 #include <net/if_bridgevar.h> /* for ifbvlan_set_t */
34 #include <netlink/route/interface.h>
35 
36 #include <netinet/in.h>
37 #include <netinet/ip_carp.h>
38 #include <netinet6/in6_var.h>
39 
40 #include <stdbool.h>
41 
42 #define ND6_IFF_DEFAULTIF    0x8000
43 
44 typedef enum {
45 	OK = 0,
46 	OTHER,
47 	IOCTL,
48 	SOCKET,
49 	NETLINK
50 } ifconfig_errtype;
51 
52 /*
53  * Opaque definition so calling application can just pass a
54  * pointer to it for library use.
55  */
56 struct ifconfig_handle;
57 typedef struct ifconfig_handle ifconfig_handle_t;
58 
59 struct ifaddrs;
60 struct ifbropreq;
61 struct ifbreq;
62 struct in6_ndireq;
63 struct lagg_reqall;
64 struct lagg_reqflags;
65 struct lagg_reqopts;
66 struct lagg_reqport;
67 
68 /** Stores extra info associated with a bridge(4) interface */
69 struct ifconfig_bridge_status {
70 	struct ifbropreq *params;	/**< current operational parameters */
71 	struct ifbreq *members;		/**< list of bridge members */
72 	ifbvlan_set_t *member_vlans;	/**< bridge member vlan sets */
73 	size_t members_count;		/**< how many member interfaces */
74 	uint32_t cache_size;		/**< size of address cache */
75 	uint32_t cache_lifetime;	/**< address cache entry lifetime */
76 	ifbr_flags_t flags;		/**< bridge flags */
77 	ether_vlanid_t defpvid;		/**< default pvid */
78 };
79 
80 struct ifconfig_capabilities {
81 	/** Current capabilities (ifconfig prints this as 'options')*/
82 	int curcap;
83 	/** Requested capabilities (ifconfig prints this as 'capabilities')*/
84 	int reqcap;
85 };
86 
87 /** Stores extra info associated with an inet address */
88 struct ifconfig_inet_addr {
89 	const struct sockaddr_in *sin;
90 	const struct sockaddr_in *netmask;
91 	const struct sockaddr_in *dst;
92 	const struct sockaddr_in *broadcast;
93 	int prefixlen;
94 	uint8_t vhid;
95 };
96 
97 /** Stores extra info associated with an inet6 address */
98 struct ifconfig_inet6_addr {
99 	struct sockaddr_in6 *sin6;
100 	struct sockaddr_in6 *dstin6;
101 	struct in6_addrlifetime lifetime;
102 	int prefixlen;
103 	uint32_t flags;
104 	uint8_t vhid;
105 };
106 
107 /** Stores extra info associated with a lagg(4) interface */
108 struct ifconfig_lagg_status {
109 	struct lagg_reqall *ra;
110 	struct lagg_reqopts *ro;
111 	struct lagg_reqflags *rf;
112 };
113 
114 /** Retrieves a new state object for use in other API calls.
115  * Example usage:
116  *{@code
117  * // Create state object
118  * ifconfig_handle_t *lifh;
119  * lifh = ifconfig_open();
120  * if (lifh == NULL) {
121  *     // Handle error
122  * }
123  *
124  * // Do stuff with the handle
125  *
126  * // Dispose of the state object
127  * ifconfig_close(lifh);
128  * lifh = NULL;
129  *}
130  */
131 ifconfig_handle_t *ifconfig_open(void);
132 
133 /** Frees resources held in the provided state object.
134  * @param h The state object to close.
135  * @see #ifconfig_open(void)
136  */
137 void ifconfig_close(ifconfig_handle_t *h);
138 
139 /** Identifies what kind of error occurred. */
140 ifconfig_errtype ifconfig_err_errtype(ifconfig_handle_t *h);
141 
142 /** Retrieves the errno associated with the error, if any. */
143 int ifconfig_err_errno(ifconfig_handle_t *h);
144 
145 typedef void (*ifconfig_foreach_func_t)(ifconfig_handle_t *h,
146     struct ifaddrs *ifa, void *udata);
147 
148 /** Iterate over every network interface
149  * @param h	An open ifconfig state object
150  * @param cb	A callback function to call with a pointer to each interface
151  * @param udata	An opaque value that will be passed to the callback.
152  * @return	0 on success, nonzero if the list could not be iterated
153  */
154 int ifconfig_foreach_iface(ifconfig_handle_t *h, ifconfig_foreach_func_t cb,
155     void *udata);
156 
157 /** Iterate over every address on a single network interface
158  * @param h	An open ifconfig state object
159  * @param ifa	A pointer that was supplied by a previous call to
160  *              ifconfig_foreach_iface
161  * @param udata	An opaque value that will be passed to the callback.
162  * @param cb	A callback function to call with a pointer to each ifaddr
163  */
164 void ifconfig_foreach_ifaddr(ifconfig_handle_t *h, struct ifaddrs *ifa,
165     ifconfig_foreach_func_t cb, void *udata);
166 
167 /** If error type was IOCTL, this identifies which request failed. */
168 unsigned long ifconfig_err_ioctlreq(ifconfig_handle_t *h);
169 int ifconfig_get_description(ifconfig_handle_t *h, const char *name,
170     char **description);
171 int ifconfig_set_description(ifconfig_handle_t *h, const char *name,
172     const char *newdescription);
173 int ifconfig_unset_description(ifconfig_handle_t *h, const char *name);
174 int ifconfig_set_name(ifconfig_handle_t *h, const char *name,
175     const char *newname);
176 int ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname,
177     char **orig_name);
178 int ifconfig_get_fib(ifconfig_handle_t *h, const char *name, int *fib);
179 int ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu);
180 int ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu);
181 int ifconfig_get_nd6(ifconfig_handle_t *h, const char *name,
182     struct in6_ndireq *nd);
183 int ifconfig_set_metric(ifconfig_handle_t *h, const char *name,
184     const int metric);
185 int ifconfig_get_metric(ifconfig_handle_t *h, const char *name, int *metric);
186 int ifconfig_set_capability(ifconfig_handle_t *h, const char *name,
187     const int capability);
188 int ifconfig_get_capability(ifconfig_handle_t *h, const char *name,
189     struct ifconfig_capabilities *capability);
190 
191 /** Retrieve the list of groups to which this interface belongs
192  * @param h	An open ifconfig state object
193  * @param name	The interface name
194  * @param ifgr	return argument.  The caller is responsible for freeing
195  *              ifgr->ifgr_groups
196  * @return	0 on success, nonzero on failure
197  */
198 int ifconfig_get_groups(ifconfig_handle_t *h, const char *name,
199     struct ifgroupreq *ifgr);
200 int ifconfig_get_ifstatus(ifconfig_handle_t *h, const char *name,
201     struct ifstat *stat);
202 
203 /*
204  * SR-IOV VF status schema contract.
205  *
206  * Bits in the presence mask are indexed by IFLAF_VF_* and distinguish an
207  * omitted fact from false or zero.  Driver-specific facts remain owned by a
208  * stable, versioned driver namespace: that driver defines the names, types,
209  * and meanings of its fields.  Their named, typed form lets generic consumers
210  * carry or display extensions without knowing each driver's schema.  Consumers
211  * that interpret extensions must ignore unknown namespaces and fields.
212  * Additive optional fields retain a namespace version; an incompatible type or
213  * semantic change requires a new version.  All pointed-to storage belongs to
214  * the returned status object and is released by ifconfig_free_vf_status().
215  * VF records are returned through a pointer vector so append-only growth of
216  * struct ifconfig_vf_info does not change the array stride seen by existing
217  * consumers.  VLAN identifier and protocol describe the PF-administered
218  * access VLAN.  VLAN PCP describes PF-administered priority in access or
219  * trunk mode, including priority-only tagging with VID 0.  These fields do
220  * not describe individual trunk filters or VF-selected priorities.
221  */
222 
223 enum ifconfig_vf_vlan_mode {
224 	IFCONFIG_VF_VLAN_UNKNOWN = IFLAF_VF_VLAN_UNKNOWN,
225 	IFCONFIG_VF_VLAN_ACCESS = IFLAF_VF_VLAN_ACCESS,
226 	IFCONFIG_VF_VLAN_TRUNK = IFLAF_VF_VLAN_TRUNK,
227 };
228 
229 enum ifconfig_vf_link_state {
230 	IFCONFIG_VF_LINK_UNKNOWN = IFLAF_VF_LINK_UNKNOWN,
231 	IFCONFIG_VF_LINK_DOWN = IFLAF_VF_LINK_DOWN,
232 	IFCONFIG_VF_LINK_UP = IFLAF_VF_LINK_UP,
233 	IFCONFIG_VF_LINK_AUTO = IFLAF_VF_LINK_AUTO,
234 };
235 
236 enum ifconfig_vf_extension_type {
237 	IFCONFIG_VF_EXT_BOOL = 1,
238 	IFCONFIG_VF_EXT_NUMBER,
239 	IFCONFIG_VF_EXT_STRING,
240 	IFCONFIG_VF_EXT_BINARY,
241 };
242 
243 struct ifconfig_vf_extension_field {
244 	char *name;
245 	enum ifconfig_vf_extension_type type;
246 	union {
247 		bool boolean;
248 		uint64_t number;
249 		char *string;
250 		struct {
251 			void *data;
252 			size_t length;
253 		} binary;
254 	} value;
255 };
256 
257 struct ifconfig_vf_extension {
258 	char *name;
259 	uint32_t version;
260 	size_t num_fields;
261 	struct ifconfig_vf_extension_field *fields;
262 };
263 
264 struct ifconfig_vf_info {
265 	uint64_t fields;
266 	uint64_t min_tx_rate_bps;	/* Zero means no guaranteed allocation. */
267 	uint64_t max_tx_rate_bps;	/* Zero means unlimited. */
268 	uint32_t index;
269 	uint32_t vlan_count;
270 	uint32_t vlan_limit;
271 	uint16_t tx_queue_count;
272 	uint16_t rx_queue_count;
273 	uint16_t vlan;
274 	uint16_t vlan_proto;		/* Host-order Ethernet type. */
275 	uint8_t vlan_pcp;
276 	uint8_t mac[ETHER_ADDR_LEN];
277 	enum ifconfig_vf_vlan_mode vlan_mode;
278 	enum ifconfig_vf_link_state link_state_policy;
279 	bool configured;
280 	bool initialized;
281 	bool allow_set_mac;
282 	bool allow_set_vlan;
283 	bool mac_anti_spoof;
284 	bool allow_promisc;
285 	bool traffic_allowed;
286 	bool fault_blocked;
287 	bool quarantined;
288 	char *api_version;
289 	size_t num_extensions;
290 	struct ifconfig_vf_extension *extensions;
291 };
292 
293 struct ifconfig_vf_status {
294 	uint64_t pf_link_speed;
295 	enum ifconfig_vf_link_state pf_link_state;
296 	bool pf_link_state_present;
297 	bool pf_link_speed_present;
298 	size_t num_vfs;
299 	struct ifconfig_vf_info **vfs;
300 };
301 
302 /** Retrieve structured SR-IOV VF status for an interface through rtnetlink.
303  * @param h	An open ifconfig state object
304  * @param name	The PF interface name
305  * @param statusp Return argument.  Free it with ifconfig_free_vf_status().
306  * @return	0 on success, -1 on failure
307  */
308 int ifconfig_get_vf_status(ifconfig_handle_t *h, const char *name,
309     struct ifconfig_vf_status **statusp);
310 void ifconfig_free_vf_status(struct ifconfig_vf_status *status);
311 
312 /** Retrieve the interface media information
313  * @param h	An open ifconfig state object
314  * @param name	The interface name
315  * @param ifmr	Return argument.  The caller is responsible for freeing it
316  * @return	0 on success, nonzero on failure
317  */
318 int ifconfig_media_get_mediareq(ifconfig_handle_t *h, const char *name,
319     struct ifmediareq **ifmr);
320 
321 const char *ifconfig_media_get_status(const struct ifmediareq *ifmr);
322 
323 typedef int ifmedia_t;
324 
325 #define INVALID_IFMEDIA ((ifmedia_t)-1)
326 
327 /** Retrieve the name of a media type
328  * @param media	The media to be named
329  * @return	A pointer to the media type name, or NULL on failure
330  */
331 const char *ifconfig_media_get_type(ifmedia_t media);
332 
333 /** Retrieve a media type by its name
334  * @param name	The name of a media type
335  * @return	The media type value, or INVALID_IFMEDIA on failure
336  */
337 ifmedia_t ifconfig_media_lookup_type(const char *name);
338 
339 /** Retrieve the name of a media subtype
340  * @param media	The media subtype to be named
341  * @return	A pointer to the media subtype name, or NULL on failure
342  */
343 const char *ifconfig_media_get_subtype(ifmedia_t media);
344 
345 /** Retrieve a media subtype by its name
346  * @param media	The top level media type whose subtype we want
347  * @param name	The name of a media subtype
348  * @return	The media subtype value, or INVALID_IFMEDIA on failure
349  */
350 ifmedia_t ifconfig_media_lookup_subtype(ifmedia_t media, const char *name);
351 
352 /** Retrieve the name of a media mode
353  * @param media	The media mode to be named
354  * @return	A pointer to the media mode name, or NULL on failure
355  */
356 const char *ifconfig_media_get_mode(ifmedia_t media);
357 
358 /** Retrieve a media mode by its name
359  * @param media	The top level media type whose mode we want
360  * @param name	The name of a media mode
361  * @return	The media mode value, or INVALID_IFMEDIA on failure
362  */
363 ifmedia_t ifconfig_media_lookup_mode(ifmedia_t media, const char *name);
364 
365 /** Retrieve an array of media options
366  * @param media	The media for which to obtain the options
367  * @return	Pointer to an array of pointers to option names,
368  * 		terminated by a NULL pointer, or simply NULL on failure.
369  * 		The caller is responsible for freeing the array but not its
370  * 		contents.
371  */
372 const char **ifconfig_media_get_options(ifmedia_t media);
373 
374 /** Retrieve an array of media options by names
375  * @param media	The top level media type whose options we want
376  * @param opts	Pointer to an array of string pointers naming options
377  * @param nopts Number of elements in the opts array
378  * @return	Pointer to an array of media options, one for each option named
379  * 		in opts.  NULL is returned instead with errno set to ENOMEM if
380  * 		allocating the return array fails or EINVAL if media is not
381  * 		valid.  A media option in the array will be INVALID_IFMEDIA
382  * 		when lookup failed for the option named in that position in
383  * 		opts.  The caller is responsible for freeing the array.
384  */
385 ifmedia_t *ifconfig_media_lookup_options(ifmedia_t media, const char **opts,
386     size_t nopts);
387 
388 /** Retrieve the reason the interface is down
389  * @param h	An open ifconfig state object
390  * @param name	The interface name
391  * @param ifdr	Return argument.
392  * @return	0 on success, nonzero on failure
393  */
394 int ifconfig_media_get_downreason(ifconfig_handle_t *h, const char *name,
395     struct ifdownreason *ifdr);
396 
397 struct ifconfig_carp {
398 	size_t		carpr_count;
399 	uint32_t	carpr_vhid;
400 	uint32_t	carpr_state;
401 	int32_t		carpr_advbase;
402 	int32_t		carpr_advskew;
403 	uint8_t		carpr_key[CARP_KEY_LEN];
404 	struct in_addr	carpr_addr;
405 	struct in6_addr	carpr_addr6;
406 	carp_version_t	carpr_version;
407 	uint8_t		carpr_vrrp_prio;
408 	uint16_t	carpr_vrrp_adv_inter;
409 };
410 
411 int ifconfig_carp_get_vhid(ifconfig_handle_t *h, const char *name,
412     struct ifconfig_carp *carpr, uint32_t vhid);
413 int ifconfig_carp_get_info(ifconfig_handle_t *h, const char *name,
414     struct ifconfig_carp *carpr, size_t ncarp);
415 int ifconfig_carp_set_info(ifconfig_handle_t *h, const char *name,
416     const struct ifconfig_carp *carpr);
417 
418 /** Retrieve additional information about an inet address
419  * @param h	An open ifconfig state object
420  * @param name	The interface name
421  * @param ifa	Pointer to the address structure of interest
422  * @param addr	Return argument.  It will be filled with additional information
423  *              about the address.
424  * @return	0 on success, nonzero on failure.
425  */
426 int ifconfig_inet_get_addrinfo(ifconfig_handle_t *h,
427     const char *name, struct ifaddrs *ifa, struct ifconfig_inet_addr *addr);
428 
429 /** Retrieve additional information about an inet6 address
430  * @param h	An open ifconfig state object
431  * @param name	The interface name
432  * @param ifa	Pointer to the address structure of interest
433  * @param addr	Return argument.  It will be filled with additional information
434  *              about the address.
435  * @return	0 on success, nonzero on failure.
436  */
437 int ifconfig_inet6_get_addrinfo(ifconfig_handle_t *h,
438     const char *name, struct ifaddrs *ifa, struct ifconfig_inet6_addr *addr);
439 
440 /** Retrieve additional information about a bridge(4) interface */
441 int ifconfig_bridge_get_bridge_status(ifconfig_handle_t *h,
442     const char *name, struct ifconfig_bridge_status **bridge);
443 
444 /** Frees the structure returned by ifconfig_bridge_get_bridge_status.  Does
445  * nothing if the argument is NULL
446  * @param bridge	Pointer to the structure to free
447  */
448 void ifconfig_bridge_free_bridge_status(struct ifconfig_bridge_status *bridge);
449 
450 /** Retrieve additional information about a lagg(4) interface */
451 int ifconfig_lagg_get_lagg_status(ifconfig_handle_t *h,
452     const char *name, struct ifconfig_lagg_status **lagg_status);
453 
454 /** Retrieve additional information about a member of a lagg(4) interface */
455 int ifconfig_lagg_get_laggport_status(ifconfig_handle_t *h,
456     const char *name, struct lagg_reqport *rp);
457 
458 /** Frees the structure returned by ifconfig_lagg_get_lagg_status.  Does
459  * nothing if the argument is NULL
460  * @param laggstat	Pointer to the structure to free
461  */
462 void ifconfig_lagg_free_lagg_status(struct ifconfig_lagg_status *laggstat);
463 
464 /** Destroy a virtual interface
465  * @param name Interface to destroy
466  */
467 int ifconfig_destroy_interface(ifconfig_handle_t *h, const char *name);
468 
469 /** Creates a (virtual) interface
470  * @param name Name of interface to create. Example: bridge or bridge42
471  * @param name ifname Is set to actual name of created interface
472  */
473 int ifconfig_create_interface(ifconfig_handle_t *h, const char *name,
474     char **ifname);
475 
476 /** Creates a (virtual) interface
477  * @param name Name of interface to create. Example: vlan0 or ix0.50
478  * @param name ifname Is set to actual name of created interface
479  * @param vlandev Name of interface to attach to
480  * @param vlanid VLAN ID/Tag. Must not be 0.
481  */
482 int ifconfig_create_interface_vlan(ifconfig_handle_t *h, const char *name,
483     char **ifname, const char *vlandev, const unsigned short vlantag);
484 
485 int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name,
486     const char *vlandev, const unsigned short vlantag);
487 
488 /** Gets the names of all interface cloners available on the system
489  * @param bufp	Set to the address of the names buffer on success or NULL
490  *              if an error occurs.  This buffer must be freed when done.
491  * @param lenp	Set to the number of names in the returned buffer or 0
492  * 		if an error occurs.  Each name is contained within an
493  * 		IFNAMSIZ length slice of the buffer, for a total buffer
494  * 		length of *lenp * IFNAMSIZ bytes.
495  */
496 int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp);
497 
498 /** Brings the interface up/down
499  * @param h	    An open ifconfig state object
500  * @param ifname    The interface name
501  * @param up	    true to bring the interface up, false to bring it down
502  * @return	    0 on success, nonzero on failure.
503  *		    On failure, the error info on the handle is set.
504  */
505 int ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up);
506