If my understanding of Yggdrasil is correct, than the link-local address of the tun device does not serve any purpose.
We could disable this address and therefore the tunnel interface does not "claim" to be able to send on that address.
So going from this:
18: ygg0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 65535 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet6 203:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/7 scope global
valid_lft forever preferred_lft forever
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
to this:
17: ygg0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 65535 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet6 203:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/7 scope global
valid_lft forever preferred_lft forever
This makes the interface list a little bit cleaner in my opinion.
You can achieve the same effect imperatively with:
# ip -6 address flush dev ygg0 scope link
I have had success with this following patch. What do you think? If you want I can make a PR out of this.
Patch
```diff
diff --git a/src/tun/tun_linux.go b/src/tun/tun_linux.go
index 98d63db..1266fca 100644
--- a/src/tun/tun_linux.go
+++ b/src/tun/tun_linux.go
@@ -60,6 +60,17 @@ func (tun *TunAdapter) setupAddress(addr string) error {
if err := netlink.LinkSetUp(nlintf); err != nil {
return fmt.Errorf("failed to bring link up: %w", err)
}
+ addrs, err := netlink.AddrList(nlintf, netlink.FAMILY_V6)
+ if err != nil {
+ return fmt.Errorf("failed to list addresses: %w", err)
+ }
+ for _, addr := range addrs {
+ if addr.Scope == int(netlink.SCOPE_LINK) {
+ if err := netlink.AddrDel(nlintf, &addr); err != nil {
+ return fmt.Errorf("failed to delete link-local address: %w", err)
+ }
+ }
+ }
// Friendly output
tun.log.Infof("Interface name: %s", tun.Name())
tun.log.Infof("Interface IPv6: %s", addr)
```
If my understanding of Yggdrasil is correct, than the link-local address of the tun device does not serve any purpose. We could disable this address and therefore the tunnel interface does not "claim" to be able to send on that address.
So going from this:
to this:
This makes the interface list a little bit cleaner in my opinion. You can achieve the same effect imperatively with:
I have had success with this following patch. What do you think? If you want I can make a PR out of this.
Patch
```diff diff --git a/src/tun/tun_linux.go b/src/tun/tun_linux.go index 98d63db..1266fca 100644 --- a/src/tun/tun_linux.go +++ b/src/tun/tun_linux.go @@ -60,6 +60,17 @@ func (tun *TunAdapter) setupAddress(addr string) error { if err := netlink.LinkSetUp(nlintf); err != nil { return fmt.Errorf("failed to bring link up: %w", err) } + addrs, err := netlink.AddrList(nlintf, netlink.FAMILY_V6) + if err != nil { + return fmt.Errorf("failed to list addresses: %w", err) + } + for _, addr := range addrs { + if addr.Scope == int(netlink.SCOPE_LINK) { + if err := netlink.AddrDel(nlintf, &addr); err != nil { + return fmt.Errorf("failed to delete link-local address: %w", err) + } + } + } // Friendly output tun.log.Infof("Interface name: %s", tun.Name()) tun.log.Infof("Interface IPv6: %s", addr) ```