summaryrefslogtreecommitdiffhomepage
path: root/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go999
1 files changed, 852 insertions, 147 deletions
diff --git a/server/server.go b/server/server.go
index 930e1067..d87bb742 100644
--- a/server/server.go
+++ b/server/server.go
@@ -16,43 +16,30 @@
package server
import (
+ "encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
+ "github.com/osrg/gobgp/packet"
"github.com/osrg/gobgp/policy"
+ "github.com/osrg/gobgp/table"
+ "gopkg.in/tomb.v2"
"net"
"os"
"strconv"
+ "time"
)
-type serverMsgType int
-
const (
- _ serverMsgType = iota
- SRV_MSG_PEER_ADDED
- SRV_MSG_PEER_DELETED
- SRV_MSG_API
- SRV_MSG_POLICY_UPDATED
+ GLOBAL_RIB_NAME = "global"
)
-type serverMsg struct {
- msgType serverMsgType
- msgData interface{}
-}
-
-type serverMsgDataPeer struct {
- peerMsgCh chan *peerMsg
- address net.IP
- As uint32
-}
-
-type peerMapInfo struct {
- peer *Peer
- serverMsgCh chan *serverMsg
- peerMsgCh chan *peerMsg
- peerMsgData *serverMsgDataPeer
- isRouteServerClient bool
+type SenderMsg struct {
+ messages []*bgp.BGPMessage
+ sendCh chan *bgp.BGPMessage
+ destination string
+ twoBytesAs bool
}
type BgpServer struct {
@@ -62,11 +49,12 @@ type BgpServer struct {
deletedPeerCh chan config.Neighbor
GrpcReqCh chan *GrpcRequest
listenPort int
- peerMap map[string]peerMapInfo
- globalRib *Peer
policyUpdateCh chan config.RoutingPolicy
policyMap map[string]*policy.Policy
routingPolicy config.RoutingPolicy
+
+ neighborMap map[string]*Peer
+ localRibMap map[string]*LocalRib
}
func NewBgpServer(port int) *BgpServer {
@@ -76,6 +64,8 @@ func NewBgpServer(port int) *BgpServer {
b.deletedPeerCh = make(chan config.Neighbor)
b.GrpcReqCh = make(chan *GrpcRequest, 1)
b.policyUpdateCh = make(chan config.RoutingPolicy)
+ b.localRibMap = make(map[string]*LocalRib)
+ b.neighborMap = make(map[string]*Peer)
b.listenPort = port
return &b
}
@@ -107,18 +97,50 @@ func listenAndAccept(proto string, port int, ch chan *net.TCPConn) (*net.TCPList
return l, nil
}
+func (server *BgpServer) addLocalRib(rib *LocalRib) {
+ server.localRibMap[rib.OwnerName()] = rib
+}
+
func (server *BgpServer) Serve() {
g := <-server.globalTypeCh
server.bgpConfig.Global = g
- globalSch := make(chan *serverMsg, 8)
- globalPch := make(chan *peerMsg, 4096)
- neighConf := config.Neighbor{
- NeighborAddress: g.RouterId,
- AfiSafiList: g.AfiSafiList,
- PeerAs: g.As,
- }
- server.globalRib = NewPeer(g, neighConf, globalSch, globalPch, nil, true, make(map[string]*policy.Policy))
+ senderCh := make(chan *SenderMsg, 1<<16)
+ go func(ch chan *SenderMsg) {
+ for {
+ // TODO: must be more clever. Slow peer makes other peers slow too.
+ m := <-ch
+ w := func(c chan *bgp.BGPMessage, msg *bgp.BGPMessage) {
+ // nasty but the peer could already become non established state before here.
+ defer func() { recover() }()
+ c <- msg
+ }
+
+ for _, b := range m.messages {
+ if m.twoBytesAs == false && b.Header.Type == bgp.BGP_MSG_UPDATE {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": m.destination,
+ "Data": b,
+ }).Debug("update for 2byte AS peer")
+ table.UpdatePathAttrs2ByteAs(b.Body.(*bgp.BGPUpdate))
+ }
+ w(m.sendCh, b)
+ }
+ }
+ }(senderCh)
+
+ // FIXME
+ rfList := func(l []config.AfiSafi) []bgp.RouteFamily {
+ rfList := []bgp.RouteFamily{}
+ for _, rf := range l {
+ k, _ := bgp.GetRouteFamily(rf.AfiSafiName)
+ rfList = append(rfList, k)
+ }
+ return rfList
+ }(g.AfiSafiList)
+
+ server.addLocalRib(NewLocalRib(GLOBAL_RIB_NAME, rfList, make(map[string]*policy.Policy)))
listenerMap := make(map[string]*net.TCPListener)
acceptCh := make(chan *net.TCPConn)
@@ -141,100 +163,372 @@ func (server *BgpServer) Serve() {
return l
}
- server.peerMap = make(map[string]peerMapInfo)
+ incoming := make(chan *fsmMsg, 4096)
+ var senderMsgs []*SenderMsg
for {
+ var firstMsg *SenderMsg
+ var sCh chan *SenderMsg
+ if len(senderMsgs) > 0 {
+ sCh = senderCh
+ firstMsg = senderMsgs[0]
+ }
select {
case conn := <-acceptCh:
remoteAddr, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
- info, found := server.peerMap[remoteAddr]
+ peer, found := server.neighborMap[remoteAddr]
if found {
log.Debug("accepted a new passive connection from ", remoteAddr)
- info.peer.PassConn(conn)
+ peer.PassConn(conn)
} else {
log.Info("can't find configuration for a new passive connection from ", remoteAddr)
conn.Close()
}
- case peer := <-server.addedPeerCh:
- addr := peer.NeighborAddress.String()
- SetTcpMD5SigSockopts(listener(peer.NeighborAddress), addr, peer.AuthPassword)
- sch := make(chan *serverMsg, 8)
- pch := make(chan *peerMsg, 4096)
- var l []*serverMsgDataPeer
- if peer.RouteServer.RouteServerClient {
- for _, v := range server.peerMap {
- if v.isRouteServerClient {
- l = append(l, v.peerMsgData)
+ case config := <-server.addedPeerCh:
+ addr := config.NeighborAddress.String()
+ _, found := server.neighborMap[addr]
+ if found {
+ log.Warn("Can't overwrite the exising peer ", addr)
+ continue
+ }
+
+ SetTcpMD5SigSockopts(listener(config.NeighborAddress), addr, config.AuthPassword)
+
+ peer := NewPeer(g, config)
+ name := config.NeighborAddress.String()
+
+ if config.RouteServer.RouteServerClient == true {
+ loc := NewLocalRib(name, peer.configuredRFlist(), make(map[string]*policy.Policy))
+ server.addLocalRib(loc)
+ loc.setPolicy(peer, server.policyMap)
+
+ pathList := make([]table.Path, 0)
+ for _, p := range server.neighborMap {
+ if p.isRouteServerClient() == false {
+ continue
+ }
+ for _, rf := range peer.configuredRFlist() {
+ pathList = append(pathList, p.adjRib.GetInPathList(rf)...)
}
}
- } else {
- globalRib := &serverMsgDataPeer{
- address: server.bgpConfig.Global.RouterId,
- peerMsgCh: globalPch,
+ pathList = applyPolicies(peer, loc, false, pathList)
+ if len(pathList) > 0 {
+ loc.rib.ProcessPaths(pathList)
}
- l = []*serverMsgDataPeer{globalRib}
- }
- p := NewPeer(server.bgpConfig.Global, peer, sch, pch, l, false, server.policyMap)
- d := &serverMsgDataPeer{
- address: peer.NeighborAddress,
- peerMsgCh: pch,
- As: peer.PeerAs,
- }
- msg := &serverMsg{
- msgType: SRV_MSG_PEER_ADDED,
- msgData: d,
- }
- if peer.RouteServer.RouteServerClient {
- sendServerMsgToRSClients(server.peerMap, msg)
- } else {
- globalSch <- msg
}
+ server.neighborMap[name] = peer
+ peer.outgoing = make(chan *bgp.BGPMessage, 128)
+ peer.startFSMHandler(incoming)
- server.peerMap[peer.NeighborAddress.String()] = peerMapInfo{
- peer: p,
- serverMsgCh: sch,
- peerMsgData: d,
- isRouteServerClient: peer.RouteServer.RouteServerClient,
- }
- case peer := <-server.deletedPeerCh:
- addr := peer.NeighborAddress.String()
- SetTcpMD5SigSockopts(listener(peer.NeighborAddress), addr, "")
- info, found := server.peerMap[addr]
+ case config := <-server.deletedPeerCh:
+ addr := config.NeighborAddress.String()
+ SetTcpMD5SigSockopts(listener(config.NeighborAddress), addr, "")
+ peer, found := server.neighborMap[addr]
if found {
log.Info("Delete a peer configuration for ", addr)
- info.peer.Stop()
- delete(server.peerMap, addr)
- msg := &serverMsg{
- msgType: SRV_MSG_PEER_DELETED,
- msgData: info.peer.peerInfo,
+ go func(addr string) {
+ t := time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h.t for ", addr) })
+ peer.fsm.h.t.Kill(nil)
+ peer.fsm.h.t.Wait()
+ t.Stop()
+ t = time.AfterFunc(time.Minute*5, func() { log.Fatal("failed to free the fsm.h for ", addr) })
+ peer.fsm.t.Kill(nil)
+ peer.fsm.t.Wait()
+ t.Stop()
+ }(addr)
+
+ m := server.dropPeerAllRoutes(peer)
+ if len(m) > 0 {
+ senderMsgs = append(senderMsgs, m...)
}
- if info.isRouteServerClient {
- sendServerMsgToRSClients(server.peerMap, msg)
- } else {
- globalSch <- msg
+ delete(server.neighborMap, addr)
+ if peer.isRouteServerClient() {
+ delete(server.localRibMap, addr)
}
} else {
log.Info("Can't delete a peer configuration for ", addr)
}
+ case e := <-incoming:
+ peer, found := server.neighborMap[e.MsgSrc]
+ if !found {
+ log.Warn("Can't find the neighbor ", e.MsgSrc)
+ break
+ }
+ m := server.handleFSMMessage(peer, e, incoming)
+ if len(m) > 0 {
+ senderMsgs = append(senderMsgs, m...)
+ }
+ case sCh <- firstMsg:
+ senderMsgs = senderMsgs[1:]
+
case grpcReq := <-server.GrpcReqCh:
- server.handleGrpc(grpcReq)
+ m := server.handleGrpc(grpcReq)
+ if len(m) > 0 {
+ senderMsgs = append(senderMsgs, m...)
+ }
case pl := <-server.policyUpdateCh:
server.handlePolicy(pl)
}
}
}
-func sendServerMsgToAll(peerMap map[string]peerMapInfo, msg *serverMsg) {
- for _, info := range peerMap {
- info.serverMsgCh <- msg
+func dropSameAsPath(asnum uint32, p []table.Path) []table.Path {
+ pathList := []table.Path{}
+ for _, path := range p {
+ asList := path.GetAsList()
+ send := true
+ for _, as := range asList {
+ if as == asnum {
+ send = false
+ break
+ }
+ }
+ if send {
+ pathList = append(pathList, path)
+ }
+ }
+ return pathList
+}
+
+func newSenderMsg(peer *Peer, messages []*bgp.BGPMessage) *SenderMsg {
+ _, y := peer.capMap[bgp.BGP_CAP_FOUR_OCTET_AS_NUMBER]
+ return &SenderMsg{
+ messages: messages,
+ sendCh: peer.outgoing,
+ destination: peer.config.NeighborAddress.String(),
+ twoBytesAs: y,
+ }
+}
+
+func filterpath(peer *Peer, pathList []table.Path) []table.Path {
+ filtered := make([]table.Path, 0)
+
+ for _, path := range pathList {
+ if _, ok := peer.rfMap[path.GetRouteFamily()]; !ok {
+ continue
+ }
+
+ if peer.config.NeighborAddress.Equal(path.GetSource().Address) {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ "Data": path,
+ }).Debug("From me, ignore.")
+ continue
+ }
+
+ if peer.config.PeerAs == path.GetSourceAs() {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ "Data": path,
+ }).Debug("AS PATH loop, ignore.")
+ continue
+ }
+ filtered = append(filtered, path.Clone(path.IsWithdraw()))
+ }
+ return filtered
+}
+
+func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg {
+ msgs := make([]*SenderMsg, 0)
+
+ for _, rf := range peer.configuredRFlist() {
+ if peer.isRouteServerClient() {
+ for _, loc := range server.localRibMap {
+ targetPeer := server.neighborMap[loc.OwnerName()]
+ if loc.isGlobal() || loc.OwnerName() == peer.config.NeighborAddress.String() {
+ continue
+ }
+ pathList, _ := loc.rib.DeletePathsforPeer(peer.peerInfo, rf)
+ pathList = dropSameAsPath(targetPeer.config.PeerAs, pathList)
+ if targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED || len(pathList) == 0 {
+ continue
+ }
+ msgList := table.CreateUpdateMsgFromPaths(pathList)
+ msgs = append(msgs, newSenderMsg(targetPeer, msgList))
+ targetPeer.adjRib.UpdateOut(pathList)
+ }
+ } else {
+ loc := server.localRibMap[GLOBAL_RIB_NAME]
+ pathList, _ := loc.rib.DeletePathsforPeer(peer.peerInfo, rf)
+ if len(pathList) == 0 {
+ continue
+ }
+ msgList := table.CreateUpdateMsgFromPaths(pathList)
+ for _, targetPeer := range server.neighborMap {
+ if targetPeer.isRouteServerClient() || targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED {
+ continue
+ }
+ targetPeer.adjRib.UpdateOut(pathList)
+ msgs = append(msgs, newSenderMsg(targetPeer, msgList))
+ }
+ }
+ }
+ return msgs
+}
+
+func applyPolicies(peer *Peer, loc *LocalRib, isExport bool, pathList []table.Path) []table.Path {
+ var defaultPolicy config.DefaultPolicyType
+ if isExport == true {
+ defaultPolicy = loc.defaultExportPolicy
+ } else {
+ defaultPolicy = loc.defaultImportPolicy
+ }
+
+ ret := make([]table.Path, 0, len(pathList))
+ for _, path := range pathList {
+ if !path.IsWithdraw() {
+ var applied bool = false
+ applied, path = loc.applyPolicies(isExport, path)
+ if applied {
+ if path == nil {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ "Data": path,
+ }).Debug("Policy applied and rejected.")
+ continue
+ }
+ } else if defaultPolicy != config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ "Data": path,
+ }).Debug("Default policy applied and rejected.")
+ continue
+ }
+ }
+ // FIXME: probably we already clone.
+ ret = append(ret, path.Clone(path.IsWithdraw()))
}
+ return ret
}
-func sendServerMsgToRSClients(peerMap map[string]peerMapInfo, msg *serverMsg) {
- for _, info := range peerMap {
- if info.isRouteServerClient {
- info.serverMsgCh <- msg
+func (server *BgpServer) propagateUpdate(neighborAddress string, RouteServerClient bool, pathList []table.Path) []*SenderMsg {
+ msgs := make([]*SenderMsg, 0)
+
+ if RouteServerClient {
+ for _, loc := range server.localRibMap {
+ targetPeer := server.neighborMap[loc.OwnerName()]
+ if loc.isGlobal() || loc.OwnerName() == neighborAddress {
+ continue
+ }
+ sendPathList, _ := loc.rib.ProcessPaths(applyPolicies(targetPeer, loc, false, dropSameAsPath(targetPeer.config.PeerAs, filterpath(targetPeer, pathList))))
+ if targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED || len(sendPathList) == 0 {
+ continue
+ }
+ sendPathList = applyPolicies(targetPeer, loc, true, sendPathList)
+ if len(sendPathList) == 0 {
+ continue
+ }
+ msgList := table.CreateUpdateMsgFromPaths(sendPathList)
+ targetPeer.adjRib.UpdateOut(sendPathList)
+ msgs = append(msgs, newSenderMsg(targetPeer, msgList))
+ }
+ } else {
+ globalLoc := server.localRibMap[GLOBAL_RIB_NAME]
+ sendPathList, _ := globalLoc.rib.ProcessPaths(pathList)
+ if len(sendPathList) == 0 {
+ return msgs
+ }
+
+ for _, targetPeer := range server.neighborMap {
+ if targetPeer.isRouteServerClient() || targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED {
+ continue
+ }
+ f := filterpath(targetPeer, sendPathList)
+ for _, path := range f {
+ path.SetNexthop(targetPeer.config.LocalAddress)
+ }
+ targetPeer.adjRib.UpdateOut(f)
+ msgList := table.CreateUpdateMsgFromPaths(f)
+ msgs = append(msgs, newSenderMsg(targetPeer, msgList))
}
}
+ return msgs
+}
+
+func (server *BgpServer) handleFSMMessage(peer *Peer, e *fsmMsg, incoming chan *fsmMsg) []*SenderMsg {
+ msgs := make([]*SenderMsg, 0)
+
+ switch e.MsgType {
+ case FSM_MSG_STATE_CHANGE:
+ nextState := e.MsgData.(bgp.FSMState)
+ oldState := bgp.FSMState(peer.config.BgpNeighborCommonState.State)
+ go func(t *tomb.Tomb, addr string, oldState, newState bgp.FSMState) {
+ e := time.AfterFunc(time.Second*30, func() { log.Fatal("failed to free the fsm.h.t for ", addr, oldState, newState) })
+ t.Wait()
+ e.Stop()
+ }(&peer.fsm.h.t, peer.config.NeighborAddress.String(), oldState, nextState)
+ peer.config.BgpNeighborCommonState.State = uint32(nextState)
+ peer.fsm.StateChange(nextState)
+ globalRib := server.localRibMap[GLOBAL_RIB_NAME]
+
+ if oldState == bgp.BGP_FSM_ESTABLISHED {
+ t := time.Now()
+ if t.Sub(time.Unix(peer.config.BgpNeighborCommonState.Uptime, 0)) < FLOP_THRESHOLD {
+ peer.config.BgpNeighborCommonState.Flops++
+ }
+
+ for _, rf := range peer.configuredRFlist() {
+ peer.adjRib.DropAll(rf)
+ }
+
+ msgs = append(msgs, server.dropPeerAllRoutes(peer)...)
+ }
+
+ close(peer.outgoing)
+ peer.outgoing = make(chan *bgp.BGPMessage, 128)
+ if nextState == bgp.BGP_FSM_ESTABLISHED {
+ pathList := make([]table.Path, 0)
+ if peer.isRouteServerClient() {
+ loc := server.localRibMap[peer.config.NeighborAddress.String()]
+ pathList = applyPolicies(peer, loc, true, peer.getBests(loc))
+ } else {
+ peer.config.LocalAddress = peer.fsm.LocalAddr()
+ for _, path := range peer.getBests(globalRib) {
+ p := path.Clone(path.IsWithdraw())
+ p.SetNexthop(peer.config.LocalAddress)
+ pathList = append(pathList, p)
+ }
+ }
+ if len(pathList) > 0 {
+ peer.adjRib.UpdateOut(pathList)
+ msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(pathList)))
+ }
+ } else {
+ peer.config.BgpNeighborCommonState.Downtime = time.Now().Unix()
+ }
+ // clear counter
+ if peer.fsm.adminState == ADMIN_STATE_DOWN {
+ peer.config.BgpNeighborCommonState = config.BgpNeighborCommonState{}
+ }
+ peer.startFSMHandler(incoming)
+
+ case FSM_MSG_BGP_MESSAGE:
+ switch m := e.MsgData.(type) {
+ case *bgp.MessageError:
+ msgs = append(msgs, newSenderMsg(peer, []*bgp.BGPMessage{bgp.NewBGPNotificationMessage(m.TypeCode, m.SubTypeCode, m.Data)}))
+ case *bgp.BGPMessage:
+ pathList, update := peer.handleBGPmessage(m)
+ if update == false {
+ if len(pathList) > 0 {
+ msgList := table.CreateUpdateMsgFromPaths(pathList)
+ msgs = append(msgs, newSenderMsg(peer, msgList))
+ }
+ break
+ }
+ msgs = append(msgs, server.propagateUpdate(peer.config.NeighborAddress.String(),
+ peer.isRouteServerClient(), pathList)...)
+ default:
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ "Data": e.MsgData,
+ }).Panic("unknonw msg type")
+ }
+ }
+ return msgs
}
func (server *BgpServer) SetGlobalType(g config.Global) {
@@ -265,80 +559,483 @@ func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) {
func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) {
server.SetPolicy(pl)
- msg := &serverMsg{
- msgType: SRV_MSG_POLICY_UPDATED,
- msgData: server.policyMap,
+ for _, loc := range server.localRibMap {
+ if loc.isGlobal() {
+ continue
+ }
+ targetPeer := server.neighborMap[loc.OwnerName()]
+ loc.setPolicy(targetPeer, server.policyMap)
+ }
+}
+
+func (server *BgpServer) checkNeighborRequest(grpcReq *GrpcRequest) (*Peer, error) {
+ remoteAddr := grpcReq.RemoteAddr
+ peer, found := server.neighborMap[remoteAddr]
+ if !found {
+ result := &GrpcResponse{}
+ result.ResponseErr = fmt.Errorf("Neighbor that has %v doesn't exist.", remoteAddr)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return nil, result.ResponseErr
+ }
+ return peer, nil
+}
+
+func handleGlobalRibRequest(grpcReq *GrpcRequest, peerInfo *table.PeerInfo) []table.Path {
+ pathList := []table.Path{}
+ result := &GrpcResponse{}
+
+ rf := grpcReq.RouteFamily
+ path, ok := grpcReq.Data.(*api.Path)
+ if !ok {
+ result.ResponseErr = fmt.Errorf("type assertion failed")
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+ var isWithdraw bool
+ if grpcReq.RequestType == REQ_GLOBAL_DELETE {
+ isWithdraw = true
+ }
+
+ var nlri bgp.AddrPrefixInterface
+ pattr := make([]bgp.PathAttributeInterface, 0)
+ pattr = append(pattr, bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP))
+ asparam := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{peerInfo.AS})
+ pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
+
+ switch rf {
+ case bgp.RF_IPv4_UC:
+ ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
+ if ip.To4() == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", path.Nlri.Prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+ ones, _ := net.Mask.Size()
+ nlri = &bgp.NLRInfo{
+ IPAddrPrefix: *bgp.NewIPAddrPrefix(uint8(ones), ip.String()),
+ }
+
+ pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0"))
+
+ case bgp.RF_IPv6_UC:
+
+ ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
+ if ip.To16() == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", path.Nlri.Prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+ ones, _ := net.Mask.Size()
+ nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
+
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri}))
+
+ case bgp.RF_EVPN:
+ mac, err := net.ParseMAC(path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
+ if err != nil {
+ result.ResponseErr = fmt.Errorf("Invalid mac: %s", path.Nlri.EvpnNlri.MacIpAdv.MacAddr)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+ ip := net.ParseIP(path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
+ if ip == nil {
+ result.ResponseErr = fmt.Errorf("Invalid ip prefix: %s", path.Nlri.EvpnNlri.MacIpAdv.IpAddr)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+ iplen := net.IPv4len * 8
+ if ip.To4() == nil {
+ iplen = net.IPv6len * 8
+ }
+
+ macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
+ RD: bgp.NewRouteDistinguisherTwoOctetAS(0, 0),
+ ESI: bgp.EthernetSegmentIdentifier{
+ Type: bgp.ESI_ARBITRARY,
+ },
+ MacAddressLength: 48,
+ MacAddress: mac,
+ IPAddressLength: uint8(iplen),
+ IPAddress: ip,
+ Labels: []uint32{0},
+ }
+ nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri}))
+ case bgp.RF_ENCAP:
+ endpoint := net.ParseIP(path.Nlri.Prefix)
+ if endpoint == nil {
+ result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+
+ }
+ nlri = bgp.NewEncapNLRI(endpoint.String())
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri}))
+
+ iterSubTlvs := func(subTlvs []*api.TunnelEncapSubTLV) {
+ for _, subTlv := range subTlvs {
+ if subTlv.Type == api.ENCAP_SUBTLV_TYPE_COLOR {
+ color := subTlv.Color
+ subTlv := &bgp.TunnelEncapSubTLV{
+ Type: bgp.ENCAP_SUBTLV_TYPE_COLOR,
+ Value: &bgp.TunnelEncapSubTLVColor{color},
+ }
+ tlv := &bgp.TunnelEncapTLV{
+ Type: bgp.TUNNEL_TYPE_VXLAN,
+ Value: []*bgp.TunnelEncapSubTLV{subTlv},
+ }
+ attr := bgp.NewPathAttributeTunnelEncap([]*bgp.TunnelEncapTLV{tlv})
+ pattr = append(pattr, attr)
+ break
+ }
+ }
+ }
+
+ iterTlvs := func(tlvs []*api.TunnelEncapTLV) {
+ for _, tlv := range tlvs {
+ if tlv.Type == api.TUNNEL_TYPE_VXLAN {
+ iterSubTlvs(tlv.SubTlv)
+ break
+ }
+ }
+ }
+
+ func(attrs []*api.PathAttr) {
+ for _, attr := range attrs {
+ if attr.Type == api.BGP_ATTR_TYPE_TUNNEL_ENCAP {
+ iterTlvs(attr.TunnelEncap)
+ break
+ }
+ }
+ }(path.Attrs)
+
+ case bgp.RF_RTC_UC:
+ var ec bgp.ExtendedCommunityInterface
+ target := path.Nlri.RtNlri.Target
+ ec_type := target.Type
+ ec_subtype := target.Subtype
+ switch ec_type {
+ case api.EXTENDED_COMMUNITIE_TYPE_TWO_OCTET_AS_SPECIFIC:
+ if target.Asn == 0 && target.LocalAdmin == 0 {
+ break
+ }
+ ec = &bgp.TwoOctetAsSpecificExtended{
+ SubType: bgp.ExtendedCommunityAttrSubType(ec_subtype),
+ AS: uint16(target.Asn),
+ LocalAdmin: target.LocalAdmin,
+ IsTransitive: true,
+ }
+ default:
+ result.ResponseErr = fmt.Errorf("Invalid endpoint ip address: %s", path.Nlri.Prefix)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+
+ nlri = bgp.NewRouteTargetMembershipNLRI(peerInfo.AS, ec)
+
+ pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri}))
+
+ default:
+ result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf)
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
+ }
+
+ p, err := table.CreatePath(peerInfo, nlri, pattr, isWithdraw, time.Now())
+ if err != nil {
+ result.ResponseErr = err
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return pathList
}
- sendServerMsgToAll(server.peerMap, msg)
+ return []table.Path{p}
}
-func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
+func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
+ msgs := make([]*SenderMsg, 0)
+
switch grpcReq.RequestType {
+ case REQ_GLOBAL_RIB:
+ if t, ok := server.localRibMap[GLOBAL_RIB_NAME].rib.Tables[grpcReq.RouteFamily]; ok {
+ for _, dst := range t.GetDestinations() {
+ result := &GrpcResponse{}
+ result.Data = dst.ToApiStruct()
+ grpcReq.ResponseCh <- result
+ }
+ }
+ close(grpcReq.ResponseCh)
+
+ case REQ_GLOBAL_ADD, REQ_GLOBAL_DELETE:
+ pi := &table.PeerInfo{
+ AS: server.bgpConfig.Global.As,
+ LocalID: server.bgpConfig.Global.RouterId,
+ }
+ pathList := handleGlobalRibRequest(grpcReq, pi)
+ if len(pathList) > 0 {
+ server.propagateUpdate("", false, pathList)
+ grpcReq.ResponseCh <- &GrpcResponse{}
+ close(grpcReq.ResponseCh)
+ }
+
case REQ_NEIGHBORS:
- for _, info := range server.peerMap {
+ for _, peer := range server.neighborMap {
result := &GrpcResponse{
- Data: info.peer.ToApiStruct(),
+ Data: peer.ToApiStruct(),
}
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
+
case REQ_NEIGHBOR:
- remoteAddr := grpcReq.RemoteAddr
- var result *GrpcResponse
- info, found := server.peerMap[remoteAddr]
- if found {
- result = &GrpcResponse{
- Data: info.peer.ToApiStruct(),
- }
- } else {
- result = &GrpcResponse{
- ResponseErr: fmt.Errorf("Neighbor that has %v doesn't exist.", remoteAddr),
- }
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ result := &GrpcResponse{
+ Data: peer.ToApiStruct(),
}
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
- case REQ_GLOBAL_RIB, REQ_GLOBAL_ADD, REQ_GLOBAL_DELETE:
- msg := &serverMsg{
- msgType: SRV_MSG_API,
- msgData: grpcReq,
- }
- server.globalRib.serverMsgCh <- msg
- case REQ_LOCAL_RIB, REQ_NEIGHBOR_SHUTDOWN, REQ_NEIGHBOR_RESET,
- REQ_NEIGHBOR_SOFT_RESET, REQ_NEIGHBOR_SOFT_RESET_IN, REQ_NEIGHBOR_SOFT_RESET_OUT,
- REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT,
- REQ_NEIGHBOR_ENABLE, REQ_NEIGHBOR_DISABLE,
- REQ_NEIGHBOR_POLICY:
- remoteAddr := grpcReq.RemoteAddr
- result := &GrpcResponse{}
- info, found := server.peerMap[remoteAddr]
- if found {
- msg := &serverMsg{
- msgType: SRV_MSG_API,
- msgData: grpcReq,
+
+ case REQ_LOCAL_RIB:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ if peer.fsm.adminState != ADMIN_STATE_DOWN {
+ remoteAddr := grpcReq.RemoteAddr
+ if t, ok := server.localRibMap[remoteAddr].rib.Tables[grpcReq.RouteFamily]; ok {
+ for _, dst := range t.GetDestinations() {
+ result := &GrpcResponse{}
+ result.Data = dst.ToApiStruct()
+ grpcReq.ResponseCh <- result
+ }
}
- info.peer.serverMsgCh <- msg
+ }
+ close(grpcReq.ResponseCh)
+
+ case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ rf := grpcReq.RouteFamily
+ var paths []table.Path
+
+ if grpcReq.RequestType == REQ_ADJ_RIB_IN {
+ paths = peer.adjRib.GetInPathList(rf)
+ log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths))
} else {
- result.ResponseErr = fmt.Errorf("Neighbor that has %v doesn't exist.", remoteAddr)
+ paths = peer.adjRib.GetOutPathList(rf)
+ log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths))
+ }
+
+ for _, p := range paths {
+ result := &GrpcResponse{}
+ path := &api.Path{}
+ j, _ := json.Marshal(p)
+ err := json.Unmarshal(j, path)
+ if err != nil {
+ result.ResponseErr = err
+ } else {
+ result.Data = path
+ }
grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
+
+ case REQ_NEIGHBOR_SHUTDOWN:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ m := bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil)
+ msgs = append(msgs, newSenderMsg(peer, []*bgp.BGPMessage{m}))
+ grpcReq.ResponseCh <- &GrpcResponse{}
+ close(grpcReq.ResponseCh)
+
+ case REQ_NEIGHBOR_RESET:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ peer.fsm.idleHoldTime = peer.config.Timers.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)
+ if err != nil {
+ break
+ }
+ // soft-reconfiguration inbound
+ pathList := peer.adjRib.GetInPathList(grpcReq.RouteFamily)
+ msgs = append(msgs, server.propagateUpdate(peer.config.NeighborAddress.String(),
+ peer.isRouteServerClient(), pathList)...)
+
+ if grpcReq.RequestType == REQ_NEIGHBOR_SOFT_RESET_IN {
+ grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)
+ break
}
- case REQ_NEIGHBOR_POLICY_ADD_IMPORT, REQ_NEIGHBOR_POLICY_ADD_EXPORT, REQ_NEIGHBOR_POLICY_DEL_IMPORT, REQ_NEIGHBOR_POLICY_DEL_EXPORT:
- remoteAddr := grpcReq.RemoteAddr
+ fallthrough
+ case REQ_NEIGHBOR_SOFT_RESET_OUT:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ pathList := peer.adjRib.GetOutPathList(grpcReq.RouteFamily)
+ msgList := table.CreateUpdateMsgFromPaths(pathList)
+ msgs = append(msgs, newSenderMsg(peer, msgList))
+ grpcReq.ResponseCh <- &GrpcResponse{}
+ close(grpcReq.ResponseCh)
+
+ case REQ_NEIGHBOR_ENABLE, REQ_NEIGHBOR_DISABLE:
+ peer, err1 := server.checkNeighborRequest(grpcReq)
+ if err1 != nil {
+ break
+ }
+ var err api.Error
result := &GrpcResponse{}
- info, found := server.peerMap[remoteAddr]
- if found {
- reqApplyPolicy := grpcReq.Data.(*api.ApplyPolicy)
- grpcReq.Data = []interface{}{reqApplyPolicy, server.policyMap}
- msg := &serverMsg{
- msgType: SRV_MSG_API,
- msgData: grpcReq,
- }
- info.peer.serverMsgCh <- msg
+ if grpcReq.RequestType == REQ_NEIGHBOR_ENABLE {
+ select {
+ case peer.fsm.adminStateCh <- ADMIN_STATE_UP:
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ }).Debug("ADMIN_STATE_UP requested")
+ err.Code = api.Error_SUCCESS
+ err.Msg = "ADMIN_STATE_UP"
+ default:
+ log.Warning("previous request is still remaining. : ", peer.config.NeighborAddress)
+ err.Code = api.Error_FAIL
+ err.Msg = "previous request is still remaining"
+ }
} else {
- result.ResponseErr = fmt.Errorf("Neighbor that has %v doesn't exist.", remoteAddr)
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
+ select {
+ case peer.fsm.adminStateCh <- ADMIN_STATE_DOWN:
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": peer.config.NeighborAddress,
+ }).Debug("ADMIN_STATE_DOWN requested")
+ err.Code = api.Error_SUCCESS
+ err.Msg = "ADMIN_STATE_DOWN"
+ default:
+ log.Warning("previous request is still remaining. : ", peer.config.NeighborAddress)
+ err.Code = api.Error_FAIL
+ err.Msg = "previous request is still remaining"
+ }
}
+ result.Data = err
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+
+ case REQ_NEIGHBOR_POLICY:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+
+ resInPolicies := []*api.PolicyDefinition{}
+ resOutPolicies := []*api.PolicyDefinition{}
+ // Add importpolies that has been set in the configuration file to the list.
+ // However, peer haven't target importpolicy when add PolicyDefinition of name only to the list.
+ conInPolicyNames := peer.config.ApplyPolicy.ImportPolicies
+ loc := server.localRibMap[peer.config.NeighborAddress.String()]
+ for _, conInPolicyName := range conInPolicyNames {
+ match := false
+ for _, inPolicy := range loc.importPolicies {
+ if conInPolicyName == inPolicy.Name {
+ match = true
+ resInPolicies = append(resInPolicies, inPolicy.ToApiStruct())
+ break
+ }
+ }
+ if !match {
+ resInPolicies = append(resInPolicies, &api.PolicyDefinition{PolicyDefinitionName: conInPolicyName})
+ }
+ }
+ // Add importpolies that has been set in the configuration file to the list.
+ // However, peer haven't target importpolicy when add PolicyDefinition of name only to the list.
+ conOutPolicyNames := peer.config.ApplyPolicy.ExportPolicies
+ for _, conOutPolicyName := range conOutPolicyNames {
+ match := false
+ for _, outPolicy := range loc.exportPolicies {
+ if conOutPolicyName == outPolicy.Name {
+ match = true
+ resOutPolicies = append(resOutPolicies, outPolicy.ToApiStruct())
+ break
+ }
+ }
+ if !match {
+ resOutPolicies = append(resOutPolicies, &api.PolicyDefinition{PolicyDefinitionName: conOutPolicyName})
+ }
+ }
+ defaultInPolicy := policy.ROUTE_REJECT
+ defaultOutPolicy := policy.ROUTE_REJECT
+ if loc.defaultImportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
+ defaultInPolicy = policy.ROUTE_ACCEPT
+ }
+ if loc.defaultExportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
+ defaultOutPolicy = policy.ROUTE_ACCEPT
+ }
+ result := &GrpcResponse{
+ Data: &api.ApplyPolicy{
+ DefaultImportPolicy: defaultInPolicy,
+ ImportPolicies: resInPolicies,
+ DefaultExportPolicy: defaultOutPolicy,
+ ExportPolicies: resOutPolicies,
+ },
+ }
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+
+ case REQ_NEIGHBOR_POLICY_ADD_IMPORT, REQ_NEIGHBOR_POLICY_ADD_EXPORT, REQ_NEIGHBOR_POLICY_DEL_IMPORT, REQ_NEIGHBOR_POLICY_DEL_EXPORT:
+ peer, err := server.checkNeighborRequest(grpcReq)
+ if err != nil {
+ break
+ }
+ reqApplyPolicy := grpcReq.Data.(*api.ApplyPolicy)
+ grpcReq.Data = []interface{}{reqApplyPolicy, server.policyMap}
+
+ reqPolicyMap := server.policyMap
+ applyPolicy := &peer.config.ApplyPolicy
+ var defInPolicy, defOutPolicy config.DefaultPolicyType
+ if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_ADD_IMPORT {
+ if reqApplyPolicy.DefaultImportPolicy != policy.ROUTE_ACCEPT {
+ defInPolicy = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE
+ }
+ peer.config.ApplyPolicy.DefaultImportPolicy = defInPolicy
+ applyPolicy.ImportPolicies = policy.PoliciesToString(reqApplyPolicy.ImportPolicies)
+ } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_ADD_EXPORT {
+ if reqApplyPolicy.DefaultExportPolicy != policy.ROUTE_ACCEPT {
+ defOutPolicy = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE
+ }
+ peer.config.ApplyPolicy.DefaultExportPolicy = defOutPolicy
+ applyPolicy.ExportPolicies = policy.PoliciesToString(reqApplyPolicy.ExportPolicies)
+ } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_DEL_IMPORT {
+ peer.config.ApplyPolicy.DefaultImportPolicy = config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE
+ peer.config.ApplyPolicy.ImportPolicies = make([]string, 0)
+ } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_DEL_EXPORT {
+ peer.config.ApplyPolicy.DefaultExportPolicy = config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE
+ peer.config.ApplyPolicy.ExportPolicies = make([]string, 0)
+ }
+ loc := server.localRibMap[peer.config.NeighborAddress.String()]
+ loc.setPolicy(peer, reqPolicyMap)
+ grpcReq.ResponseCh <- &GrpcResponse{}
+ close(grpcReq.ResponseCh)
+
case REQ_POLICY_PREFIXES:
info := server.routingPolicy.DefinedSets.PrefixSetList
result := &GrpcResponse{}
@@ -355,6 +1052,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
+
case REQ_POLICY_PREFIX:
name := grpcReq.Data.(string)
info := server.routingPolicy.DefinedSets.PrefixSetList
@@ -376,6 +1074,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
+
case REQ_POLICY_PREFIX_ADD:
reqPrefixSet := grpcReq.Data.(*api.PrefixSet)
conPrefixSetList := server.routingPolicy.DefinedSets.PrefixSetList
@@ -400,6 +1099,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
server.handlePolicy(server.routingPolicy)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
+
case REQ_POLICY_PREFIX_DELETE:
reqPrefixSet := grpcReq.Data.(*api.PrefixSet)
conPrefixSetList := server.routingPolicy.DefinedSets.PrefixSetList
@@ -407,7 +1107,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
isReqPrefixSet, prefixSet := policy.PrefixSetToConfigStruct(reqPrefixSet)
if isReqPrefixSet {
// If only name of the PrefixSet is same, delete all of the elements of the PrefixSet.
- // If the same element PrefixSet, delete the it's element from PrefixSet.
+ //If the same element PrefixSet, delete the it's element from PrefixSet.
idxPrefixSet, idxPrefix := policy.IndexOfPrefixSet(conPrefixSetList, prefixSet)
prefix := prefixSet.PrefixList[0]
if idxPrefixSet == -1 {
@@ -440,12 +1140,14 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
server.handlePolicy(server.routingPolicy)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
+
case REQ_POLICY_PREFIXES_DELETE:
result := &GrpcResponse{}
server.routingPolicy.DefinedSets.PrefixSetList = make([]config.PrefixSet, 0)
server.handlePolicy(server.routingPolicy)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
+
case REQ_POLICY_NEIGHBORS:
info := server.routingPolicy.DefinedSets.NeighborSetList
result := &GrpcResponse{}
@@ -462,6 +1164,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
+
case REQ_POLICY_NEIGHBOR:
name := grpcReq.Data.(string)
info := server.routingPolicy.DefinedSets.NeighborSetList
@@ -483,6 +1186,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
+
case REQ_POLICY_NEIGHBOR_ADD:
reqNeighborSet := grpcReq.Data.(*api.NeighborSet)
conNeighborSetList := server.routingPolicy.DefinedSets.NeighborSetList
@@ -677,4 +1381,5 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
}
+ return msgs
}