summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-10-04 15:48:19 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-10-09 20:18:09 +0900
commit352d8e2056fceb3bc0e85f5b8436f7eff0f44711 (patch)
treeea4cb33d22eef65a5b635c9a47debb740b144aa8
parentdd6140c6a28eb6e2dc41b47611240647e2b938fd (diff)
server: store import/export config in TabelManager instead of Peer
this is a preparation to apply policy to global rib. Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--server/peer.go60
-rw-r--r--server/server.go94
-rw-r--r--table/table_manager.go103
3 files changed, 148 insertions, 109 deletions
diff --git a/server/peer.go b/server/peer.go
index 4a602675..e3a8c7ab 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -44,20 +44,18 @@ type Peer struct {
defaultInPolicy config.DefaultPolicyType
accepted uint32
staleAccepted bool
- importPolicies []*table.Policy
- defaultImportPolicy config.DefaultPolicyType
- exportPolicies []*table.Policy
- defaultExportPolicy config.DefaultPolicyType
isConfederationMember bool
recvOpen *bgp.BGPMessage
+ localRib *table.TableManager
}
func NewPeer(g config.Global, conf config.Neighbor) *Peer {
peer := &Peer{
- gConf: g,
- conf: conf,
- rfMap: make(map[bgp.RouteFamily]bool),
- capMap: make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface),
+ gConf: g,
+ conf: conf,
+ rfMap: make(map[bgp.RouteFamily]bool),
+ capMap: make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface),
+ outgoing: make(chan *bgp.BGPMessage, 128),
}
conf.NeighborState.SessionState = uint32(bgp.BGP_FSM_IDLE)
@@ -77,6 +75,9 @@ func NewPeer(g config.Global, conf config.Neighbor) *Peer {
}
peer.adjRib = table.NewAdjRib(peer.configuredRFlist())
peer.fsm = NewFSM(&g, &conf)
+ if peer.isRouteServerClient() {
+ peer.localRib = table.NewTableManager(conf.NeighborConfig.NeighborAddress.String(), peer.configuredRFlist(), g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
+ }
if conf.NeighborConfig.PeerAs != g.GlobalConfig.As {
for _, member := range g.Confederation.ConfederationConfig.MemberAs {
@@ -374,47 +375,16 @@ func (peer *Peer) setPolicy(policyMap map[string]*table.Policy) {
peer.inPolicies = inPolicies
peer.defaultInPolicy = policyConf.ApplyPolicyConfig.DefaultInPolicy
- importPolicies := make([]*table.Policy, 0)
- for _, policyName := range policyConf.ApplyPolicyConfig.ImportPolicy {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": peer.conf.NeighborConfig.NeighborAddress,
- "PolicyName": policyName,
- }).Info("import-policy installed")
- if pol, ok := policyMap[policyName]; ok {
- log.Debug("import policy : ", pol)
- importPolicies = append(importPolicies, pol)
- }
- }
- peer.importPolicies = importPolicies
- peer.defaultImportPolicy = policyConf.ApplyPolicyConfig.DefaultImportPolicy
-
- exportPolicies := make([]*table.Policy, 0)
- for _, policyName := range policyConf.ApplyPolicyConfig.ExportPolicy {
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": peer.conf.NeighborConfig.NeighborAddress,
- "PolicyName": policyName,
- }).Info("export-policy installed")
- if pol, ok := policyMap[policyName]; ok {
- log.Debug("export policy : ", pol)
- exportPolicies = append(exportPolicies, pol)
- }
- }
- peer.exportPolicies = exportPolicies
- peer.defaultExportPolicy = policyConf.ApplyPolicyConfig.DefaultExportPolicy
+ peer.localRib.SetPolicy(policyConf, policyMap)
}
func (peer *Peer) GetPolicy(d table.PolicyDirection) []*table.Policy {
switch d {
case table.POLICY_DIRECTION_IN:
return peer.inPolicies
- case table.POLICY_DIRECTION_IMPORT:
- return peer.importPolicies
- case table.POLICY_DIRECTION_EXPORT:
- return peer.exportPolicies
+ default:
+ return peer.localRib.GetPolicy(d)
}
- return nil
}
func (peer *Peer) GetDefaultPolicy(d table.PolicyDirection) table.RouteType {
@@ -422,10 +392,8 @@ func (peer *Peer) GetDefaultPolicy(d table.PolicyDirection) table.RouteType {
switch d {
case table.POLICY_DIRECTION_IN:
def = peer.defaultInPolicy
- case table.POLICY_DIRECTION_IMPORT:
- def = peer.defaultImportPolicy
- case table.POLICY_DIRECTION_EXPORT:
- def = peer.defaultExportPolicy
+ default:
+ return peer.localRib.GetDefaultPolicy(d)
}
if def == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
diff --git a/server/server.go b/server/server.go
index de0dabc3..38c4ea63 100644
--- a/server/server.go
+++ b/server/server.go
@@ -92,7 +92,7 @@ type BgpServer struct {
broadcastReqs []*GrpcRequest
broadcastMsgs []broadcastMsg
neighborMap map[string]*Peer
- localRibMap map[string]*table.TableManager
+ globalRib *table.TableManager
zclient *zebra.Client
roaClient *roaClient
bmpClient *bmpClient
@@ -111,7 +111,6 @@ func NewBgpServer(port int) *BgpServer {
b.bmpConnCh = make(chan *bmpConn)
b.GrpcReqCh = make(chan *GrpcRequest, 1)
b.policyUpdateCh = make(chan config.RoutingPolicy)
- b.localRibMap = make(map[string]*table.TableManager)
b.neighborMap = make(map[string]*Peer)
b.listenPort = port
b.roaClient, _ = newROAClient(config.RpkiServers{})
@@ -142,10 +141,6 @@ func listenAndAccept(proto string, port int, ch chan *net.TCPConn) (*net.TCPList
return l, nil
}
-func (server *BgpServer) addLocalRib(rib *table.TableManager) {
- server.localRibMap[rib.OwnerName()] = rib
-}
-
func (server *BgpServer) Serve() {
g := <-server.globalTypeCh
server.bgpConfig.Global = g
@@ -216,7 +211,7 @@ func (server *BgpServer) Serve() {
return rfList
}(g.AfiSafis.AfiSafiList)
- server.addLocalRib(table.NewTableManager(GLOBAL_RIB_NAME, rfList, g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel))
+ server.globalRib = table.NewTableManager(GLOBAL_RIB_NAME, rfList, g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
listenerMap := make(map[string]*net.TCPListener)
acceptCh := make(chan *net.TCPConn)
@@ -358,13 +353,8 @@ func (server *BgpServer) Serve() {
SetTcpMD5SigSockopts(listener(config.NeighborConfig.NeighborAddress), addr, config.NeighborConfig.AuthPassword)
peer := NewPeer(g, config)
- name := config.NeighborConfig.NeighborAddress.String()
-
- if config.RouteServer.RouteServerConfig.RouteServerClient {
- rib := table.NewTableManager(name, peer.configuredRFlist(), g.MplsLabelRange.MinLabel, g.MplsLabelRange.MaxLabel)
- server.addLocalRib(rib)
+ if peer.isRouteServerClient() {
peer.setPolicy(server.policyMap)
-
pathList := make([]*table.Path, 0)
for _, p := range server.neighborMap {
if p.isRouteServerClient() == false {
@@ -376,11 +366,10 @@ func (server *BgpServer) Serve() {
}
pathList, _ = peer.ApplyPolicy(table.POLICY_DIRECTION_IMPORT, pathList)
if len(pathList) > 0 {
- rib.ProcessPaths(pathList)
+ peer.localRib.ProcessPaths(pathList)
}
}
- server.neighborMap[name] = peer
- peer.outgoing = make(chan *bgp.BGPMessage, 128)
+ server.neighborMap[addr] = peer
peer.startFSMHandler(incoming)
server.broadcastPeerState(peer)
case config := <-server.deletedPeerCh:
@@ -405,9 +394,6 @@ func (server *BgpServer) Serve() {
senderMsgs = append(senderMsgs, m...)
}
delete(server.neighborMap, addr)
- if peer.isRouteServerClient() {
- delete(server.localRibMap, addr)
- }
} else {
log.Info("Can't delete a peer configuration for ", addr)
}
@@ -550,9 +536,9 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg {
for _, rf := range peer.configuredRFlist() {
if peer.isRouteServerClient() {
- for _, rib := range server.localRibMap {
- targetPeer := server.neighborMap[rib.OwnerName()]
- if rib.OwnerName() == GLOBAL_RIB_NAME || rib.OwnerName() == peer.conf.NeighborConfig.NeighborAddress.String() {
+ for _, targetPeer := range server.neighborMap {
+ rib := targetPeer.localRib
+ if !targetPeer.isRouteServerClient() || rib.OwnerName() == peer.conf.NeighborConfig.NeighborAddress.String() {
continue
}
pathList, _ := rib.DeletePathsforPeer(peer.peerInfo, rf)
@@ -564,7 +550,7 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg {
targetPeer.adjRib.UpdateOut(pathList)
}
} else {
- rib := server.localRibMap[GLOBAL_RIB_NAME]
+ rib := server.globalRib
pathList, _ := rib.DeletePathsforPeer(peer.peerInfo, rf)
if len(pathList) == 0 {
continue
@@ -662,10 +648,9 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
msgs := make([]*SenderMsg, 0)
if peer != nil && peer.isRouteServerClient() {
pathList, _ = peer.ApplyPolicy(table.POLICY_DIRECTION_IN, pathList)
- for _, rib := range server.localRibMap {
- targetPeer := server.neighborMap[rib.OwnerName()]
- neighborAddress := peer.conf.NeighborConfig.NeighborAddress.String()
- if rib.OwnerName() == GLOBAL_RIB_NAME || rib.OwnerName() == neighborAddress {
+ for _, targetPeer := range server.neighborMap {
+ rib := targetPeer.localRib
+ if !targetPeer.isRouteServerClient() || rib.OwnerName() == peer.conf.NeighborConfig.NeighborAddress.String() {
continue
}
sendPathList, _ := targetPeer.ApplyPolicy(table.POLICY_DIRECTION_IMPORT, pathList)
@@ -682,7 +667,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
msgs = append(msgs, newSenderMsg(targetPeer, msgList))
}
} else {
- rib := server.localRibMap[GLOBAL_RIB_NAME]
+ rib := server.globalRib
sendPathList, _ := rib.ProcessPaths(pathList)
if len(sendPathList) == 0 {
return msgs
@@ -883,16 +868,12 @@ func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) {
func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) {
server.SetPolicy(pl)
- for _, rib := range server.localRibMap {
- if rib.OwnerName() == GLOBAL_RIB_NAME {
- continue
- }
- targetPeer := server.neighborMap[rib.OwnerName()]
+ for _, peer := range server.neighborMap {
log.WithFields(log.Fields{
"Topic": "Peer",
- "Key": targetPeer.conf.NeighborConfig.NeighborAddress,
+ "Key": peer.conf.NeighborConfig.NeighborAddress,
}).Info("call set policy")
- targetPeer.setPolicy(server.policyMap)
+ peer.setPolicy(server.policyMap)
}
}
@@ -1074,12 +1055,12 @@ func (server *BgpServer) handleModPathRequest(grpcReq *GrpcRequest) []*table.Pat
rf = bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI())
if arg.Resource == api.Resource_VRF {
- label, err := server.localRibMap[GLOBAL_RIB_NAME].GetNextLabel(arg.Name, nexthop, path.IsWithdraw)
+ label, err := server.globalRib.GetNextLabel(arg.Name, nexthop, path.IsWithdraw)
if err != nil {
result.ResponseErr = err
goto ERR
}
- vrf := server.localRibMap[GLOBAL_RIB_NAME].Vrfs[arg.Name]
+ vrf := server.globalRib.Vrfs[arg.Name]
switch rf {
case bgp.RF_IPv4_UC:
n := nlri.(*bgp.IPAddrPrefix)
@@ -1114,7 +1095,7 @@ func (server *BgpServer) handleModPathRequest(grpcReq *GrpcRequest) []*table.Pat
macIpAdv := evpnNlri.RouteTypeData.(*bgp.EVPNMacIPAdvertisementRoute)
etag := macIpAdv.ETag
mac := macIpAdv.MacAddress
- paths := server.localRibMap[GLOBAL_RIB_NAME].GetBestPathList(bgp.RF_EVPN)
+ paths := server.globalRib.GetBestPathList(bgp.RF_EVPN)
if m := getMacMobilityExtendedCommunity(etag, mac, paths); m != nil {
extcomms = append(extcomms, m)
}
@@ -1138,7 +1119,7 @@ ERR:
}
func (server *BgpServer) handleVrfMod(arg *api.ModVrfArguments) ([]*table.Path, error) {
- rib := server.localRibMap[GLOBAL_RIB_NAME]
+ rib := server.globalRib
var msgs []*table.Path
switch arg.Operation {
case api.Operation_ADD:
@@ -1189,7 +1170,7 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path {
switch req.RequestType {
case REQ_VRF:
name := req.Name
- rib := server.localRibMap[GLOBAL_RIB_NAME]
+ rib := server.globalRib
vrfs := rib.Vrfs
if _, ok := vrfs[name]; !ok {
result.ResponseErr = fmt.Errorf("vrf %s not found", name)
@@ -1221,7 +1202,7 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path {
}
goto END
case REQ_VRFS:
- vrfs := server.localRibMap[GLOBAL_RIB_NAME].Vrfs
+ vrfs := server.globalRib.Vrfs
for _, vrf := range vrfs {
req.ResponseCh <- &GrpcResponse{
Data: vrf.ToApiStruct(),
@@ -1253,16 +1234,17 @@ func sendMultipleResponses(grpcReq *GrpcRequest, results []*GrpcResponse) {
}
func (server *BgpServer) getBestFromLocal(peer *Peer) ([]*table.Path, []*table.Path) {
- pathList := make([]*table.Path, 0)
- filtered := make([]*table.Path, 0)
+ var pathList []*table.Path
+ var filtered []*table.Path
if peer.isRouteServerClient() {
- rib := server.localRibMap[peer.conf.NeighborConfig.NeighborAddress.String()]
- pathList, filtered = peer.ApplyPolicy(table.POLICY_DIRECTION_EXPORT, filterpath(peer, peer.getBests(rib)))
+ pathList, filtered = peer.ApplyPolicy(table.POLICY_DIRECTION_EXPORT, filterpath(peer, peer.getBests(peer.localRib)))
} else {
- rib := server.localRibMap[GLOBAL_RIB_NAME]
+ rib := server.globalRib
l, _ := peer.fsm.LocalHostPort()
peer.conf.Transport.TransportConfig.LocalAddress = net.ParseIP(l)
- for _, path := range filterpath(peer, peer.getBests(rib)) {
+ bests := filterpath(peer, peer.getBests(rib))
+ pathList = make([]*table.Path, 0, len(bests))
+ for _, path := range bests {
path.UpdatePathAttrs(&server.bgpConfig.Global, &peer.conf)
pathList = append(pathList, path)
}
@@ -1315,11 +1297,11 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
switch grpcReq.RequestType {
case REQ_GLOBAL_RIB:
var results []*GrpcResponse
- if t, ok := server.localRibMap[GLOBAL_RIB_NAME].Tables[grpcReq.RouteFamily]; ok {
+ if t, ok := server.globalRib.Tables[grpcReq.RouteFamily]; ok {
results = make([]*GrpcResponse, len(t.GetDestinations()))
switch grpcReq.RouteFamily {
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
- results = sortedDsts(server.localRibMap[GLOBAL_RIB_NAME].Tables[grpcReq.RouteFamily])
+ results = sortedDsts(server.globalRib.Tables[grpcReq.RouteFamily])
default:
i := 0
for _, dst := range t.GetDestinations() {
@@ -1370,12 +1352,11 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
var results []*GrpcResponse
if peer.isRouteServerClient() && peer.fsm.adminState != ADMIN_STATE_DOWN {
- remoteAddr := grpcReq.Name
- if t, ok := server.localRibMap[remoteAddr].Tables[grpcReq.RouteFamily]; ok {
+ if t, ok := peer.localRib.Tables[grpcReq.RouteFamily]; ok {
results = make([]*GrpcResponse, len(t.GetDestinations()))
switch grpcReq.RouteFamily {
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
- results = sortedDsts(server.localRibMap[remoteAddr].Tables[grpcReq.RouteFamily])
+ results = sortedDsts(peer.localRib.Tables[grpcReq.RouteFamily])
default:
i := 0
for _, dst := range t.GetDestinations() {
@@ -2309,15 +2290,14 @@ func (server *BgpServer) handleMrt(grpcReq *GrpcRequest) {
switch grpcReq.RequestType {
case REQ_MRT_GLOBAL_RIB:
- rib = server.localRibMap[GLOBAL_RIB_NAME]
+ rib = server.globalRib
case REQ_MRT_LOCAL_RIB:
- _, err := server.checkNeighborRequest(grpcReq)
+ peer, err := server.checkNeighborRequest(grpcReq)
if err != nil {
return
}
- var ok bool
- rib, ok = server.localRibMap[grpcReq.Name]
- if !ok {
+ rib = peer.localRib
+ if rib == nil {
result.ResponseErr = fmt.Errorf("no local rib for %s", grpcReq.Name)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
diff --git a/table/table_manager.go b/table/table_manager.go
index 6ea2841a..a8d9e8ff 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -19,6 +19,7 @@ import (
"bytes"
"fmt"
log "github.com/Sirupsen/logrus"
+ "github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet"
"net"
"reflect"
@@ -107,12 +108,16 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo) []*Path {
}
type TableManager struct {
- Tables map[bgp.RouteFamily]*Table
- Vrfs map[string]*Vrf
- owner string
- minLabel uint32
- maxLabel uint32
- nextLabel uint32
+ Tables map[bgp.RouteFamily]*Table
+ Vrfs map[string]*Vrf
+ owner string
+ minLabel uint32
+ maxLabel uint32
+ nextLabel uint32
+ importPolicies []*Policy
+ defaultImportPolicy config.DefaultPolicyType
+ exportPolicies []*Policy
+ defaultExportPolicy config.DefaultPolicyType
}
func NewTableManager(owner string, rfList []bgp.RouteFamily, minLabel, maxLabel uint32) *TableManager {
@@ -130,6 +135,92 @@ func NewTableManager(owner string, rfList []bgp.RouteFamily, minLabel, maxLabel
return t
}
+func (manager *TableManager) SetPolicy(c config.ApplyPolicy, p map[string]*Policy) {
+ manager.defaultImportPolicy = c.ApplyPolicyConfig.DefaultImportPolicy
+ manager.defaultExportPolicy = c.ApplyPolicyConfig.DefaultExportPolicy
+ f := func(dir string, arg []string) []*Policy {
+ ret := make([]*Policy, 0, len(arg))
+ for _, name := range arg {
+ pol, ok := p[name]
+ if !ok {
+ log.WithFields(log.Fields{
+ "Topic": "table",
+ "Key": manager.owner,
+ "PolicyName": name,
+ }).Warnf("not found %s. failed to set %s policy", name, dir)
+ continue
+ }
+ ret = append(ret, pol)
+ log.WithFields(log.Fields{
+ "Topic": "table",
+ "Key": manager.owner,
+ "PolicyName": name,
+ }).Infof("%s policy installed", dir)
+ }
+ return ret
+ }
+ manager.importPolicies = f("import", c.ApplyPolicyConfig.ImportPolicy)
+ manager.exportPolicies = f("export", c.ApplyPolicyConfig.ExportPolicy)
+
+}
+
+func (manager *TableManager) GetPolicy(d PolicyDirection) []*Policy {
+ switch d {
+ case POLICY_DIRECTION_IMPORT:
+ return manager.importPolicies
+ case POLICY_DIRECTION_EXPORT:
+ return manager.exportPolicies
+ }
+ return nil
+}
+
+func (manager *TableManager) GetDefaultPolicy(d PolicyDirection) RouteType {
+ var def config.DefaultPolicyType
+ switch d {
+ case POLICY_DIRECTION_IMPORT:
+ def = manager.defaultImportPolicy
+ case POLICY_DIRECTION_EXPORT:
+ def = manager.defaultExportPolicy
+ }
+
+ if def == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
+ return ROUTE_TYPE_ACCEPT
+ }
+ return ROUTE_TYPE_REJECT
+}
+
+func (manager *TableManager) ApplyPolicy(d PolicyDirection, paths []*Path) []*Path {
+ newpaths := make([]*Path, 0, len(paths))
+ for _, path := range paths {
+ result := ROUTE_TYPE_NONE
+ newpath := path
+ for _, p := range manager.GetPolicy(d) {
+ result, newpath = p.Apply(path)
+ if result != ROUTE_TYPE_NONE {
+ break
+ }
+ }
+
+ if result == ROUTE_TYPE_NONE {
+ result = manager.GetDefaultPolicy(d)
+ }
+
+ switch result {
+ case ROUTE_TYPE_ACCEPT:
+ newpaths = append(newpaths, newpath)
+ case ROUTE_TYPE_REJECT:
+ path.Filtered = true
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Key": path.GetSource().Address,
+ "Path": path,
+ "Direction": d,
+ }).Debug("reject")
+ }
+ }
+ return newpaths
+}
+
func (manager *TableManager) GetNextLabel(name, nexthop string, isWithdraw bool) (uint32, error) {
var label uint32
var err error