Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <algorithm>
6 : #include <fstream>
7 : #include <iostream>
8 : #include <string>
9 : #include <vector>
10 :
11 : #include <base/logging.h>
12 : #include <base/lifetime.h>
13 : #include <base/misc_utils.h>
14 : #include <io/event_manager.h>
15 : #include <ifmap/ifmap_link.h>
16 : #include <cmn/agent_cmn.h>
17 : #include <vnc_cfg_types.h>
18 : #include <agent_types.h>
19 :
20 : #include <base/sandesh/task_types.h>
21 :
22 : #include <init/agent_param.h>
23 : #include <cmn/agent_signal.h>
24 : #include <cfg/cfg_init.h>
25 : #include <cfg/cfg_mirror.h>
26 : #include <cmn/agent.h>
27 : #include <cmn/event_notifier.h>
28 : #include <cmn/xmpp_server_address_parser.h>
29 : #include <controller/controller_init.h>
30 : #include <controller/controller_peer.h>
31 :
32 : #include <oper/operdb_init.h>
33 : #include <oper/config_manager.h>
34 : #include <oper/interface_common.h>
35 : #include <oper/health_check.h>
36 : #include <oper/metadata_ip.h>
37 : #include <oper/multicast.h>
38 : #include <oper/nexthop.h>
39 : #include <oper/mirror_table.h>
40 : #include <oper/mpls.h>
41 : #include <oper/peer.h>
42 : #include <xmpp/xmpp_client.h>
43 :
44 : #include <filter/acl.h>
45 :
46 : #include <cmn/agent_factory.h>
47 : #include <net/if.h>
48 :
49 : const std::string Agent::null_string_ = "";
50 : const std::set<std::string> Agent::null_string_list_;
51 : const std::string Agent::fabric_vn_name_ =
52 : "default-domain:default-project:ip-fabric";
53 : std::string Agent::fabric_vrf_name_ =
54 : "default-domain:default-project:ip-fabric:__default__";
55 : std::string Agent::fabric_policy_vrf_name_ =
56 : "default-domain:default-project:ip-fabric:ip-fabric";
57 : const std::string Agent::link_local_vn_name_ =
58 : "default-domain:default-project:__link_local__";
59 : const std::string Agent::link_local_vrf_name_ =
60 : "default-domain:default-project:__link_local__:__link_local__";
61 : const MacAddress Agent::vrrp_mac_(0x00, 0x00, 0x5E, 0x00, 0x01, 0x00);
62 : // use the following MAC when sending data to left or right SI interfaces
63 : const MacAddress Agent::left_si_mac_(0x02, 0x00, 0x00, 0x00, 0x00, 0x01);
64 : const MacAddress Agent::right_si_mac_(0x02, 0x00, 0x00, 0x00, 0x00, 0x02);
65 : const MacAddress Agent::pkt_interface_mac_(0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
66 : const std::string Agent::bcast_mac_ = "FF:FF:FF:FF:FF:FF";
67 : const std::string Agent::xmpp_dns_server_connection_name_prefix_ = "dns-server:";
68 : const std::string Agent::xmpp_control_node_connection_name_prefix_ = "control-node:";
69 : const uint16_t Agent::kDefaultVmiVmVnUveInterval = 30; //in seconds
70 : const std::string Agent::v4_link_local_subnet_ = "169.254.0.0";
71 : const std::string Agent::v6_link_local_subnet_ = "FE80::";
72 :
73 : SandeshTraceBufferPtr TaskTraceBuf(SandeshTraceBufferCreate("TaskTrace", 5000));
74 : Agent *Agent::singleton_;
75 :
76 0 : IpAddress Agent::GetMirrorSourceIp(const IpAddress &dest) {
77 0 : IpAddress sip;
78 0 : if (dest.is_v4()) {
79 0 : if (router_id() == dest) {
80 : // If source IP and dest IP are same,
81 : // linux kernel will drop the packet.
82 : // Hence we will use link local IP address as sip.
83 0 : sip = Ip4Address(METADATA_IP_ADDR);
84 : } else {
85 0 : sip = router_id();
86 : }
87 0 : } else if (dest.is_v6()) {
88 0 : sip = Ip6Address::v4_mapped(router_id());
89 : }
90 0 : return sip;
91 : }
92 :
93 15 : const string &Agent::GetHostInterfaceName() const {
94 : // There is single host interface. Its addressed by type and not name
95 15 : return Agent::null_string_;
96 : };
97 :
98 0 : std::string Agent::GetUuidStr(boost::uuids::uuid uuid_val) const {
99 0 : std::ostringstream str;
100 0 : str << uuid_val;
101 0 : return str.str();
102 0 : }
103 :
104 176 : const string &Agent::vhost_interface_name() const {
105 176 : return vhost_interface_name_;
106 : };
107 :
108 3 : bool Agent::is_vhost_interface_up() const {
109 3 : if (tor_agent_enabled() || test_mode()|| isMockMode()) {
110 3 : return true;
111 : }
112 :
113 : static const int log_rate_limit = 15;
114 : struct ifreq ifr;
115 : static int err_count = 0;
116 0 : int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
117 0 : memset(&ifr, 0, sizeof(ifr));
118 0 : strcpy(ifr.ifr_name, vhost_interface_name().c_str());
119 0 : int err = ioctl(sock, SIOCGIFFLAGS, &ifr);
120 0 : if (err < 0 || !(ifr.ifr_flags & IFF_UP)) {
121 0 : close(sock);
122 0 : if ((err_count % log_rate_limit) == 0) {
123 0 : LOG(DEBUG, "vhost is down");
124 : }
125 0 : err_count++;
126 0 : return false;
127 : }
128 0 : err = ioctl(sock, SIOCGIFADDR, &ifr);
129 0 : if (false == is_l3mh() && err < 0) {
130 0 : close(sock);
131 0 : if ((err_count % log_rate_limit) == 0) {
132 0 : LOG(DEBUG, "vhost is up. but ip is not set");
133 : }
134 0 : err_count++;
135 0 : return false;
136 : }
137 0 : close(sock);
138 0 : return true;
139 : }
140 :
141 72 : bool Agent::isXenMode() {
142 72 : return params_->isXenMode();
143 : }
144 :
145 0 : bool Agent::isKvmMode() {
146 0 : return params_->isKvmMode();
147 : }
148 :
149 0 : bool Agent::isDockerMode() {
150 0 : return params_->isDockerMode();
151 : }
152 :
153 5 : bool Agent::isMockMode() const {
154 5 : return params_->cat_is_agent_mocked();
155 : }
156 :
157 0 : std::string Agent::AgentGUID() const {
158 0 : char *envval = NULL;
159 0 : assert(params_);
160 0 : return std::string(((envval = getenv("LOGNAME"))== NULL)? "" : envval)
161 0 : + "_" + agent_name() + "_" + integerToString(getpid());
162 : }
163 :
164 50 : static void SetTaskPolicyOne(const char *task, const char *exclude_list[],
165 : int count) {
166 50 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
167 50 : TaskPolicy policy;
168 290 : for (int i = 0; i < count; ++i) {
169 240 : int task_id = scheduler->GetTaskId(exclude_list[i]);
170 240 : policy.push_back(TaskExclusion(task_id));
171 : }
172 50 : scheduler->SetPolicy(scheduler->GetTaskId(task), policy);
173 50 : }
174 :
175 2 : void Agent::SetAgentTaskPolicy() {
176 : /*
177 : * TODO(roque): this method should not be called by the agent constructor.
178 : */
179 : static bool initialized = false;
180 2 : if (initialized) {
181 0 : return;
182 : }
183 2 : initialized = true;
184 :
185 2 : const char *db_exclude_list[] = {
186 : kTaskFlowEvent,
187 : kTaskFlowKSync,
188 : kTaskFlowUpdate,
189 : kTaskFlowDelete,
190 : kTaskFlowAudit,
191 : kTaskFlowStatsUpdate,
192 : "Agent::Services",
193 : "Agent::StatsCollector",
194 : kTaskFlowStatsCollector,
195 : kTaskSessionStatsCollector,
196 : kTaskSessionStatsCollectorEvent,
197 : "sandesh::RecvQueue",
198 : "Agent::Uve",
199 : "Agent::KSync",
200 : "Agent::PktFlowResponder",
201 : "Agent::Profile",
202 : "Agent::PktHandler",
203 : "Agent::Diag",
204 : "http::RequestHandlerTask",
205 : kTaskHealthCheck,
206 : kTaskCryptTunnel,
207 : kTaskDBExclude,
208 : AGENT_SHUTDOWN_TASKNAME,
209 : AGENT_INIT_TASKNAME,
210 : AGENT_SANDESH_TASKNAME,
211 : kTaskConfigManager,
212 : INSTANCE_MANAGER_TASK_NAME,
213 : kAgentResourceBackUpTask,
214 : kAgentResourceRestoreTask,
215 : kTaskMacLearning
216 : };
217 2 : SetTaskPolicyOne("db::DBTable", db_exclude_list,
218 : sizeof(db_exclude_list) / sizeof(char *));
219 :
220 : // ConfigManager task
221 2 : const char *config_manager_exclude_list[] = {
222 : AGENT_SHUTDOWN_TASKNAME,
223 : AGENT_INIT_TASKNAME
224 : };
225 2 : SetTaskPolicyOne(kTaskConfigManager, config_manager_exclude_list,
226 : sizeof(config_manager_exclude_list) / sizeof(char *));
227 :
228 2 : const char *flow_table_exclude_list[] = {
229 : "Agent::PktFlowResponder",
230 : AGENT_SHUTDOWN_TASKNAME,
231 : AGENT_INIT_TASKNAME
232 : };
233 2 : SetTaskPolicyOne(kTaskFlowEvent, flow_table_exclude_list,
234 : sizeof(flow_table_exclude_list) / sizeof(char *));
235 :
236 2 : SetTaskPolicyOne(kTaskFlowKSync, flow_table_exclude_list,
237 : sizeof(flow_table_exclude_list) / sizeof(char *));
238 :
239 2 : SetTaskPolicyOne(kTaskFlowUpdate, flow_table_exclude_list,
240 : sizeof(flow_table_exclude_list) / sizeof(char *));
241 :
242 2 : SetTaskPolicyOne(kTaskFlowDelete, flow_table_exclude_list,
243 : sizeof(flow_table_exclude_list) / sizeof(char *));
244 :
245 2 : const char *sandesh_exclude_list[] = {
246 : "db::DBTable",
247 : "Agent::Services",
248 : "Agent::StatsCollector",
249 : "io::ReaderTask",
250 : "Agent::PktFlowResponder",
251 : "Agent::Profile",
252 : "BFD",
253 : AGENT_SHUTDOWN_TASKNAME,
254 : AGENT_INIT_TASKNAME,
255 : AGENT_SANDESH_TASKNAME
256 : };
257 2 : SetTaskPolicyOne("sandesh::RecvQueue", sandesh_exclude_list,
258 : sizeof(sandesh_exclude_list) / sizeof(char *));
259 :
260 2 : const char *xmpp_config_exclude_list[] = {
261 : "Agent::Services",
262 : "Agent::StatsCollector",
263 : "sandesh::RecvQueue",
264 : "io::ReaderTask",
265 : "Agent::ControllerXmpp",
266 : "db::Walker",
267 : "db::DBTable",
268 : "xmpp::StateMachine",
269 : "bgp::ShowCommand",
270 : AGENT_SHUTDOWN_TASKNAME,
271 : AGENT_INIT_TASKNAME
272 : };
273 2 : SetTaskPolicyOne("bgp::Config", xmpp_config_exclude_list,
274 : sizeof(xmpp_config_exclude_list) / sizeof(char *));
275 :
276 2 : const char *controller_xmpp_exclude_list[] = {
277 : "Agent::Services",
278 : "io::ReaderTask",
279 : "db::DBTable",
280 : AGENT_SHUTDOWN_TASKNAME,
281 : AGENT_INIT_TASKNAME
282 : };
283 2 : SetTaskPolicyOne("Agent::ControllerXmpp", controller_xmpp_exclude_list,
284 : sizeof(controller_xmpp_exclude_list) / sizeof(char *));
285 :
286 2 : const char *walker_exclude_list[] = {
287 : "Agent::ControllerXmpp",
288 : "db::DBTable",
289 : // For ToR Agent Agent::KSync and db::Walker both task tries
290 : // to modify route path list inline (out of DB table context) to
291 : // manage route exports from dynamic peer before release the peer
292 : // which is resulting in parallel access, for now we will avoid this
293 : // race by adding task exclusion policy.
294 : // TODO(prabhjot): need to remove this task exclusion one dynamic peer
295 : // handling is done.
296 : "Agent::KSync",
297 : AGENT_SHUTDOWN_TASKNAME,
298 : AGENT_INIT_TASKNAME
299 : };
300 2 : SetTaskPolicyOne("db::Walker", walker_exclude_list,
301 : sizeof(walker_exclude_list) / sizeof(char *));
302 :
303 2 : const char *ksync_exclude_list[] = {
304 : "db::DBTable",
305 : AGENT_SHUTDOWN_TASKNAME,
306 : AGENT_INIT_TASKNAME
307 : };
308 2 : SetTaskPolicyOne("Agent::KSync", ksync_exclude_list,
309 : sizeof(ksync_exclude_list) / sizeof(char *));
310 :
311 2 : const char *stats_collector_exclude_list[] = {
312 : "Agent::PktFlowResponder",
313 : AGENT_SHUTDOWN_TASKNAME,
314 : AGENT_INIT_TASKNAME
315 : };
316 2 : SetTaskPolicyOne("Agent::StatsCollector", stats_collector_exclude_list,
317 : sizeof(stats_collector_exclude_list) / sizeof(char *));
318 :
319 2 : const char *flow_stats_exclude_list[] = {
320 : AGENT_SHUTDOWN_TASKNAME,
321 : AGENT_INIT_TASKNAME
322 : };
323 2 : SetTaskPolicyOne(kTaskFlowStatsCollector, flow_stats_exclude_list,
324 : sizeof(flow_stats_exclude_list) / sizeof(char *));
325 :
326 2 : const char *session_stats_exclude_list[] = {
327 : kTaskSessionStatsCollectorEvent,
328 : AGENT_SHUTDOWN_TASKNAME,
329 : AGENT_INIT_TASKNAME
330 : };
331 2 : SetTaskPolicyOne(kTaskSessionStatsCollector, session_stats_exclude_list,
332 : sizeof(session_stats_exclude_list) / sizeof(char *));
333 :
334 2 : const char *session_stats_event_exclude_list[] = {
335 : AGENT_SHUTDOWN_TASKNAME,
336 : AGENT_INIT_TASKNAME
337 : };
338 2 : SetTaskPolicyOne(kTaskSessionStatsCollectorEvent, session_stats_exclude_list,
339 : sizeof(session_stats_event_exclude_list) / sizeof(char *));
340 2 : const char *metadata_exclude_list[] = {
341 : "xmpp::StateMachine",
342 : "http::RequestHandlerTask"
343 : };
344 2 : SetTaskPolicyOne("http client", metadata_exclude_list,
345 : sizeof(metadata_exclude_list) / sizeof(char *));
346 :
347 2 : const char *xmpp_state_machine_exclude_list[] = {
348 : "io::ReaderTask"
349 : };
350 2 : SetTaskPolicyOne("xmpp::StateMachine", xmpp_state_machine_exclude_list,
351 : sizeof(xmpp_state_machine_exclude_list) / sizeof(char *));
352 :
353 2 : const char *agent_init_exclude_list[] = {
354 : "xmpp::StateMachine",
355 : "http client",
356 : "db::DBTable",
357 : AGENT_SANDESH_TASKNAME,
358 : AGENT_SHUTDOWN_TASKNAME,
359 : kAgentResourceBackUpTask,
360 : kAgentResourceRestoreTask
361 : };
362 2 : SetTaskPolicyOne(AGENT_INIT_TASKNAME, agent_init_exclude_list,
363 : sizeof(agent_init_exclude_list) / sizeof(char *));
364 :
365 2 : const char *flow_stats_manager_exclude_list[] = {
366 : "Agent::StatsCollector",
367 : kTaskFlowStatsCollector,
368 : kTaskFlowMgmt,
369 : AGENT_SHUTDOWN_TASKNAME,
370 : AGENT_INIT_TASKNAME
371 : };
372 2 : SetTaskPolicyOne(AGENT_FLOW_STATS_MANAGER_TASK,
373 : flow_stats_manager_exclude_list,
374 : sizeof(flow_stats_manager_exclude_list) / sizeof(char *));
375 :
376 2 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
377 2 : scheduler->RegisterLog(boost::bind(&Agent::TaskTrace, this,
378 : _1, _2, _3, _4, _5));
379 :
380 2 : const char *db_exclude_task_exclude_list[] = {
381 : "Agent::Uve",
382 : "sandesh::RecvQueue",
383 : "Agent::ControllerXmpp",
384 : "bgp::Config",
385 : AGENT_SHUTDOWN_TASKNAME,
386 : AGENT_INIT_TASKNAME
387 : };
388 2 : SetTaskPolicyOne(kTaskDBExclude, db_exclude_task_exclude_list,
389 : sizeof(db_exclude_task_exclude_list) / sizeof(char *));
390 :
391 2 : const char *flow_stats_update_exclude_list[] = {
392 : "Agent::Uve"
393 : };
394 2 : SetTaskPolicyOne(kTaskFlowStatsUpdate, flow_stats_update_exclude_list,
395 : sizeof(flow_stats_update_exclude_list) / sizeof(char *));
396 :
397 2 : const char *profile_task_exclude_list[] = {
398 : AGENT_FLOW_STATS_MANAGER_TASK,
399 : AGENT_SHUTDOWN_TASKNAME,
400 : AGENT_INIT_TASKNAME
401 : };
402 2 : SetTaskPolicyOne("Agent::Profile", profile_task_exclude_list,
403 : sizeof(profile_task_exclude_list) / sizeof(char *));
404 :
405 : //event notify exclude list
406 2 : const char *event_notify_exclude_list[] = {
407 : "Agent::ControllerXmpp",
408 : "db::DBTable",
409 : kAgentResourceBackUpTask,
410 : AGENT_SHUTDOWN_TASKNAME,
411 : AGENT_INIT_TASKNAME
412 : };
413 2 : SetTaskPolicyOne(kEventNotifierTask, event_notify_exclude_list,
414 : sizeof(event_notify_exclude_list) / sizeof(char *));
415 :
416 : // Health Check task
417 2 : const char *health_check_exclude_list[] = {
418 : kTaskFlowMgmt
419 : };
420 2 : SetTaskPolicyOne(kTaskHealthCheck, health_check_exclude_list,
421 : sizeof(health_check_exclude_list) / sizeof(char *));
422 :
423 2 : const char *rest_api_exclude_list[] = {
424 : "db::DBTable",
425 : };
426 2 : SetTaskPolicyOne("Agent::RestApi", rest_api_exclude_list,
427 : sizeof(rest_api_exclude_list) / sizeof(char *));
428 :
429 : }
430 :
431 2 : void Agent::CreateLifetimeManager() {
432 2 : lifetime_manager_ = new LifetimeManager(
433 2 : TaskScheduler::GetInstance()->GetTaskId("db::DBTable"));
434 2 : }
435 :
436 2 : void Agent::ShutdownLifetimeManager() {
437 2 : delete lifetime_manager_;
438 2 : lifetime_manager_ = NULL;
439 2 : }
440 :
441 6 : uint32_t Agent::GenerateHash(std::vector<std::string> &list) {
442 :
443 6 : std::string concat_servers;
444 6 : std::vector<std::string>::iterator iter;
445 6 : for (iter = list.begin();
446 12 : iter != list.end(); iter++) {
447 6 : concat_servers += *iter;
448 : }
449 :
450 : boost::hash<std::string> string_hash;
451 12 : return(string_hash(concat_servers));
452 6 : }
453 :
454 2 : void Agent::InitControllerList() {
455 2 : XmppServerAddressParser parser(XMPP_SERVER_PORT, MAX_XMPP_SERVERS);
456 2 : parser.ParseAddresses(controller_list_, xs_addr_, xs_port_);
457 2 : }
458 :
459 2 : void Agent::InitDnsList() {
460 2 : XmppServerAddressParser parser(XMPP_DNS_SERVER_PORT, MAX_XMPP_SERVERS);
461 2 : parser.ParseAddresses(dns_list_, dns_addr_, dns_port_);
462 2 : }
463 :
464 2 : void Agent::InitializeFilteredParams() {
465 2 : InitControllerList();
466 2 : InitDnsList();
467 2 : }
468 :
469 2 : void Agent::CopyFilteredParams() {
470 :
471 : // Controller
472 : // 1. Save checksum of the Configured List
473 : // 2. Randomize the Configured List
474 2 : std::vector<string> list = params_->controller_server_list();
475 2 : uint32_t new_chksum = GenerateHash(list);
476 2 : if (new_chksum != controller_chksum_) {
477 2 : controller_chksum_ = new_chksum;
478 2 : controller_list_ = params_->controller_server_list();
479 2 : std::random_shuffle(controller_list_.begin(), controller_list_.end());
480 : }
481 :
482 : // Dns
483 : // 1. Save checksum of the Configured List
484 : // 2. Pick first two DNS Servers to connect
485 2 : list.clear();
486 2 : list = params_->dns_server_list();
487 2 : new_chksum = GenerateHash(list);
488 2 : if (new_chksum != dns_chksum_) {
489 2 : dns_chksum_ = new_chksum;
490 2 : dns_list_ = params_->dns_server_list();
491 : }
492 :
493 : // Collector
494 : // 1. Save checksum of the Configured List
495 : // 2. Randomize the Configured List
496 2 : list.clear();
497 2 : list = params_->collector_server_list();
498 2 : new_chksum = GenerateHash(list);
499 2 : if (new_chksum != collector_chksum_) {
500 2 : collector_chksum_ = new_chksum;
501 2 : collector_list_ = params_->collector_server_list();
502 2 : std::random_shuffle(collector_list_.begin(), collector_list_.end());
503 : }
504 2 : }
505 :
506 : // Get configuration from AgentParam into Agent
507 2 : void Agent::CopyConfig(AgentParam *params) {
508 2 : params_ = params;
509 :
510 2 : xs_auth_enable_ = params_->xmpp_auth_enabled();
511 2 : dns_auth_enable_ = params_->xmpp_dns_auth_enabled();
512 2 : xs_server_cert_ = params_->xmpp_server_cert();
513 2 : xs_server_key_ = params_->xmpp_server_key();
514 2 : xs_ca_cert_ = params_->xmpp_ca_cert();
515 2 : subcluster_name_ = params_->subcluster_name();
516 :
517 2 : CopyFilteredParams();
518 2 : InitializeFilteredParams();
519 :
520 2 : vhost_interface_name_ = params_->vhost_name();
521 :
522 : // Don't fetch the VHOST conf for tor agent. For tor agent, vhost conf will
523 : // not be populated into eth_port_list_ from conf file.
524 2 : if (params_->eth_port_list().size() != 0) {
525 2 : ip_fabric_intf_name_ = params_->eth_port_list()[0].c_str(); /* PKC: Using first element for now */
526 : }
527 2 : ip_fabric_intf_name_list_ = params_->eth_port_list();
528 2 : ip_fabric_intf_addr_list_ = params_->eth_port_addr_list();
529 2 : crypt_intf_name_ = params_->crypt_port();
530 2 : host_name_ = params_->host_name();
531 2 : agent_name_ = params_->host_name();
532 2 : prog_name_ = params_->program_name();
533 2 : introspect_port_ = params_->http_server_port();
534 2 : prefix_len_ = params_->vhost_plen();
535 2 : gateway_list_ = params_->gateway_list();
536 2 : router_id_ = params_->vhost_addr();
537 2 : loopback_ip_ = params_->loopback_ip();
538 2 : if (params_->loopback_ip() != Ip4Address(0)) {
539 0 : router_id_ = params_->loopback_ip();
540 0 : is_l3mh_ = true;
541 : }
542 2 : if (router_id_.to_ulong()) {
543 2 : router_id_configured_ = false;
544 : }
545 :
546 2 : router_id6_ = Ip6Address::v4_mapped(router_id_);
547 2 : compute_node_ip_ = router_id_;
548 2 : if (params_->tunnel_type() == "MPLSoUDP")
549 0 : TunnelType::SetDefaultType(TunnelType::MPLS_UDP);
550 2 : else if (params_->tunnel_type() == "VXLAN")
551 0 : TunnelType::SetDefaultType(TunnelType::VXLAN);
552 : else
553 2 : TunnelType::SetDefaultType(TunnelType::MPLS_GRE);
554 :
555 2 : simulate_evpn_tor_ = params->simulate_evpn_tor();
556 2 : test_mode_ = params_->test_mode();
557 2 : tsn_no_forwarding_enabled_ = (params_->isTsnAgent() &&
558 0 : !params_->IsForwardingEnabled());
559 2 : tsn_enabled_ = params_->isTsnAgent();
560 2 : tor_agent_enabled_ = params_->isTorAgent();
561 2 : forwarding_enabled_ = params_->IsForwardingEnabled();
562 2 : server_gateway_mode_ = params_->isServerGatewayMode();
563 2 : vcpe_gateway_mode_ = params_->isVcpeGatewayMode();
564 2 : pbb_gateway_mode_ = params_->isPbbGatewayMode();
565 2 : flow_thread_count_ = params_->flow_thread_count();
566 2 : flow_trace_enable_ = params_->flow_trace_enable();
567 2 : flow_add_tokens_ = params_->flow_add_tokens();
568 2 : flow_ksync_tokens_ = params_->flow_ksync_tokens();
569 2 : flow_del_tokens_ = params_->flow_del_tokens();
570 2 : flow_update_tokens_ = params_->flow_update_tokens();
571 2 : tbb_keepawake_timeout_ = params_->tbb_keepawake_timeout();
572 2 : task_monitor_timeout_msec_ = params_->task_monitor_timeout_msec();
573 2 : vr_limit_high_watermark_ = params_->vr_object_high_watermark();
574 2 : vr_limit_low_watermark_ = vr_limit_high_watermark_ - 5;
575 2 : vr_limits_exceeded_map_.insert(VrLimitData("vr_nexthops", "Normal"));
576 2 : vr_limits_exceeded_map_.insert(VrLimitData("vr_mpls_labels", "Normal"));
577 2 : }
578 :
579 8 : void Agent::set_cn_mcast_builder(AgentXmppChannel *peer) {
580 8 : cn_mcast_builder_ = peer;
581 8 : }
582 :
583 2 : void Agent::InitCollector() {
584 : /* We need to do sandesh initialization here */
585 :
586 : /* If collector configuration is specified, use that for connection to
587 : * collector. If not we still need to invoke InitGenerator to initialize
588 : * introspect.
589 : */
590 2 : Module::type module = static_cast<Module::type>(module_type_);
591 : NodeType::type node_type =
592 2 : g_vns_constants.Module2NodeType.find(module)->second;
593 2 : if (GetCollectorlist().size() != 0) {
594 4 : Sandesh::InitGenerator(module_name(),
595 : host_name(),
596 2 : g_vns_constants.NodeTypeNames.find(node_type)->second,
597 2 : instance_id_,
598 : event_manager(),
599 2 : params_->http_server_port(),
600 2 : GetCollectorlist(),
601 4 : NULL, params_->derived_stats_map(),
602 2 : params_->sandesh_config());
603 : } else {
604 0 : Sandesh::InitGenerator(module_name(),
605 : host_name(),
606 0 : g_vns_constants.NodeTypeNames.find(node_type)->second,
607 0 : instance_id_,
608 : event_manager(),
609 0 : params_->http_server_port(),
610 0 : NULL, params_->derived_stats_map(),
611 0 : params_->sandesh_config());
612 : }
613 :
614 2 : if (params_->cat_is_agent_mocked()) {
615 0 : std::cout << "Agent Name: " << params_->agent_name()
616 0 : << " Introspect Port: " << Sandesh::http_port() << std::endl;
617 0 : std::string sub("{\"HTTPPort\":");
618 0 : std::string pidstring = integerToString(getpid());
619 :
620 0 : pidstring += ".json";
621 0 : sub += integerToString(Sandesh::http_port()) + "}";
622 :
623 0 : std::ofstream outfile(pidstring.c_str(), std::ofstream::out);
624 0 : outfile << sub;
625 0 : outfile.close();
626 0 : }
627 2 : }
628 :
629 0 : void Agent::ReConnectCollectors() {
630 : // ReConnect Collectors
631 0 : Sandesh::ReConfigCollectors(
632 0 : Agent::GetInstance()->GetCollectorlist());
633 0 : }
634 :
635 2 : void Agent::InitDone() {
636 2 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
637 : // Its observed that sometimes TBB scheduler misses spawn events
638 : // and doesnt schedule a task till its triggered again. As a work around
639 : // dummy timer is created at scheduler with default timeout of 1 sec
640 : // that fires and awake TBB periodically. Modify the timeout if required.
641 2 : if (tbb_keepawake_timeout_) {
642 2 : scheduler->ModifyTbbKeepAwakeTimeout(tbb_keepawake_timeout_);
643 : }
644 :
645 : // Its observed that sometimes TBB stops scheduling tasks altogether.
646 : // Initiate a monitor which asserts if no task is spawned for a given time.
647 2 : if (task_monitor_timeout_msec_) {
648 2 : scheduler->EnableMonitor(event_manager(), tbb_keepawake_timeout_,
649 2 : task_monitor_timeout_msec_, 400);
650 : }
651 2 : }
652 :
653 0 : static bool interface_exist(string &name) {
654 0 : struct if_nameindex *ifs = NULL;
655 0 : struct if_nameindex *head = NULL;
656 0 : bool ret = false;
657 0 : string tname = "";
658 :
659 0 : ifs = if_nameindex();
660 0 : if (ifs == NULL) {
661 0 : LOG(INFO, "No interface exists!");
662 0 : return ret;
663 : }
664 0 : head = ifs;
665 0 : while (ifs->if_name && ifs->if_index) {
666 0 : tname = ifs->if_name;
667 0 : if (string::npos != tname.find(name)) {
668 0 : ret = true;
669 0 : name = tname;
670 0 : break;
671 : }
672 0 : ifs++;
673 : }
674 0 : if_freenameindex(head);
675 0 : return ret;
676 0 : }
677 :
678 2 : void Agent::InitXenLinkLocalIntf() {
679 2 : if (!params_->isXenMode() || params_->xen_ll_name() == "")
680 2 : return;
681 :
682 0 : string dev_name = params_->xen_ll_name();
683 0 : if(!interface_exist(dev_name)) {
684 0 : LOG(INFO, "Interface " << dev_name << " not found");
685 0 : return;
686 : }
687 0 : params_->set_xen_ll_name(dev_name);
688 :
689 : //We create a kernel visible interface to support xapi
690 : //Once we support dpdk on xen, we should change
691 : //the transport type to KNI
692 0 : InetInterface::Create(intf_table_, params_->xen_ll_name(),
693 : InetInterface::LINK_LOCAL, link_local_vrf_name_,
694 0 : params_->xen_ll_addr(), params_->xen_ll_plen(),
695 0 : params_->xen_ll_gw(), NullString(), link_local_vrf_name_,
696 : Interface::TRANSPORT_ETHERNET);
697 0 : }
698 :
699 2 : void Agent::InitPeers() {
700 : // Create peer entries
701 2 : local_peer_.reset(new Peer(Peer::LOCAL_PEER, LOCAL_PEER_NAME, false));
702 4 : local_vm_peer_.reset(new Peer(Peer::LOCAL_VM_PEER, LOCAL_VM_PEER_NAME,
703 2 : false));
704 4 : linklocal_peer_.reset(new Peer(Peer::LINKLOCAL_PEER, LINKLOCAL_PEER_NAME,
705 2 : false));
706 2 : ecmp_peer_.reset(new Peer(Peer::ECMP_PEER, ECMP_PEER_NAME, true));
707 2 : vgw_peer_.reset(new Peer(Peer::VGW_PEER, VGW_PEER_NAME, true));
708 2 : evpn_routing_peer_.reset(new EvpnRoutingPeer());
709 2 : vxlan_bgp_peer_.reset(new VxlanBgpPeer());
710 2 : evpn_peer_.reset(new EvpnPeer());
711 2 : inet_evpn_peer_.reset(new InetEvpnPeer());
712 4 : multicast_peer_.reset(new Peer(Peer::MULTICAST_PEER, MULTICAST_PEER_NAME,
713 2 : false));
714 4 : multicast_tor_peer_.reset(new Peer(Peer::MULTICAST_TOR_PEER,
715 2 : MULTICAST_TOR_PEER_NAME, false));
716 4 : multicast_tree_builder_peer_.reset(
717 : new Peer(Peer::MULTICAST_FABRIC_TREE_BUILDER,
718 : MULTICAST_FABRIC_TREE_BUILDER_NAME,
719 2 : false));
720 4 : mac_vm_binding_peer_.reset(new Peer(Peer::MAC_VM_BINDING_PEER,
721 2 : MAC_VM_BINDING_PEER_NAME, false));
722 4 : mac_learning_peer_.reset(new Peer(Peer::MAC_LEARNING_PEER,
723 : MAC_LEARNING_PEER_NAME,
724 2 : false));
725 4 : fabric_rt_export_peer_.reset(new Peer(Peer::LOCAL_VM_PEER,
726 : FABRIC_RT_EXPORT,
727 2 : true));
728 4 : local_vm_export_peer_.reset(new Peer(Peer::LOCAL_VM_PEER,
729 : LOCAL_VM_EXPORT_PEER,
730 2 : true));
731 2 : }
732 :
733 0 : void Agent::ReconfigSignalHandler(boost::system::error_code ec, int signum) {
734 0 : LOG(DEBUG, "Received SIGHUP to apply updated configuration");
735 : // Read the configuration
736 0 : params_->ReInit();
737 : // Generates checksum, randomizes and saves the list
738 0 : CopyFilteredParams();
739 : // ReConnnect only ones whose checksums are different
740 0 : controller()->ReConnect();
741 : // ReConnect Collectors
742 0 : ReConnectCollectors();
743 0 : }
744 :
745 0 : void Agent::DebugSignalHandler(boost::system::error_code ec, int signum) {
746 0 : LOG(INFO, "Received SIGUSR1 to update debug configuration");
747 : //Read the debug configuration
748 0 : params_->DebugInit();
749 0 : }
750 :
751 2 : Agent::Agent() :
752 2 : params_(NULL), cfg_(NULL), stats_(NULL), ksync_(NULL), uve_(NULL),
753 2 : stats_collector_(NULL), flow_stats_manager_(NULL), pkt_(NULL),
754 2 : services_(NULL), vgw_(NULL), rest_server_(NULL), port_ipc_handler_(NULL),
755 2 : oper_db_(NULL), diag_table_(NULL), controller_(NULL), resource_manager_(),
756 2 : event_notifier_(), event_mgr_(NULL),
757 6 : agent_xmpp_channel_(), ifmap_channel_(),
758 18 : xmpp_client_(), xmpp_init_(), dns_xmpp_channel_(), dns_xmpp_client_(),
759 6 : dns_xmpp_init_(), agent_stale_cleaner_(NULL), cn_mcast_builder_(NULL),
760 2 : metadata_server_port_(0), host_name_(""), agent_name_(""),
761 2 : prog_name_(""), introspect_port_(0),
762 2 : instance_id_(g_vns_constants.INSTANCE_ID_DEFAULT),
763 2 : module_type_(Module::VROUTER_AGENT), module_name_(),
764 2 : db_(NULL), task_scheduler_(NULL), agent_init_(NULL), fabric_vrf_(NULL),
765 2 : fabric_policy_vrf_(NULL),
766 2 : intf_table_(NULL), health_check_table_(), metadata_ip_allocator_(),
767 2 : metadata_ip6_allocator_(nullptr), nh_table_(NULL), uc_rt_table_(NULL), mc_rt_table_(NULL),
768 2 : evpn_rt_table_(NULL), l2_rt_table_(NULL), vrf_table_(NULL),
769 2 : vm_table_(NULL), vn_table_(NULL), sg_table_(NULL), mpls_table_(NULL),
770 2 : acl_table_(NULL), mirror_table_(NULL), vrf_assign_table_(NULL),
771 2 : vxlan_table_(NULL), service_instance_table_(NULL),
772 2 : physical_device_table_(NULL), physical_device_vn_table_(NULL),
773 2 : config_manager_(), mirror_cfg_table_(NULL),
774 2 : intf_mirror_cfg_table_(NULL), router_id6_(Ip4Address(0)), router_id_(0), prefix_len_(0),
775 4 : gateway_list_(0), compute_node_ip_(0), xs_cfg_addr_(""), xs_idx_(0),
776 10 : xs_addr_(), xs_port_(),
777 12 : xs_stime_(), xs_auth_enable_(false), xs_dns_idx_(0), dns_addr_(),
778 6 : dns_port_(), dns_auth_enable_(false),
779 6 : controller_chksum_(0), dns_chksum_(0), collector_chksum_(0),
780 2 : ip_fabric_intf_name_(""), crypt_intf_name_(""),
781 2 : vhost_interface_name_(""),
782 2 : pkt_interface_name_("pkt0"), arp_proto_(NULL),
783 2 : dhcp_proto_(NULL), dns_proto_(NULL), icmp_proto_(NULL),
784 2 : dhcpv6_proto_(NULL), icmpv6_proto_(NULL), flow_proto_(NULL),
785 2 : mac_learning_proto_(NULL), mac_learning_module_(NULL),
786 2 : local_peer_(), local_vm_peer_(), linklocal_peer_(),
787 2 : ecmp_peer_(), vgw_peer_(), evpn_routing_peer_(),
788 2 : vxlan_bgp_peer_(), evpn_peer_(), multicast_peer_(),
789 2 : multicast_tor_peer_(), multicast_tree_builder_peer_(),mac_vm_binding_peer_(),
790 2 : inet_evpn_peer_(), mac_learning_peer_(), fabric_rt_export_peer_(),
791 2 : local_vm_export_peer_(), agent_signal_(), ifmap_parser_(NULL),
792 2 : router_id_configured_(false), mirror_src_udp_port_(0),
793 2 : lifetime_manager_(NULL), ksync_sync_mode_(false), mgmt_ip_(""),
794 2 : vxlan_network_identifier_mode_(AUTOMATIC), vhost_interface_(NULL),
795 2 : crypt_interface_(NULL), connection_state_(NULL), test_mode_(false),
796 2 : xmpp_dns_test_mode_(false),
797 2 : init_done_(false), resource_manager_ready_(false),
798 2 : simulate_evpn_tor_(false), tsn_no_forwarding_enabled_(false),
799 2 : tsn_enabled_(false),
800 2 : tor_agent_enabled_(false), forwarding_enabled_(true),
801 2 : server_gateway_mode_(false), pbb_gateway_mode_(false),
802 2 : inet_labeled_enabled_(false),
803 2 : flow_table_size_(0), flow_thread_count_(0), flow_trace_enable_(true),
804 2 : max_vm_flows_perc_(FLOWS_LIMIT_UNLIMITED),
805 2 : max_vm_flows_(FLOWS_LIMIT_UNLIMITED),
806 2 : global_max_vmi_flows_(FLOWS_LIMIT_UNLIMITED),
807 2 : ovsdb_client_(NULL), vrouter_server_ip_(0),
808 2 : vrouter_server_port_(0), vrouter_max_labels_(0), vrouter_max_nexthops_(0),
809 2 : vrouter_max_interfaces_(0), vrouter_max_vrfs_(0),
810 2 : vrouter_max_mirror_entries_(0), vrouter_max_bridge_entries_(0),
811 4 : vrouter_max_oflow_bridge_entries_(0), vrouter_priority_tagging_(true),
812 2 : flow_stats_req_handler_(NULL),
813 2 : tbb_keepawake_timeout_(kDefaultTbbKeepawakeTimeout),
814 2 : task_monitor_timeout_msec_(kDefaultTaskMonitorTimeout),
815 2 : vr_limit_high_watermark_(kDefaultHighWatermark),
816 2 : vr_limit_low_watermark_(kDefaultLowWatermark),
817 12 : loopback_ip_(), is_l3mh_(false), ip_fabric_intf_name_list_() {
818 :
819 2 : assert(singleton_ == NULL);
820 2 : singleton_ = this;
821 2 : db_ = new DB();
822 2 : assert(db_);
823 :
824 2 : event_mgr_ = new EventManager();
825 2 : assert(event_mgr_);
826 :
827 2 : SetAgentTaskPolicy();
828 2 : CreateLifetimeManager();
829 :
830 2 : Module::type module = static_cast<Module::type>(module_type_);
831 2 : module_name_ = g_vns_constants.ModuleNames.find(module)->second;
832 :
833 2 : agent_signal_.reset(
834 : AgentStaticObjectFactory::Create<AgentSignal>(event_mgr_));
835 2 : agent_signal_.get()->RegisterSigHupHandler(
836 : boost::bind(&Agent::ReconfigSignalHandler, this, _1, _2));
837 2 : agent_signal_.get()->RegisterDebugSigHandler(
838 : boost::bind(&Agent::DebugSignalHandler, this, _1, _2));
839 :
840 2 : config_manager_.reset(new ConfigManager(this));
841 6 : for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
842 4 : (agent_xmpp_channel_[count]).reset();
843 : }
844 2 : }
845 :
846 20 : Agent::~Agent() {
847 2 : uve_ = NULL;
848 2 : flow_stats_manager_ = NULL;
849 :
850 2 : agent_signal_->Terminate();
851 2 : agent_signal_.reset();
852 :
853 2 : ShutdownLifetimeManager();
854 :
855 2 : delete db_;
856 2 : db_ = NULL;
857 2 : singleton_ = NULL;
858 :
859 2 : if (task_scheduler_) {
860 2 : task_scheduler_->Terminate();
861 2 : task_scheduler_ = NULL;
862 : }
863 :
864 2 : delete event_mgr_;
865 2 : event_mgr_ = NULL;
866 26 : }
867 :
868 5222 : AgentConfig *Agent::cfg() const {
869 5222 : return cfg_;
870 : }
871 :
872 2 : void Agent::set_cfg(AgentConfig *cfg) {
873 2 : cfg_ = cfg;
874 2 : }
875 :
876 4 : DiagTable *Agent::diag_table() const {
877 4 : return diag_table_;
878 : }
879 :
880 2 : void Agent::set_diag_table(DiagTable *table) {
881 2 : diag_table_ = table;
882 2 : }
883 :
884 736 : AgentStats *Agent::stats() const {
885 736 : return stats_;
886 : }
887 :
888 2 : void Agent::set_stats(AgentStats *stats) {
889 2 : stats_ = stats;
890 2 : }
891 :
892 1499 : ConfigManager *Agent::config_manager() const {
893 1499 : return config_manager_.get();
894 : }
895 :
896 0 : EventNotifier *Agent::event_notifier() const {
897 0 : return event_notifier_;
898 : }
899 :
900 2 : void Agent::set_event_notifier(EventNotifier *val) {
901 2 : event_notifier_ = val;
902 2 : }
903 :
904 906 : KSync *Agent::ksync() const {
905 906 : return ksync_;
906 : }
907 :
908 2 : void Agent::set_ksync(KSync *ksync) {
909 2 : ksync_ = ksync;
910 2 : }
911 :
912 324 : AgentUveBase *Agent::uve() const {
913 324 : return uve_;
914 : }
915 :
916 2 : void Agent::set_uve(AgentUveBase *uve) {
917 2 : uve_ = uve;
918 2 : }
919 :
920 4 : AgentStatsCollector *Agent::stats_collector() const {
921 4 : return stats_collector_;
922 : }
923 :
924 2 : void Agent::set_stats_collector(AgentStatsCollector *asc) {
925 2 : stats_collector_ = asc;
926 2 : }
927 :
928 188 : FlowStatsManager *Agent::flow_stats_manager() const {
929 188 : return flow_stats_manager_;
930 : }
931 :
932 2 : void Agent::set_flow_stats_manager(FlowStatsManager *aging_module) {
933 2 : flow_stats_manager_ = aging_module;
934 2 : }
935 :
936 13 : HealthCheckTable *Agent::health_check_table() const {
937 13 : return health_check_table_;
938 : }
939 :
940 2 : void Agent::set_health_check_table(HealthCheckTable *table) {
941 2 : health_check_table_ = table;
942 2 : }
943 :
944 8 : BridgeDomainTable* Agent::bridge_domain_table() const {
945 8 : return bridge_domain_table_;
946 : }
947 :
948 2 : void Agent::set_bridge_domain_table(BridgeDomainTable *table) {
949 2 : bridge_domain_table_ = table;
950 2 : }
951 :
952 12 : MetaDataIpAllocator *Agent::metadata_ip_allocator() const {
953 12 : return metadata_ip_allocator_.get();
954 : }
955 :
956 2 : void Agent::set_metadata_ip_allocator(MetaDataIpAllocator *allocator) {
957 2 : metadata_ip_allocator_.reset(allocator);
958 2 : }
959 :
960 12 : MetaDataIpAllocator *Agent::metadata_ip6_allocator() const {
961 12 : return metadata_ip6_allocator_.get();
962 : }
963 :
964 2 : void Agent::set_metadata_ip6_allocator(MetaDataIpAllocator *allocator) {
965 2 : metadata_ip6_allocator_.reset(allocator);
966 2 : }
967 :
968 2950 : PktModule *Agent::pkt() const {
969 2950 : return pkt_;
970 : }
971 :
972 2 : void Agent::set_pkt(PktModule *pkt) {
973 2 : pkt_ = pkt;
974 2 : }
975 :
976 72 : ServicesModule *Agent::services() const {
977 72 : return services_;
978 : }
979 :
980 1 : void Agent::set_services(ServicesModule *services) {
981 1 : services_ = services;
982 1 : }
983 :
984 55 : VNController *Agent::controller() const {
985 55 : return controller_;
986 : }
987 :
988 2 : void Agent::set_controller(VNController *val) {
989 2 : controller_ = val;
990 2 : }
991 :
992 6 : VirtualGateway *Agent::vgw() const {
993 6 : return vgw_;
994 : }
995 :
996 0 : void Agent::set_vgw(VirtualGateway *vgw) {
997 0 : vgw_ = vgw;
998 0 : }
999 :
1000 0 : RestServer *Agent::rest_server() const {
1001 0 : return rest_server_;
1002 : }
1003 :
1004 0 : void Agent::set_rest_server(RestServer *r) {
1005 0 : rest_server_ = r;
1006 0 : }
1007 :
1008 142 : PortIpcHandler *Agent::port_ipc_handler() const {
1009 142 : return port_ipc_handler_;
1010 : }
1011 :
1012 2 : void Agent::set_port_ipc_handler(PortIpcHandler *r) {
1013 2 : port_ipc_handler_ = r;
1014 2 : }
1015 :
1016 3357 : OperDB *Agent::oper_db() const {
1017 3357 : return oper_db_;
1018 : }
1019 :
1020 2 : void Agent::set_oper_db(OperDB *oper_db) {
1021 2 : oper_db_ = oper_db;
1022 2 : }
1023 :
1024 978 : ResourceManager *Agent::resource_manager() const {
1025 978 : return resource_manager_;
1026 : }
1027 :
1028 2 : void Agent::set_resource_manager(ResourceManager *val) {
1029 2 : resource_manager_ = val;
1030 2 : }
1031 :
1032 39 : DomainConfig *Agent::domain_config_table() const {
1033 39 : return oper_db_->domain_config_table();
1034 : }
1035 :
1036 1168 : bool Agent::isVmwareMode() const {
1037 1168 : return params_->isVmwareMode();
1038 : }
1039 :
1040 86 : bool Agent::isVmwareVcenterMode() const {
1041 86 : if (isVmwareMode() == false)
1042 86 : return false;
1043 :
1044 0 : return params_->isVmwareVcenterMode();
1045 : }
1046 :
1047 1332 : void Agent::ConcurrencyCheck() {
1048 1332 : if (test_mode_) {
1049 1332 : CHECK_CONCURRENCY("db::DBTable", "Agent::KSync", AGENT_INIT_TASKNAME,
1050 : kTaskFlowMgmt, kTaskFlowUpdate,
1051 : kTaskFlowEvent, kTaskFlowDelete, kTaskFlowKSync,
1052 : kTaskHealthCheck, kTaskCryptTunnel, kAgentResourceRestoreTask);
1053 : }
1054 1332 : }
1055 :
1056 12 : bool Agent::vrouter_on_nic_mode() const {
1057 12 : return params_->vrouter_on_nic_mode();
1058 : }
1059 :
1060 14 : bool Agent::vrouter_on_host_dpdk() const {
1061 14 : return params_->vrouter_on_host_dpdk();
1062 : }
1063 :
1064 0 : bool Agent::vrouter_on_host() const {
1065 0 : return params_->vrouter_on_host();
1066 : }
1067 :
1068 : uint16_t
1069 9 : Agent::ProtocolStringToInt(const std::string &proto_arg) {
1070 9 : std::string proto = proto_arg;
1071 :
1072 9 : std::transform(proto.begin(), proto.end(), proto.begin(), ::tolower);
1073 :
1074 9 : if (proto == "tcp") {
1075 0 : return IPPROTO_TCP;
1076 : }
1077 :
1078 9 : if (proto == "udp") {
1079 9 : return IPPROTO_UDP;
1080 : }
1081 :
1082 0 : if (proto == "sctp") {
1083 0 : return IPPROTO_SCTP;
1084 : }
1085 :
1086 0 : if (proto =="icmp") {
1087 0 : return IPPROTO_ICMP;
1088 : }
1089 :
1090 0 : if (proto == "icmp6") {
1091 0 : return IPPROTO_ICMPV6;
1092 : }
1093 :
1094 0 : return atoi(proto.c_str());
1095 9 : }
1096 :
1097 49 : Agent::ForwardingMode Agent::TranslateForwardingMode
1098 : (const std::string &mode) const {
1099 49 : if (mode == "l2")
1100 0 : return Agent::L2;
1101 49 : else if (mode == "l3")
1102 0 : return Agent::L3;
1103 49 : else if (mode == "l2_l3")
1104 0 : return Agent::L2_L3;
1105 :
1106 49 : return Agent::NONE;
1107 : }
1108 :
1109 6 : void Agent::update_max_vm_flows(uint32_t flow_table_size) {
1110 6 : if (flow_table_size == 0) {
1111 0 : return;
1112 : }
1113 6 : if (max_vm_flows_perc_ >= 100) {
1114 0 : max_vm_flows_ = flow_table_size;
1115 6 : } else if (max_vm_flows_perc_ == FLOWS_LIMIT_UNLIMITED) {
1116 6 : max_vm_flows_ = flow_table_size;
1117 : } else {
1118 0 : max_vm_flows_ = (flow_table_size / 100) * max_vm_flows_perc_;
1119 : }
1120 : }
1121 :
1122 2 : void Agent::set_flow_table_size(uint32_t count) {
1123 2 : flow_table_size_ = count;
1124 2 : update_max_vm_flows(flow_table_size_);
1125 2 : }
1126 :
1127 3 : void Agent::set_controller_xmpp_channel(AgentXmppChannel *channel, uint8_t idx) {
1128 3 : assert(channel != NULL);
1129 3 : (agent_xmpp_channel_[idx]).reset(channel);
1130 3 : }
1131 :
1132 4 : void Agent::reset_controller_xmpp_channel(uint8_t idx) {
1133 4 : (agent_xmpp_channel_[idx]).reset();
1134 4 : }
1135 :
1136 7 : boost::shared_ptr<AgentXmppChannel> Agent::controller_xmpp_channel_ref(uint8_t idx) {
1137 7 : return agent_xmpp_channel_[idx];
1138 : }
1139 :
1140 0 : void Agent::TaskTrace(const char *file_name, uint32_t line_no,
1141 : const Task *task, const char *description,
1142 : uint64_t delay) {
1143 0 : TaskTrace::TraceMsg(TaskTraceBuf, file_name, line_no,
1144 0 : task->task_code_id(), task->task_data_id(),
1145 0 : description, delay, task->Description());
1146 0 : }
1147 :
1148 26 : bool Agent::MeasureQueueDelay() {
1149 26 : return params_->measure_queue_delay();
1150 : }
1151 :
1152 0 : void Agent::SetMeasureQueueDelay(bool val) {
1153 0 : return params_->set_measure_queue_delay(val);
1154 : }
1155 :
1156 0 : void Agent::SetXmppDscp(uint8_t val) {
1157 0 : for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
1158 0 : XmppClient *client = xmpp_client_[count];
1159 0 : if (client) {
1160 0 : client->SetDscpValue(val, XmppInit::kControlNodeJID);
1161 : }
1162 0 : client = dns_xmpp_client_[count];
1163 0 : if (client) {
1164 0 : client->SetDscpValue(val, XmppInit::kDnsNodeJID);
1165 : }
1166 : }
1167 0 : }
1168 :
1169 0 : VrouterObjectLimits Agent::GetVrouterObjectLimits() {
1170 0 : VrouterObjectLimits vr_limits;
1171 0 : vr_limits.set_max_labels(vrouter_max_labels());
1172 0 : vr_limits.set_max_nexthops(vrouter_max_nexthops());
1173 0 : vr_limits.set_max_interfaces(vrouter_max_interfaces());
1174 0 : vr_limits.set_max_vrfs(vrouter_max_vrfs());
1175 0 : vr_limits.set_max_mirror_entries(vrouter_max_mirror_entries());
1176 0 : vr_limits.set_vrouter_max_bridge_entries(vrouter_max_bridge_entries());
1177 0 : vr_limits.set_vrouter_max_oflow_bridge_entries(
1178 : vrouter_max_oflow_bridge_entries());
1179 0 : vr_limits.set_vrouter_build_info(vrouter_build_info());
1180 0 : vr_limits.set_vrouter_max_flow_entries(vrouter_max_flow_entries());
1181 0 : vr_limits.set_vrouter_max_oflow_entries(vrouter_max_oflow_entries());
1182 0 : vr_limits.set_vrouter_priority_tagging(vrouter_priority_tagging());
1183 0 : return vr_limits;
1184 0 : }
1185 :
1186 2 : void Agent::SetResourceManagerReady() {
1187 2 : resource_manager_ready_ = true;
1188 2 : config_manager_->Start();
1189 2 : }
1190 :
1191 4 : uint8_t Agent::GetInterfaceTransport() const {
1192 4 : if (params()->vrouter_on_host_dpdk()) {
1193 0 : return Interface::TRANSPORT_PMD;
1194 : }
1195 4 : return Interface::TRANSPORT_ETHERNET;
1196 : }
1197 :
1198 :
1199 0 : std::string AgentBackTrace(int skip = 1)
1200 : {
1201 0 : std::ostringstream sbuffer;
1202 : void *callstack[128];
1203 : char buffer[1024];
1204 0 : const int nMaxFrames = sizeof(callstack) / sizeof(callstack[0]);
1205 0 : int nFrames = backtrace(callstack, nMaxFrames);
1206 :
1207 0 : for (int i = skip; i < nFrames; i++) {
1208 : Dl_info info;
1209 0 : if (dladdr(callstack[i], &info)) {
1210 0 : char *demangled = NULL;
1211 : int status;
1212 0 : demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
1213 0 : snprintf(buffer, sizeof(buffer), "%-3d %p %s + %zd\n",
1214 : i, callstack[i],
1215 0 : status == 0 ? demangled : info.dli_sname,
1216 0 : (char *)callstack[i] - (char *)info.dli_saddr);
1217 0 : free(demangled);
1218 : } else {
1219 0 : snprintf(buffer, sizeof(buffer), "%-3d %p\n",
1220 : i, callstack[i]);
1221 : }
1222 0 : sbuffer << buffer;
1223 : }
1224 0 : if (nFrames == nMaxFrames)
1225 0 : sbuffer << " [truncated]\n";
1226 :
1227 0 : return sbuffer.str();
1228 0 : }
|