mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 08:46:58 +08:00
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:
committed by
Nikos Mavrogiannopoulos
parent
2e5bd4bbf8
commit
2a6111eef8
28
src/tun.c
28
src/tun.c
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user