Re: [PATCH 3/6] Create solaris specific getifaddrs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reviewed-by: Steven Dake <sdake@xxxxxxxxxx>

On 02/15/2012 09:09 AM, Jan Friesse wrote:
> This not only makes possible to use generic totemip_iface_check, but
> also fixes some problems with previous implementation (fixed mask, not
> very well supported ipv6, ...)
> 
> Tested on OpenIndiana 151a
> 
> Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx>
> ---
>  exec/totemip.c |  195 ++++++++++++++++++++++++++++++--------------------------
>  1 files changed, 105 insertions(+), 90 deletions(-)
> 
> diff --git a/exec/totemip.c b/exec/totemip.c
> index 93f933d..c6109c1 100644
> --- a/exec/totemip.c
> +++ b/exec/totemip.c
> @@ -339,95 +339,7 @@ int totemip_sockaddr_to_totemip_convert(const struct sockaddr_storage *saddr,
>  	return ret;
>  }
>  
> -/*
> - * On Solaris, man if_tcp describes this method
> - */
> -#if defined(COROSYNC_SOLARIS)
> -int totemip_iface_check(struct totem_ip_address *bindnet,
> -	struct totem_ip_address *boundto,
> -	int *interface_up,
> -	int *interface_num,
> -	int mask_high_bit)
> -{
> -	struct sockaddr_storage bindnet_ss;
> -	struct sockaddr_in *bindnet_sin = (struct sockaddr_in *)&bindnet_ss;
> -        struct sockaddr_in *sockaddr_in;
> -        int id_fd;
> -        struct lifconf lifconf;
> -	struct lifreq *lifreq;
> -        int numreqs = 0;
> -        int i;
> -        in_addr_t mask_addr;
> -	int res = -1;
> -	int addrlen;
> -
> -	totemip_totemip_to_sockaddr_convert (bindnet,
> -		0, &bindnet_ss, &addrlen);
> -
> -	*interface_up = 0;
> -	id_fd = socket (AF_INET, SOCK_STREAM, 0);
> -	lifconf.lifc_family = AF_UNSPEC;
> -	lifconf.lifc_flags = 0;
> -	lifconf.lifc_buf = NULL;
> -	lifconf.lifc_len = 0;
> -	do {
> -		numreqs += 32;
> -		lifconf.lifc_len = sizeof (struct lifreq) * numreqs;
> -		lifconf.lifc_buf = (void *)realloc(lifconf.lifc_buf, lifconf.lifc_len);
> -		res = ioctl (id_fd, SIOCGLIFCONF, &lifconf);
> -		if (res < 0) {
> -			close (id_fd);
> -			return -1;
> -		}
> -	} while (lifconf.lifc_len == sizeof (struct lifconf) * numreqs);
> -	res = -1;
> -
> -	lifreq = (struct lifreq *)lifconf.lifc_buf;
> -	/*
> -	* Find interface address to bind to
> -	*/
> -	for (i = 0; i < lifconf.lifc_len / sizeof (struct lifreq); i++) {
> -		sockaddr_in = (struct sockaddr_in *)&lifreq[i].lifr_addr;
> -		mask_addr = inet_addr ("255.255.255.0");
> -
> -		if ((sockaddr_in->sin_family == AF_INET) &&
> -			(sockaddr_in->sin_addr.s_addr & mask_addr) ==
> -			(bindnet_sin->sin_addr.s_addr & mask_addr)) {
> -
> -			res = i;
> -
> -			/*
> -			 * Setup boundto output
> -			 */
> -			totemip_sockaddr_to_totemip_convert((struct sockaddr_storage *)sockaddr_in, boundto);
> -			boundto->nodeid = sockaddr_in->sin_addr.s_addr;
> -#if __BYTE_ORDER == __BIG_ENDIAN
> -			boundto->nodeid = swab32 (boundto->nodeid);
> -#endif
> -
> -			if (ioctl(id_fd, SIOCGLIFFLAGS, &lifreq[i]) < 0) {
> -				printf ("couldn't do ioctl\n");
> -			}
> -
> -			*interface_up = lifreq[i].lifr_flags & IFF_UP;
> -
> -			if (ioctl(id_fd, SIOCGLIFINDEX, &lifreq[i]) < 0) {
> -				printf ("couldn't do ioctl\n");
> -			}
> -			*interface_num = lifreq[i].lifr_index;
> -
> -
> -			break;
> -		}
> -	}
> -	free (lifconf.lifc_buf);
> -	close (id_fd);
> -
> -	return (res);
> -}
> -#endif
> -
> -#ifdef HAVE_GETIFADDRS
> +#if defined(HAVE_GETIFADDRS)
>  int totemip_getifaddrs(struct list_head *addrs)
>  {
>  	struct ifaddrs *ifap, *ifa;
> @@ -490,7 +402,110 @@ error_free_ifaddrs:
>  	freeifaddrs(ifap);
>  	return (-1);
>  }
> -#else
> +#elif defined(SOLARIS)
> +/*
> + * On Solaris, man if_tcp describes this method
> + */
> +int totemip_getifaddrs(struct list_head *addrs)
> +{
> +	int id_fd;
> +	int numreqs;
> +	int res;
> +	struct lifconf lifconf;
> +	struct lifreq *lifreq;
> +	int i, j;
> +	struct totem_ip_if_address *if_addr;
> +	short family;
> +
> +	list_init(addrs);
> +
> +	for (family = 0; family < 2; family++) {
> +		numreqs = 0;
> +		res = -1;
> +
> +		lifconf.lifc_family = (family == 0 ? AF_INET : AF_INET6);
> +		id_fd = socket (lifconf.lifc_family, SOCK_STREAM, 0);
> +		lifconf.lifc_flags = 0;
> +		lifconf.lifc_buf = NULL;
> +		lifconf.lifc_len = 0;
> +		do {
> +			numreqs += 32;
> +			lifconf.lifc_len = sizeof (struct lifreq) * numreqs;
> +			lifconf.lifc_buf = (void *)realloc(lifconf.lifc_buf, lifconf.lifc_len);
> +			res = ioctl (id_fd, SIOCGLIFCONF, &lifconf);
> +			if (res < 0) {
> +				close (id_fd);
> +			}
> +		} while (res >= 0 && lifconf.lifc_len == sizeof (struct lifconf) * numreqs);
> +
> +		if (res < 0)
> +			continue ;
> +
> +		lifreq = (struct lifreq *)lifconf.lifc_buf;
> +		for (i = 0; i < lifconf.lifc_len / sizeof (struct lifreq); i++) {
> +			if (ioctl(id_fd, SIOCGLIFADDR, &lifreq[i]) < 0)
> +				continue ;
> +
> +			if (lifreq[i].lifr_addr.ss_family != AF_INET && lifreq[i].lifr_addr.ss_family != AF_INET6)
> +				continue ;
> +
> +			if_addr = malloc(sizeof(struct totem_ip_if_address));
> +			if (if_addr == NULL) {
> +				goto error_free_ifaddrs;
> +			}
> +
> +			memset(if_addr, 0, sizeof(struct totem_ip_if_address));
> +
> +			if_addr->name = strdup(lifreq[i].lifr_name);
> +			if (if_addr->name == NULL) {
> +				goto error_free_addr;
> +			}
> +
> +			if (totemip_sockaddr_to_totemip_convert(&lifreq[i].lifr_addr, &if_addr->ip_addr) == -1) {
> +				goto error_free_addr_name;
> +			}
> +
> +			if (ioctl(id_fd, SIOCGLIFSUBNET, &lifreq[i]) < 0)
> +				continue ;
> +
> +			/*
> +			 * lifreq doesn't contain mask address. But It length of prefix in bits,
> +			 * so we can generate mask.
> +			 */
> +			memset(&if_addr->mask_addr, 0, sizeof(if_addr->mask_addr));
> +			if_addr->mask_addr.family = if_addr->ip_addr.family;
> +			for (j = 0; j < lifreq[i].lifr_addrlen; j++) {
> +				if_addr->mask_addr.addr[j / 8] |= 1 << (7 - (j % 8));
> +			}
> +			if (ioctl(id_fd, SIOCGLIFFLAGS, &lifreq[i]) >= 0) {
> +				if_addr->interface_up = lifreq[i].lifr_flags & IFF_UP;
> +			}
> +			if (ioctl(id_fd, SIOCGLIFINDEX, &lifreq[i]) >= 0) {
> +				if_addr->interface_num = lifreq[i].lifr_index;
> +			}
> +
> +			list_add(&if_addr->list, addrs);
> +		}
> +
> +		free (lifconf.lifc_buf);
> +		close (id_fd);
> +	}
> +
> +	return (0);
> +
> +error_free_addr_name:
> +	free(if_addr->name);
> +
> +error_free_addr:
> +	free(if_addr);
> +
> +error_free_ifaddrs:
> +	totemip_freeifaddrs(addrs);
> +	free (lifconf.lifc_buf);
> +	close (id_fd);
> +
> +	return (-1);
> +}
>  #endif /* HAVE_GETIFADDRS */
>  
>  void totemip_freeifaddrs(struct list_head *addrs)

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux