summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/peer.go114
-rw-r--r--server/server.go41
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)
}
}