summaryrefslogtreecommitdiffhomepage
path: root/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go232
1 files changed, 57 insertions, 175 deletions
diff --git a/server/server.go b/server/server.go
index fd8a8d36..54702226 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1047,87 +1047,27 @@ func getMacMobilityExtendedCommunity(etag uint32, mac net.HardwareAddr, evpnPath
return nil
}
-func (server *BgpServer) Api2PathList(resource api.Resource, name string, ApiPathList []*api.Path) ([]*table.Path, error) {
- var nlri bgp.AddrPrefixInterface
- var nexthop string
- var pi *table.PeerInfo
-
- paths := make([]*table.Path, 0, len(ApiPathList))
-
- for _, path := range ApiPathList {
- seen := make(map[bgp.BGPAttrType]bool)
-
- pattr := make([]bgp.PathAttributeInterface, 0)
- extcomms := make([]bgp.ExtendedCommunityInterface, 0)
-
- if path.SourceAsn != 0 {
- pi = &table.PeerInfo{
- AS: path.SourceAsn,
- LocalID: net.ParseIP(path.SourceId),
- }
- } else {
- pi = &table.PeerInfo{
- AS: server.bgpConfig.Global.Config.As,
- LocalID: net.ParseIP(server.bgpConfig.Global.Config.RouterId).To4(),
- }
- }
-
- if len(path.Nlri) > 0 {
- nlri = &bgp.IPAddrPrefix{}
- err := nlri.DecodeFromBytes(path.Nlri)
- if err != nil {
- return nil, err
- }
- }
-
- for _, attr := range path.Pattrs {
- p, err := bgp.GetPathAttribute(attr)
- if err != nil {
- return nil, err
- }
-
- err = p.DecodeFromBytes(attr)
- if err != nil {
- return nil, err
- }
-
- if _, ok := seen[p.GetType()]; !ok {
- seen[p.GetType()] = true
- } else {
- return nil, fmt.Errorf("the path attribute apears twice. Type : " + strconv.Itoa(int(p.GetType())))
- }
- switch p.GetType() {
- case bgp.BGP_ATTR_TYPE_NEXT_HOP:
- nexthop = p.(*bgp.PathAttributeNextHop).Value.String()
- case bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES:
- value := p.(*bgp.PathAttributeExtendedCommunities).Value
- if len(value) > 0 {
- extcomms = append(extcomms, value...)
- }
- case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI:
- mpreach := p.(*bgp.PathAttributeMpReachNLRI)
- if len(mpreach.Value) != 1 {
- return nil, fmt.Errorf("include only one route in mp_reach_nlri")
- }
- nlri = mpreach.Value[0]
- nexthop = mpreach.Nexthop.String()
- default:
- pattr = append(pattr, p)
- }
- }
+func (server *BgpServer) fixupApiPath(vrfId string, pathList []*table.Path) error {
+ pi := &table.PeerInfo{
+ AS: server.bgpConfig.Global.Config.As,
+ LocalID: net.ParseIP(server.bgpConfig.Global.Config.RouterId).To4(),
+ }
- if nlri == nil || nexthop == "" {
- return nil, fmt.Errorf("not found nlri or nexthop")
+ for _, path := range pathList {
+ if path.GetSource() == nil {
+ path.SetSource(pi)
}
+ extcomms := make([]bgp.ExtendedCommunityInterface, 0)
+ nlri := path.GetNlri()
rf := bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI())
- if resource == api.Resource_VRF {
- label, err := server.globalRib.GetNextLabel(name, nexthop, path.IsWithdraw)
+ if vrfId != "" {
+ label, err := server.globalRib.GetNextLabel(vrfId, path.GetNexthop().String(), path.IsWithdraw)
if err != nil {
- return nil, err
+ return err
}
- vrf := server.globalRib.Vrfs[name]
+ vrf := server.globalRib.Vrfs[vrfId]
switch rf {
case bgp.RF_IPv4_UC:
n := nlri.(*bgp.IPAddrPrefix)
@@ -1144,17 +1084,10 @@ func (server *BgpServer) Api2PathList(resource api.Resource, name string, ApiPat
n.RouteTypeData.(*bgp.EVPNMulticastEthernetTagRoute).RD = vrf.Rd
}
default:
- return nil, fmt.Errorf("unsupported route family for vrf: %s", rf)
+ return fmt.Errorf("unsupported route family for vrf: %s", rf)
}
extcomms = append(extcomms, vrf.ExportRt...)
}
-
- if resource != api.Resource_VRF && rf == bgp.RF_IPv4_UC {
- pattr = append(pattr, bgp.NewPathAttributeNextHop(nexthop))
- } else {
- pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri}))
- }
-
if rf == bgp.RF_EVPN {
evpnNlri := nlri.(*bgp.EVPNNLRI)
if evpnNlri.RouteType == bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT {
@@ -1169,104 +1102,70 @@ func (server *BgpServer) Api2PathList(resource api.Resource, name string, ApiPat
}
if len(extcomms) > 0 {
- pattr = append(pattr, bgp.NewPathAttributeExtendedCommunities(extcomms))
+ path.SetExtCommunities(extcomms, false)
}
- newPath := table.NewPath(pi, nlri, path.IsWithdraw, pattr, time.Now(), path.NoImplicitWithdraw)
- newPath.SetIsFromExternal(path.IsFromExternal)
- paths = append(paths, newPath)
-
}
- return paths, nil
+ return nil
}
-func (server *BgpServer) handleAddPathRequest(grpcReq *GrpcRequest) []*table.Path {
- var err error
- var uuidBytes []byte
- paths := make([]*table.Path, 0, 1)
- arg, ok := grpcReq.Data.(*api.AddPathRequest)
- if !ok {
- err = fmt.Errorf("type assertion failed")
- } else {
- paths, err = server.Api2PathList(arg.Resource, arg.VrfId, []*api.Path{arg.Path})
- if err == nil {
- u := uuid.NewV4()
- uuidBytes = u.Bytes()
- paths[0].SetUUID(uuidBytes)
+func (s *BgpServer) AddPath(vrfId string, pathList []*table.Path) (uuidBytes []byte, err error) {
+ ch := make(chan struct{})
+ defer func() { <-ch }()
+
+ s.mgmtCh <- func() {
+ defer close(ch)
+
+ if err = s.fixupApiPath(vrfId, pathList); err == nil {
+ if len(pathList) == 1 {
+ uuidBytes = uuid.NewV4().Bytes()
+ pathList[0].SetUUID(uuidBytes)
+ }
+ s.propagateUpdate(nil, pathList)
}
}
- grpcReq.ResponseCh <- &GrpcResponse{
- ResponseErr: err,
- Data: &api.AddPathResponse{
- Uuid: uuidBytes,
- },
- }
- close(grpcReq.ResponseCh)
- return paths
+ return uuidBytes, nil
}
-func (server *BgpServer) handleDeletePathRequest(grpcReq *GrpcRequest) []*table.Path {
- var err error
- paths := make([]*table.Path, 0, 1)
- arg, ok := grpcReq.Data.(*api.DeletePathRequest)
- if !ok {
- err = fmt.Errorf("type assertion failed")
- } else {
- if len(arg.Uuid) > 0 {
+func (s *BgpServer) DeletePath(uuid []byte, f bgp.RouteFamily, vrfId string, pathList []*table.Path) (err error) {
+ ch := make(chan struct{})
+ defer func() { <-ch }()
+
+ s.mgmtCh <- func() {
+ defer close(ch)
+
+ deletePathList := make([]*table.Path, 0)
+ if len(uuid) > 0 {
path := func() *table.Path {
- for _, path := range server.globalRib.GetPathList(table.GLOBAL_RIB_NAME, server.globalRib.GetRFlist()) {
- if len(path.UUID()) > 0 && bytes.Equal(path.UUID(), arg.Uuid) {
+ for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, s.globalRib.GetRFlist()) {
+ if len(path.UUID()) > 0 && bytes.Equal(path.UUID(), uuid) {
return path
}
}
return nil
}()
if path != nil {
- paths = append(paths, path.Clone(true))
+ deletePathList = append(deletePathList, path.Clone(true))
} else {
err = fmt.Errorf("Can't find a specified path")
}
- } else if arg.Path != nil {
- arg.Path.IsWithdraw = true
- paths, err = server.Api2PathList(arg.Resource, arg.VrfId, []*api.Path{arg.Path})
- } else {
+ } else if len(pathList) == 0 {
// delete all paths
- families := server.globalRib.GetRFlist()
- if arg.Family != 0 {
- families = []bgp.RouteFamily{bgp.RouteFamily(arg.Family)}
+ families := s.globalRib.GetRFlist()
+ if f != 0 {
+ families = []bgp.RouteFamily{f}
}
- for _, path := range server.globalRib.GetPathList(table.GLOBAL_RIB_NAME, families) {
- paths = append(paths, path.Clone(true))
+ for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, families) {
+ deletePathList = append(deletePathList, path.Clone(true))
}
+ } else {
+ if err = s.fixupApiPath(vrfId, pathList); err != nil {
+ return
+ }
+ deletePathList = pathList
}
+ s.propagateUpdate(nil, deletePathList)
}
- grpcReq.ResponseCh <- &GrpcResponse{
- ResponseErr: err,
- Data: &api.DeletePathResponse{},
- }
- close(grpcReq.ResponseCh)
- return paths
-}
-
-func (server *BgpServer) handleInjectMrtRequest(grpcReq *GrpcRequest) []*table.Path {
- var err error
- var paths []*table.Path
- arg, ok := grpcReq.Data.(*api.InjectMrtRequest)
- if !ok {
- err = fmt.Errorf("type assertion failed")
- }
- if err == nil {
- paths, err = server.Api2PathList(arg.Resource, arg.VrfId, arg.Paths)
- if err == nil {
- return paths
- }
- }
- result := &GrpcResponse{
- ResponseErr: err,
- }
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return []*table.Path{}
-
+ return err
}
func (server *BgpServer) handleAddVrfRequest(grpcReq *GrpcRequest) ([]*table.Path, error) {
@@ -1603,16 +1502,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
Data: bmpmsgs,
}
close(grpcReq.ResponseCh)
- case REQ_ADD_PATH:
- pathList := server.handleAddPathRequest(grpcReq)
- if len(pathList) > 0 {
- server.propagateUpdate(nil, pathList)
- }
- case REQ_DELETE_PATH:
- pathList := server.handleDeletePathRequest(grpcReq)
- if len(pathList) > 0 {
- server.propagateUpdate(nil, pathList)
- }
case REQ_BMP_NEIGHBORS:
//TODO: merge REQ_NEIGHBORS and REQ_BMP_NEIGHBORS
msgs := make([]*bmp.BMPMessage, 0, len(server.neighborMap))
@@ -1905,13 +1794,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
server.handleEnableMrtRequest(grpcReq)
case REQ_DISABLE_MRT:
server.handleDisableMrtRequest(grpcReq)
- case REQ_INJECT_MRT:
- pathList := server.handleInjectMrtRequest(grpcReq)
- if len(pathList) > 0 {
- server.propagateUpdate(nil, pathList)
- grpcReq.ResponseCh <- &GrpcResponse{}
- close(grpcReq.ResponseCh)
- }
case REQ_ADD_BMP:
server.handleAddBmp(grpcReq)
case REQ_DELETE_BMP:
@@ -1938,7 +1820,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
for _, p := range c.RedistributeRouteTypeList {
protos = append(protos, string(p))
}
- z, err := newZebraWatcher(server.GrpcReqCh, c.Url, protos)
+ z, err := newZebraWatcher(server, c.Url, protos)
if err == nil {
server.watchers.addWatcher(WATCHER_ZEBRA, z)
}