diff --git a/src/bgp/bgp_peer.sandesh b/src/bgp/bgp_peer.sandesh index 1c6e8e2c4e1..fd393108f24 100644 --- a/src/bgp/bgp_peer.sandesh +++ b/src/bgp/bgp_peer.sandesh @@ -243,6 +243,11 @@ struct ShowRoutingInstanceTable { 15: u64 walkers; } +struct ShowInstanceRoutingPolicyInfo { + 1: string policy_name (link="ShowRoutingPolicyReq"); + 2: u32 generation; +} + struct ShowRoutingInstance { 1: string name (link="ShowRoutingInstanceReq"); // Routing instance name 3: string virtual_network; // Virtual network @@ -254,6 +259,7 @@ struct ShowRoutingInstance { 7: bool deleted; // Deletion in progress 9: string deleted_at; // Delete timestamp 2: optional list tables; + 11: optional list routing_policies; } response sandesh ShowRoutingInstanceResp { @@ -406,7 +412,7 @@ struct ShowBgpStaticRouteConfig { } struct ShowBgpInstanceRoutingPolicyConfig { - 1: string policy_name; + 1: string policy_name (link="ShowBgpRoutingPolicyConfigReq"); 2: string sequence; } diff --git a/src/bgp/bgp_show_routing_instance.cc b/src/bgp/bgp_show_routing_instance.cc index 220c3d0bf4e..d50fcdc8c99 100644 --- a/src/bgp/bgp_show_routing_instance.cc +++ b/src/bgp/bgp_show_routing_instance.cc @@ -9,6 +9,7 @@ #include "bgp/bgp_peer_internal_types.h" #include "bgp/bgp_peer_membership.h" #include "bgp/routing-instance/routing_instance.h" +#include "bgp/routing-policy/routing_policy.h" using std::string; using std::vector; @@ -72,6 +73,15 @@ static void FillRoutingInstanceInfo(ShowRoutingInstance *sri, srit_list.push_back(srit); } sri->set_tables(srit_list); + vector policy_list; + BOOST_FOREACH(RoutingPolicyInfo info, rtinstance->routing_policies()) { + ShowInstanceRoutingPolicyInfo show_policy_info; + RoutingPolicyPtr policy = info.first; + show_policy_info.set_policy_name(policy->name()); + show_policy_info.set_generation(info.second); + policy_list.push_back(show_policy_info); + } + sri->set_routing_policies(policy_list); } } diff --git a/src/bgp/routing-policy/SConscript b/src/bgp/routing-policy/SConscript index 18c30d33205..27bcbee69c2 100644 --- a/src/bgp/routing-policy/SConscript +++ b/src/bgp/routing-policy/SConscript @@ -12,8 +12,14 @@ env.Append(CPPPATH = [env['TOP'] + '/bgp']) env.Append(CPPPATH = [env['TOP'] + '/db']) env.Append(CPPPATH = [env['TOP'] + '/io']) -librouting_policy = env.Library('routing_policy', +# Generate the source files +SandeshGenFiles = env.SandeshGenCpp('routing_policy.sandesh') +SandeshGenFiles += env.SandeshGenOnlyCpp('routing_policy_internal.sandesh') +SandeshGenSrcs = env.ExtractCpp(SandeshGenFiles) + +librouting_policy = env.Library('routing_policy', SandeshGenSrcs + ['routing_policy.cc', 'routing_policy_action.cc', - 'routing_policy_match.cc']) + 'routing_policy_match.cc', + 'show_routing_policy.cc']) diff --git a/src/bgp/routing-policy/routing_policy.h b/src/bgp/routing-policy/routing_policy.h index e85b228b6fd..c2afdf4bbad 100644 --- a/src/bgp/routing-policy/routing_policy.h +++ b/src/bgp/routing-policy/routing_policy.h @@ -255,6 +255,7 @@ class RoutingPolicy { PolicyResult operator()(const BgpRoute *route, BgpAttr *attr) const; uint32_t generation() const { return generation_; } + uint32_t refcount() const { return refcount_; } private: friend class RoutingPolicyMgr; diff --git a/src/bgp/routing-policy/routing_policy.sandesh b/src/bgp/routing-policy/routing_policy.sandesh new file mode 100644 index 00000000000..1178216c245 --- /dev/null +++ b/src/bgp/routing-policy/routing_policy.sandesh @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. + */ + +include "bgp/bgp_peer.sandesh" +include "bgp/routing-policy/routing_policy_internal.sandesh" + +struct PolicyTermInfo { + 1: bool terminal; + 2: list matches; + 3: list actions; +} + +struct ShowRoutingPolicyInfo { + 1: string name; + 2: u32 generation; + 3: u32 ref_count; + 4: list terms; + 5: bool deleted; +} + +response sandesh ShowRoutingPolicyResp { + 1: list routing_policies; + 2: optional string next_batch (link="ShowRoutingPolicyReqIterate", + link_title="next_batch"); +} + +request sandesh ShowRoutingPolicyReq { + 1: string search_string; +} diff --git a/src/bgp/routing-policy/routing_policy_action.cc b/src/bgp/routing-policy/routing_policy_action.cc index 9f2e248f0a7..ce3b123b5ac 100644 --- a/src/bgp/routing-policy/routing_policy_action.cc +++ b/src/bgp/routing-policy/routing_policy_action.cc @@ -7,16 +7,20 @@ #include #include +#include #include #include #include #include +using std::copy; +using std::ostringstream; +using std::string; -UpdateCommunity::UpdateCommunity(const std::vector communities, - std::string op) { - BOOST_FOREACH(const std::string &community, communities) { +UpdateCommunity::UpdateCommunity(const std::vector communities, + string op) { + BOOST_FOREACH(const string &community, communities) { uint32_t value = CommunityType::CommunityFromString(community); if (value) communities_.push_back(value); } @@ -53,8 +57,19 @@ void UpdateCommunity::operator()(BgpAttr *attr) const { } } -std::string UpdateCommunity::ToString() const { - return "Update Community"; +string UpdateCommunity::ToString() const { + ostringstream oss; + if (op_ == SET) oss << "community set [ "; + else if (op_ == ADD) oss << "community add [ "; + else if (op_ == REMOVE) oss << "community remove [ "; + + BOOST_FOREACH(uint32_t community, communities()) { + string name = CommunityType::CommunityToString(community); + oss << name << ","; + } + oss.seekp(-1, oss.cur); + oss << " ]"; + return oss.str(); } bool UpdateCommunity::IsEqual(const RoutingPolicyAction &community) const { @@ -73,8 +88,10 @@ void UpdateLocalPref::operator()(BgpAttr *attr) const { attr->set_local_pref(local_pref_); } -std::string UpdateLocalPref::ToString() const { - return "Update LocalPref"; +string UpdateLocalPref::ToString() const { + ostringstream oss; + oss << "local-pref " << local_pref_; + return oss.str(); } bool UpdateLocalPref::IsEqual(const RoutingPolicyAction &local_pref) const { diff --git a/src/bgp/routing-policy/routing_policy_internal.sandesh b/src/bgp/routing-policy/routing_policy_internal.sandesh new file mode 100644 index 00000000000..8aa31997c0b --- /dev/null +++ b/src/bgp/routing-policy/routing_policy_internal.sandesh @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. + */ +request sandesh ShowRoutingPolicyReqIterate { + 1: string iterate_info; +} diff --git a/src/bgp/routing-policy/routing_policy_match.cc b/src/bgp/routing-policy/routing_policy_match.cc index e45af8f61a6..0f2272baafd 100644 --- a/src/bgp/routing-policy/routing_policy_match.cc +++ b/src/bgp/routing-policy/routing_policy_match.cc @@ -7,12 +7,15 @@ #include #include +#include #include #include -MatchCommunity::MatchCommunity(const std::vector &communities) { - BOOST_FOREACH(const std::string &community, communities) { +using std::ostringstream; +using std::string; +MatchCommunity::MatchCommunity(const std::vector &communities) { + BOOST_FOREACH(const string &community, communities) { uint32_t value = CommunityType::CommunityFromString(community); // Invalid community from config is ignored if (value) { @@ -43,8 +46,16 @@ bool MatchCommunity::Match(const BgpRoute *route, return false; } -std::string MatchCommunity::ToString() const { - return "Match community"; +string MatchCommunity::ToString() const { + ostringstream oss; + oss << "community [ "; + BOOST_FOREACH(uint32_t community, communities()) { + string name = CommunityType::CommunityToString(community); + oss << name << ","; + } + oss.seekp(-1, oss.cur); + oss << " ]"; + return oss.str(); } bool MatchCommunity::IsEqual(const RoutingPolicyMatch &community) const { @@ -54,8 +65,7 @@ bool MatchCommunity::IsEqual(const RoutingPolicyMatch &community) const { } template -MatchPrefix::MatchPrefix(const std::string &prefix, - const std::string &match_type) { +MatchPrefix::MatchPrefix(const string &prefix, const string &match_type) { boost::system::error_code ec; match_prefix_ = PrefixT::FromString(prefix, &ec); if (strcmp(match_type.c_str(), "exact") == 0) { @@ -98,8 +108,12 @@ bool MatchPrefix::IsEqual(const RoutingPolicyMatch &prefix) const { } template -std::string MatchPrefix::ToString() const { - return "Match Prefix"; +string MatchPrefix::ToString() const { + ostringstream oss; + oss << "prefix " << match_prefix_.ToString(); + if (match_type_ == LONGER) oss << " longer"; + else if (match_type_ == ORLONGER) oss << " orlonger"; + return oss.str(); } template class MatchPrefix; diff --git a/src/bgp/routing-policy/show_routing_policy.cc b/src/bgp/routing-policy/show_routing_policy.cc new file mode 100644 index 00000000000..59ddb1464eb --- /dev/null +++ b/src/bgp/routing-policy/show_routing_policy.cc @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. + */ + +#include "bgp/bgp_show_handler.h" + +#include + +#include "bgp/bgp_server.h" +#include "bgp/bgp_show_handler.h" +#include "bgp/routing-policy/routing_policy.h" +#include "bgp/routing-policy/routing_policy_action.h" +#include "bgp/routing-policy/routing_policy_match.h" +#include "bgp/routing-policy/routing_policy_types.h" + +using std::string; +using std::vector; + +// +// Fill in information for a policy. +// +static void FillRoutingPolicyInfo(ShowRoutingPolicyInfo *srpi, + const BgpSandeshContext *bsc, const RoutingPolicy *policy, + bool summary) { + srpi->set_name(policy->name()); + srpi->set_generation(policy->generation()); + srpi->set_ref_count(policy->refcount()); + srpi->set_deleted(policy->deleted()); + vector term_list; + BOOST_FOREACH(RoutingPolicy::PolicyTermPtr term, policy->terms()) { + PolicyTermInfo show_term; + show_term.set_terminal(term->terminal()); + vector match_list; + BOOST_FOREACH(RoutingPolicyMatch *match, term->matches()) { + match_list.push_back(match->ToString()); + } + show_term.set_matches(match_list); + vector action_list; + BOOST_FOREACH(RoutingPolicyAction *action, term->actions()) { + action_list.push_back(action->ToString()); + } + show_term.set_actions(action_list); + term_list.push_back(show_term); + } + srpi->set_terms(term_list); +} + +// +// Fill in information for list of policies. +// +static bool FillRoutingPolicyInfoList(const BgpSandeshContext *bsc, + bool summary, uint32_t page_limit, uint32_t iter_limit, + const string &start_policy, const string &search_string, + vector *srpi_list, string *next_policy) { + RoutingPolicyMgr *rpm = bsc->bgp_server->routing_policy_mgr(); + RoutingPolicyMgr::const_name_iterator it = + rpm->name_clower_bound(start_policy); + for (uint32_t iter_count = 0; it != rpm->name_cend(); ++it, ++iter_count) { + const RoutingPolicy *policy = it->second; + if (!search_string.empty() && + (policy->name().find(search_string) == string::npos) && + (search_string != "deleted" || !policy->deleted())) { + continue; + } + ShowRoutingPolicyInfo srpi; + FillRoutingPolicyInfo(&srpi, bsc, policy, summary); + srpi_list->push_back(srpi); + if (srpi_list->size() >= page_limit) + break; + if (iter_count >= iter_limit) + break; + } + + // All done if we've looked at all policies. + if (it == rpm->name_cend() || ++it == rpm->name_end()) + return true; + + // Return true if we've reached the page limit, false if we've reached the + // iteration limit. + bool done = srpi_list->size() >= page_limit; + *next_policy = it->second->name(); + return done; +} + +// Specialization of BgpShowHandler<>::CallbackCommon. +template <> +bool BgpShowHandler::CallbackCommon( + const BgpSandeshContext *bsc, Data *data) { + uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit; + uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit; + string next_policy; + bool done = FillRoutingPolicyInfoList(bsc, false, page_limit, iter_limit, + data->next_entry, data->search_string, &data->show_list, + &next_policy); + if (!next_policy.empty()) + SaveContextToData(next_policy, done, data); + return done; +} + +// Specialization of BgpShowHandler<>::FillShowList. +template <> +void BgpShowHandler::FillShowList( + ShowRoutingPolicyResp *resp, + const vector &show_list) { + resp->set_routing_policies(show_list); +} + +// Handler for ShowRoutingPolicyReq. +void ShowRoutingPolicyReq::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRoutingPolicyReq, + ShowRoutingPolicyReqIterate, + ShowRoutingPolicyResp, + ShowRoutingPolicyInfo>::Callback, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRoutingPolicyReq, + ShowRoutingPolicyReqIterate, + ShowRoutingPolicyResp, + ShowRoutingPolicyInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} + +// +// Handler for ShowRoutingPolicyReqIterate. +// +void ShowRoutingPolicyReqIterate::HandleRequest() const { + RequestPipeline::PipeSpec ps(this); + RequestPipeline::StageSpec s1; + TaskScheduler *scheduler = TaskScheduler::GetInstance(); + + s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand"); + s1.cbFn_ = boost::bind(&BgpShowHandler< + ShowRoutingPolicyReq, + ShowRoutingPolicyReqIterate, + ShowRoutingPolicyResp, + ShowRoutingPolicyInfo>::CallbackIterate, _1, _2, _3, _4, _5); + s1.allocFn_ = BgpShowHandler< + ShowRoutingPolicyReq, + ShowRoutingPolicyReqIterate, + ShowRoutingPolicyResp, + ShowRoutingPolicyInfo>::CreateData; + s1.instances_.push_back(0); + ps.stages_.push_back(s1); + RequestPipeline rp(ps); +} diff --git a/src/bgp/test/routing_policy_test.cc b/src/bgp/test/routing_policy_test.cc index 7be69e391e2..f79ed4be9f1 100644 --- a/src/bgp/test/routing_policy_test.cc +++ b/src/bgp/test/routing_policy_test.cc @@ -12,11 +12,15 @@ #include "bgp/bgp_config_ifmap.h" #include "bgp/bgp_config_parser.h" #include "bgp/bgp_factory.h" +#include "bgp/bgp_sandesh.h" #include "bgp/inet/inet_table.h" #include "bgp/inet6/inet6_table.h" #include "bgp/l3vpn/inetvpn_table.h" #include "bgp/origin-vn/origin_vn.h" #include "bgp/routing-instance/rtarget_group_mgr.h" +#include "bgp/routing-policy/routing_policy_action.h" +#include "bgp/routing-policy/routing_policy_match.h" +#include "bgp/routing-policy/routing_policy_types.h" #include "bgp/test/bgp_server_test_util.h" #include "bgp/test/bgp_test_util.h" #include "control-node/control_node.h" @@ -263,7 +267,6 @@ class RoutingPolicyTest : public ::testing::Test { return rt; } - vector GetOriginalCommunityListFromRoute(const BgpPath *path) { const Community *comm = path->GetOriginalAttr()->community(); if (comm == NULL) return vector(); @@ -275,7 +278,6 @@ class RoutingPolicyTest : public ::testing::Test { return list; } - vector GetCommunityListFromRoute(const BgpPath *path) { const Community *comm = path->GetAttr()->community(); if (comm == NULL) return vector(); @@ -287,6 +289,14 @@ class RoutingPolicyTest : public ::testing::Test { return list; } + const RoutingPolicy *FindRoutingPolicy(const string &policy_name) { + return bgp_server_->routing_policy_mgr()->GetRoutingPolicy(policy_name); + } + + const RoutingInstance *FindRoutingInstance(const string &inst) { + return bgp_server_->routing_instance_mgr()->GetRoutingInstance(inst); + } + EventManager evm_; DB config_db_; DBGraph config_graph_; @@ -1857,7 +1867,7 @@ TEST_F(RoutingPolicyTest, PolicyUpdate_ToReject) { // // 1. Routing instance is attached two network policies -// 2. Add route that matches both policies. +// 2. Add route that matches both policies. // Route matches the first policy and rejected // 3. Update of the order of network policy on the routing instance // 4. Route matches first policy and accepted @@ -1909,7 +1919,7 @@ TEST_F(RoutingPolicyTest, MultiplePolicies_UpdateOrder) { // // 1. Routing instance is attached two network policies -// 2. Add route that matches both policies. +// 2. Add route that matches both policies. // Route matches the first policy and accepted // 3. Update of the order of network policy on the routing instance // 4. Route matches the second policy and rejected @@ -1963,6 +1973,320 @@ TEST_F(RoutingPolicyTest, MultiplePolicies_UpdateOrder_1) { "2001:db8:85a3::8a2e:370:7334/128"); } +static void ValidateShowRoutingPolicyResponse( + Sandesh *sandesh, bool *done, + const vector &policy_list) { + ShowRoutingPolicyResp *resp = + dynamic_cast(sandesh); + EXPECT_TRUE(resp != NULL); + EXPECT_EQ(policy_list.size(), resp->get_routing_policies().size()); + + BOOST_FOREACH(const ShowRoutingPolicyInfo &policy, policy_list) { + bool found = false; + BOOST_FOREACH(const ShowRoutingPolicyInfo &resp_policy, + resp->get_routing_policies()) { + if (policy.get_name() == resp_policy.get_name()) { + found = true; + EXPECT_EQ(policy.get_terms().size(), + resp_policy.get_terms().size()); + ASSERT_TRUE(std::equal(policy.get_terms().begin(), + policy.get_terms().end(), + resp_policy.get_terms().begin())); + break; + } + } + EXPECT_TRUE(found); + LOG(DEBUG, "Verified " << policy.get_name()); + } + + *done = true; +} + +static void ValidateShowRoutingInstanceRoutingPolicyResponse( + Sandesh *sandesh, bool *done, + const vector &policy_list) { + ShowRoutingInstanceResp *resp = + dynamic_cast(sandesh); + EXPECT_TRUE(resp != NULL); + EXPECT_EQ(1, resp->get_instances().size()); + EXPECT_EQ(policy_list.size(), + resp->get_instances()[0].get_routing_policies().size()); + BOOST_FOREACH(const ShowInstanceRoutingPolicyInfo &info, policy_list) { + bool found = false; + BOOST_FOREACH(const ShowInstanceRoutingPolicyInfo &resp_info, + resp->get_instances()[0].get_routing_policies()) { + if (info.get_policy_name() == resp_info.get_policy_name()) { + found = true; + EXPECT_EQ(info.get_generation(), resp_info.get_generation()); + break; + } + } + EXPECT_TRUE(found); + } + *done = true; +} + +TEST_F(RoutingPolicyTest, ShowPolicy_0) { + string content = + FileRead("controller/src/bgp/testdata/routing_policy_6c.xml"); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + + BgpSandeshContext sandesh_context; + sandesh_context.bgp_server = bgp_server_.get(); + Sandesh::set_client_context(&sandesh_context); + + vector policy_list; + + vector policy_name_list = list_of("basic"); + BOOST_FOREACH(string policy_name, policy_name_list) { + const RoutingPolicy *policy = FindRoutingPolicy(policy_name); + ASSERT_TRUE(policy != NULL); + ShowRoutingPolicyInfo show_policy; + show_policy.set_name(policy->name()); + show_policy.set_deleted(policy->deleted()); + show_policy.set_generation(policy->generation()); + show_policy.set_ref_count(policy->refcount()); + std::vector terms_list; + BOOST_FOREACH(RoutingPolicy::PolicyTermPtr term, policy->terms()) { + PolicyTermInfo show_term; + show_term.set_terminal(term->terminal()); + vector match_list; + BOOST_FOREACH(RoutingPolicyMatch *match, term->matches()) { + match_list.push_back(match->ToString()); + } + show_term.set_matches(match_list); + vector action_list; + BOOST_FOREACH(RoutingPolicyAction *action, term->actions()) { + action_list.push_back(action->ToString()); + } + show_term.set_actions(action_list); + terms_list.push_back(show_term); + } + show_policy.set_terms(terms_list); + policy_list.push_back(show_policy); + } + + bool validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingPolicyResponse, _1, &validate_done, + policy_list)); + + ShowRoutingPolicyReq *show_req = new ShowRoutingPolicyReq; + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + vector instance_policy_list; + const RoutingInstance *rtinstance = FindRoutingInstance("test"); + BOOST_FOREACH(RoutingPolicyInfo info, rtinstance->routing_policies()) { + ShowInstanceRoutingPolicyInfo sirpi; + sirpi.set_generation(info.second); + sirpi.set_policy_name(info.first->name()); + instance_policy_list.push_back(sirpi); + } + + validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingInstanceRoutingPolicyResponse, + _1, &validate_done, instance_policy_list)); + + ShowRoutingInstanceReq *show_instance_req = new ShowRoutingInstanceReq; + show_instance_req->set_search_string("test"); + show_instance_req->HandleRequest(); + show_instance_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); +} + +// show policy test with multiple policies +TEST_F(RoutingPolicyTest, ShowPolicy_1) { + string content = + FileRead("controller/src/bgp/testdata/routing_policy_1a.xml"); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + + BgpSandeshContext sandesh_context; + sandesh_context.bgp_server = bgp_server_.get(); + Sandesh::set_client_context(&sandesh_context); + + vector policy_list; + + vector policy_name_list = list_of("basic_0")("basic_1"); + BOOST_FOREACH(string policy_name, policy_name_list) { + const RoutingPolicy *policy = FindRoutingPolicy(policy_name); + ASSERT_TRUE(policy != NULL); + ShowRoutingPolicyInfo show_policy; + show_policy.set_name(policy->name()); + show_policy.set_deleted(policy->deleted()); + show_policy.set_generation(policy->generation()); + show_policy.set_ref_count(policy->refcount()); + std::vector terms_list; + BOOST_FOREACH(RoutingPolicy::PolicyTermPtr term, policy->terms()) { + PolicyTermInfo show_term; + show_term.set_terminal(term->terminal()); + vector match_list; + BOOST_FOREACH(RoutingPolicyMatch *match, term->matches()) { + match_list.push_back(match->ToString()); + } + show_term.set_matches(match_list); + vector action_list; + BOOST_FOREACH(RoutingPolicyAction *action, term->actions()) { + action_list.push_back(action->ToString()); + } + show_term.set_actions(action_list); + terms_list.push_back(show_term); + } + show_policy.set_terms(terms_list); + policy_list.push_back(show_policy); + } + + // Introspect with no search string + bool validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingPolicyResponse, _1, &validate_done, + policy_list)); + ShowRoutingPolicyReq *show_req = new ShowRoutingPolicyReq; + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + // Introspect with empty search string + validate_done = false; + show_req = new ShowRoutingPolicyReq; + show_req->set_search_string(""); + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + // Introspect with "a" search string + validate_done = false; + show_req = new ShowRoutingPolicyReq; + show_req->set_search_string("a"); + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + // Introspect with "basic_1" search string + validate_done = false; + policy_list[0] = policy_list[1]; + policy_list.resize(1); + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingPolicyResponse, _1, &validate_done, + policy_list)); + show_req = new ShowRoutingPolicyReq; + show_req->set_search_string("basic_1"); + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + vector instance_policy_list; + const RoutingInstance *rtinstance = FindRoutingInstance("test"); + BOOST_FOREACH(RoutingPolicyInfo info, rtinstance->routing_policies()) { + ShowInstanceRoutingPolicyInfo sirpi; + sirpi.set_generation(info.second); + sirpi.set_policy_name(info.first->name()); + instance_policy_list.push_back(sirpi); + } + + validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingInstanceRoutingPolicyResponse, + _1, &validate_done, instance_policy_list)); + + ShowRoutingInstanceReq *show_instance_req = new ShowRoutingInstanceReq; + show_instance_req->set_search_string("test"); + show_instance_req->HandleRequest(); + show_instance_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); +} + +// Show policy after policy update +TEST_F(RoutingPolicyTest, ShowPolicy_2) { + string content = + FileRead("controller/src/bgp/testdata/routing_policy_6c.xml"); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + + // Now update the policy + content = FileRead("controller/src/bgp/testdata/routing_policy_2.xml"); + EXPECT_TRUE(parser_.Parse(content)); + task_util::WaitForIdle(); + + BgpSandeshContext sandesh_context; + sandesh_context.bgp_server = bgp_server_.get(); + Sandesh::set_client_context(&sandesh_context); + + vector policy_list; + + vector policy_name_list = list_of("basic"); + BOOST_FOREACH(string policy_name, policy_name_list) { + const RoutingPolicy *policy = FindRoutingPolicy(policy_name); + ASSERT_TRUE(policy != NULL); + ShowRoutingPolicyInfo show_policy; + show_policy.set_name(policy->name()); + show_policy.set_deleted(policy->deleted()); + show_policy.set_generation(policy->generation()); + show_policy.set_ref_count(policy->refcount()); + std::vector terms_list; + BOOST_FOREACH(RoutingPolicy::PolicyTermPtr term, policy->terms()) { + PolicyTermInfo show_term; + show_term.set_terminal(term->terminal()); + vector match_list; + BOOST_FOREACH(RoutingPolicyMatch *match, term->matches()) { + match_list.push_back(match->ToString()); + } + show_term.set_matches(match_list); + vector action_list; + BOOST_FOREACH(RoutingPolicyAction *action, term->actions()) { + action_list.push_back(action->ToString()); + } + show_term.set_actions(action_list); + terms_list.push_back(show_term); + } + show_policy.set_terms(terms_list); + policy_list.push_back(show_policy); + } + + bool validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingPolicyResponse, _1, &validate_done, + policy_list)); + + ShowRoutingPolicyReq *show_req = new ShowRoutingPolicyReq; + show_req->HandleRequest(); + show_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); + + vector instance_policy_list; + const RoutingInstance *rtinstance = FindRoutingInstance("test"); + BOOST_FOREACH(RoutingPolicyInfo info, rtinstance->routing_policies()) { + ShowInstanceRoutingPolicyInfo sirpi; + sirpi.set_generation(info.second); + sirpi.set_policy_name(info.first->name()); + instance_policy_list.push_back(sirpi); + } + + validate_done = false; + Sandesh::set_response_callback( + boost::bind(ValidateShowRoutingInstanceRoutingPolicyResponse, + _1, &validate_done, instance_policy_list)); + + ShowRoutingInstanceReq *show_instance_req = new ShowRoutingInstanceReq; + show_instance_req->set_search_string("test"); + show_instance_req->HandleRequest(); + show_instance_req->Release(); + task_util::WaitForIdle(); + TASK_UTIL_EXPECT_TRUE(validate_done); +} + class TestEnvironment : public ::testing::Environment { virtual ~TestEnvironment() { } }; diff --git a/src/control-node/SConscript b/src/control-node/SConscript index 75f538d7ee8..5e4f14fc5ee 100644 --- a/src/control-node/SConscript +++ b/src/control-node/SConscript @@ -162,7 +162,7 @@ if sys.platform != 'darwin': '-lbgp_l3vpn', '-lbgp_inet', '-lbgp_inet6', '-lbgp_inet6vpn', '-lbgp_evpn', '-lbgp_ermvpn', '-lextended_community', '-lrtarget', - '-lifmap_server', '-lcpuinfo', '-lrouting_instance', + '-lifmap_server', '-lcpuinfo', '-lrouting_instance', '-lrouting_policy', '-Wl,--no-whole-archive']) else: env.Prepend(LINKFLAGS = ['-Wl,-force_load,' + lib_l3vpn.path])