summaryrefslogtreecommitdiffhomepage
path: root/config/default.go
diff options
context:
space:
mode:
Diffstat (limited to 'config/default.go')
-rw-r--r--config/default.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/config/default.go b/config/default.go
index ef3da7f1..e4cfeb4c 100644
--- a/config/default.go
+++ b/config/default.go
@@ -6,6 +6,7 @@ import (
"github.com/osrg/gobgp/packet/bmp"
"github.com/osrg/gobgp/packet/rtr"
"github.com/spf13/viper"
+ "github.com/vishvananda/netlink"
"net"
)
@@ -71,6 +72,54 @@ func getIPv6LinkLocalAddress(ifname string) (string, error) {
return "", fmt.Errorf("no ipv6 link local address for %s", ifname)
}
+func isLocalLinkLocalAddress(ifindex int, addr net.IP) (bool, error) {
+ ifi, err := net.InterfaceByIndex(ifindex)
+ if err != nil {
+ return false, err
+ }
+ addrs, err := ifi.Addrs()
+ if err != nil {
+ return false, err
+ }
+ for _, a := range addrs {
+ if ip, _, _ := net.ParseCIDR(a.String()); addr.Equal(ip) {
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
+func GetIPv6LinkLocalNeighborAddress(ifname string) (string, error) {
+ ifi, err := net.InterfaceByName(ifname)
+ if err != nil {
+ return "", err
+ }
+ neighs, err := netlink.NeighList(ifi.Index, netlink.FAMILY_V6)
+ if err != nil {
+ return "", err
+ }
+ cnt := 0
+ var addr net.IP
+ for _, neigh := range neighs {
+ local, err := isLocalLinkLocalAddress(ifi.Index, neigh.IP)
+ if err != nil {
+ return "", err
+ }
+ if neigh.IP.IsLinkLocalUnicast() && !local {
+ addr = neigh.IP
+ cnt += 1
+ }
+ }
+
+ if cnt == 0 {
+ return "", fmt.Errorf("no ipv6 link-local neighbor found")
+ } else if cnt > 1 {
+ return "", fmt.Errorf("found %d link-local neighbors. only support p2p link", cnt)
+ }
+
+ return fmt.Sprintf("%s%%%s", addr, ifname), nil
+}
+
func SetDefaultNeighborConfigValues(n *Neighbor, asn uint32) error {
return setDefaultNeighborConfigValuesWithViper(nil, n, asn)
}
@@ -103,6 +152,14 @@ func setDefaultNeighborConfigValuesWithViper(v *viper.Viper, n *Neighbor, asn ui
n.Timers.Config.IdleHoldTimeAfterReset = float64(DEFAULT_IDLE_HOLDTIME_AFTER_RESET)
}
+ if n.Config.NeighborInterface != "" {
+ addr, err := GetIPv6LinkLocalNeighborAddress(n.Config.NeighborInterface)
+ if err != nil {
+ return err
+ }
+ n.Config.NeighborAddress = addr
+ }
+
if n.Transport.Config.LocalAddress == "" {
if n.Config.NeighborAddress == "" {
return fmt.Errorf("no neighbor address/interface specified")