summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-08-01 08:11:14 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-08-02 10:48:58 +0900
commit1890b4c5ef28fde6cff478a78e1ded3a65badd6b (patch)
tree332875e27ca4e85c3432c884dd038dc161be7dc3
parenta46e8b6826fe95ff09278d75474faf7a14b5d8b1 (diff)
config: support unnumbered bgp peering
from configuration file: ```toml [[neighbors]] [[neighbors.afi-safis]] neighbor-interface = "eth0" peer-as = 65000 ``` Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--config/bgp_configs.go10
-rw-r--r--config/default.go57
-rw-r--r--server/server.go7
-rw-r--r--tools/pyang_plugins/gobgp.yang12
4 files changed, 86 insertions, 0 deletions
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")
diff --git a/server/server.go b/server/server.go
index 9820f898..036a94ba 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1730,6 +1730,13 @@ func (s *BgpServer) AddNeighbor(c *config.Neighbor) (err error) {
func (server *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) error {
addr := c.Config.NeighborAddress
+ if intf := c.Config.NeighborInterface; intf != "" {
+ var err error
+ addr, err = config.GetIPv6LinkLocalNeighborAddress(intf)
+ if err != nil {
+ return err
+ }
+ }
n, y := server.neighborMap[addr]
if !y {
return fmt.Errorf("Can't delete a peer configuration for %s", addr)
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index ee158866..98d42729 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -655,6 +655,18 @@ module gobgp {
}
+ augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:config" {
+ leaf neighbor-interface {
+ type string;
+ }
+ }
+
+ augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:state" {
+ leaf neighbor-interface {
+ type string;
+ }
+ }
+
augment "/bgp:bgp/bgp:neighbors/bgp:neighbor/bgp:transport/bgp:config" {
leaf remote-port {
type inet:port-number;