I can create a tun device by using: ifconfig tun0 create ifconfig tun 10.1.2.0 196.2.3.4 ifconfig tun alias 196.2.3.3 196.2.3.4 ifconfig up This works great and allows me to use the 10.1.2.0 and have it tunneled over the second (aliased) tunnel when I set up the correct route using /sbin/route add -net 10.0.0.0/8 -iface tun0. I have this setup, using IPv6 only working as it is supposed to. To explain what I am am actually achieving with this: In the background I am using BGP over a one-to-one VPN software using the tunnel interface. Doing the same thing on IPv6, however doesn't work when I add an alias, using the same destination address twice: ifconfig tun0 inet6 fdaa:abc:abc:abc::1 fe80::111:0 prefixlen /128 ifconfig tun0 inet6 alias fe80::111:1 fe80::111:0 prefixlen /128 ifconfig: ioctl (SIOCAIFADDR): File exists Using another destination address this works however. Since this works on IPv4 I'd expect it to work here as well.
I have same bug on 12.1… "file exists": ``` socket(PF_INET,SOCK_DGRAM|SOCK_CLOEXEC,0) = 3 (0x3) ioctl(3,SIOCGIFINDEX,0x7fffffff9f20) = 0 (0x0) close(3) = 0 (0x0) __sysctl(0x7fffffff9f40,0x6,0x0,0x7fffffff9f38,0x0,0x0) = 0 (0x0) __sysctl(0x7fffffff9f40,0x6,0x80161e000,0x7fffffff9f38,0x0,0x0) = 0 (0x0) socket(PF_INET6,SOCK_DGRAM,0) = 3 (0x3) ioctl(3,SIOCDIFADDR_IN6,0x1054278) ERR#49 'Can't assign requested address' ioctl(3,SIOCAIFADDR_IN6,0x1054278) ERR#17 'File exists' ifconfig: write(2,"ifconfig: ",10) = 10 (0xa) ioctl (SIOCAIFADDR)write(2,"ioctl (SIOCAIFADDR)",19) = 19 (0x13) : write(2,": ",2) = 2 (0x2) File exists write(2,"File exists\n",12) = 12 (0xc) exit(0x1) process exit, rval = 1 ```
We've been encountering this in https://github.com/tailscale/tailscale/issues/1307 The problem occurs because rtrequest1_fib returns EEXIST. root@freebsd12:~ # dtrace -n 'fbt:::return /(int)arg1 == EEXIST / { stack(); }' -c "ifconfig tun0 inet6 fd7a:115c:a1e0:ab12:4843:cd96:625c:1f1b fd7a:115c:a1e0:ab12:4843:cd96:625c:1f1b prefixlen 128" dtrace: description 'fbt:::return ' matched 29364 probes ifconfig: ioctl (SIOCAIFADDR): File exists dtrace: pid 1175 exited with status 1 CPU ID FUNCTION:NAME 1 52657 rtrequest1_fib:return kernel`rtinit+0x421 kernel`in6_update_ifa+0xc6b kernel`in6_control+0x96f kernel`ifioctl+0x47f kernel`kern_ioctl+0x2b7 kernel`sys_ioctl+0xfa kernel`amd64_syscall+0x387 kernel`0xffffffff8106785e That happens because rn_addroute returns NULL: rn_addroute(void *v_arg, void *n_arg, struct radix_head *head, struct radix_node treenodes[2]) ... /* * Deal with duplicated keys: attach node to previous instance */ saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes); if (keyduplicated) { for (t = tt; tt; t = tt, tt = tt->rn_dupedkey) { #ifdef RADIX_MPATH /* permit multipath, if enabled for the family */ ... #endif if (tt->rn_mask == netmask) return (0); There is a bunch of code within the #ifdef RADIX_MPATH block above. Enabling RADIX_MPATH in the kernel config does allow the tun0 address assignment to succeed, though I haven't fully tested if it works as expected. It looks like this behavior was understood, in a comment in sys/netinet6/in6.c:in6_notify_ifa from 2004: /* * If a new destination address is specified for a point-to-point * interface, install a route to the destination as an interface * direct route. * XXX: the logic below rejects assigning multiple addresses on a p2p. * interface that share the same destination. */ plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
(In reply to Christian Sturm from comment #0) The IPv6 stack does not behave the same as IPv4 stack. In this case, you can add an IPv6 alias without the destination address to tun0. ``` ifconfig tun0 inet6 2001:db8:: 2001:db8::1 prefixlen 128 ifconfig tun0 inet6 alias 2001:db8::2 prefixlen 128 ``` The long answer: In principle, a tunnel interface can be unnumbered. For a router, you can "borrow" the global unique address on loopback interface as the local address. As for numbered tunnel interface, is the peer should be numbered? No, at least in principle not required. We give another thought on the remote address of tunnel interface, if both ends are numbered, then should either end has only exactly one IP address? No. Due to historical reason, the destination address of tunnel interface can not be omitted of the FreeBSD IPv4 stack implementation. But it is not the case of IPv6 stack. Still we can teach the FreeBSD kernel to "smartly" process IPv6 aliases with same destination address.