From 1890b4c5ef28fde6cff478a78e1ded3a65badd6b Mon Sep 17 00:00:00 2001 From: ISHIDA Wataru Date: Mon, 1 Aug 2016 08:11:14 +0000 Subject: config: support unnumbered bgp peering from configuration file: ```toml [[neighbors]] [[neighbors.afi-safis]] neighbor-interface = "eth0" peer-as = 65000 ``` Signed-off-by: ISHIDA Wataru --- config/bgp_configs.go | 10 +++++++++ config/default.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) (limited to 'config') diff --git a/config/bgp_configs.go b/config/bgp_configs.go index 44afcb82..1636073c 100644 --- a/config/bgp_configs.go +++ b/config/bgp_configs.go @@ -2477,6 +2477,8 @@ type NeighborState struct { EstablishedCount uint32 `mapstructure:"established-count"` // original -> gobgp:flops Flops uint32 `mapstructure:"flops"` + // original -> gobgp:neighbor-interface + NeighborInterface string `mapstructure:"neighbor-interface"` } func (lhs *NeighborState) Equal(rhs *NeighborState) bool { @@ -2551,6 +2553,9 @@ func (lhs *NeighborState) Equal(rhs *NeighborState) bool { if lhs.Flops != rhs.Flops { return false } + if lhs.NeighborInterface != rhs.NeighborInterface { + return false + } return true } @@ -2583,6 +2588,8 @@ type NeighborConfig struct { // original -> gobgp:admin-down //gobgp:admin-down's original type is boolean AdminDown bool `mapstructure:"admin-down"` + // original -> gobgp:neighbor-interface + NeighborInterface string `mapstructure:"neighbor-interface"` } func (lhs *NeighborConfig) Equal(rhs *NeighborConfig) bool { @@ -2622,6 +2629,9 @@ func (lhs *NeighborConfig) Equal(rhs *NeighborConfig) bool { if lhs.AdminDown != rhs.AdminDown { return false } + if lhs.NeighborInterface != rhs.NeighborInterface { + return false + } return true } 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") -- cgit v1.2.3