summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorYuji Oshima <yuji.oshima0x3fd@gmail.com>2015-10-29 17:26:01 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-10-29 17:26:01 +0900
commitb780fed28a735fa97cfbb220769f6f2082543674 (patch)
treeb45b5ed4b2c56f93a70c44b7c4404df6e9d22582 /server
parent645ce47b986cf7296d217bc98af7b4a8446833a9 (diff)
api: confirm api.Peer to openconfig and add ModPeer api
Signed-off-by: YujiOshima <yuji.oshima0x3fd@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r--server/grpc_server.go5
-rw-r--r--server/peer.go114
-rw-r--r--server/server.go172
3 files changed, 236 insertions, 55 deletions
diff --git a/server/grpc_server.go b/server/grpc_server.go
index f6f233a0..348d11c7 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -40,6 +40,7 @@ const (
REQ_NEIGHBOR_SOFT_RESET_OUT
REQ_NEIGHBOR_ENABLE
REQ_NEIGHBOR_DISABLE
+ REQ_MOD_NEIGHBOR
REQ_GLOBAL_RIB
REQ_MONITOR_GLOBAL_BEST_CHANGED
REQ_MONITOR_NEIGHBOR_PEER_STATE
@@ -308,6 +309,10 @@ func (s *Server) ModVrf(ctx context.Context, arg *api.ModVrfArguments) (*api.Err
return s.mod(REQ_VRF_MOD, arg)
}
+func (s *Server) ModNeighbor(ctx context.Context, arg *api.ModNeighborArguments) (*api.Error, error) {
+ return s.mod(REQ_MOD_NEIGHBOR, arg)
+}
+
func (s *Server) GetDefinedSet(ctx context.Context, arg *api.DefinedSet) (*api.DefinedSet, error) {
d, err := s.get(REQ_DEFINED_SET, arg)
if err != nil {
diff --git a/server/peer.go b/server/peer.go
index f21ed0bd..26158a1e 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -298,26 +298,20 @@ func (peer *Peer) ToApiStruct() *api.Peer {
}
conf := &api.PeerConf{
- RemoteIp: c.NeighborConfig.NeighborAddress.String(),
- Id: peer.peerInfo.ID.To4().String(),
- RemoteAs: c.NeighborConfig.PeerAs,
- RemoteCap: remoteCap,
- LocalCap: localCap,
- KeepaliveInterval: uint32(peer.conf.Timers.TimersConfig.KeepaliveInterval),
- Holdtime: uint32(peer.conf.Timers.TimersConfig.HoldTime),
+ NeighborAddress: c.NeighborConfig.NeighborAddress.String(),
+ PeerAs: c.NeighborConfig.PeerAs,
+ LocalAs: c.NeighborConfig.LocalAs,
+ PeerType: uint32(c.NeighborConfig.PeerType),
+ AuthPassword: c.NeighborConfig.AuthPassword,
+ RemovePrivateAs: uint32(c.NeighborConfig.RemovePrivateAs),
+ RouteFlapDamping: c.NeighborConfig.RouteFlapDamping,
+ SendCommunity: uint32(c.NeighborConfig.SendCommunity),
+ Description: c.NeighborConfig.Description,
+ PeerGroup: c.NeighborConfig.PeerGroup,
}
- s := &c.NeighborState
timer := &c.Timers
-
- uptime := int64(0)
- if timer.TimersState.Uptime != 0 {
- uptime = int64(time.Now().Sub(time.Unix(timer.TimersState.Uptime, 0)).Seconds())
- }
- downtime := int64(0)
- if timer.TimersState.Downtime != 0 {
- downtime = int64(time.Now().Sub(time.Unix(timer.TimersState.Downtime, 0)).Seconds())
- }
+ s := &c.NeighborState
advertized := uint32(0)
received := uint32(0)
@@ -334,6 +328,15 @@ func (peer *Peer) ToApiStruct() *api.Peer {
}
}
+ uptime := int64(0)
+ if timer.TimersState.Uptime != 0 {
+ uptime = int64(time.Now().Sub(time.Unix(timer.TimersState.Uptime, 0)).Seconds())
+ }
+ downtime := int64(0)
+ if timer.TimersState.Downtime != 0 {
+ downtime = int64(time.Now().Sub(time.Unix(timer.TimersState.Downtime, 0)).Seconds())
+ }
+
keepalive := uint32(0)
if f.negotiatedHoldTime != 0 {
if f.negotiatedHoldTime < timer.TimersConfig.HoldTime {
@@ -343,38 +346,57 @@ func (peer *Peer) ToApiStruct() *api.Peer {
}
}
- info := &api.PeerInfo{
- BgpState: f.state.String(),
- AdminState: f.adminState.String(),
- FsmEstablishedTransitions: s.EstablishedCount,
- TotalMessageOut: s.Messages.Sent.Total,
- TotalMessageIn: s.Messages.Received.Total,
- UpdateMessageOut: s.Messages.Sent.Update,
- UpdateMessageIn: s.Messages.Received.Update,
- KeepAliveMessageOut: s.Messages.Sent.Keepalive,
- KeepAliveMessageIn: s.Messages.Received.Keepalive,
- OpenMessageOut: s.Messages.Sent.Open,
- OpenMessageIn: s.Messages.Received.Open,
- NotificationOut: s.Messages.Sent.Notification,
- NotificationIn: s.Messages.Received.Notification,
- RefreshMessageOut: s.Messages.Sent.Refresh,
- RefreshMessageIn: s.Messages.Received.Refresh,
- DiscardedOut: s.Messages.Sent.Discarded,
- DiscardedIn: s.Messages.Received.Discarded,
- Uptime: uptime,
- Downtime: downtime,
- Received: received,
- Accepted: accepted,
- Advertized: advertized,
- OutQ: uint32(len(peer.outgoing)),
- Flops: s.Flops,
- NegotiatedHoldtime: uint32(f.negotiatedHoldTime),
- KeepaliveInterval: keepalive,
+ timerconf := &api.TimersConfig{
+ ConnectRetry: uint64(timer.TimersConfig.ConnectRetry),
+ HoldTime: uint64(timer.TimersConfig.HoldTime),
+ KeepaliveInterval: uint64(keepalive),
+ MinimumAdvertisementInterval: uint64(timer.TimersConfig.MinimumAdvertisementInterval),
+ }
+
+ timerstate := &api.TimersState{
+ Uptime: uint64(uptime),
+ Downtime: uint64(downtime),
+ }
+
+ apitimer := &api.Timers{
+ Config: timerconf,
+ State: timerstate,
+ }
+ msgrcv := &api.Message{
+ NOTIFICATION: s.Messages.Received.Notification,
+ UPDATE: s.Messages.Received.Update,
+ OPEN: s.Messages.Received.Open,
+ KEEPALIVE: s.Messages.Received.Keepalive,
+ REFRESH: s.Messages.Received.Refresh,
+ DISCARDED: s.Messages.Received.Discarded,
+ TOTAL: s.Messages.Received.Total,
+ }
+ msgsnt := &api.Message{
+ NOTIFICATION: s.Messages.Sent.Notification,
+ UPDATE: s.Messages.Sent.Update,
+ OPEN: s.Messages.Sent.Open,
+ KEEPALIVE: s.Messages.Sent.Keepalive,
+ REFRESH: s.Messages.Sent.Refresh,
+ DISCARDED: s.Messages.Sent.Discarded,
+ TOTAL: s.Messages.Sent.Total,
+ }
+ msg := &api.Messages{
+ Received: msgrcv,
+ Sent: msgsnt,
+ }
+ info := &api.PeerState{
+ BgpState: f.state.String(),
+ AdminState: f.adminState.String(),
+ Messages: msg,
+ Received: received,
+ Accepted: accepted,
+ Advertized: advertized,
}
return &api.Peer{
- Conf: conf,
- Info: info,
+ Conf: conf,
+ Info: info,
+ Timers: apitimer,
}
}
diff --git a/server/server.go b/server/server.go
index a14f8395..49b584ca 100644
--- a/server/server.go
+++ b/server/server.go
@@ -80,6 +80,7 @@ type BgpServer struct {
addedPeerCh chan config.Neighbor
deletedPeerCh chan config.Neighbor
updatedPeerCh chan config.Neighbor
+ fsmincomingCh chan *fsmMsg
rpkiConfigCh chan config.RpkiServers
bmpConfigCh chan config.BmpServers
dumper *dumper
@@ -90,6 +91,7 @@ type BgpServer struct {
policy *table.RoutingPolicy
broadcastReqs []*GrpcRequest
broadcastMsgs []broadcastMsg
+ listenerMap map[string]*net.TCPListener
neighborMap map[string]*Peer
globalRib *table.TableManager
zclient *zebra.Client
@@ -210,12 +212,12 @@ func (server *BgpServer) Serve() {
return rfList
}
server.globalRib = table.NewTableManager(GLOBAL_RIB_NAME, toRFlist(g.AfiSafis.AfiSafiList), g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
- listenerMap := make(map[string]*net.TCPListener)
+ server.listenerMap = make(map[string]*net.TCPListener)
acceptCh := make(chan *net.TCPConn)
l4, err1 := listenAndAccept("tcp4", server.listenPort, acceptCh)
- listenerMap["tcp4"] = l4
+ server.listenerMap["tcp4"] = l4
l6, err2 := listenAndAccept("tcp6", server.listenPort, acceptCh)
- listenerMap["tcp6"] = l6
+ server.listenerMap["tcp6"] = l6
if err1 != nil && err2 != nil {
log.Fatal("can't listen either v4 and v6")
os.Exit(1)
@@ -224,14 +226,14 @@ func (server *BgpServer) Serve() {
listener := func(addr net.IP) *net.TCPListener {
var l *net.TCPListener
if addr.To4() != nil {
- l = listenerMap["tcp4"]
+ l = server.listenerMap["tcp4"]
} else {
- l = listenerMap["tcp6"]
+ l = server.listenerMap["tcp6"]
}
return l
}
- incoming := make(chan *fsmMsg, 4096)
+ server.fsmincomingCh = make(chan *fsmMsg, 4096)
var senderMsgs []*SenderMsg
var zapiMsgCh chan *zebra.Message
@@ -367,7 +369,7 @@ func (server *BgpServer) Serve() {
}
}
server.neighborMap[addr] = peer
- peer.startFSMHandler(incoming)
+ peer.startFSMHandler(server.fsmincomingCh)
server.broadcastPeerState(peer)
case config := <-server.deletedPeerCh:
addr := config.NeighborConfig.NeighborAddress.String()
@@ -399,13 +401,13 @@ func (server *BgpServer) Serve() {
peer := server.neighborMap[addr]
peer.conf = config
server.setPolicyByConfig(peer, config.ApplyPolicy)
- case e := <-incoming:
+ case e := <-server.fsmincomingCh:
peer, found := server.neighborMap[e.MsgSrc]
if !found {
log.Warn("Can't find the neighbor ", e.MsgSrc)
break
}
- m := server.handleFSMMessage(peer, e, incoming)
+ m := server.handleFSMMessage(peer, e, server.fsmincomingCh)
if len(m) > 0 {
senderMsgs = append(senderMsgs, m...)
}
@@ -1544,6 +1546,15 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
result.Data = err
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
+ case REQ_MOD_NEIGHBOR:
+ m, err := server.handleGrpcModNeighbor(grpcReq)
+ grpcReq.ResponseCh <- &GrpcResponse{
+ ResponseErr: err,
+ }
+ if len(m) > 0 {
+ msgs = append(msgs, m...)
+ }
+ close(grpcReq.ResponseCh)
case REQ_DEFINED_SET:
if err := server.handleGrpcGetDefinedSet(grpcReq); err != nil {
grpcReq.ResponseCh <- &GrpcResponse{
@@ -1644,6 +1655,149 @@ func (server *BgpServer) handleGrpcGetDefinedSet(grpcReq *GrpcRequest) error {
}
return nil
}
+func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*SenderMsg, err error) {
+ arg := grpcReq.Data.(*api.ModNeighborArguments)
+ addr := arg.Peer.Conf.NeighborAddress
+ n, ok := server.neighborMap[addr]
+ 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:
+ if ok {
+ return nil, fmt.Errorf("Can't overwrite the exising peer %s", addr)
+ } else {
+ log.Infof("Peer %s is added", addr)
+ }
+ SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), addr, arg.Peer.Conf.AuthPassword)
+ var loc *table.TableManager
+ if arg.Peer.RouteServer != nil {
+ if arg.Peer.RouteServer.RouteServerClient {
+ apitoRFlist := func(l []*api.AfiSafi) []bgp.RouteFamily {
+ rfList := []bgp.RouteFamily{}
+ for _, rf := range l {
+ k, _ := bgp.GetRouteFamily(rf.Name)
+ rfList = append(rfList, k)
+ }
+ return rfList
+ }
+ loc = table.NewTableManager(addr, apitoRFlist(arg.Peer.Afisafis.Afisafi), server.bgpConfig.Global.MplsLabelRange.MinLabel, server.bgpConfig.Global.MplsLabelRange.MaxLabel)
+ } else {
+ loc = server.globalRib
+ }
+ } else {
+ loc = server.globalRib
+ }
+ apitoConfig := func(a *api.Peer) config.Neighbor {
+ var pconf config.Neighbor
+ if a.Conf != nil {
+ pconf.NeighborAddress = net.ParseIP(a.Conf.NeighborAddress)
+ pconf.NeighborConfig.PeerAs = a.Conf.PeerAs
+ pconf.NeighborConfig.LocalAs = a.Conf.LocalAs
+ if pconf.NeighborConfig.PeerAs != server.bgpConfig.Global.GlobalConfig.As {
+ pconf.NeighborConfig.PeerType = config.PEER_TYPE_EXTERNAL
+ } else {
+ pconf.NeighborConfig.PeerType = config.PEER_TYPE_INTERNAL
+ }
+ pconf.NeighborConfig.AuthPassword = a.Conf.AuthPassword
+ pconf.NeighborConfig.RemovePrivateAs = config.RemovePrivateAsOption(a.Conf.RemovePrivateAs)
+ pconf.NeighborConfig.RouteFlapDamping = a.Conf.RouteFlapDamping
+ pconf.NeighborConfig.SendCommunity = config.CommunityType(a.Conf.SendCommunity)
+ pconf.NeighborConfig.Description = a.Conf.Description
+ pconf.NeighborConfig.PeerGroup = a.Conf.PeerGroup
+ pconf.NeighborConfig.NeighborAddress = net.ParseIP(a.Conf.NeighborAddress)
+ }
+ if a.Timers != nil {
+ if a.Timers.Config != nil {
+ pconf.Timers.TimersConfig.ConnectRetry = float64(a.Timers.Config.ConnectRetry)
+ pconf.Timers.TimersConfig.HoldTime = float64(a.Timers.Config.HoldTime)
+ pconf.Timers.TimersConfig.KeepaliveInterval = float64(a.Timers.Config.KeepaliveInterval)
+ pconf.Timers.TimersConfig.MinimumAdvertisementInterval = float64(a.Timers.Config.MinimumAdvertisementInterval)
+ }
+ } else {
+ pconf.Timers.TimersConfig.ConnectRetry = float64(config.DEFAULT_CONNECT_RETRY)
+ pconf.Timers.TimersConfig.HoldTime = float64(config.DEFAULT_HOLDTIME)
+ pconf.Timers.TimersConfig.KeepaliveInterval = float64(config.DEFAULT_HOLDTIME / 3)
+ }
+ if a.RouteReflector != nil {
+ pconf.RouteReflector.RouteReflectorConfig.RouteReflectorClusterId = config.RrClusterIdType(a.RouteReflector.RouteReflectorClusterId)
+ pconf.RouteReflector.RouteReflectorConfig.RouteReflectorClient = a.RouteReflector.RouteReflectorClient
+ }
+ if a.RouteServer != nil {
+ pconf.RouteServer.RouteServerConfig.RouteServerClient = a.RouteServer.RouteServerClient
+ }
+ if a.ApplyPolicy != nil {
+ if a.ApplyPolicy.ImportPolicy != nil {
+ pconf.ApplyPolicy.ApplyPolicyConfig.DefaultImportPolicy = config.DefaultPolicyType(a.ApplyPolicy.ImportPolicy.Default)
+ for _, p := range a.ApplyPolicy.ImportPolicy.Policies {
+ pconf.ApplyPolicy.ApplyPolicyConfig.ImportPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.ImportPolicy, p.Name)
+ }
+ }
+ if a.ApplyPolicy.ExportPolicy != nil {
+ pconf.ApplyPolicy.ApplyPolicyConfig.DefaultExportPolicy = config.DefaultPolicyType(a.ApplyPolicy.ExportPolicy.Default)
+ for _, p := range a.ApplyPolicy.ExportPolicy.Policies {
+ pconf.ApplyPolicy.ApplyPolicyConfig.ExportPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.ExportPolicy, p.Name)
+ }
+ }
+ if a.ApplyPolicy.InPolicy != nil {
+ pconf.ApplyPolicy.ApplyPolicyConfig.DefaultInPolicy = config.DefaultPolicyType(a.ApplyPolicy.InPolicy.Default)
+ for _, p := range a.ApplyPolicy.InPolicy.Policies {
+ pconf.ApplyPolicy.ApplyPolicyConfig.InPolicy = append(pconf.ApplyPolicy.ApplyPolicyConfig.InPolicy, p.Name)
+ }
+ }
+ }
+ return pconf
+ }
+ configneigh := apitoConfig(arg.Peer)
+ peer := NewPeer(server.bgpConfig.Global, configneigh, loc)
+ server.setPolicyByConfig(peer, configneigh.ApplyPolicy)
+ if peer.isRouteServerClient() {
+ pathList := make([]*table.Path, 0)
+ rfList := peer.configuredRFlist()
+ for _, p := range server.neighborMap {
+ if p.isRouteServerClient() == true {
+ pathList = append(pathList, p.getAccepted(rfList)...)
+ }
+ }
+ pathList, _ = peer.ApplyPolicy(table.POLICY_DIRECTION_IMPORT, pathList)
+ if len(pathList) > 0 {
+ peer.localRib.ProcessPaths(pathList)
+ }
+ }
+ server.neighborMap[addr] = peer
+ peer.startFSMHandler(server.fsmincomingCh)
+ server.broadcastPeerState(peer)
+ case api.Operation_DEL:
+ SetTcpMD5SigSockopts(listener(net.ParseIP(addr)), 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) })
+ n.fsm.h.t.Kill(nil)
+ n.fsm.h.t.Wait()
+ t.Stop()
+ t = time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h for ", addr) })
+ n.fsm.t.Kill(nil)
+ n.fsm.t.Wait()
+ t.Stop()
+ }(addr)
+ m := server.dropPeerAllRoutes(n)
+ if len(m) > 0 {
+ sMsgs = append(sMsgs, m...)
+ }
+ delete(server.neighborMap, addr)
+ }
+ return sMsgs, err
+}
func (server *BgpServer) handleGrpcModDefinedSet(grpcReq *GrpcRequest) error {
arg := grpcReq.Data.(*api.ModDefinedSetArguments)