diff options
-rw-r--r-- | gobgp/cmd/neighbor.go | 20 | ||||
-rw-r--r-- | server/server.go | 83 |
2 files changed, 68 insertions, 35 deletions
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index 45f8445a..cbf0a592 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -736,12 +736,22 @@ func NewNeighborCmd() *cobra.Command { c := &cobra.Command{ Use: name, Run: func(cmd *cobra.Command, args []string) { - remoteIP := net.ParseIP(args[len(args)-1]) - if remoteIP == nil { - fmt.Println("invalid ip address:", args[len(args)-1]) - os.Exit(1) + addr := "" + switch name { + case CMD_RESET, CMD_SOFT_RESET, CMD_SOFT_RESET_IN, CMD_SOFT_RESET_OUT, CMD_SHUTDOWN: + if args[len(args)-1] == "all" { + addr = "all" + } + } + if addr == "" { + remoteIP := net.ParseIP(args[len(args)-1]) + if remoteIP == nil { + fmt.Println("invalid ip address:", args[len(args)-1]) + os.Exit(1) + } + addr = remoteIP.String() } - err := f(cmd.Use, remoteIP.String(), args[:len(args)-1]) + err := f(cmd.Use, addr, args[:len(args)-1]) if err != nil { fmt.Println(err) os.Exit(1) 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) |