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