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