diff options
Diffstat (limited to 'usr/src/lib/libinetcfg/common/inetcfg.c')
-rw-r--r-- | usr/src/lib/libinetcfg/common/inetcfg.c | 460 |
1 files changed, 5 insertions, 455 deletions
diff --git a/usr/src/lib/libinetcfg/common/inetcfg.c b/usr/src/lib/libinetcfg/common/inetcfg.c index e1f09a881a..d5a27f23ea 100644 --- a/usr/src/lib/libinetcfg/common/inetcfg.c +++ b/usr/src/lib/libinetcfg/common/inetcfg.c @@ -44,9 +44,6 @@ #define ICFG_FAMILY(handle) handle->ifh_interface.if_protocol -#define ICFG_TUNNEL_PROTOCOL(protocol) \ - (protocol == IFTAP_IPV6) ? AF_INET6 : AF_INET - #define ICFG_SOCKADDR_LEN(protocol) \ (protocol == AF_INET) ? \ (socklen_t)sizeof (struct sockaddr_in) : \ @@ -66,12 +63,11 @@ static char *errmsgs[ICFG_NERR] = { /* 0 ICFG_SUCCESS */ "Success", /* 1 ICFG_FAILURE */ "Failure", -/* 2 ICFG_NOT_TUNNEL */ "Tunnel operation attempted on non-tunnel", -/* 3 ICFG_NOT_SET */ "Could not return non-existent value", -/* 4 ICFG_BAD_ADDR */ "Invalid Address", -/* 5 ICFG_BAD_PROT */ "Wrong protocol family for operation", -/* 6 ICFG_DAD_FAILED */ "Duplicate address detection failure", -/* 7 ICFG_DAD_FOUND */ "Duplicate address detected" +/* 2 ICFG_NOT_SET */ "Could not return non-existent value", +/* 3 ICFG_BAD_ADDR */ "Invalid Address", +/* 4 ICFG_BAD_PROT */ "Wrong protocol family for operation", +/* 5 ICFG_DAD_FAILED */ "Duplicate address detection failure", +/* 6 ICFG_DAD_FOUND */ "Duplicate address detected" }; /* @@ -156,110 +152,6 @@ to_sockaddr_storage(sa_family_t af, const struct sockaddr *addr, } /* - * Ensures that the tunnel parameter data for the tunnel associated with - * the handle is cached. If the 'force_update' argument is TRUE, then the - * cache should be updated. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -static int -get_tunnel_params(icfg_handle_t handle, boolean_t force_update) -{ - struct iftun_req *params; - - if ((handle->ifh_tunnel_params != NULL) && (!force_update)) { - return (ICFG_SUCCESS); - } - - if (strchr(handle->ifh_interface.if_name, ICFG_LOGICAL_SEP) != NULL) { - return (ICFG_NOT_TUNNEL); - } - - if ((params = calloc(1, sizeof (struct iftun_req))) == NULL) { - return (ICFG_FAILURE); - } - - (void) strlcpy(params->ifta_lifr_name, handle->ifh_interface.if_name, - sizeof (params->ifta_lifr_name)); - - if (ioctl(handle->ifh_sock, SIOCGTUNPARAM, (caddr_t)params) < 0) { - free(params); - if ((errno == EOPNOTSUPP) || (errno == EINVAL)) { - return (ICFG_NOT_TUNNEL); - } - return (ICFG_FAILURE); - } - - /* - * We assert that the iftun_req version is the right one - * and that the lower and upper protocols are set to either - * IPv4 or IPv6. Otherwise, some of our APIs are buggy. - */ - assert((params->ifta_vers == IFTUN_VERSION) && - ((params->ifta_lower == IFTAP_IPV4) || - (params->ifta_lower == IFTAP_IPV6)) && - ((params->ifta_upper == IFTAP_IPV4) || - (params->ifta_upper == IFTAP_IPV6))); - - if (handle->ifh_tunnel_params != NULL) { - free(handle->ifh_tunnel_params); - } - handle->ifh_tunnel_params = params; - - return (ICFG_SUCCESS); -} - -/* - * Sets a tunnel destination or source address (depending upon 'type') on - * a tunnel interface. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -static int -set_tunnel_address(icfg_handle_t handle, const struct sockaddr *addr, - socklen_t addrlen, int type) -{ - struct sockaddr_storage laddr; - sa_family_t lower_family; - struct iftun_req *params; - int ret; - - assert((type == IFTUN_SRC) || (type == IFTUN_DST)); - - if ((ret = get_tunnel_params(handle, B_TRUE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - if (params->ifta_lower == IFTAP_IPV4) { - lower_family = AF_INET; - } else { - lower_family = AF_INET6; - } - - ret = to_sockaddr_storage(lower_family, addr, addrlen, &laddr); - if (ret != ICFG_SUCCESS) { - return (ret); - } - - if (type == IFTUN_SRC) { - params->ifta_saddr = laddr; - } else { - params->ifta_daddr = laddr; - } - - (void) strlcpy(params->ifta_lifr_name, handle->ifh_interface.if_name, - sizeof (params->ifta_lifr_name)); - params->ifta_flags |= type; - - if (ioctl(handle->ifh_sock, SIOCSTUNPARAM, (caddr_t)params) < 0) { - return (ICFG_FAILURE); - } - - return (ICFG_SUCCESS); -} - -/* * Return the appropriate error message for a given ICFG error. */ const char * @@ -311,7 +203,6 @@ icfg_open(icfg_handle_t *handle, const icfg_if_t *interface) loc_handle->ifh_sock = sock; loc_handle->ifh_interface = *interface; - loc_handle->ifh_tunnel_params = NULL; *handle = loc_handle; @@ -326,351 +217,10 @@ void icfg_close(icfg_handle_t handle) { (void) close(handle->ifh_sock); - if (handle->ifh_tunnel_params != NULL) { - free(handle->ifh_tunnel_params); - } free(handle); } /* - * Refreshes the tunnel parameter data cache associated with the interface - * represented by the handle. Tunnel parameter data is cached by the - * libinetcfg library by the first call to to any of the tunnel related APIs. - * Since there is no synchronization between consumers of the library and - * non-users of this library, the cache may contain stale data. Users may - * wish to use this API to refresh the cache before subsequent calls to the - * other tunnel related APIs. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_refresh_tunnel_cache(icfg_handle_t handle) -{ - return (get_tunnel_params(handle, B_TRUE)); -} - -/* - * Sets the destination address for the tunnel interface represented - * by 'handle'. - * - * The 'addr' argument points to either a sockaddr_in structure - * (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds - * the IP address. The 'addrlen' argument gives the length of the - * 'addr' structure. - * - * This API will always result in an update of the tunnel parameter - * data cache. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_set_tunnel_dest(icfg_handle_t handle, const struct sockaddr *addr, - socklen_t addrlen) -{ - return (set_tunnel_address(handle, addr, addrlen, IFTUN_DST)); -} - -/* - * Sets the source address for the tunnel interface represented - * by 'handle'. - * - * The 'addr' argument points to either a sockaddr_in structure - * (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds - * the IP address. The 'addrlen' argument gives the length of the - * 'addr' structure. - * - * This API will always result in an update of the tunnel parameter - * data cache. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_set_tunnel_src(icfg_handle_t handle, const struct sockaddr *addr, - socklen_t addrlen) -{ - return (set_tunnel_address(handle, addr, addrlen, IFTUN_SRC)); -} - -/* - * Sets the hop limit for the tunnel interface represented by - * the handle to the value contained in the 'limit' argument. - * - * This API will always result in an update of the tunnel parameter data cache. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_set_tunnel_hoplimit(icfg_handle_t handle, uint8_t limit) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_TRUE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - (void) strlcpy(params->ifta_lifr_name, handle->ifh_interface.if_name, - sizeof (params->ifta_lifr_name)); - - params->ifta_hop_limit = limit; - params->ifta_flags |= IFTUN_HOPLIMIT; - - if (ioctl(handle->ifh_sock, SIOCSTUNPARAM, (caddr_t)params) < 0) { - return (ICFG_FAILURE); - } - - return (ICFG_SUCCESS); -} - -/* - * Sets the encapsulation limit for the tunnel interface represented by - * the handle to the value contained in the 'limit' argument. If the - * value of the limit is negative, then the encapsulation limit is disabled. - * - * This API will always result in an update of the tunnel parameter data cache. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_set_tunnel_encaplimit(icfg_handle_t handle, int16_t limit) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_TRUE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - (void) strlcpy(params->ifta_lifr_name, handle->ifh_interface.if_name, - sizeof (params->ifta_lifr_name)); - - params->ifta_encap_lim = limit; - params->ifta_flags |= IFTUN_ENCAP; - - if (ioctl(handle->ifh_sock, SIOCSTUNPARAM, (caddr_t)params) < 0) { - return (ICFG_FAILURE); - } - - return (ICFG_SUCCESS); -} - -/* - * Returns the source address for the tunnel interface represented - * by 'handle'. - * - * The 'addr' argument is a result parameter that is filled in with - * the requested address. The format of the 'addr' parameter is - * determined by the address family of the interface. - * - * The 'addrlen' argument is a value-result parameter. Initially, - * it contains the amount of space pointed to by 'addr'; on return - * it contains the length in bytes of the address returned. - * - * Note that if 'addrlen' is not large enough for the returned - * address value, then ICFG_FAILURE will be returned and errno - * will be set to ENOSPC. - * - * This API will retrieve the tunnel source value from the tunnel - * parameter data cache and will only update the cache if no data has - * yet been cached for this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or - * ICFG_FAILURE. - */ -int -icfg_get_tunnel_src(icfg_handle_t handle, struct sockaddr *addr, - socklen_t *addrlen) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - if (!(params->ifta_flags & IFTUN_SRC)) { - return (ICFG_NOT_SET); - } - - if (params->ifta_lower == IFTAP_IPV4) { - assert(params->ifta_saddr.ss_family == AF_INET); - } else { - assert(params->ifta_saddr.ss_family == AF_INET6); - } - - return (to_sockaddr(params->ifta_saddr.ss_family, addr, addrlen, - ¶ms->ifta_saddr)); -} - -/* - * Returns the destination address for the tunnel interface - * represented by 'handle'. - * - * The 'addr' argument is a result parameter that is filled in - * with the requested address. The format of the 'addr' parameter - * is determined by the address family of the interface. - * - * The 'addrlen' argument is a value-result parameter. Initially, it - * contains the amount of space pointed to by 'addr'; on return it - * contains the length in bytes of the address returned. - * - * Note that if 'addrlen' is not large enough for the returned address - * value, then ICFG_FAILURE will be returned and errno will be set - * to ENOSPC. - * - * This API will retrieve the tunnel destination value from the tunnel - * parameter data cache and will only update the cache if no data has yet - * been cached for this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or - * ICFG_FAILURE. - */ -int -icfg_get_tunnel_dest(icfg_handle_t handle, struct sockaddr *addr, - socklen_t *addrlen) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - if (!(params->ifta_flags & IFTUN_DST)) { - return (ICFG_NOT_SET); - } - - if (params->ifta_lower == IFTAP_IPV4) { - assert(params->ifta_daddr.ss_family == AF_INET); - } else if (params->ifta_lower == IFTAP_IPV6) { - assert(params->ifta_daddr.ss_family == AF_INET6); - } - - return (to_sockaddr(params->ifta_daddr.ss_family, addr, addrlen, - ¶ms->ifta_daddr)); -} - -/* - * Returns the tunnel hop limit (if any). The value of the limit - * will be copied into the buffer supplied by the 'limit' argument. - * - * This API will retrieve the hoplimit value from the tunnel parameter data - * cache and will only update the cache if no data has yet been cached for - * this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or - * ICFG_FAILURE. - */ -int -icfg_get_tunnel_hoplimit(icfg_handle_t handle, uint8_t *limit) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - if (!(params->ifta_flags & IFTUN_HOPLIMIT)) { - return (ICFG_NOT_SET); - } - - *limit = params->ifta_hop_limit; - - return (ICFG_SUCCESS); -} - -/* - * Returns the tunnel encapsulation limit (if any). The value of the limit - * will be copied into the buffer supplied by the 'limit' argument. - * - * This API will retrieve the encapsulation limit value from the tunnel - * parameter data cache and will only update the cache if no data has yet - * been cached for this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or - * ICFG_FAILURE. - */ -int -icfg_get_tunnel_encaplimit(icfg_handle_t handle, int16_t *limit) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - if (!(params->ifta_flags & IFTUN_ENCAP)) { - return (ICFG_NOT_SET); - } - - *limit = params->ifta_encap_lim; - - return (ICFG_SUCCESS); -} - -/* - * Returns the protocol family (AF_INET or AF_INET6) of the protocol - * actually being used to tunnel the data. The value of the protocol family - * will be copied into the buffer supplied by the 'protocol' argument. - * - * This API will retrieve the protocol value from the tunnel parameter data - * cache and will only update the cache if no data has yet been cached for - * this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_get_tunnel_lower(icfg_handle_t handle, int *protocol) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - *protocol = ICFG_TUNNEL_PROTOCOL(params->ifta_lower); - - return (ICFG_SUCCESS); -} - -/* - * Returns the protocol family (AF_INET or AF_INET6) of the protocol - * actually being tunneled. The value of the protocol family will be copied - * into the buffer supplied by the 'protocol' argument. - * - * This API will retrieve the protocolvalue from the tunnel parameter data - * cache and will only update the cache if no data has yet been cached for - * this tunnel. - * - * Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE. - */ -int -icfg_get_tunnel_upper(icfg_handle_t handle, int *protocol) -{ - struct iftun_req *params; - int ret; - - if ((ret = get_tunnel_params(handle, B_FALSE)) != ICFG_SUCCESS) { - return (ret); - } - params = handle->ifh_tunnel_params; - - *protocol = ICFG_TUNNEL_PROTOCOL(params->ifta_upper); - - return (ICFG_SUCCESS); -} - -/* * Any time that flags are changed on an interface where either the new or the * existing flags have IFF_UP set, we'll get at least one RTM_IFINFO message to * announce the flag status. Typically, there are two such messages: one |