diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-07-29 15:37:15 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-07-29 16:31:35 +0900 |
commit | 7e74c11fdd07c0b48b81ced78178cc6e7fe3c296 (patch) | |
tree | 0bf2d92b0042b728b969359b476dfbe1c4578606 /config | |
parent | 59997e8daaf9793caecf178c770d9bb3882b148f (diff) |
config: simplify ipv6 link local address peering
from cli:
```
gobgp neighbor add fe80::902f:4eff:fe52:6985%eth0 as 65000
```
from configuration file:
```toml
[[neighbors]]
[[neighbors.afi-safis]]
[neighbors.config]
neighbor-address = "fe80::902f:4eff:fe52:6985%eth0"
peer-as = 65000
```
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'config')
-rw-r--r-- | config/default.go | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/config/default.go b/config/default.go index e0564c0e..d2911036 100644 --- a/config/default.go +++ b/config/default.go @@ -52,6 +52,25 @@ func extractArray(intf interface{}) ([]interface{}, error) { return nil, nil } +func getIPv6LinkLocalAddress(ifname string) (string, error) { + ifi, err := net.InterfaceByName(ifname) + if err != nil { + return "", err + } + addrs, err := ifi.Addrs() + if err != nil { + return "", err + } + for _, addr := range addrs { + if ip, _, err := net.ParseCIDR(addr.String()); err != nil { + return "", err + } else if ip.To4() == nil && ip.IsLinkLocalUnicast() { + return fmt.Sprintf("%s%%%s", ip.String(), ifname), nil + } + } + return "", fmt.Errorf("no ipv6 link local address for %s", ifname) +} + func SetDefaultNeighborConfigValues(n *Neighbor, asn uint32) error { return setDefaultNeighborConfigValuesWithViper(nil, n, asn) } @@ -85,28 +104,33 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui } if n.Transport.Config.LocalAddress == "" { - if n.Config.NeighborAddress != "" { - v6 := true - if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { - v6 = false - } - if v6 { - n.Transport.Config.LocalAddress = "::" - } else { - n.Transport.Config.LocalAddress = "0.0.0.0" - } - } else { + if n.Config.NeighborAddress == "" { return fmt.Errorf("no neighbor address/interface specified") } + ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress) + if err != nil { + return err + } + localAddress := "0.0.0.0" + if ipAddr.IP.To4() == nil { + localAddress = "::" + if ipAddr.Zone != "" { + localAddress, err = getIPv6LinkLocalAddress(ipAddr.Zone) + if err != nil { + return err + } + } + } + n.Transport.Config.LocalAddress = localAddress } if len(n.AfiSafis) == 0 { - if ip := net.ParseIP(n.Config.NeighborAddress); ip.To4() != nil { + if ipAddr, err := net.ResolveIPAddr("ip", n.Config.NeighborAddress); err != nil { + return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress) + } else if ipAddr.IP.To4() != nil { n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV4_UNICAST, true)} - } else if ip.To16() != nil { - n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true)} } else { - return fmt.Errorf("invalid neighbor address: %s", n.Config.NeighborAddress) + n.AfiSafis = []AfiSafi{defaultAfiSafi(AFI_SAFI_TYPE_IPV6_UNICAST, true)} } } else { afs, err := extractArray(v.Get("neighbor.afi-safis")) |