summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-02-04 14:24:18 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-02-04 23:34:24 -0800
commitc9436bc7218800ef6911dab6eed7d7ddf3378e94 (patch)
tree6001d367aa133e28fddb460647c37e3ac5aef168
parent7f6831ce1228e42b717f5bf3e507ddae06483ba1 (diff)
server: add support specifying addresses to listen
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--config/bgp_configs.go2
-rw-r--r--docs/sources/configuration.md8
-rw-r--r--server/server.go83
-rw-r--r--tools/pyang_plugins/gobgp.yang3
4 files changed, 61 insertions, 35 deletions
diff --git a/config/bgp_configs.go b/config/bgp_configs.go
index c6a3e53e..4191bbd2 100644
--- a/config/bgp_configs.go
+++ b/config/bgp_configs.go
@@ -1448,6 +1448,8 @@ type Neighbor struct {
type ListenConfig struct {
// original -> gobgp:port
Port int32 `mapstructure:"port"`
+ // original -> gobgp:local-address
+ LocalAddressList []string `mapstructure:"local-address-list"`
}
//struct for container gobgp:mpls-label-range
diff --git a/docs/sources/configuration.md b/docs/sources/configuration.md
index abe04d32..4866d950 100644
--- a/docs/sources/configuration.md
+++ b/docs/sources/configuration.md
@@ -22,6 +22,14 @@
[global.mpls-label-range]
min-label = 1000
max-label = 2000
+ [global.listen-config]
+ # listen port (by default 179)
+ port = 1790
+ # to disable listening
+ # port = -1
+
+ # listen address list (by default "0.0.0.0" and "::")
+ local-address-list = ["192.168.10.1", "2001:db8::1"]
[[rpki-servers]]
[rpki-servers.config]
diff --git a/server/server.go b/server/server.go
index 25ccb9e5..a6d663a7 100644
--- a/server/server.go
+++ b/server/server.go
@@ -102,7 +102,7 @@ type BgpServer struct {
policy *table.RoutingPolicy
broadcastReqs []*GrpcRequest
broadcastMsgs []broadcastMsg
- listenerMap map[string]*net.TCPListener
+ listeners []*net.TCPListener
neighborMap map[string]*Peer
globalRib *table.TableManager
zclient *zebra.Client
@@ -128,13 +128,21 @@ func NewBgpServer() *BgpServer {
}
// avoid mapped IPv6 address
-func listenAndAccept(proto string, port uint32, ch chan *net.TCPConn) (*net.TCPListener, error) {
- service := ":" + strconv.Itoa(int(port))
- addr, _ := net.ResolveTCPAddr(proto, service)
+func listenAndAccept(address string, port uint32, ch chan *net.TCPConn) (*net.TCPListener, error) {
+ proto := "tcp4"
+ if ip := net.ParseIP(address); ip == nil {
+ return nil, fmt.Errorf("can't listen on %s", address)
+ } else if strings.Contains(address, ":") {
+ address = fmt.Sprintf("[%s]", address)
+ proto = "tcp6"
+ }
+ addr, err := net.ResolveTCPAddr(proto, fmt.Sprintf("%s:%d", address, port))
+ if err != nil {
+ return nil, err
+ }
l, err := net.ListenTCP(proto, addr)
if err != nil {
- log.Info(err)
return nil, err
}
go func() {
@@ -163,6 +171,18 @@ func (server *BgpServer) notify2watchers(typ watcherEventType, ev watcherEvent)
return nil
}
+func (server *BgpServer) Listeners(addr string) []*net.TCPListener {
+ list := make([]*net.TCPListener, 0, len(server.listeners))
+ rhs := net.ParseIP(addr).To4() != nil
+ for _, l := range server.listeners {
+ lhs := net.ParseIP(l.Addr().String()).To4() != nil
+ if lhs == rhs {
+ list = append(list, l)
+ }
+ }
+ return list
+}
+
func (server *BgpServer) Serve() {
var g config.Global
for {
@@ -256,27 +276,21 @@ func (server *BgpServer) Serve() {
rfs, _ := config.AfiSafis(g.AfiSafis).ToRfList()
server.globalRib = table.NewTableManager(rfs, g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
- server.listenerMap = make(map[string]*net.TCPListener)
+ server.listeners = make([]*net.TCPListener, 0, 2)
acceptCh := make(chan *net.TCPConn, 4096)
if g.ListenConfig.Port > 0 {
- l4, err1 := listenAndAccept("tcp4", uint32(g.ListenConfig.Port), acceptCh)
- server.listenerMap["tcp4"] = l4
- l6, err2 := listenAndAccept("tcp6", uint32(g.ListenConfig.Port), acceptCh)
- server.listenerMap["tcp6"] = l6
- if err1 != nil && err2 != nil {
- log.Fatal("can't listen either v4 and v6")
- os.Exit(1)
+ list := []string{"0.0.0.0", "::"}
+ if len(g.ListenConfig.LocalAddressList) > 0 {
+ list = g.ListenConfig.LocalAddressList
}
- }
-
- listener := func(addr string) *net.TCPListener {
- var l *net.TCPListener
- if net.ParseIP(addr).To4() != nil {
- l = server.listenerMap["tcp4"]
- } else {
- l = server.listenerMap["tcp6"]
+ for _, addr := range list {
+ l, err := listenAndAccept(addr, uint32(g.ListenConfig.Port), acceptCh)
+ if err != nil {
+ log.Fatal(err)
+ os.Exit(1)
+ }
+ server.listeners = append(server.listeners, l)
}
- return l
}
server.fsmincomingCh = make(chan *FsmMsg, 4096)
@@ -393,7 +407,9 @@ func (server *BgpServer) Serve() {
continue
}
if g.ListenConfig.Port > 0 {
- SetTcpMD5SigSockopts(listener(addr), addr, config.Config.AuthPassword)
+ for _, l := range server.Listeners(addr) {
+ SetTcpMD5SigSockopts(l, addr, config.Config.AuthPassword)
+ }
}
peer := NewPeer(g, config, server.globalRib, server.policy)
server.setPolicyByConfig(peer.ID(), config.ApplyPolicy)
@@ -416,7 +432,9 @@ func (server *BgpServer) Serve() {
server.broadcastPeerState(peer, bgp.BGP_FSM_IDLE)
case config := <-server.deletedPeerCh:
addr := config.Config.NeighborAddress
- SetTcpMD5SigSockopts(listener(addr), addr, "")
+ for _, l := range server.Listeners(addr) {
+ SetTcpMD5SigSockopts(l, addr, "")
+ }
peer, found := server.neighborMap[addr]
if found {
log.Info("Delete a peer configuration for ", addr)
@@ -2118,15 +2136,6 @@ func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*S
if arg.Operation != api.Operation_ADD && !ok {
return nil, fmt.Errorf("not found neighbor %s", addr)
}
- listener := func(addr net.IP) *net.TCPListener {
- var l *net.TCPListener
- if addr.To4() != nil {
- l = server.listenerMap["tcp4"]
- } else {
- l = server.listenerMap["tcp6"]
- }
- return l
- }
switch arg.Operation {
case api.Operation_ADD:
@@ -2136,7 +2145,9 @@ func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*S
log.Infof("Peer %s is added", addr)
}
if server.bgpConfig.Global.ListenConfig.Port > 0 {
- SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), addr, arg.Peer.Conf.AuthPassword)
+ for _, l := range server.Listeners(addr) {
+ SetTcpMD5SigSockopts(l, addr, arg.Peer.Conf.AuthPassword)
+ }
}
apitoConfig := func(a *api.Peer) (config.Neighbor, error) {
var pconf config.Neighbor
@@ -2245,7 +2256,9 @@ func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*S
peer.startFSMHandler(server.fsmincomingCh, server.fsmStateCh)
server.broadcastPeerState(peer, bgp.BGP_FSM_IDLE)
case api.Operation_DEL:
- SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), addr, "")
+ for _, l := range server.Listeners(addr) {
+ SetTcpMD5SigSockopts(l, addr, "")
+ }
log.Info("Delete a peer configuration for ", addr)
go func(addr string) {
t := time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h.t for ", addr) })
diff --git a/tools/pyang_plugins/gobgp.yang b/tools/pyang_plugins/gobgp.yang
index 29e3342d..0a60ac6f 100644
--- a/tools/pyang_plugins/gobgp.yang
+++ b/tools/pyang_plugins/gobgp.yang
@@ -726,6 +726,9 @@ module gobgp {
leaf port {
type int32;
}
+ leaf-list local-address {
+ type string;
+ }
}
}
}