summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-10-07 23:51:44 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-10-08 00:18:03 +0900
commitbf98af5a968491059c01729d613098133eb32788 (patch)
treea4a10efca6a9756c717b5dd1a24189c91e8be22e /server
parent477869cfec7032b4b4aaac9e5508a951246caf2d (diff)
gobgp: support admin operations for multiple peers
You can do something like: $ gobgp neighbor all softreset Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r--server/server.go83
1 files changed, 53 insertions, 30 deletions
diff --git a/server/server.go b/server/server.go
index d69d2f1e..893658b1 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1282,13 +1282,25 @@ func (server *BgpServer) getBestFromLocal(peer *Peer) ([]*table.Path, []*table.P
func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
var msgs []*SenderMsg
- logOp := func(peer *Peer, action string) {
+ logOp := func(addr string, action string) {
log.WithFields(log.Fields{
"Topic": "Operation",
- "Key": peer.conf.NeighborConfig.NeighborAddress.String(),
+ "Key": addr,
}).Info(action)
}
+ reqToPeers := func(grpcReq *GrpcRequest) ([]*Peer, error) {
+ peers := make([]*Peer, 0)
+ if grpcReq.Name == "all" {
+ for _, p := range server.neighborMap {
+ peers = append(peers, p)
+ }
+ return peers, nil
+ }
+ peer, err := server.checkNeighborRequest(grpcReq)
+ return []*Peer{peer}, err
+ }
+
sortedDsts := func(t *table.Table) []*GrpcResponse {
results := make([]*GrpcResponse, len(t.GetDestinations()))
@@ -1433,42 +1445,50 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
go sendMultipleResponses(grpcReq, results)
case REQ_NEIGHBOR_SHUTDOWN:
- peer, err := server.checkNeighborRequest(grpcReq)
+ peers, err := reqToPeers(grpcReq)
if err != nil {
break
}
- logOp(peer, "Neighbor shutdown")
+ logOp(grpcReq.Name, "Neighbor shutdown")
m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil)
- msgs = []*SenderMsg{newSenderMsg(peer, []*bgp.BGPMessage{m})}
+ for _, peer := range peers {
+ msgs = append(msgs, newSenderMsg(peer, []*bgp.BGPMessage{m}))
+ }
grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)
case REQ_NEIGHBOR_RESET:
- peer, err := server.checkNeighborRequest(grpcReq)
+ peers, err := reqToPeers(grpcReq)
if err != nil {
break
}
- logOp(peer, "Neighbor reset")
- peer.fsm.idleHoldTime = peer.conf.Timers.TimersConfig.IdleHoldTimeAfterReset
- m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil)
- msgs = []*SenderMsg{newSenderMsg(peer, []*bgp.BGPMessage{m})}
+ logOp(grpcReq.Name, "Neighbor reset")
+ for _, peer := range peers {
+ peer.fsm.idleHoldTime = peer.conf.Timers.TimersConfig.IdleHoldTimeAfterReset
+ m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil)
+ msgs = append(msgs, newSenderMsg(peer, []*bgp.BGPMessage{m}))
+ }
grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)
case REQ_NEIGHBOR_SOFT_RESET, REQ_NEIGHBOR_SOFT_RESET_IN:
- peer, err := server.checkNeighborRequest(grpcReq)
+ peers, err := reqToPeers(grpcReq)
if err != nil {
break
}
- peer.accepted = 0
+ for _, peer := range peers {
+ peer.accepted = 0
+ }
if grpcReq.RequestType == REQ_NEIGHBOR_SOFT_RESET {
- logOp(peer, "Neighbor soft reset")
+ logOp(grpcReq.Name, "Neighbor soft reset")
} else {
- logOp(peer, "Neighbor soft reset in")
+ logOp(grpcReq.Name, "Neighbor soft reset in")
}
- pathList := peer.adjRib.GetInPathList(grpcReq.RouteFamily)
- msgs = server.propagateUpdate(peer, pathList)
+ for _, peer := range peers {
+ pathList := peer.adjRib.GetInPathList(grpcReq.RouteFamily)
+ msgs = append(msgs, server.propagateUpdate(peer, pathList)...)
+ }
if grpcReq.RequestType == REQ_NEIGHBOR_SOFT_RESET_IN {
grpcReq.ResponseCh <- &GrpcResponse{}
@@ -1477,26 +1497,29 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
fallthrough
case REQ_NEIGHBOR_SOFT_RESET_OUT:
- peer, err := server.checkNeighborRequest(grpcReq)
+ peers, err := reqToPeers(grpcReq)
if err != nil {
break
}
if grpcReq.RequestType == REQ_NEIGHBOR_SOFT_RESET_OUT {
- logOp(peer, "Neighbor soft reset out")
- }
- for _, rf := range peer.configuredRFlist() {
- peer.adjRib.DropOut(rf)
- }
- pathList, filtered := server.getBestFromLocal(peer)
- if len(pathList) > 0 {
- peer.adjRib.UpdateOut(pathList)
- msgs = []*SenderMsg{newSenderMsg(peer, table.CreateUpdateMsgFromPaths(pathList))}
+ logOp(grpcReq.Name, "Neighbor soft reset out")
}
- if len(filtered) > 0 {
- for _, p := range filtered {
- p.IsWithdraw = true
+ for _, peer := range peers {
+ for _, rf := range peer.configuredRFlist() {
+ peer.adjRib.DropOut(rf)
+ }
+
+ pathList, filtered := server.getBestFromLocal(peer)
+ if len(pathList) > 0 {
+ peer.adjRib.UpdateOut(pathList)
+ msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(pathList)))
+ }
+ if len(filtered) > 0 {
+ for _, p := range filtered {
+ p.IsWithdraw = true
+ }
+ msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(filtered)))
}
- msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(filtered)))
}
grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)