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