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