Line data Source code
1 : /*
2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "base/logging.h"
6 : #include "base/timer.h"
7 : #include <sandesh/sandesh_trace.h>
8 : #include "cmn/agent_cmn.h"
9 : #include "init/agent_param.h"
10 : #include "xmpp/xmpp_init.h"
11 : #include "pugixml/pugixml.hpp"
12 : #include "oper/global_system_config.h"
13 : #include "oper/vrf.h"
14 : #include "oper/peer.h"
15 : #include "oper/mirror_table.h"
16 : #include "oper/multicast.h"
17 : #include "oper/operdb_init.h"
18 : #include "oper/instance_manager.h"
19 : #include "controller/controller_types.h"
20 : #include "controller/controller_init.h"
21 : #include "controller/controller_timer.h"
22 : #include "controller/controller_peer.h"
23 : #include "controller/controller_ifmap.h"
24 :
25 : #define SECS_TO_USECS(t) t * 1000 * 1000
26 : #define SECS_TO_MSECS(t) t * 1000
27 :
28 : // Creates new timer
29 13 : ControllerTimer::ControllerTimer(Agent *agent,
30 : const std::string &timer_name,
31 13 : uint32_t timer_interval)
32 13 : : agent_(agent), last_restart_time_(0),
33 13 : xmpp_server_(""), timer_name_(timer_name),
34 13 : timer_interval_(timer_interval) {
35 13 : controller_timer_ =
36 26 : TimerManager::CreateTimer(*(agent->event_manager()->
37 13 : io_service()), timer_name,
38 : TaskScheduler::GetInstance()->
39 : GetTaskId("Agent::ControllerXmpp"), 0);
40 13 : }
41 :
42 13 : ControllerTimer::~ControllerTimer() {
43 : //Delete timer
44 13 : if (controller_timer_) {
45 13 : TimerManager::DeleteTimer(controller_timer_);
46 : }
47 13 : }
48 :
49 0 : void ControllerTimer::Fire() {
50 0 : controller_timer_->Fire();
51 0 : }
52 :
53 4 : bool ControllerTimer::Cancel() {
54 4 : CONTROLLER_TRACE(Timer, "ControllerTimer", timer_name(), "");
55 4 : last_restart_time_ = 0;
56 4 : xmpp_server_.clear();
57 :
58 4 : if (controller_timer_ == NULL) {
59 0 : CONTROLLER_TRACE(Timer, "No controller timer", timer_name(), "");
60 0 : return true;
61 : }
62 :
63 4 : return controller_timer_->Cancel();
64 : }
65 :
66 : // Set the last_restart_time and update the owner of the timer with XmppServer
67 4 : void ControllerTimer::Start(AgentXmppChannel *agent_xmpp_channel) {
68 4 : if (controller_timer_->running()) {
69 0 : if (controller_timer_->Cancel() == false) {
70 0 : CONTROLLER_TRACE(Timer, "Cancel during restart of timer failed",
71 : timer_name(), agent_xmpp_channel->GetXmppServer());
72 : }
73 : }
74 :
75 : // Start the timer fresh
76 4 : controller_timer_->Start(GetTimerInterval(),
77 : boost::bind(&ControllerTimer::TimerExpiredCallback, this));
78 4 : CONTROLLER_TRACE(Timer, "Start", timer_name(),
79 : agent_xmpp_channel->GetXmppServer());
80 :
81 4 : last_restart_time_ = UTCTimestampUsec();
82 4 : xmpp_server_ = agent_xmpp_channel->GetXmppServer();
83 4 : }
84 :
85 0 : bool ControllerTimer::running() const {
86 0 : return controller_timer_->running();
87 : }
88 :
89 : // Start the timer again if extension interval is not zero.
90 : // If extension interval is not present then execute the expiration
91 : // handler.
92 4 : bool ControllerTimer::TimerExpiredCallback() {
93 :
94 4 : bool ret = TimerExpirationDone();
95 4 : CONTROLLER_TRACE(Timer, "Called Timer Expiration Routine", timer_name(),
96 : xmpp_server_);
97 :
98 : //Reset all parameters
99 4 : xmpp_server_.clear();
100 4 : return ret;
101 : }
102 :
103 2 : ConfigCleanupTimer::ConfigCleanupTimer(Agent *agent) :
104 : ControllerTimer(agent, "Agent Config Stale cleanup timer",
105 2 : SECS_TO_MSECS(agent->params()->
106 : llgr_params().stale_config_cleanup_time())),
107 4 : sequence_number_(0) {
108 2 : }
109 :
110 0 : void ConfigCleanupTimer::Start(AgentXmppChannel *channel) {
111 0 : sequence_number_ =
112 0 : agent_->ifmap_xmpp_channel(agent_->ifmap_active_xmpp_server_index())->
113 0 : GetSeqNumber();
114 :
115 0 : ControllerTimer::Start(channel);
116 0 : }
117 :
118 1 : bool ConfigCleanupTimer::TimerExpirationDone() {
119 1 : agent_->ifmap_stale_cleaner()->StaleTimeout(sequence_number_);
120 1 : agent_->oper_db()->instance_manager()->StaleTimeout();
121 1 : return false;
122 : }
123 :
124 0 : uint32_t ConfigCleanupTimer::GetTimerInterval() const {
125 0 : return SECS_TO_MSECS(agent_->params()->
126 : llgr_params().stale_config_cleanup_time());
127 : }
128 :
129 2 : EndOfConfigTimer::EndOfConfigTimer(Agent *agent,
130 2 : AgentIfMapXmppChannel *config_channel) :
131 : ControllerTimer(agent, "End of config identification timer",
132 2 : SECS_TO_MSECS(agent->params()->
133 : llgr_params().config_poll_time())),
134 4 : config_channel_(config_channel) {
135 2 : Reset();
136 2 : }
137 :
138 2 : void EndOfConfigTimer::Reset() {
139 2 : last_config_receive_time_ = 0;
140 2 : inactivity_detected_time_ = 0;
141 2 : end_of_config_processed_time_ = 0;
142 2 : config_inactivity_time_ = 0;
143 2 : fallback_interval_ = 0;
144 2 : fallback_ = false;
145 2 : GresEnabled(agent_->oper_db()->global_system_config()->
146 2 : gres_parameters().IsEnabled());
147 2 : }
148 :
149 0 : void EndOfConfigTimer::Start(AgentXmppChannel *agent_xmpp_channel) {
150 0 : Reset();
151 0 : agent_->controller()->StopEndOfRibTx();
152 0 : ControllerTimer::Start(agent_xmpp_channel);
153 0 : }
154 :
155 : //Identify silence of 30 seconds on config channel
156 1 : bool EndOfConfigTimer::TimerExpirationDone() {
157 1 : uint64_t current_time = UTCTimestampUsec();
158 : //Config has been seen within inactivity time
159 1 : bool config_seen = false;
160 :
161 1 : if (last_config_receive_time_ != 0) {
162 0 : if ((current_time - last_config_receive_time_) <
163 0 : GetInactivityInterval()) {
164 0 : config_seen = true;
165 : }
166 : }
167 :
168 : //When config is regularly seen on channel, put stale timeout to worst.
169 1 : if ((current_time - last_restart_time_) >= GetFallbackInterval()) {
170 1 : fallback_ = true;
171 : }
172 :
173 : // End of config is enqueued in VNController work queue for processing.
174 1 : if (fallback_ || !config_seen) {
175 1 : inactivity_detected_time_ = UTCTimestampUsec();
176 1 : config_channel_->EnqueueEndOfConfig();
177 1 : return false;
178 : }
179 0 : return true;
180 : }
181 :
182 0 : uint32_t EndOfConfigTimer::GetTimerInterval() const {
183 0 : return SECS_TO_MSECS(agent_->params()->
184 : llgr_params().config_poll_time());
185 : }
186 :
187 1 : uint32_t EndOfConfigTimer::GetFallbackInterval() const {
188 1 : return fallback_interval_;
189 : }
190 :
191 0 : uint32_t EndOfConfigTimer::GetInactivityInterval() const {
192 0 : return config_inactivity_time_;
193 : }
194 :
195 2 : void EndOfConfigTimer::GresEnabled(bool enable) {
196 2 : if (enable) {
197 0 : config_inactivity_time_ = SECS_TO_USECS(agent_->params()->
198 : llgr_params().config_inactivity_time());
199 0 : fallback_interval_ = SECS_TO_USECS(agent_->params()->
200 : llgr_params().config_fallback_time());
201 : } else {
202 2 : config_inactivity_time_ = 0;
203 2 : fallback_interval_ = 0;
204 : }
205 2 : }
206 :
207 3 : EndOfRibTxTimer::EndOfRibTxTimer(Agent *agent) :
208 : ControllerTimer(agent, "End of rib Tx identification timer",
209 3 : SECS_TO_MSECS(agent->params()->
210 : llgr_params().end_of_rib_tx_poll_time())),
211 6 : agent_xmpp_channel_(NULL) {
212 3 : Reset();
213 3 : }
214 :
215 3 : void EndOfRibTxTimer::Reset() {
216 3 : end_of_rib_tx_time_ = 0;
217 3 : last_route_published_time_ = 0;
218 3 : fallback_ = false;
219 3 : fallback_interval_ = 0;
220 3 : GresEnabled(agent_->oper_db()->global_system_config()->
221 3 : gres_parameters().IsEnabled());
222 3 : }
223 :
224 0 : void EndOfRibTxTimer::Start(AgentXmppChannel *agent_xmpp_channel) {
225 0 : Reset();
226 0 : agent_xmpp_channel_ = agent_xmpp_channel;
227 0 : ControllerTimer::Start(agent_xmpp_channel);
228 0 : }
229 :
230 0 : bool EndOfRibTxTimer::TimerExpirationDone() {
231 0 : uint64_t current_time = UTCTimestampUsec();
232 0 : uint8_t index = agent_xmpp_channel_->GetXmppServerIdx();
233 0 : bool end_of_rib = false;
234 :
235 : // Check for fallback
236 0 : if (last_route_published_time_ == 0) {
237 0 : if ((current_time - agent_->controller_xmpp_channel_setup_time(index)) >
238 0 : GetFallbackInterval()) {
239 0 : end_of_rib = true;
240 : } else {
241 0 : return true;
242 : }
243 : }
244 :
245 : // Check for inactivity
246 0 : if ((current_time - last_route_published_time_) > GetInactivityInterval()) {
247 0 : end_of_rib = true;
248 : }
249 :
250 0 : if (end_of_rib) {
251 : // Start walk to delete stale routes.
252 0 : agent_xmpp_channel_->StartEndOfRibTxWalker();
253 : //Notify
254 0 : agent_->event_notifier()->
255 0 : Notify(new EventNotifyKey(EventNotifyKey::END_OF_RIB));
256 0 : return false;
257 : }
258 :
259 0 : return true;
260 : }
261 :
262 0 : uint32_t EndOfRibTxTimer::GetTimerInterval() const {
263 0 : return SECS_TO_MSECS(agent_->params()->
264 : llgr_params().end_of_rib_tx_poll_time());
265 : }
266 :
267 0 : uint32_t EndOfRibTxTimer::GetFallbackInterval() const {
268 0 : return fallback_interval_;
269 : }
270 :
271 0 : uint32_t EndOfRibTxTimer::GetInactivityInterval() const {
272 0 : return end_of_rib_tx_time_;
273 : }
274 :
275 3 : void EndOfRibTxTimer::GresEnabled(bool enable) {
276 3 : if (enable) {
277 0 : end_of_rib_tx_time_ = SECS_TO_USECS(agent_->params()->
278 : llgr_params().end_of_rib_tx_inactivity_time());
279 0 : fallback_interval_ = SECS_TO_USECS(agent_->params()->
280 : llgr_params().end_of_rib_tx_fallback_time());
281 : } else {
282 3 : end_of_rib_tx_time_ = 0;
283 3 : fallback_interval_ = 0;
284 : }
285 3 : }
286 :
287 3 : EndOfRibRxTimer::EndOfRibRxTimer(Agent *agent) :
288 : ControllerTimer(agent, "End of rib Rx path timer",
289 3 : SECS_TO_MSECS(agent->params()->
290 : llgr_params().end_of_rib_rx_fallback_time())),
291 6 : agent_xmpp_channel_(NULL) {
292 3 : Reset();
293 3 : }
294 :
295 1 : void EndOfRibRxTimer::Start(AgentXmppChannel *agent_xmpp_channel) {
296 1 : agent_xmpp_channel_ = agent_xmpp_channel;
297 1 : ControllerTimer::Start(agent_xmpp_channel);
298 1 : }
299 :
300 1 : bool EndOfRibRxTimer::TimerExpirationDone() {
301 1 : end_of_rib_rx_time_ = UTCTimestampUsec();
302 1 : fallback_ = true;
303 1 : agent_xmpp_channel_->EndOfRibRx();
304 1 : return false;
305 : }
306 :
307 3 : void EndOfRibRxTimer::Reset() {
308 3 : end_of_rib_rx_time_ = 0;
309 3 : end_of_rib_rx_fallback_time_ = 0;
310 3 : fallback_ = false;
311 3 : GresEnabled(agent_->oper_db()->global_system_config()->
312 3 : gres_parameters().IsEnabled());
313 3 : }
314 :
315 1 : uint32_t EndOfRibRxTimer::GetTimerInterval() const {
316 1 : return end_of_rib_rx_fallback_time_;
317 : }
318 :
319 3 : void EndOfRibRxTimer::GresEnabled(bool enable) {
320 3 : if (enable) {
321 0 : end_of_rib_rx_fallback_time_ = agent_->oper_db()->
322 0 : global_system_config()->gres_parameters().end_of_rib_time();
323 0 : if (end_of_rib_rx_fallback_time_ == 0) {
324 0 : end_of_rib_rx_fallback_time_ = SECS_TO_MSECS(agent_->params()->
325 : llgr_params().end_of_rib_rx_fallback_time());
326 : }
327 : } else {
328 3 : end_of_rib_rx_fallback_time_ = 0;
329 : }
330 3 : }
331 :
332 3 : LlgrStaleTimer::LlgrStaleTimer(Agent *agent) :
333 : ControllerTimer(agent, "Llgr stale timer",
334 3 : SECS_TO_MSECS(agent->oper_db()->global_system_config()->
335 : gres_parameters().llgr_stale_time())),
336 6 : agent_xmpp_channel_(NULL) {
337 3 : Reset();
338 3 : }
339 :
340 3 : void LlgrStaleTimer::Start(AgentXmppChannel *agent_xmpp_channel) {
341 3 : Reset();
342 3 : agent_xmpp_channel_ = agent_xmpp_channel;
343 3 : ControllerTimer::Start(agent_xmpp_channel);
344 3 : }
345 :
346 3 : bool LlgrStaleTimer::TimerExpirationDone() {
347 3 : agent_xmpp_channel_->EndOfRibRx();
348 3 : return false;
349 : }
350 :
351 6 : void LlgrStaleTimer::Reset() {
352 6 : llgr_stale_time_ = 0;
353 6 : GresEnabled(agent_->oper_db()->global_system_config()->
354 6 : gres_parameters().IsEnabled());
355 6 : }
356 :
357 3 : uint32_t LlgrStaleTimer::GetTimerInterval() const {
358 3 : return llgr_stale_time_;
359 : }
360 :
361 6 : void LlgrStaleTimer::GresEnabled(bool enable) {
362 6 : if (enable) {
363 0 : llgr_stale_time_ = SECS_TO_MSECS(agent_->oper_db()->
364 : global_system_config()->gres_parameters().llgr_stale_time());
365 0 : if (llgr_stale_time_ == 0) {
366 0 : llgr_stale_time_ = SECS_TO_MSECS(agent_->params()->
367 : llgr_params().llgr_stale_time());
368 : }
369 : } else {
370 6 : llgr_stale_time_ = 0;
371 : }
372 6 : }
|