summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-02-01 22:46:33 +0900
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2016-02-01 23:11:12 +0900
commit21b7301e049dc1ac5128001e49ec1a2b194ead7b (patch)
treeeeec9bec953df8e5bc2b92ee2fdcedad492a2646
parent2419b8add20024c3c90210a36cf208a8ef467a10 (diff)
server: fix soft-reset-in to handle in-policy change properly
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--server/server.go10
-rw-r--r--table/adj.go11
-rw-r--r--table/path.go2
-rw-r--r--test/scenario_test/route_server_policy_test.py132
4 files changed, 153 insertions, 2 deletions
diff --git a/server/server.go b/server/server.go
index a49914e0..c90f8306 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1885,10 +1885,18 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
for _, peer := range peers {
pathList := []*table.Path{}
for _, path := range peer.adjRibIn.PathList([]bgp.RouteFamily{grpcReq.RouteFamily}, false) {
- if path = server.policy.ApplyPolicy(peer.ID(), table.POLICY_DIRECTION_IN, path, nil); path != nil {
+ exResult := path.Filtered(peer.ID())
+ path.Filter(peer.ID(), table.POLICY_DIRECTION_NONE)
+ if server.policy.ApplyPolicy(peer.ID(), table.POLICY_DIRECTION_IN, path, nil) != nil {
pathList = append(pathList, path.Clone(false))
+ } else {
+ path.Filter(peer.ID(), table.POLICY_DIRECTION_IN)
+ if exResult != table.POLICY_DIRECTION_IN {
+ pathList = append(pathList, path.Clone(true))
+ }
}
}
+ peer.adjRibIn.RefreshAcceptedNumber([]bgp.RouteFamily{grpcReq.RouteFamily})
m, _ := server.propagateUpdate(peer, pathList)
msgs = append(msgs, m...)
}
diff --git a/table/adj.go b/table/adj.go
index f7914557..65d9d161 100644
--- a/table/adj.go
+++ b/table/adj.go
@@ -75,6 +75,17 @@ func (adj *AdjRib) Update(pathList []*Path) {
}
}
+func (adj *AdjRib) RefreshAcceptedNumber(rfList []bgp.RouteFamily) {
+ for _, rf := range rfList {
+ adj.accepted[rf] = 0
+ for _, p := range adj.table[rf] {
+ if p.Filtered(adj.id) != POLICY_DIRECTION_IN {
+ adj.accepted[rf]++
+ }
+ }
+ }
+}
+
func (adj *AdjRib) PathList(rfList []bgp.RouteFamily, accepted bool) []*Path {
pathList := make([]*Path, 0, adj.Count(rfList))
for _, rf := range rfList {
diff --git a/table/path.go b/table/path.go
index 65c33a26..12739ec6 100644
--- a/table/path.go
+++ b/table/path.go
@@ -214,7 +214,7 @@ func (path *Path) ToApiStruct(id string) *api.Path {
Age: int64(time.Now().Sub(path.OriginInfo().timestamp).Seconds()),
IsWithdraw: path.IsWithdraw,
Validation: int32(path.OriginInfo().validation.ToInt()),
- Filtered: path.Filtered(id) > POLICY_DIRECTION_NONE,
+ Filtered: path.Filtered(id) == POLICY_DIRECTION_IN,
Family: family,
}
}
diff --git a/test/scenario_test/route_server_policy_test.py b/test/scenario_test/route_server_policy_test.py
index f01d63e3..28163796 100644
--- a/test/scenario_test/route_server_policy_test.py
+++ b/test/scenario_test/route_server_policy_test.py
@@ -3316,6 +3316,138 @@ class ExportPolicyExCommunityAdd(object):
lookup_scenario("ExportPolicyExCommunityAdd").check2(env)
+@register_scenario
+class InPolicyUpdate2(object):
+ """
+ No.47 in-policy update test
+ r1:192.168.2.0
+ r2:192.168.20.0
+ r3:192.168.200.0
+ -------------------------------------------
+ | q1 |
+ e1 ->(r1,r2,r3)-> | ->(r1,r2)-> rib ->(r1,r2)-> adj-rib-out | ->(r1,r2)-> q1
+ | |
+ | q2 |
+ | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2
+ -------------------------------------------
+ |
+ update distribute policy
+ |
+ V
+ -------------------------------------
+ | q1 |
+ e1 ->(r1,r2,r3)-> | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q1
+ | |
+ | q2 |
+ | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2
+ -------------------------------------
+ """
+ @staticmethod
+ def boot(env):
+ lookup_scenario('ImportPolicy').boot(env)
+
+ @staticmethod
+ def setup(env):
+ g1 = env.g1
+ e1 = env.e1
+ q1 = env.q1
+ q2 = env.q2
+
+ p0 = {'ip-prefix': '192.168.20.0/24'}
+
+ ps0 = {'prefix-set-name': 'ps0',
+ 'prefix-list': [p0]}
+ g1.set_prefix_set(ps0)
+
+ ns0 = {'neighbor-set-name': 'ns0',
+ 'neighbor-info-list': [g1.peers[e1]['neigh_addr'].split('/')[0]]}
+ g1.set_neighbor_set(ns0)
+
+ st0 = {'name': 'st0',
+ 'conditions': {
+ 'match-prefix-set': {'prefix-set': ps0['prefix-set-name']},
+ 'match-neighbor-set': {'neighbor-set': ns0['neighbor-set-name']}},
+ 'actions': {'route-disposition': {'accept-route': False}}}
+
+ policy = {'name': 'policy0',
+ 'type': 'in',
+ 'statements': [st0]}
+ g1.add_policy(policy, e1)
+
+ e1.add_route('192.168.2.0/24')
+ e1.add_route('192.168.20.0/24')
+ e1.add_route('192.168.200.0/24')
+
+ for c in [e1, q1, q2]:
+ g1.wait_for(BGP_FSM_ESTABLISHED, c)
+
+ @staticmethod
+ def check(env):
+ g1 = env.g1
+ e1 = env.e1
+ q1 = env.q1
+ q2 = env.q2
+ wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3)
+ wait_for(lambda: len(g1.get_local_rib(q1)) == 2)
+ wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2)
+ wait_for(lambda: len(q1.get_global_rib()) == 2)
+ wait_for(lambda: len(g1.get_local_rib(q2)) == 2)
+ wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2)
+ wait_for(lambda: len(q2.get_global_rib()) == 2)
+
+ @staticmethod
+ def setup2(env):
+ g1 = env.g1
+ e1 = env.e1
+ q1 = env.q1
+ q2 = env.q2
+ g1.clear_policy()
+
+ p0 = {'ip-prefix': '192.168.20.0/24'}
+ p1 = {'ip-prefix': '192.168.200.0/24'}
+
+ ps0 = {'prefix-set-name': 'ps0',
+ 'prefix-list': [p0, p1]}
+ g1.set_prefix_set(ps0)
+
+ ns0 = {'neighbor-set-name': 'ns0',
+ 'neighbor-info-list': [g1.peers[e1]['neigh_addr'].split('/')[0]]}
+ g1.set_neighbor_set(ns0)
+
+ st0 = {'name': 'st0',
+ 'conditions': {'match-prefix-set': {'prefix-set': ps0['prefix-set-name']},
+ 'match-neighbor-set': {'neighbor-set': ns0['neighbor-set-name']}},
+ 'actions': {'route-disposition': {'accept-route': False}}}
+
+ policy = {'name': 'policy0',
+ 'type': 'in',
+ 'statements': [st0]}
+ g1.add_policy(policy, e1)
+ g1.softreset(e1)
+
+ @staticmethod
+ def check2(env):
+ g1 = env.g1
+ e1 = env.e1
+ q1 = env.q1
+ q2 = env.q2
+ wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3)
+ wait_for(lambda: len(g1.get_local_rib(q1)) == 1)
+ wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1)
+ wait_for(lambda: len(q1.get_global_rib()) == 1)
+ wait_for(lambda: len(g1.get_local_rib(q2)) == 1)
+ wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1)
+ wait_for(lambda: len(q2.get_global_rib()) == 1)
+
+ @staticmethod
+ def executor(env):
+ lookup_scenario("InPolicyUpdate2").boot(env)
+ lookup_scenario("InPolicyUpdate2").setup(env)
+ lookup_scenario("InPolicyUpdate2").check(env)
+ lookup_scenario("InPolicyUpdate2").setup2(env)
+ lookup_scenario("InPolicyUpdate2").check2(env)
+
+
class TestGoBGPBase():
wait_per_retry = 5