diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/peer.go | 114 | ||||
-rw-r--r-- | server/server.go | 41 |
2 files changed, 107 insertions, 48 deletions
diff --git a/server/peer.go b/server/peer.go index 8c3b2426..2e97ccee 100644 --- a/server/peer.go +++ b/server/peer.go @@ -41,6 +41,8 @@ type Peer struct { adjRib *table.AdjRib peerInfo *table.PeerInfo outgoing chan *bgp.BGPMessage + distPolicies []*policy.Policy + defaultDistributePolicy config.DefaultPolicyType } func NewPeer(g config.Global, config config.Neighbor) *Peer { @@ -170,8 +172,10 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) ([]*table.Path, bool, []*b break } table.UpdatePathAttrs4ByteAs(body) - pathList = table.ProcessMessage(m, peer.peerInfo) - peer.adjRib.UpdateIn(pathList) + originalPaths := table.ProcessMessage(m, peer.peerInfo) + peer.adjRib.UpdateIn(originalPaths) + // apply distribute filter before propagate + pathList = applyPolicies(peer, nil, POLICY_DIRECTION_DISTRIBUTE, originalPaths) } return pathList, update, bgpMsgList } @@ -298,6 +302,35 @@ func (peer *Peer) ToApiStruct() *api.Peer { } } +func (peer *Peer) setPolicy(policyMap map[string]*policy.Policy) { + // configure distribute policy + policyConfig := peer.config.ApplyPolicy + distPolicies := make([]*policy.Policy, 0) + for _, policyName := range policyConfig.DistributePolicies { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.config.NeighborAddress, + "PolicyName": policyName, + }).Info("distribute policy installed") + if pol, ok := policyMap[policyName]; ok { + log.Debug("distribute policy : ", pol) + distPolicies = append(distPolicies, pol) + } + } + peer.distPolicies = distPolicies + peer.defaultDistributePolicy = policyConfig.DefaultDistributePolicy + +} + + +func (peer *Peer) applyPolicies(original table.Path) (bool, table.Path) { + policies := peer.distPolicies + var d Direction = POLICY_DIRECTION_DISTRIBUTE + + return applyPolicy("Peer", peer.config.NeighborAddress.String(), d, policies, original) +} + + type LocalRib struct { rib *table.TableManager importPolicies []*policy.Policy @@ -377,43 +410,44 @@ func (loc *LocalRib) setPolicy(peer *Peer, policyMap map[string]*policy.Policy) // modified path. // If action of the policy is 'reject', return nil // -func (loc *LocalRib) applyPolicies(isExport bool, original *table.Path) (bool, *table.Path) { - - var applied bool = true +func (loc *LocalRib) applyPolicies(d Direction, original *table.Path) (bool, *table.Path) { var policies []*policy.Policy - var direction string - if isExport == true { - policies = loc.exportPolicies - direction = "export" - } else { - policies = loc.importPolicies - direction = "import" - } - - for _, pol := range policies { - if result, action, newpath := pol.Apply(original); result { - log.Debug("newpath: ", newpath) - if action == policy.ROUTE_TYPE_REJECT { - log.WithFields(log.Fields{ - "Topic": "Loc", - "Key": loc.OwnerName(), - "NRLI": original.GetNlri(), - "Dir": direction, - }).Debug("path was rejected") - // return applied, nil, this means path was rejected - return applied, nil - } else { - // return applied, new path - return applied, newpath - } - } - } - log.WithFields(log.Fields{ - "Topic": "Loc", - "Key": loc.OwnerName(), - "Len": len(policies), - "NRLI": original, - "Dir": direction, - }).Debug("no policy applied") - return !applied, original + switch(d) { + case POLICY_DIRECTION_EXPORT: + policies = loc.exportPolicies + case POLICY_DIRECTION_IMPORT: + policies = loc.importPolicies + } + return applyPolicy("Loc", loc.OwnerName(), d, policies, original) } + +func applyPolicy(component, owner string, d Direction, policies []*policy.Policy, original table.Path) (bool, table.Path){ + var applied bool = true + for _, pol := range policies { + if result, action, newpath := pol.Apply(original); result { + log.Debug("newpath: ", newpath) + if action == policy.ROUTE_TYPE_REJECT { + log.WithFields(log.Fields{ + "Topic": component, + "Key": owner, + "NRLI": original.GetNlri(), + "Dir": d, + }).Debug("path was rejected") + // return applied, nil, this means path was rejected + return applied, nil + } else { + // return applied, new path + return applied, newpath + } + } + } + + log.WithFields(log.Fields{ + "Topic": component, + "Key": owner, + "Len": len(policies), + "NRLI": original, + "Dir": d, + }).Debug("no policy applied") + return !applied, original +}
\ No newline at end of file diff --git a/server/server.go b/server/server.go index 96fb651d..fa831c19 100644 --- a/server/server.go +++ b/server/server.go @@ -34,6 +34,14 @@ const ( GLOBAL_RIB_NAME = "global" ) +type Direction string + +const ( + POLICY_DIRECTION_IMPORT Direction = "import" + POLICY_DIRECTION_EXPORT = "export" + POLICY_DIRECTION_DISTRIBUTE = "distribute" +) + type SenderMsg struct { messages []*bgp.BGPMessage sendCh chan *bgp.BGPMessage @@ -200,6 +208,8 @@ func (server *BgpServer) Serve() { loc := NewLocalRib(name, peer.configuredRFlist(), make(map[string]*policy.Policy)) server.addLocalRib(loc) loc.setPolicy(peer, server.policyMap) + // set distribute policy + peer.setPolicy(server.policyMap) pathList := make([]*table.Path, 0) for _, p := range server.neighborMap { @@ -210,7 +220,7 @@ func (server *BgpServer) Serve() { pathList = append(pathList, p.adjRib.GetInPathList(rf)...) } } - pathList = applyPolicies(peer, loc, false, pathList) + pathList = applyPolicies(peer, loc, POLICY_DIRECTION_IMPORT, pathList) if len(pathList) > 0 { loc.rib.ProcessPaths(pathList) } @@ -370,19 +380,32 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg { return msgs } -func applyPolicies(peer *Peer, loc *LocalRib, isExport bool, pathList []*table.Path) []*table.Path { +func applyPolicies(peer *Peer, loc *LocalRib, d Direction, pathList []*table.Path) []*table.Path { var defaultPolicy config.DefaultPolicyType - if isExport == true { + switch d { + case POLICY_DIRECTION_EXPORT: defaultPolicy = loc.defaultExportPolicy - } else { + case POLICY_DIRECTION_IMPORT: defaultPolicy = loc.defaultImportPolicy + case POLICY_DIRECTION_DISTRIBUTE: + defaultPolicy = peer.defaultDistributePolicy + default: + log.WithFields(log.Fields{ + "Topic": "Server", + "Key": peer.config.NeighborAddress, + }).Error("direction is not specified.") } 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 d == POLICY_DIRECTION_DISTRIBUTE { + applied, path = peer.applyPolicies(path) + } else { + applied, path = loc.applyPolicies(d, path) + } + if applied { if path == nil { log.WithFields(log.Fields{ @@ -462,11 +485,11 @@ func (server *BgpServer) propagateUpdate(neighborAddress string, RouteServerClie if loc.isGlobal() || loc.OwnerName() == neighborAddress { continue } - sendPathList, _ := loc.rib.ProcessPaths(applyPolicies(targetPeer, loc, false, dropSameAsPath(targetPeer.config.PeerAs, filterpath(targetPeer, pathList)))) + sendPathList, _ := loc.rib.ProcessPaths(applyPolicies(targetPeer, loc, POLICY_DIRECTION_IMPORT, 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) + sendPathList = applyPolicies(targetPeer, loc, POLICY_DIRECTION_EXPORT, sendPathList) if len(sendPathList) == 0 { continue } @@ -534,7 +557,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *fsmMsg, incoming chan * pathList := make([]*table.Path, 0) if peer.isRouteServerClient() { loc := server.localRibMap[peer.config.NeighborAddress.String()] - pathList = applyPolicies(peer, loc, true, peer.getBests(loc)) + pathList = applyPolicies(peer, loc, POLICY_DIRECTION_EXPORT, peer.getBests(loc)) } else { peer.config.LocalAddress = peer.fsm.LocalAddr() for _, path := range peer.getBests(globalRib) { @@ -621,6 +644,8 @@ func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) { } targetPeer := server.neighborMap[loc.OwnerName()] loc.setPolicy(targetPeer, server.policyMap) + // set distribute policy + targetPeer.setPolicy(server.policyMap) } } |