Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 :
6 : #include "base/regex.h"
7 : #include "bgp/bgp_config.h"
8 : #include "bgp/bgp_server.h"
9 : #include "bgp/bgp_show_handler.h"
10 : #include "bgp/bgp_table.h"
11 : #include "bgp/routing-instance/routing_instance.h"
12 : #include "bgp/routing-instance/static_route.h"
13 : #include "bgp/routing-instance/static_route_types.h"
14 :
15 : using contrail::regex;
16 : using contrail::regex_match;
17 : using contrail::regex_search;
18 : using std::string;
19 : using std::vector;
20 :
21 224 : static bool FillStaticRouteInfo(Address::Family family,
22 : const string &search_string,
23 : const regex &search_expr,
24 : StaticRouteEntriesInfo &info,
25 : RoutingInstance *rtinstance) {
26 : const BgpTable *table =
27 224 : static_cast<const BgpTable *>(rtinstance->GetTable(family));
28 224 : if (!table)
29 0 : return false;
30 372 : if ((!regex_search(table->name(), search_expr)) &&
31 148 : (search_string != "deleted" || !table->IsDeleted())) {
32 148 : return false;
33 : }
34 :
35 76 : IStaticRouteMgr *imanager = rtinstance->static_route_mgr(family);
36 76 : if (!imanager)
37 38 : return false;
38 38 : return imanager->FillStaticRouteInfo(rtinstance, &info);
39 : }
40 :
41 : // Specialization of BgpShowHandler<>::CallbackCommon.
42 : template <>
43 38 : bool BgpShowHandler<ShowStaticRouteReq, ShowStaticRouteReqIterate,
44 : ShowStaticRouteResp, StaticRouteEntriesInfo>::CallbackCommon(
45 : const BgpSandeshContext *bsc, Data *data) {
46 38 : uint32_t page_limit = bsc->page_limit() ? bsc->page_limit() : kPageLimit;
47 38 : uint32_t iter_limit = bsc->iter_limit() ? bsc->iter_limit() : kIterLimit;
48 38 : RoutingInstanceMgr *rim = bsc->bgp_server->routing_instance_mgr();
49 :
50 38 : regex search_expr(data->search_string);
51 : RoutingInstanceMgr::const_name_iterator it =
52 38 : rim->name_clower_bound(data->next_entry);
53 150 : for (uint32_t iter_count = 0; it != rim->name_cend(); ++it, ++iter_count) {
54 112 : RoutingInstance *rinstance = it->second;
55 112 : StaticRouteEntriesInfo info;
56 112 : if (FillStaticRouteInfo(Address::INET, data->search_string,
57 : search_expr, info, rinstance)) {
58 19 : data->show_list.push_back(info);
59 : }
60 112 : if (FillStaticRouteInfo(Address::INET6, data->search_string,
61 : search_expr, info, rinstance)) {
62 19 : data->show_list.push_back(info);
63 : }
64 :
65 112 : if (data->show_list.size() >= page_limit)
66 0 : break;
67 112 : if (iter_count >= iter_limit)
68 0 : break;
69 112 : }
70 :
71 : // All done if we've looked at all instances.
72 38 : if (it == rim->name_cend() || ++it == rim->name_cend())
73 38 : return true;
74 :
75 : // Return true if we've reached the page limit, false if we've reached the
76 : // iteration limit.
77 0 : bool done = data->show_list.size() >= page_limit;
78 0 : SaveContextToData(it->second->name(), done, data);
79 0 : return done;
80 38 : }
81 :
82 : // Specialization of BgpShowHandler<>::FillShowList.
83 : template <>
84 38 : void BgpShowHandler<ShowStaticRouteReq, ShowStaticRouteReqIterate,
85 : ShowStaticRouteResp, StaticRouteEntriesInfo>::FillShowList(
86 : ShowStaticRouteResp *resp,
87 : const vector<StaticRouteEntriesInfo> &show_list) {
88 38 : resp->set_static_route_entries(show_list);
89 38 : }
90 :
91 : // Handler for ShowStaticRouteReq.
92 38 : void ShowStaticRouteReq::HandleRequest() const {
93 38 : RequestPipeline::PipeSpec ps(this);
94 38 : RequestPipeline::StageSpec s1;
95 38 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
96 :
97 38 : s1.taskId_ = scheduler->GetTaskId("bgp::StaticRoute");
98 : s1.cbFn_ = boost::bind(&BgpShowHandler<
99 : ShowStaticRouteReq,
100 : ShowStaticRouteReqIterate,
101 : ShowStaticRouteResp,
102 38 : StaticRouteEntriesInfo>::Callback, _1, _2, _3, _4, _5);
103 : s1.allocFn_ = BgpShowHandler<
104 : ShowStaticRouteReq,
105 : ShowStaticRouteReqIterate,
106 : ShowStaticRouteResp,
107 38 : StaticRouteEntriesInfo>::CreateData;
108 38 : s1.instances_.push_back(0);
109 38 : ps.stages_.push_back(s1);
110 38 : RequestPipeline rp(ps);
111 38 : }
112 :
113 : //
114 : // Handler for ShowStaticRouteReqIterate.
115 : //
116 0 : void ShowStaticRouteReqIterate::HandleRequest() const {
117 0 : RequestPipeline::PipeSpec ps(this);
118 0 : RequestPipeline::StageSpec s1;
119 0 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
120 :
121 0 : s1.taskId_ = scheduler->GetTaskId("bgp::StaticRoute");
122 : s1.cbFn_ = boost::bind(&BgpShowHandler<
123 : ShowStaticRouteReq,
124 : ShowStaticRouteReqIterate,
125 : ShowStaticRouteResp,
126 0 : StaticRouteEntriesInfo>::CallbackIterate, _1, _2, _3, _4, _5);
127 : s1.allocFn_ = BgpShowHandler<
128 : ShowStaticRouteReq,
129 : ShowStaticRouteReqIterate,
130 : ShowStaticRouteResp,
131 0 : StaticRouteEntriesInfo>::CreateData;
132 0 : s1.instances_.push_back(0);
133 0 : ps.stages_.push_back(s1);
134 0 : RequestPipeline rp(ps);
135 0 : }
|