summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-07-29 15:37:15 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-07-29 16:31:35 +0900
commit7e74c11fdd07c0b48b81ced78178cc6e7fe3c296 (patch)
tree0bf2d92b0042b728b969359b476dfbe1c4578606
parent59997e8daaf9793caecf178c770d9bb3882b148f (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>
-rw-r--r--config/default.go54
-rw-r--r--gobgp/cmd/common.go14
-rw-r--r--gobgp/cmd/neighbor.go15
-rw-r--r--server/server.go2
4 files changed, 57 insertions, 28 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"))
diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go
index 9a4b8164..0c3e4c48 100644
--- a/gobgp/cmd/common.go
+++ b/gobgp/cmd/common.go
@@ -26,6 +26,7 @@ import (
"os"
"sort"
"strconv"
+ "strings"
"time"
)
@@ -264,7 +265,7 @@ func extractReserved(args, keys []string) map[string][]string {
}
type PeerConf struct {
- RemoteIp net.IP `json:"remote_ip,omitempty"`
+ RemoteIp string `json:"remote_ip,omitempty"`
Id net.IP `json:"id,omitempty"`
RemoteAs uint32 `json:"remote_as,omitempty"`
LocalAs uint32 `json:"local-as,omitempty"`
@@ -294,8 +295,9 @@ func ApiStruct2Peer(p *gobgpapi.Peer) *Peer {
c, _ := bgp.DecodeCapability(buf)
remoteCaps = append(remoteCaps, c)
}
+ remoteIp, _ := net.ResolveIPAddr("ip", p.Conf.NeighborAddress)
conf := PeerConf{
- RemoteIp: net.ParseIP(p.Conf.NeighborAddress),
+ RemoteIp: remoteIp.String(),
Id: net.ParseIP(p.Conf.Id),
RemoteAs: p.Conf.PeerAs,
LocalAs: p.Conf.LocalAs,
@@ -325,8 +327,8 @@ func (p peers) Swap(i, j int) {
func (p peers) Less(i, j int) bool {
p1 := p[i].Conf.RemoteIp
p2 := p[j].Conf.RemoteIp
- p1Isv4 := p1.To4() != nil
- p2Isv4 := p2.To4() != nil
+ p1Isv4 := !strings.Contains(p1, ":")
+ p2Isv4 := !strings.Contains(p2, ":")
if p1Isv4 != p2Isv4 {
if p1Isv4 {
return true
@@ -337,8 +339,8 @@ func (p peers) Less(i, j int) bool {
if p1Isv4 {
addrlen = 32
}
- strings := sort.StringSlice{cidr2prefix(fmt.Sprintf("%s/%d", p1.String(), addrlen)),
- cidr2prefix(fmt.Sprintf("%s/%d", p2.String(), addrlen))}
+ strings := sort.StringSlice{cidr2prefix(fmt.Sprintf("%s/%d", p1, addrlen)),
+ cidr2prefix(fmt.Sprintf("%s/%d", p2, addrlen))}
return strings.Less(0, 1)
}
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index bf687772..3856949a 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -39,8 +39,8 @@ func getNeighbors() (peers, error) {
m := peers{}
for _, p := range r.Peers {
if neighborsOpts.Transport != "" {
- addr := net.ParseIP(p.Conf.NeighborAddress)
- if addr.To4() != nil {
+ addr, _ := net.ResolveIPAddr("ip", p.Conf.NeighborAddress)
+ if addr.IP.To4() != nil {
if neighborsOpts.Transport != "ipv4" {
continue
}
@@ -61,7 +61,7 @@ func getNeighbor(addr string) (*Peer, error) {
return nil, e
}
for _, p := range l {
- if p.Conf.RemoteIp.String() == addr {
+ if p.Conf.RemoteIp == addr {
return p, nil
}
}
@@ -94,8 +94,8 @@ func showNeighbors() error {
now := time.Now()
for _, p := range m {
- if len(p.Conf.RemoteIp) > maxaddrlen {
- maxaddrlen = len(p.Conf.RemoteIp)
+ if l := len(p.Conf.RemoteIp); l > maxaddrlen {
+ maxaddrlen = l
}
if len(fmt.Sprint(p.Conf.RemoteAs)) > maxaslen {
maxaslen = len(fmt.Sprint(p.Conf.RemoteAs))
@@ -771,9 +771,12 @@ func modNeighbor(cmdType string, args []string) error {
usage += " as <VALUE>"
}
- if len(m[""]) != 1 || net.ParseIP(m[""][0]) == nil {
+ if len(m[""]) != 1 {
return fmt.Errorf("%s", usage)
}
+ if _, err := net.ResolveIPAddr("ip", m[""][0]); err != nil {
+ return err
+ }
var err error
switch cmdType {
case CMD_ADD:
diff --git a/server/server.go b/server/server.go
index ee8374a6..cfbe514f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -162,7 +162,7 @@ func (server *BgpServer) Serve() {
passConn := func(conn *net.TCPConn) {
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
ipaddr, _ := net.ResolveIPAddr("ip", host)
- remoteAddr := ipaddr.IP.String()
+ remoteAddr := ipaddr.String()
peer, found := server.neighborMap[remoteAddr]
if found {
if peer.fsm.adminState != ADMIN_STATE_UP {