Fix tun IPv6 on platforms that use SIOCAIFADDR_IN6.

Also remove a redundant call to SIOCDIFADDR. A freshly
cloned tun interface should not have existing aliases.
This commit is contained in:
Brian Chu
2014-06-02 20:38:05 +00:00
committed by Nikos Mavrogiannopoulos
parent 2e5bd4bbf8
commit 2a6111eef8

View File

@@ -126,11 +126,10 @@ int set_ipv6_addr(main_server_st * s, struct proc_st *proc)
return ret; return ret;
} }
#elif defined(SIOCSIFPHYADDR_IN6) #elif defined(SIOCAIFADDR_IN6)
#warning "IPv6 support on this platform is untested" #include <netinet6/nd6.h>
/* untested code for FreeBSD */
static static
int set_ipv6_addr(main_server_st * s, struct proc_st *proc) int set_ipv6_addr(main_server_st * s, struct proc_st *proc)
{ {
@@ -149,12 +148,24 @@ int set_ipv6_addr(main_server_st * s, struct proc_st *proc)
memset(&ifr6, 0, sizeof(ifr6)); memset(&ifr6, 0, sizeof(ifr6));
snprintf(ifr6.ifra_name, IFNAMSIZ, "%s", proc->tun_lease.name); snprintf(ifr6.ifra_name, IFNAMSIZ, "%s", proc->tun_lease.name);
memcpy(&ifr6.ifra_addr, SA_IN6_P(&proc->ipv6->lip), memcpy(&ifr6.ifra_addr.sin6_addr, SA_IN6_P(&proc->ipv6->lip),
SA_IN_SIZE(proc->ipv6->lip_len)); SA_IN_SIZE(proc->ipv6->lip_len));
memcpy(&ifr6.ifra_dstaddr, SA_IN6_P(&proc->ipv6->rip), ifr6.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
SA_IN_SIZE(proc->ipv6->rip_len)); ifr6.ifra_addr.sin6_family = AF_INET6;
ret = ioctl(fd, SIOCSIFPHYADDR_IN6, &ifr6); memcpy(&ifr6.ifra_dstaddr.sin6_addr, SA_IN6_P(&proc->ipv6->rip),
SA_IN_SIZE(proc->ipv6->rip_len));
ifr6.ifra_dstaddr.sin6_len = sizeof(struct sockaddr_in6);
ifr6.ifra_dstaddr.sin6_family = AF_INET6;
memset(&ifr6.ifra_prefixmask.sin6_addr, 0xff, sizeof(struct in6_addr));
ifr6.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
ifr6.ifra_prefixmask.sin6_family = AF_INET6;
ifr6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
ifr6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
ret = ioctl(fd, SIOCAIFADDR_IN6, &ifr6);
if (ret != 0) { if (ret != 0) {
e = errno; e = errno;
mslog(s, NULL, LOG_ERR, "%s: Error setting IPv6: %s\n", mslog(s, NULL, LOG_ERR, "%s: Error setting IPv6: %s\n",
@@ -212,9 +223,6 @@ static int set_network_info(main_server_st * s, struct proc_st *proc)
#ifdef SIOCAIFADDR #ifdef SIOCAIFADDR
snprintf(ifr.ifra_name, IFNAMSIZ, "%s", proc->tun_lease.name); snprintf(ifr.ifra_name, IFNAMSIZ, "%s", proc->tun_lease.name);
/* remove old addresses */
while (ioctl(fd, SIOCDIFADDR, &ifr) == 0);
memcpy(&ifr.ifra_addr, &proc->ipv4->lip, proc->ipv4->lip_len); memcpy(&ifr.ifra_addr, &proc->ipv4->lip, proc->ipv4->lip_len);
ifr.ifra_addr.sin_len = sizeof(struct sockaddr_in); ifr.ifra_addr.sin_len = sizeof(struct sockaddr_in);
ifr.ifra_addr.sin_family = AF_INET; ifr.ifra_addr.sin_family = AF_INET;