diff options
-rw-r--r-- | server/server.go | 10 | ||||
-rw-r--r-- | table/adj.go | 11 | ||||
-rw-r--r-- | table/path.go | 2 | ||||
-rw-r--r-- | test/scenario_test/route_server_policy_test.py | 132 |
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 |