mirror of
https://github.com/osrg/gobgp.git
synced 2024-05-11 05:55:10 +00:00
move gRPC-related code for REQ_ADD_PATH and REQ_DELETE_PATH to grpc_server.go
Signed-off-by: FUJITA Tomonori <[email protected]>
This commit is contained in:
+105
-14
@@ -31,6 +31,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -57,7 +58,6 @@ const (
|
||||
REQ_MONITOR_NEIGHBOR_PEER_STATE
|
||||
REQ_ENABLE_MRT
|
||||
REQ_DISABLE_MRT
|
||||
REQ_INJECT_MRT
|
||||
REQ_ADD_BMP
|
||||
REQ_DELETE_BMP
|
||||
REQ_VALIDATE_RIB
|
||||
@@ -434,20 +434,112 @@ func (s *Server) DisableNeighbor(ctx context.Context, arg *api.DisableNeighborRe
|
||||
return d.(*api.DisableNeighborResponse), err
|
||||
}
|
||||
|
||||
func (s *Server) AddPath(ctx context.Context, arg *api.AddPathRequest) (*api.AddPathResponse, error) {
|
||||
d, err := s.get(REQ_ADD_PATH, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (s *Server) api2PathList(resource api.Resource, ApiPathList []*api.Path) ([]*table.Path, error) {
|
||||
var nlri bgp.AddrPrefixInterface
|
||||
var nexthop string
|
||||
var pi *table.PeerInfo
|
||||
|
||||
pathList := 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),
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
if nlri == nil || nexthop == "" {
|
||||
return nil, fmt.Errorf("not found nlri or nexthop")
|
||||
}
|
||||
|
||||
rf := bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI())
|
||||
|
||||
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 len(extcomms) > 0 {
|
||||
pattr = append(pattr, bgp.NewPathAttributeExtendedCommunities(extcomms))
|
||||
}
|
||||
newPath := table.NewPath(pi, nlri, path.IsWithdraw, pattr, time.Now(), path.NoImplicitWithdraw)
|
||||
newPath.SetIsFromExternal(path.IsFromExternal)
|
||||
pathList = append(pathList, newPath)
|
||||
}
|
||||
return d.(*api.AddPathResponse), err
|
||||
return pathList, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddPath(ctx context.Context, arg *api.AddPathRequest) (*api.AddPathResponse, error) {
|
||||
pathList, err := s.api2PathList(arg.Resource, []*api.Path{arg.Path})
|
||||
var uuid []byte
|
||||
if err == nil {
|
||||
uuid, err = s.bgpServer.AddPath(arg.VrfId, pathList)
|
||||
}
|
||||
return &api.AddPathResponse{Uuid: uuid}, err
|
||||
}
|
||||
|
||||
func (s *Server) DeletePath(ctx context.Context, arg *api.DeletePathRequest) (*api.DeletePathResponse, error) {
|
||||
d, err := s.get(REQ_DELETE_PATH, arg)
|
||||
pathList, err := func() ([]*table.Path, error) {
|
||||
if arg.Path != nil {
|
||||
arg.Path.IsWithdraw = true
|
||||
return s.api2PathList(arg.Resource, []*api.Path{arg.Path})
|
||||
}
|
||||
return []*table.Path{}, nil
|
||||
}()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.(*api.DeletePathResponse), err
|
||||
return &api.DeletePathResponse{}, s.bgpServer.DeletePath(arg.Uuid, bgp.RouteFamily(arg.Family), arg.VrfId, pathList)
|
||||
}
|
||||
|
||||
func (s *Server) EnableMrt(ctx context.Context, arg *api.EnableMrtRequest) (*api.EnableMrtResponse, error) {
|
||||
@@ -480,13 +572,12 @@ func (s *Server) InjectMrt(stream api.GobgpApi_InjectMrtServer) error {
|
||||
return fmt.Errorf("unsupported resource: %s", arg.Resource)
|
||||
}
|
||||
|
||||
req := NewGrpcRequest(REQ_INJECT_MRT, "", bgp.RouteFamily(0), arg)
|
||||
s.bgpServerCh <- req
|
||||
|
||||
res := <-req.ResponseCh
|
||||
if err := res.Err(); err != nil {
|
||||
log.Debug(err.Error())
|
||||
if pathList, err := s.api2PathList(arg.Resource, arg.Paths); err != nil {
|
||||
return err
|
||||
} else {
|
||||
if _, err = s.bgpServer.AddPath("", pathList); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return stream.SendAndClose(&api.InjectMrtResponse{})
|
||||
|
||||
+61
-179
@@ -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
|
||||
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(),
|
||||
}
|
||||
|
||||
paths := make([]*table.Path, 0, len(ApiPathList))
|
||||
for _, path := range pathList {
|
||||
if path.GetSource() == nil {
|
||||
path.SetSource(pi)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
if nlri == nil || nexthop == "" {
|
||||
return nil, fmt.Errorf("not found nlri or nexthop")
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
newPath := table.NewPath(pi, nlri, path.IsWithdraw, pattr, time.Now(), path.NoImplicitWithdraw)
|
||||
newPath.SetIsFromExternal(path.IsFromExternal)
|
||||
paths = append(paths, newPath)
|
||||
|
||||
}
|
||||
return paths, 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)
|
||||
path.SetExtCommunities(extcomms, false)
|
||||
}
|
||||
}
|
||||
grpcReq.ResponseCh <- &GrpcResponse{
|
||||
ResponseErr: err,
|
||||
Data: &api.AddPathResponse{
|
||||
Uuid: uuidBytes,
|
||||
},
|
||||
}
|
||||
close(grpcReq.ResponseCh)
|
||||
return paths
|
||||
return 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) 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)
|
||||
}
|
||||
}
|
||||
return uuidBytes, nil
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
+10
-33
@@ -18,7 +18,6 @@ package server
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
api "github.com/osrg/gobgp/api"
|
||||
"github.com/osrg/gobgp/packet/bgp"
|
||||
"github.com/osrg/gobgp/table"
|
||||
"github.com/osrg/gobgp/zebra"
|
||||
@@ -26,6 +25,7 @@ import (
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newIPRouteMessage(dst []*table.Path) *zebra.Message {
|
||||
@@ -94,7 +94,7 @@ func newIPRouteMessage(dst []*table.Path) *zebra.Message {
|
||||
}
|
||||
}
|
||||
|
||||
func createRequestFromIPRouteMessage(m *zebra.Message) *api.AddPathRequest {
|
||||
func createPathFromIPRouteMessage(m *zebra.Message) *table.Path {
|
||||
|
||||
header := m.Header
|
||||
body := m.Body.(*zebra.IPRouteBody)
|
||||
@@ -144,33 +144,16 @@ func createRequestFromIPRouteMessage(m *zebra.Message) *api.AddPathRequest {
|
||||
med := bgp.NewPathAttributeMultiExitDisc(body.Metric)
|
||||
pattr = append(pattr, med)
|
||||
|
||||
binPattrs := make([][]byte, 0, len(pattr))
|
||||
for _, a := range pattr {
|
||||
bin, _ := a.Serialize()
|
||||
binPattrs = append(binPattrs, bin)
|
||||
}
|
||||
|
||||
binNlri, _ := nlri.Serialize()
|
||||
|
||||
path := &api.Path{
|
||||
Nlri: binNlri,
|
||||
Pattrs: binPattrs,
|
||||
IsWithdraw: isWithdraw,
|
||||
Family: uint32(family),
|
||||
IsFromExternal: true,
|
||||
}
|
||||
return &api.AddPathRequest{
|
||||
Resource: api.Resource_GLOBAL,
|
||||
Path: path,
|
||||
}
|
||||
|
||||
path := table.NewPath(nil, nlri, isWithdraw, pattr, time.Now(), false)
|
||||
path.SetIsFromExternal(true)
|
||||
return path
|
||||
}
|
||||
|
||||
type zebraWatcher struct {
|
||||
t tomb.Tomb
|
||||
ch chan watcherEvent
|
||||
client *zebra.Client
|
||||
apiCh chan *GrpcRequest
|
||||
server *BgpServer
|
||||
}
|
||||
|
||||
func (w *zebraWatcher) notify(t watcherEventType) chan watcherEvent {
|
||||
@@ -196,15 +179,9 @@ func (w *zebraWatcher) loop() error {
|
||||
case msg := <-w.client.Receive():
|
||||
switch msg.Body.(type) {
|
||||
case *zebra.IPRouteBody:
|
||||
p := createRequestFromIPRouteMessage(msg)
|
||||
p := createPathFromIPRouteMessage(msg)
|
||||
if p != nil {
|
||||
ch := make(chan *GrpcResponse)
|
||||
w.apiCh <- &GrpcRequest{
|
||||
RequestType: REQ_ADD_PATH,
|
||||
Data: p,
|
||||
ResponseCh: ch,
|
||||
}
|
||||
if err := (<-ch).Err(); err != nil {
|
||||
if _, err := w.server.AddPath("", []*table.Path{p}); err != nil {
|
||||
log.Errorf("failed to add path from zebra: %s", p)
|
||||
}
|
||||
}
|
||||
@@ -229,7 +206,7 @@ func (w *zebraWatcher) loop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newZebraWatcher(apiCh chan *GrpcRequest, url string, protos []string) (*zebraWatcher, error) {
|
||||
func newZebraWatcher(s *BgpServer, url string, protos []string) (*zebraWatcher, error) {
|
||||
l := strings.SplitN(url, ":", 2)
|
||||
if len(l) != 2 {
|
||||
return nil, fmt.Errorf("unsupported url: %s", url)
|
||||
@@ -251,7 +228,7 @@ func newZebraWatcher(apiCh chan *GrpcRequest, url string, protos []string) (*zeb
|
||||
w := &zebraWatcher{
|
||||
ch: make(chan watcherEvent),
|
||||
client: cli,
|
||||
apiCh: apiCh,
|
||||
server: s,
|
||||
}
|
||||
w.t.Go(w.loop)
|
||||
return w, nil
|
||||
|
||||
+12
-33
@@ -16,7 +16,6 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/osrg/gobgp/gobgp/cmd"
|
||||
"github.com/osrg/gobgp/table"
|
||||
"github.com/osrg/gobgp/zebra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -53,14 +52,9 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
|
||||
m.Header = *h
|
||||
m.Body = b
|
||||
|
||||
p := createRequestFromIPRouteMessage(m)
|
||||
assert.NotNil(p)
|
||||
paths, err := cmd.ApiStruct2Path(p.Path)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(paths), 1)
|
||||
path := paths[0]
|
||||
pp := table.NewPath(nil, path.Nlri, path.IsWithdraw, path.PathAttrs, time.Now(), false)
|
||||
pp.SetIsFromExternal(p.Path.IsFromExternal)
|
||||
path := createPathFromIPRouteMessage(m)
|
||||
pp := table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false)
|
||||
pp.SetIsFromExternal(path.IsFromExternal())
|
||||
assert.Equal("0.0.0.0", pp.GetNexthop().String())
|
||||
assert.Equal("192.168.100.0/24", pp.GetNlri().String())
|
||||
assert.True(pp.IsFromExternal())
|
||||
@@ -69,14 +63,9 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
|
||||
// withdraw
|
||||
h.Command = zebra.IPV4_ROUTE_DELETE
|
||||
m.Header = *h
|
||||
p = createRequestFromIPRouteMessage(m)
|
||||
assert.NotNil(p)
|
||||
paths, err = cmd.ApiStruct2Path(p.Path)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(paths), 1)
|
||||
path = paths[0]
|
||||
pp = table.NewPath(nil, path.Nlri, path.IsWithdraw, path.PathAttrs, time.Now(), false)
|
||||
pp.SetIsFromExternal(p.Path.IsFromExternal)
|
||||
path = createPathFromIPRouteMessage(m)
|
||||
pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false)
|
||||
pp.SetIsFromExternal(path.IsFromExternal())
|
||||
assert.Equal("0.0.0.0", pp.GetNexthop().String())
|
||||
assert.Equal("192.168.100.0/24", pp.GetNlri().String())
|
||||
med, _ := pp.GetMed()
|
||||
@@ -92,14 +81,9 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
|
||||
m.Header = *h
|
||||
m.Body = b
|
||||
|
||||
p = createRequestFromIPRouteMessage(m)
|
||||
assert.NotNil(p)
|
||||
paths, err = cmd.ApiStruct2Path(p.Path)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(paths), 1)
|
||||
path = paths[0]
|
||||
pp = table.NewPath(nil, path.Nlri, path.IsWithdraw, path.PathAttrs, time.Now(), false)
|
||||
pp.SetIsFromExternal(p.Path.IsFromExternal)
|
||||
path = createPathFromIPRouteMessage(m)
|
||||
pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false)
|
||||
pp.SetIsFromExternal(path.IsFromExternal())
|
||||
assert.Equal("::", pp.GetNexthop().String())
|
||||
assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String())
|
||||
med, _ = pp.GetMed()
|
||||
@@ -110,14 +94,9 @@ func Test_createRequestFromIPRouteMessage(t *testing.T) {
|
||||
// withdraw
|
||||
h.Command = zebra.IPV6_ROUTE_DELETE
|
||||
m.Header = *h
|
||||
p = createRequestFromIPRouteMessage(m)
|
||||
assert.NotNil(p)
|
||||
paths, err = cmd.ApiStruct2Path(p.Path)
|
||||
assert.Nil(err)
|
||||
assert.Equal(len(paths), 1)
|
||||
path = paths[0]
|
||||
pp = table.NewPath(nil, path.Nlri, path.IsWithdraw, path.PathAttrs, time.Now(), false)
|
||||
pp.SetIsFromExternal(p.Path.IsFromExternal)
|
||||
path = createPathFromIPRouteMessage(m)
|
||||
pp = table.NewPath(nil, path.GetNlri(), path.IsWithdraw, path.GetPathAttrs(), time.Now(), false)
|
||||
pp.SetIsFromExternal(path.IsFromExternal())
|
||||
assert.Equal("::", pp.GetNexthop().String())
|
||||
assert.Equal("2001:db8:0:f101::/64", pp.GetNlri().String())
|
||||
assert.True(pp.IsFromExternal())
|
||||
|
||||
+1
-2
@@ -91,7 +91,6 @@ func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pa
|
||||
log.WithFields(log.Fields{
|
||||
"Topic": "Table",
|
||||
"Key": nlri.String(),
|
||||
"Peer": source.Address.String(),
|
||||
}).Error("Need to provide patattrs for the path that is not withdraw.")
|
||||
return nil
|
||||
}
|
||||
@@ -331,7 +330,7 @@ func (path *Path) GetRouteFamily() bgp.RouteFamily {
|
||||
return bgp.AfiSafiToRouteFamily(path.OriginInfo().nlri.AFI(), path.OriginInfo().nlri.SAFI())
|
||||
}
|
||||
|
||||
func (path *Path) setSource(source *PeerInfo) {
|
||||
func (path *Path) SetSource(source *PeerInfo) {
|
||||
path.OriginInfo().source = source
|
||||
}
|
||||
func (path *Path) GetSource() *PeerInfo {
|
||||
|
||||
Reference in New Issue
Block a user