Line data Source code
1 : /*
2 : * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <boost/foreach.hpp>
6 :
7 : #include "bgp/bgp_server.h"
8 : #include "bgp/bgp_show_handler.h"
9 : #include "bgp/routing-policy/routing_policy.h"
10 : #include "bgp/routing-policy/routing_policy_action.h"
11 : #include "bgp/routing-policy/routing_policy_match.h"
12 : #include "bgp/routing-policy/routing_policy_types.h"
13 :
14 : using std::string;
15 : using std::vector;
16 :
17 : //
18 : // Fill in information for a policy.
19 : //
20 9 : static void FillRoutingPolicyInfo(ShowRoutingPolicyInfo *srpi,
21 : const BgpSandeshContext *bsc, const RoutingPolicy *policy,
22 : bool summary) {
23 9 : srpi->set_name(policy->name());
24 9 : srpi->set_generation(policy->generation());
25 9 : srpi->set_ref_count(policy->refcount());
26 9 : srpi->set_deleted(policy->deleted());
27 9 : vector<PolicyTermInfo> term_list;
28 37 : BOOST_FOREACH(RoutingPolicy::PolicyTermPtr term, policy->terms()) {
29 14 : PolicyTermInfo show_term;
30 14 : show_term.set_terminal(term->terminal());
31 14 : vector<string> match_list;
32 42 : BOOST_FOREACH(RoutingPolicyMatch *match, term->matches()) {
33 14 : match_list.push_back(match->ToString());
34 : }
35 14 : show_term.set_matches(match_list);
36 14 : vector<string> action_list;
37 64 : BOOST_FOREACH(RoutingPolicyAction *action, term->actions()) {
38 25 : action_list.push_back(action->ToString());
39 : }
40 14 : show_term.set_actions(action_list);
41 14 : term_list.push_back(show_term);
42 28 : }
43 9 : srpi->set_terms(term_list);
44 9 : }
45 :
46 : //
47 : // Fill in information for list of policies.
48 : //
49 6 : static bool FillRoutingPolicyInfoList(const BgpSandeshContext *bsc,
50 : bool summary, uint32_t page_limit, uint32_t iter_limit,
51 : const string &start_policy, const string &search_string,
52 : vector<ShowRoutingPolicyInfo> *srpi_list, string *next_policy) {
53 6 : RoutingPolicyMgr *rpm = bsc->bgp_server->routing_policy_mgr();
54 : RoutingPolicyMgr::const_name_iterator it =
55 6 : rpm->name_clower_bound(start_policy);
56 16 : for (uint32_t iter_count = 0; it != rpm->name_cend(); ++it, ++iter_count) {
57 10 : const RoutingPolicy *policy = it->second;
58 14 : if (!search_string.empty() &&
59 14 : (policy->name().find(search_string) == string::npos) &&
60 1 : (search_string != "deleted" || !policy->deleted())) {
61 1 : continue;
62 : }
63 9 : ShowRoutingPolicyInfo srpi;
64 9 : FillRoutingPolicyInfo(&srpi, bsc, policy, summary);
65 9 : srpi_list->push_back(srpi);
66 9 : if (srpi_list->size() >= page_limit)
67 0 : break;
68 9 : if (iter_count >= iter_limit)
69 0 : break;
70 9 : }
71 :
72 : // All done if we've looked at all policies.
73 6 : if (it == rpm->name_cend() || ++it == rpm->name_end())
74 6 : return true;
75 :
76 : // Return true if we've reached the page limit, false if we've reached the
77 : // iteration limit.
78 0 : bool done = srpi_list->size() >= page_limit;
79 0 : *next_policy = it->second->name();
80 0 : return done;
81 : }
82 :
83 : // Specialization of BgpShowHandler<>::CallbackCommon.
84 : template <>
85 6 : bool BgpShowHandler<ShowRoutingPolicyReq, ShowRoutingPolicyReqIterate,
86 : ShowRoutingPolicyResp, ShowRoutingPolicyInfo>::CallbackCommon(
87 : const BgpSandeshContext *bsc, Data *data) {
88 6 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
89 6 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
90 6 : string next_policy;
91 12 : bool done = FillRoutingPolicyInfoList(bsc, false, page_limit, iter_limit,
92 6 : data->next_entry, data->search_string, &data->show_list,
93 : &next_policy);
94 6 : if (!next_policy.empty())
95 0 : SaveContextToData(next_policy, done, data);
96 6 : return done;
97 6 : }
98 :
99 : // Specialization of BgpShowHandler<>::FillShowList.
100 : template <>
101 6 : void BgpShowHandler<ShowRoutingPolicyReq, ShowRoutingPolicyReqIterate,
102 : ShowRoutingPolicyResp, ShowRoutingPolicyInfo>::FillShowList(
103 : ShowRoutingPolicyResp *resp,
104 : const vector<ShowRoutingPolicyInfo> &show_list) {
105 6 : resp->set_routing_policies(show_list);
106 6 : }
107 :
108 : // Handler for ShowRoutingPolicyReq.
109 6 : void ShowRoutingPolicyReq::HandleRequest() const {
110 6 : RequestPipeline::PipeSpec ps(this);
111 6 : RequestPipeline::StageSpec s1;
112 6 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
113 :
114 6 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
115 : s1.cbFn_ = boost::bind(&BgpShowHandler<
116 : ShowRoutingPolicyReq,
117 : ShowRoutingPolicyReqIterate,
118 : ShowRoutingPolicyResp,
119 6 : ShowRoutingPolicyInfo>::Callback, _1, _2, _3, _4, _5);
120 : s1.allocFn_ = BgpShowHandler<
121 : ShowRoutingPolicyReq,
122 : ShowRoutingPolicyReqIterate,
123 : ShowRoutingPolicyResp,
124 6 : ShowRoutingPolicyInfo>::CreateData;
125 6 : s1.instances_.push_back(0);
126 6 : ps.stages_.push_back(s1);
127 6 : RequestPipeline rp(ps);
128 6 : }
129 :
130 : //
131 : // Handler for ShowRoutingPolicyReqIterate.
132 : //
133 0 : void ShowRoutingPolicyReqIterate::HandleRequest() const {
134 0 : RequestPipeline::PipeSpec ps(this);
135 0 : RequestPipeline::StageSpec s1;
136 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
137 :
138 0 : s1.taskId_ = scheduler->GetTaskId("bgp::ShowCommand");
139 : s1.cbFn_ = boost::bind(&BgpShowHandler<
140 : ShowRoutingPolicyReq,
141 : ShowRoutingPolicyReqIterate,
142 : ShowRoutingPolicyResp,
143 0 : ShowRoutingPolicyInfo>::CallbackIterate, _1, _2, _3, _4, _5);
144 : s1.allocFn_ = BgpShowHandler<
145 : ShowRoutingPolicyReq,
146 : ShowRoutingPolicyReqIterate,
147 : ShowRoutingPolicyResp,
148 0 : ShowRoutingPolicyInfo>::CreateData;
149 0 : s1.instances_.push_back(0);
150 0 : ps.stages_.push_back(s1);
151 0 : RequestPipeline rp(ps);
152 0 : }
|