OpenSDN source code
vrouter_uve_entry_base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sstream>
6 #include <fstream>
7 #include <sandesh/common/vns_types.h>
9 #include <cfg/cfg_init.h>
10 #include <init/agent_param.h>
11 #include <oper/interface_common.h>
12 #include <oper/interface.h>
13 #include <oper/vm.h>
14 #include <oper/vn.h>
15 #include <oper/mirror_table.h>
17 #include <uve/agent_uve_base.h>
18 #include <cmn/agent_stats.h>
19 #include <base/cpuinfo.h>
20 #include <base/util.h>
21 #include <cmn/agent_cmn.h>
22 #include <oper/operdb_init.h>
23 #include <oper/bgp_as_service.h>
24 
25 using namespace std;
26 
27 extern const std::string BuildInfo;
28 
30  : agent_(agent), phy_intf_set_(), prev_stats_(), prev_vrouter_(),
31  cpu_stats_count_(0), do_vn_walk_(false), do_vm_walk_(false),
32  do_interface_walk_(false), vn_walk_ref_(NULL), vm_walk_ref_(NULL),
33  interface_walk_ref_(NULL), vn_listener_id_(DBTableBase::kInvalidId),
34  vm_listener_id_(DBTableBase::kInvalidId),
35  intf_listener_id_(DBTableBase::kInvalidId),
36  physical_device_listener_id_(DBTableBase::kInvalidId),
37  timer_(TimerManager::CreateTimer(
38  *(agent_->event_manager())->io_service(), "UveDBWalkTimer",
39  TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
40  StartTimer();
41 
42 }
43 
45 }
46 
48  timer_->Cancel();
50  boost::bind(&VrouterUveEntryBase::TimerExpiry, this));
51 }
52 
54  bool restart = Run();
55  return restart;
56 }
57 
59  /* We don't do vn, vm and interface walks simultaneously to avoid creation
60  * of multiple threads (caused by start of walks). After all the walks are
61  * done we re-start the timer */
62  bool walk_started = StartVnWalk();
63 
64  /* If VN walk is not started, start VM walk */
65  if (!walk_started) {
66  walk_started = StartVmWalk();
67 
68  /* If neither VN nor VM walks have started, start interface walk */
69  if (!walk_started) {
70  walk_started = StartInterfaceWalk();
71 
72  /* If none of the walks are started, return true to trigger
73  * auto restart of timer */
74  if (!walk_started) {
75  return true;
76  }
77  }
78  }
79 
80  return false;
81 }
82 
84  DBEntryBase *e) {
85  const PhysicalDevice *pr = static_cast<const PhysicalDevice *>(e);
87  (e->GetState(partition->parent(), physical_device_listener_id_));
88  if (e->IsDeleted()) {
89  if (state) {
91  delete state;
92  }
93  } else {
94  if (!state) {
95  state = new VrouterPhysicalDeviceState();
97  state);
98  do_interface_walk_ = true;
99  } else {
100  if (state->master_ != pr->master()) {
101  do_interface_walk_ = true;
102  }
103  }
104  state->master_ = pr->master();
105  }
106 }
107 
109  VnTable *vn_table = agent_->vn_table();
110  vn_listener_id_ = vn_table->Register
111  (boost::bind(&VrouterUveEntryBase::VnNotify, this, _1, _2));
112 
113  VmTable *vm_table = agent_->vm_table();
114  vm_listener_id_ = vm_table->Register
115  (boost::bind(&VrouterUveEntryBase::VmNotify, this, _1, _2));
116 
117  InterfaceTable *intf_table = agent_->interface_table();
118  intf_listener_id_ = intf_table->Register
119  (boost::bind(&VrouterUveEntryBase::InterfaceNotify, this, _1, _2));
120 
123  (boost::bind(&VrouterUveEntryBase::PhysicalDeviceNotify, this, _1, _2));
124 }
125 
129  Unregister(physical_device_listener_id_);
136  if (interface_walk_ref_.get() != NULL)
138  if (vn_walk_ref_.get() != NULL)
140  if (vm_walk_ref_.get() != NULL)
142  if (timer_) {
143  timer_->Cancel();
145  timer_ = NULL;
146  }
147  vn_walk_ref_ = NULL;
148  vm_walk_ref_ = NULL;
149  interface_walk_ref_ = NULL;
150 }
151 
152 void VrouterUveEntryBase::DispatchVrouterMsg(const VrouterAgent &uve) {
153  UveVrouterAgent::Send(uve);
154 }
155 
157  VrouterAgent vrouter_agent;
158  vrouter_agent.set_name(agent_->agent_name());
159  vrouter_agent.set_virtual_machine_list(*(list.get()));
160  VrouterAgentObjectCount vm_count;
161  vm_count.set_active(list.get()->size());
162  vrouter_agent.set_vm_count(vm_count);
163  DispatchVrouterMsg(vrouter_agent);
164 
165  /* Start Interface Walk after we are done with Vm Walk */
166  bool walk_started = StartInterfaceWalk();
167 
168  /* If interface walk has not started, restart the timer */
169  if (!walk_started) {
170  StartTimer();
171  }
172  (*list).clear();
173 }
174 
176  StringVectorPtr list) {
177  VmEntry *vm = static_cast<VmEntry *>(entry);
178 
179  if (!vm->IsDeleted()) {
180  std::ostringstream ostr;
181  ostr << vm->GetUuid();
182  list.get()->push_back(ostr.str());
183  }
184  return true;
185 }
186 
188  if (!do_vm_walk_) {
189  /* There is no change in VM list. No need of walk */
190  return false;
191  }
192  if (vm_walk_ref_.get() == NULL) {
193  StringVectorPtr vm_list(new vector<string>());
195  boost::bind(&VrouterUveEntryBase::AppendVm, this, _1, _2, vm_list),
196  boost::bind(&VrouterUveEntryBase::VmWalkDone, this, _2, vm_list));
197  }
199  do_vm_walk_ = false;
200  return true;
201 }
202 
204  DBState *state = static_cast<DBState *>
205  (e->GetState(partition->parent(), vm_listener_id_));
206 
207  if (e->IsDeleted()) {
208  if (state) {
209  do_vm_walk_ = true;
210  e->ClearState(partition->parent(), vm_listener_id_);
211  delete state;
212  }
213  return;
214  }
215 
216  if (!state) {
217  state = new DBState();
218  e->SetState(partition->parent(), vm_listener_id_, state);
219  //Send vrouter object only for a add/delete
220  do_vm_walk_ = true;
221  }
222 }
223 
225  VrouterAgent vrouter_agent;
226  vrouter_agent.set_name(agent_->agent_name());
227  vrouter_agent.set_connected_networks(*(list.get()));
228  vrouter_agent.set_vn_count((*list).size());
229  DispatchVrouterMsg(vrouter_agent);
230 
231  //Update prev_vrouter_ fields. Currently used only in UT
232  prev_vrouter_.set_connected_networks(*(list.get()));
233  prev_vrouter_.set_vn_count((*list).size());
234 
235  /* Start Vm Walk after we are done with Vn Walk */
236  bool walk_started = StartVmWalk();
237 
238  /* If VM walk has not started, start interface walk */
239  if (!walk_started) {
240  walk_started = StartInterfaceWalk();
241 
242  /* If interface walk has not started, restart the timer */
243  if (!walk_started) {
244  StartTimer();
245  }
246  }
247  (*list).clear();
248 }
249 
251  StringVectorPtr list) {
252  VnEntry *vn = static_cast<VnEntry *>(entry);
253 
254  if (!vn->IsDeleted()) {
255  list.get()->push_back(vn->GetName());
256  }
257  return true;
258 }
259 
261  if (!do_vn_walk_) {
262  /* There is no change in VN list. No need of walk */
263  return false;
264  }
265  if (vn_walk_ref_.get() == NULL) {
266  StringVectorPtr vn_list(new vector<string>());
268  boost::bind(&VrouterUveEntryBase::AppendVn, this, _1, _2, vn_list),
269  boost::bind(&VrouterUveEntryBase::VnWalkDone, this, _2, vn_list));
270 
271  }
273  do_vn_walk_ = false;
274  return true;
275 }
276 
278  DBState *state = static_cast<DBState *>
279  (e->GetState(partition->parent(), vn_listener_id_));
280 
281  if (e->IsDeleted()) {
282  if (state) {
283  do_vn_walk_ = true;
284  e->ClearState(partition->parent(), vn_listener_id_);
285  delete state;
286  }
287  return;
288  }
289 
290  if (!state) {
291  state = new DBState();
292  e->SetState(partition->parent(), vn_listener_id_, state);
293  do_vn_walk_ = true;
294  }
295 }
296 
298  StringVectorPtr if_list,
299  StringVectorPtr err_if_list,
300  StringVectorPtr nova_if_list,
301  StringVectorPtr unmanaged_list) {
302  VrouterAgent vrouter_agent;
303  vrouter_agent.set_name(agent_->agent_name());
304  vrouter_agent.set_interface_list(*(if_list.get()));
305  vrouter_agent.set_error_intf_list(*(err_if_list.get()));
306  vrouter_agent.set_no_config_intf_list(*(nova_if_list.get()));
307  if (agent_->tsn_enabled()) {
308  vrouter_agent.set_unmanaged_if_list(*(unmanaged_list.get()));
309  prev_vrouter_.set_unmanaged_if_list(*(unmanaged_list.get()));
310  }
311 
312  VrouterAgentObjectCount vmi_count;
313  vmi_count.set_active((if_list.get()->size() + nova_if_list.get()->size()));
314  vrouter_agent.set_vmi_count(vmi_count);
315  vrouter_agent.set_down_interface_count((err_if_list.get()->size() +
316  nova_if_list.get()->size()));
317  DispatchVrouterMsg(vrouter_agent);
318 
319  //Update prev_vrouter_ fields. This is being used now only for UT
320  prev_vrouter_.set_interface_list(*(if_list.get()));
321  prev_vrouter_.set_error_intf_list(*(err_if_list.get()));
322  prev_vrouter_.set_no_config_intf_list(*(nova_if_list.get()));
323 
324  (*if_list).clear();
325  (*err_if_list).clear();
326  (*nova_if_list).clear();
327  (*unmanaged_list).clear();
328  /* Restart the timer after we are done with the walk */
329  StartTimer();
330 }
331 
333  DBEntryBase *entry,
334  StringVectorPtr intf_list,
335  StringVectorPtr err_if_list,
336  StringVectorPtr nova_if_list,
337  StringVectorPtr unmanaged_list) {
338  Interface *intf = static_cast<Interface *>(entry);
339 
340  if (intf->type() == Interface::VM_INTERFACE) {
341  const VmInterface *port = static_cast<const VmInterface *>(intf);
342  if (!entry->IsDeleted()) {
343  if (port->cfg_name() == agent_->NullString()) {
344  nova_if_list.get()->push_back(UuidToString(port->GetUuid()));
345  } else {
346  if (agent_->tsn_enabled()) {
347  /* For TSN nodes send VMI in interface_list if the VMI's
348  * physical device has tsn_enabled set to true. Otherwise
349  * send the VMI in unmanaged_list */
351  if (!pd || !pd->master()) {
352  unmanaged_list.get()->push_back(port->cfg_name());
353  return true;
354  }
355  AppendInterfaceInternal(port, intf_list, err_if_list);
356  } else {
357  AppendInterfaceInternal(port, intf_list, err_if_list);
358  }
359  }
360  }
361  }
362  else if (intf->type() == Interface::PHYSICAL) {
363  const PhysicalInterface *phy_intf = static_cast<const
364  PhysicalInterface *>(intf);
365  if (phy_intf) {
366  PhysicalInterface::BondChildIntfMap bond_childIntf_map =
367  phy_intf->getBondChildIntfMap();
369  bond_childIntf_map.begin();
370  for(; it != bond_childIntf_map.end(); it++) {
372  bond_intf = it->second;
373  if(!bond_intf.intf_status) {
374  err_if_list.get()->push_back(it->first);
375  }
376  }
377  }
378  }
379  return true;
380 }
381 
383  StringVectorPtr intf_list,
384  StringVectorPtr err_if_list) {
385  intf_list.get()->push_back(port->cfg_name());
386  if (!port->IsUveActive()) {
387  err_if_list.get()->push_back(port->cfg_name());
388  }
389 }
390 
392  (const VmInterface *port) {
393  const boost::uuids::uuid u = port->logical_interface();
394  if (u == boost::uuids::nil_uuid()) {
395  return NULL;
396  }
397  LogicalInterface *intf;
398  VlanLogicalInterfaceKey key(u, "");
399  intf = static_cast<LogicalInterface *>
401  if (!intf || !intf->physical_interface()) {
402  return NULL;
403  }
405 }
406 
408  PhysicalDevice *pde = NULL;
409  const RemotePhysicalInterface *rpintf;
410  const PhysicalInterface *pintf;
411  if (intf->type() == Interface::REMOTE_PHYSICAL) {
412  rpintf = static_cast<const RemotePhysicalInterface *>(intf);
413  pde = rpintf->physical_device();
414  } else if (intf->type() == Interface::PHYSICAL) {
415  pintf = static_cast<const PhysicalInterface *>(intf);
416  pde = pintf->physical_device();
417  }
418  return pde;
419 }
420 
422  if (!do_interface_walk_) {
423  /* There is no change in interface list. No need of walk */
424  return false;
425  }
426  if (interface_walk_ref_.get() == NULL) {
427  StringVectorPtr intf_list(new std::vector<std::string>());
428  StringVectorPtr err_if_list(new std::vector<std::string>());
429  StringVectorPtr nova_if_list(new std::vector<std::string>());
430  StringVectorPtr unmanaged_list(new std::vector<std::string>());
431 
433  boost::bind(&VrouterUveEntryBase::AppendInterface, this, _1, _2,
434  intf_list, err_if_list, nova_if_list, unmanaged_list),
435  boost::bind(&VrouterUveEntryBase::InterfaceWalkDone, this, _2,
436  intf_list, err_if_list, nova_if_list, unmanaged_list));
437 }
439  do_interface_walk_ = false;
440  return true;
441 }
442 
444  DBEntryBase *e) {
445  const Interface *intf = static_cast<const Interface *>(e);
446  bool set_state = false, reset_state = false;
447 
448  VrouterUveInterfaceState *state = static_cast<VrouterUveInterfaceState *>
449  (e->GetState(partition->parent(), intf_listener_id_));
450  bool vmport_active = false;
451  const VmInterface *vm_port = NULL;
452  switch(intf->type()) {
454  vm_port = static_cast<const VmInterface*>(intf);
455  if (!e->IsDeleted() && !state) {
456  set_state = true;
457  vmport_active = vm_port->IsUveActive();
458  do_interface_walk_ = true;
459  } else if (e->IsDeleted()) {
460  if (state) {
461  reset_state = true;
462  do_interface_walk_ = true;
463  }
464  } else {
465  if (state && vm_port->IsUveActive() != state->vmport_active_) {
466  do_interface_walk_ = true;
467  state->vmport_active_ = vm_port->IsUveActive();
468  }
469  }
470  break;
471  case Interface::PHYSICAL:
472  if (e->IsDeleted()) {
473  if (state) {
474  reset_state = true;
475  phy_intf_set_.erase(intf);
476  }
477  } else {
478  const PhysicalInterface* phy_if =
479  static_cast<const PhysicalInterface*>(intf);
480  /* Ignore PhysicalInterface notifications if it is not of subtype
481  * FABRIC */
482  if (phy_if->subtype() != PhysicalInterface::FABRIC) {
483  return;
484  }
485  if (!state) {
486  set_state = true;
487  phy_intf_set_.insert(intf);
488  }
489  if (phy_if) {
490  PhysicalInterface::BondChildIntfMap bond_childIntf_map =
491  phy_if->getBondChildIntfMap();
493  bond_childIntf_map.begin();
494  for(; it != bond_childIntf_map.end(); it++) {
496  bond_intf = it->second;
497  if(!bond_intf.intf_status) {
498  do_interface_walk_ = true;
499  }
500  else {
501  std::vector<std::string> prev_err_if_list =
502  prev_vrouter_.get_error_intf_list();
503  if (std::find(prev_err_if_list.begin(),
504  prev_err_if_list.end(), it->first)
505  != prev_err_if_list.end()) {
506  do_interface_walk_ = true;
507  }
508  }
509  }
510  }
511  }
512  break;
513  default:
514  break;
515  }
516  if (set_state) {
517  state = new VrouterUveInterfaceState(vmport_active);
518  e->SetState(partition->parent(), intf_listener_id_, state);
519  } else if (reset_state) {
520  e->ClearState(partition->parent(), intf_listener_id_);
521  delete state;
522  }
523  return;
524 }
525 
527  (VirtualGatewayConfig::SubnetList &source_list, vector<string> &target_list) {
528  VirtualGatewayConfig::SubnetList::iterator subnet_it =
529  source_list.begin();
530  while (subnet_it != source_list.end()) {
531  string subnet_str = subnet_it->ip_.to_string() + "/" +
532  integerToString(subnet_it->plen_);
533  target_list.push_back(subnet_str);
534  ++subnet_it;
535  }
536 }
537 
538 void VrouterUveEntryBase::BuildAgentConfig(VrouterAgent &vrouter_agent) {
539  AgentVhostConfig vhost_cfg;
540  AgentXenConfig xen_cfg;
541  AgentVmwareConfig vmware_cfg;
542  string hypervisor;
543  vector<AgentVgwConfig> gw_cfg_list;
544 
545  AgentParam *param = agent_->params();
546 
547  vrouter_agent.set_log_file(param->log_file());
548  vrouter_agent.set_config_file(param->config_file());
549  vrouter_agent.set_log_local(param->log_local());
550  vrouter_agent.set_log_flow(param->log_flow());
551  vrouter_agent.set_log_category(param->log_category());
552  vrouter_agent.set_log_level(param->log_level());
553  vrouter_agent.set_sandesh_http_port(param->http_server_port());
554  vrouter_agent.set_tunnel_type(param->tunnel_type());
555  vrouter_agent.set_hostname_cfg(param->host_name());
556  vrouter_agent.set_flow_cache_timeout_cfg(param->flow_cache_timeout());
557 
558  vrouter_agent.set_dns_server_list_cfg(param->dns_server_list());
559  vrouter_agent.set_control_node_list_cfg(param->controller_server_list());
560 
561  vrouter_agent.set_ll_max_system_flows_cfg(param->linklocal_system_flows());
562  vrouter_agent.set_ll_max_vm_flows_cfg(param->linklocal_vm_flows());
563  vrouter_agent.set_control_ip(param->mgmt_ip().to_string());
564 
565  vhost_cfg.set_name(param->vhost_name());
566  if (agent_->is_l3mh() == false) {
567  vhost_cfg.set_ip(param->vhost_addr().to_string());
568  vhost_cfg.set_ip_prefix_len(param->vhost_plen());
569  if (param->gateway_list().empty() == false) {
570  vhost_cfg.set_gateway(param->gateway_list()[0].to_string());
571  }
572  }
573  vrouter_agent.set_vhost_cfg(vhost_cfg);
574 
575  vrouter_agent.set_eth_name(param->eth_port_list());
576 
577  if (param->isKvmMode()) {
578  hypervisor = "kvm";
579  } else if (param->isXenMode()) {
580  hypervisor = "xen";
581  xen_cfg.set_xen_ll_port(param->xen_ll_name());
582  xen_cfg.set_xen_ll_ip(param->xen_ll_addr().to_string());
583  xen_cfg.set_xen_ll_prefix_len(param->xen_ll_plen());
584  vrouter_agent.set_xen_cfg(xen_cfg);
585  } else if (param->isVmwareMode()) {
586  hypervisor = "vmware";
587  vmware_cfg.set_vmware_port(param->vmware_physical_port());
588  vrouter_agent.set_vmware_cfg(vmware_cfg);
589  }
590  vrouter_agent.set_hypervisor(hypervisor);
591 
593  VirtualGatewayConfigTable::Table::iterator it = table->table().begin();
594  while (it != table->table().end()) {
595  AgentVgwConfig gw_cfg;
596  VirtualGatewayConfig::SubnetList subnet_list = it->subnets();
597  VirtualGatewayConfig::SubnetList route_list = it->routes();
598  vector<string> ip_blocks_list;
599  vector<string> route_str_list;
600 
601  SubnetToStringList(subnet_list, ip_blocks_list);
602  SubnetToStringList(route_list, route_str_list);
603 
604  gw_cfg.set_interface_name(it->interface_name());
605  gw_cfg.set_vrf_name(it->vrf_name());
606  gw_cfg.set_ip_blocks_list(ip_blocks_list);
607  gw_cfg.set_route_list(route_str_list);
608 
609  gw_cfg_list.push_back(gw_cfg);
610  ++it;
611  }
612  vrouter_agent.set_gateway_cfg_list(gw_cfg_list);
613  vrouter_agent.set_headless_mode_cfg(true);
614  vrouter_agent.set_collector_server_list_cfg(param->collector_server_list());
615  vrouter_agent.set_bgpaas_enabled(
617  vrouter_agent.set_port_mirror_enabled(MirrorTable::GetInstance()->IsConfigured());
618  vrouter_agent.set_loopback_ip(param->loopback_ip().to_string());
619  std::vector<string> gateway_list;
620  for (std::vector<Ip4Address>::const_iterator iter = param->gateway_list().begin();
621  iter != param->gateway_list().end(); ++iter) {
622  gateway_list.push_back((*iter).to_string());
623  }
624  vrouter_agent.set_gateway_list(gateway_list);
625 }
626 
627 
629  VrouterAgent vrouter_agent;
630  bool changed = false, bgp_aas, port_mirror;
631  static bool first = true;
632  vrouter_agent.set_name(agent_->agent_name());
633  Ip4Address rid = agent_->router_id();
634  vector<string> ip_list;
635  vector<string> dns_list;
636 
637  if (first) {
638  //Physical interface list
639  vnsConstants vnsVrouterType;
640  //vhost attributes
641  const Interface *vhost = agent_->vhost_interface();
642  if (vhost) {
643  AgentInterface vitf;
644  vitf.set_name(vhost->name());
645  vitf.set_mac_address(GetMacAddress(vhost->mac()));
646  vrouter_agent.set_vhost_if(vitf);
647  }
648 
649  //Configuration. Needs to be sent only once because whenever config
650  //changes agent will be restarted
651  BuildAgentConfig(vrouter_agent);
652 
653  //Set the Agent mode
654  if (agent_->tor_agent_enabled()) {
655  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
656  (VrouterAgentType::VROUTER_AGENT_TOR));
657  } else if (agent_->tsn_enabled()) {
658  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
659  (VrouterAgentType::VROUTER_AGENT_TSN));
660  } else {
661  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
662  (VrouterAgentType::VROUTER_AGENT_EMBEDDED));
663  }
664 
665  if (agent_->vrouter_on_nic_mode()) {
666  vrouter_agent.set_platform(vnsVrouterType.
667  VrouterAgentPlatformTypeMap.at
668  (VrouterAgentPlatformType::
669  VROUTER_AGENT_ON_NIC));
670  } else if (agent_->vrouter_on_host_dpdk()) {
671  vrouter_agent.set_platform(vnsVrouterType.
672  VrouterAgentPlatformTypeMap.at
673  (VrouterAgentPlatformType::
674  VROUTER_AGENT_ON_HOST_DPDK));
675  } else if (agent_->vrouter_on_host()) {
676  vrouter_agent.set_platform(vnsVrouterType.
677  VrouterAgentPlatformTypeMap.at
678  (VrouterAgentPlatformType::
679  VROUTER_AGENT_ON_HOST));
680  }
681 
682  vrouter_agent.set_subcluster_name(agent_->subcluster_name());
683  vrouter_agent.set_vr_high_watermark(agent_->vr_limit_high_watermark());
684  vrouter_agent.set_vr_low_watermark(agent_->vr_limit_low_watermark());
685  first = false;
686  changed = true;
687  }
688 
689  VrouterObjectLimits vr_limits = agent_->GetVrouterObjectLimits();
690  VrouterObjectLimits prev_vr_limits = prev_vrouter_.get_vr_limits();
691  if (vr_limits != prev_vr_limits) {
692  vrouter_agent.set_vr_limits(vr_limits);
693  prev_vrouter_.set_vr_limits(vr_limits);
694  changed = true;
695  }
696 
697  if (prev_vrouter_.get_build_info() != BuildInfo) {
698  vrouter_agent.set_build_info(BuildInfo);
699  prev_vrouter_.set_build_info(BuildInfo);
700  changed = true;
701  }
702 
703  bgp_aas = agent_->oper_db()->bgp_as_a_service()->IsConfigured();
704  if (prev_vrouter_.get_bgpaas_enabled() != bgp_aas) {
705  vrouter_agent.set_bgpaas_enabled(bgp_aas);
706  prev_vrouter_.set_bgpaas_enabled(bgp_aas);
707  changed = true;
708  }
709 
710  port_mirror = MirrorTable::GetInstance()->IsConfigured();
711  if (prev_vrouter_.get_port_mirror_enabled() != port_mirror) {
712  vrouter_agent.set_port_mirror_enabled(port_mirror);
713  prev_vrouter_.set_port_mirror_enabled(port_mirror);
714  changed = true;
715  }
716 
717  vector<AgentInterface> phy_if_list;
718  PhysicalInterfaceSet::iterator it = phy_intf_set_.begin();
719  while (it != phy_intf_set_.end()) {
720  AgentInterface pitf;
721  const Interface *intf = *it;
722  const PhysicalInterface *port = static_cast
723  <const PhysicalInterface *>(intf);
724  pitf.set_name(intf->name());
725  pitf.set_mac_address(GetMacAddress(port->mac()));
726  phy_if_list.push_back(pitf);
727  ++it;
728  }
729  if (prev_vrouter_.get_phy_if() != phy_if_list) {
730  vrouter_agent.set_phy_if(phy_if_list);
731  prev_vrouter_.set_phy_if(phy_if_list);
732  changed = true;
733  }
734 
735  std::vector<AgentXmppPeer> xmpp_list;
736  for (int count = 0; count < MAX_XMPP_SERVERS; count++) {
737  AgentXmppPeer peer;
738  if (!agent_->controller_ifmap_xmpp_server(count).empty()) {
739  peer.set_ip(agent_->controller_ifmap_xmpp_server(count));
741  if (ch == NULL) {
742  continue;
743  }
744  XmppChannel *xc = ch->GetXmppChannel();
745  if (xc == NULL) {
746  continue;
747  }
748  if (ch->bgp_peer_id() && xc->GetPeerState() == xmps::READY) {
749  peer.set_status(true);
750  } else {
751  peer.set_status(false);
752  }
753  peer.set_setup_time(agent_->controller_xmpp_channel_setup_time(count));
754  if (agent_->ifmap_active_xmpp_server_index() == count) {
755  peer.set_primary(true);
756  } else {
757  peer.set_primary(false);
758  }
759  xmpp_list.push_back(peer);
760  }
761  }
762 
763  if (!prev_vrouter_.__isset.xmpp_peer_list ||
764  prev_vrouter_.get_xmpp_peer_list() != xmpp_list) {
765  vrouter_agent.set_xmpp_peer_list(xmpp_list);
766  prev_vrouter_.set_xmpp_peer_list(xmpp_list);
767  changed = true;
768  }
769  /* Self IP list should be populated only if router_id is configured */
770  if (agent_->router_id_configured()) {
771  ip_list.push_back(rid.to_string());
772  if (!prev_vrouter_.__isset.self_ip_list ||
773  prev_vrouter_.get_self_ip_list() != ip_list) {
774 
775  vrouter_agent.set_self_ip_list(ip_list);
776  prev_vrouter_.set_self_ip_list(ip_list);
777  changed = true;
778  }
779  }
780 
781  for (int idx = 0; idx < MAX_XMPP_SERVERS; idx++) {
782  if (!agent_->dns_server(idx).empty()) {
783  dns_list.push_back(agent_->dns_server(idx));
784  }
785  }
786 
787  if (!prev_vrouter_.__isset.dns_servers ||
788  prev_vrouter_.get_dns_servers() != dns_list) {
789  vrouter_agent.set_dns_servers(dns_list);
790  prev_vrouter_.set_dns_servers(dns_list);
791  changed = true;
792  }
793 
794  std::vector<VrouterAgentResUsage> limit_exceeded_list;
795  VrouterAgentResUsage usage;
796  bool limit_exceeded = false;
797  bool table_limit = false;
799  for(VrLimitExceeded::iterator res_map_it = res_usage_map.begin();
800  res_map_it != res_usage_map.end(); ++res_map_it ) {
801  if (res_map_it->second != "Normal") {
802  usage.set_name(res_map_it->first);
803  usage.set_status(res_map_it->second);
804  limit_exceeded_list.push_back(usage);
805  if (res_map_it->second == "TableLimit" && !table_limit) {
806  table_limit = true;
807  limit_exceeded = true;
808  } else if (res_map_it->second == "Exceeded" && !limit_exceeded ) {
809  limit_exceeded = true;
810  table_limit = false;
811  }
812  }
813  }
814 
815  if (!prev_vrouter_.__isset.vr_limit_exceeded_list ||
816  prev_vrouter_.get_vr_limit_exceeded_list() != limit_exceeded_list) {
817  vrouter_agent.set_vr_limit_exceeded_list(limit_exceeded_list);
818  prev_vrouter_.set_vr_limit_exceeded_list(limit_exceeded_list);
819  vrouter_agent.set_res_limit(limit_exceeded);
820  vrouter_agent.set_res_table_limit(table_limit);
821  changed = true;
822  }
823 
824  if (agent_->is_l3mh()) {
825  std::vector<L3mhPhysicalInterfaceStatus> vr_l3mh_intf_list;
826  bool l3mh_phy_interface_down = false;
827  PhysicalInterfaceSet::iterator it = phy_intf_set_.begin();
828  while (it != phy_intf_set_.end()) {
829  L3mhPhysicalInterfaceStatus l3mh_interface_status;
830  const Interface *intf = *it;
831  l3mh_interface_status.set_name(intf->name());
832  l3mh_interface_status.set_active(intf->os_oper_state());
833  vr_l3mh_intf_list.push_back(l3mh_interface_status);
834  if (!intf->os_oper_state())
835  l3mh_phy_interface_down = true;
836  ++it;
837  }
838 
839  if (!prev_vrouter_.__isset.vr_l3mh_intf_list ||
840  prev_vrouter_.get_vr_l3mh_intf_list() != vr_l3mh_intf_list) {
841  vrouter_agent.set_vr_l3mh_intf_list(vr_l3mh_intf_list);
842  prev_vrouter_.set_vr_l3mh_intf_list(vr_l3mh_intf_list);
843  vrouter_agent.set_l3mh_phy_interface_down(l3mh_phy_interface_down);
844  changed = true;
845  }
846 
847  }
848  if (changed) {
849  DispatchVrouterMsg(vrouter_agent);
850  }
851 
852  VrouterStatsAgent stats;
853  stats.set_name(agent_->agent_name());
855  /* CPU stats needs to be sent every minute. We are using '% 2' below
856  * because timer is fired every 30 secs. If the timer interval is changed
857  * we need to fix the '%' value below accordingly */
858  if ((cpu_stats_count_ % 2) == 0) {
859  static bool cpu_first = true;
860  CpuLoadInfo cpu_load_info;
861  CpuLoadData::FillCpuInfo(cpu_load_info, true);
862  if (prev_stats_.get_cpu_info() != cpu_load_info || cpu_first) {
863  stats.set_cpu_info(cpu_load_info);
864  prev_stats_.set_cpu_info(cpu_load_info);
865  changed = true;
866  cpu_first = false;
868  }
869 
870  //Stats oracle interface for cpu and mem stats. Needs to be sent
871  //always regardless of whether the stats have changed since last send
872  BuildAndSendComputeCpuStateMsg(cpu_load_info);
873  cpu_stats_count_ = 0;
874  }
875  return changed;
876 }
877 
879  (const vector<string> &list) {
880  VrouterAgent vrouter_agent;
881  vrouter_agent.set_name(agent_->agent_name());
882  if (agent_->tor_agent_enabled()) {
883  vrouter_agent.set_tor_prouter_list(list);
884  } else if (agent_->tsn_enabled()) {
885  vrouter_agent.set_tsn_prouter_list(list);
886  } else {
887  vrouter_agent.set_embedded_prouter_list(list);
888  }
889  DispatchVrouterMsg(vrouter_agent);
890 }
891 
893  return mac.ToString();
894 }
895 
896 void VrouterUveEntryBase::DispatchVrouterStatsMsg(const VrouterStatsAgent &uve) {
897  VrouterStats::Send(uve);
898 }
899 
900 void VrouterUveEntryBase::DispatchComputeCpuStateMsg(const ComputeCpuState &ccs) {
901  ComputeCpuStateTrace::Send(ccs);
902 }
903 
905  ComputeCpuState astate;
906  VrouterCpuInfo ainfo;
907  vector<VrouterCpuInfo> aciv;
908 
909  astate.set_name(agent_->agent_name());
910  ainfo.set_cpu_share(info.get_cpu_share());
911  ainfo.set_mem_virt(info.get_meminfo().get_virt());
912  ainfo.set_mem_res(info.get_meminfo().get_res());
913  const SysMemInfo &sys_mem_info(info.get_sys_mem_info());
914  ainfo.set_used_sys_mem(sys_mem_info.get_used() -
915  sys_mem_info.get_buffers() - sys_mem_info.get_cached());
916  ainfo.set_one_min_cpuload(info.get_cpuload().get_one_min_avg());
917  aciv.push_back(ainfo);
918  astate.set_cpu_info(aciv);
920 }
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
std::map< std::string, std::string > VrLimitExceeded
Definition: agent.h:214
#define kTaskDBExclude
Definition: agent.h:338
#define MAX_XMPP_SERVERS
Definition: agent.h:291
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
const std::string & vmware_physical_port() const
Definition: agent_param.h:330
const std::string & tunnel_type() const
Definition: agent_param.h:239
const int vhost_plen() const
Definition: agent_param.h:188
bool isXenMode() const
Definition: agent_param.h:335
const std::string & host_name() const
Definition: agent_param.h:312
uint32_t linklocal_vm_flows() const
Definition: agent_param.h:254
uint32_t flow_cache_timeout() const
Definition: agent_param.h:255
const std::vector< std::string > collector_server_list() const
Definition: agent_param.h:304
const std::string & log_category() const
Definition: agent_param.h:300
const std::string & config_file() const
Definition: agent_param.h:286
const std::string log_file() const
Definition: agent_param.h:288
uint32_t linklocal_system_flows() const
Definition: agent_param.h:253
const std::string & vhost_name() const
Definition: agent_param.h:182
bool log_flow() const
Definition: agent_param.h:292
const Ip4Address & vhost_addr() const
Definition: agent_param.h:183
bool log_local() const
Definition: agent_param.h:291
VirtualGatewayConfigTable * vgw_config_table() const
Definition: agent_param.h:327
const AddressList & gateway_list() const
Definition: agent_param.h:190
const std::string & xen_ll_name() const
Definition: agent_param.h:194
const Ip4Address & xen_ll_addr() const
Definition: agent_param.h:198
uint16_t http_server_port() const
Definition: agent_param.h:310
const Ip4Address & loopback_ip() const
Definition: agent_param.h:575
const std::vector< std::string > controller_server_list() const
Definition: agent_param.h:216
const std::string & log_level() const
Definition: agent_param.h:299
const std::vector< std::string > & eth_port_list() const
Definition: agent_param.h:204
bool isKvmMode() const
Definition: agent_param.h:336
const int xen_ll_plen() const
Definition: agent_param.h:200
bool isVmwareMode() const
Definition: agent_param.h:338
const Ip4Address & mgmt_ip() const
Definition: agent_param.h:238
const std::vector< std::string > dns_server_list() const
Definition: agent_param.h:220
static const uint32_t kDefaultInterval
XmppChannel * GetXmppChannel()
BgpPeer * bgp_peer_id()
Definition: agent.h:360
InterfaceTable * interface_table() const
Definition: agent.h:467
const std::string & subcluster_name() const
Definition: agent.h:755
bool vrouter_on_nic_mode() const
Definition: agent.cc:1056
VmTable * vm_table() const
Definition: agent.h:492
AgentXmppChannel * controller_xmpp_channel(uint8_t idx) const
Definition: agent.h:811
OperDB * oper_db() const
Definition: agent.cc:1016
VrLimitExceeded & get_vr_limits_exceeded_map()
Definition: agent.h:1387
const std::string & dns_server(uint8_t idx) const
Definition: agent.h:859
const uint64_t controller_xmpp_channel_setup_time(uint8_t idx) const
Definition: agent.h:803
bool vrouter_on_host() const
Definition: agent.cc:1064
AgentParam * params() const
Definition: agent.h:1226
const std::string & agent_name() const
Definition: agent.h:880
bool tsn_enabled() const
Definition: agent.h:1164
bool router_id_configured()
Definition: agent.h:678
bool is_l3mh() const
Definition: agent.h:727
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:732
float vr_limit_high_watermark()
Definition: agent.h:1399
bool vrouter_on_host_dpdk() const
Definition: agent.cc:1060
static const std::string & NullString()
Definition: agent.h:439
VnTable * vn_table() const
Definition: agent.h:497
PhysicalDeviceTable * physical_device_table() const
Definition: agent.h:630
bool tor_agent_enabled() const
Definition: agent.h:1166
const Interface * vhost_interface() const
Definition: agent.h:937
Ip4Address router_id() const
Definition: agent.h:668
const int8_t & ifmap_active_xmpp_server_index() const
Definition: agent.h:782
float vr_limit_low_watermark()
Definition: agent.h:1407
VrouterObjectLimits GetVrouterObjectLimits()
Definition: agent.cc:1169
static void FillCpuInfo(CpuLoadInfo &info, bool system)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
static const int kInvalidId
Definition: db_table.h:64
void Unregister(ListenerId listener)
Definition: db_table.cc:186
DBTableBase * parent()
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:613
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:619
@ VM_INTERFACE
Definition: interface.h:35
@ PHYSICAL
Definition: interface.h:29
@ REMOTE_PHYSICAL
Definition: interface.h:31
const MacAddress & mac() const
Definition: interface.h:131
bool os_oper_state() const
Definition: interface.h:132
const std::string & name() const
Definition: interface.h:114
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
Type type() const
Definition: interface.h:112
bool IsUveActive() const
Definition: interface.cc:1486
Interface * physical_interface() const
std::string ToString() const
Definition: mac_address.cc:53
bool IsConfigured()
static MirrorTable * GetInstance()
Definition: mirror_table.h:156
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
bool master() const
const BondChildIntfMap & getBondChildIntfMap() const
SubType subtype() const
std::map< const std::string, Bond_ChildIntf > BondChildIntfMap
BondChildIntfMap::const_iterator BondChildIntfMapIterator
PhysicalDevice * physical_device() const
PhysicalDevice * physical_device() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
bool Cancel()
Definition: timer.cc:150
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
const Table & table() const
Definition: cfg_vgw.h:129
std::vector< Subnet > SubnetList
Definition: cfg_vgw.h:30
Definition: vm.h:32
const boost::uuids::uuid & GetUuid() const
Definition: vm.h:46
const boost::uuids::uuid & logical_interface() const
const std::string & cfg_name() const
Definition: vm.h:78
Definition: vn.h:151
const string & GetName() const
Definition: vn.h:162
Definition: vn.h:335
std::string GetMacAddress(const MacAddress &mac) const
void VmWalkDone(DBTableBase *base, StringVectorPtr list)
virtual void DispatchComputeCpuStateMsg(const ComputeCpuState &ccs)
void InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e)
PhysicalDevice * VmiToPhysicalDevice(const VmInterface *port)
bool AppendVn(DBTablePartBase *part, DBEntryBase *e, StringVectorPtr l)
DBTableBase::ListenerId vm_listener_id_
void VnNotify(DBTablePartBase *partition, DBEntryBase *e)
DBTable::DBTableWalkRef vn_walk_ref_
PhysicalDevice * InterfaceToPhysicalDevice(Interface *intf)
DBTable::DBTableWalkRef interface_walk_ref_
virtual void DispatchVrouterMsg(const VrouterAgent &uve)
void BuildAgentConfig(VrouterAgent &vrouter_agent)
DBTableBase::ListenerId vn_listener_id_
void SendVrouterProuterAssociation(const std::vector< std::string > &list)
DBTableBase::ListenerId intf_listener_id_
virtual void DispatchVrouterStatsMsg(const VrouterStatsAgent &uve)
PhysicalInterfaceSet phy_intf_set_
void VmNotify(DBTablePartBase *partition, DBEntryBase *e)
void SubnetToStringList(VirtualGatewayConfig::SubnetList &l1, std::vector< std::string > &l2)
DBTable::DBTableWalkRef vm_walk_ref_
VrouterStatsAgent prev_stats_
void InterfaceWalkDone(DBTableBase *base, StringVectorPtr if_l, StringVectorPtr err_if_l, StringVectorPtr nova_if_l, StringVectorPtr unmanaged_list)
DBTableBase::ListenerId physical_device_listener_id_
bool AppendVm(DBTablePartBase *part, DBEntryBase *e, StringVectorPtr l)
void BuildAndSendComputeCpuStateMsg(const CpuLoadInfo &info)
bool AppendInterface(DBTablePartBase *part, DBEntryBase *entry, StringVectorPtr intf_list, StringVectorPtr err_list, StringVectorPtr nova_if_list, StringVectorPtr unmanaged_list)
void AppendInterfaceInternal(const VmInterface *port, StringVectorPtr intf_list, StringVectorPtr err_if_list)
void VnWalkDone(DBTableBase *base, StringVectorPtr list)
boost::shared_ptr< std::vector< std::string > > StringVectorPtr
void PhysicalDeviceNotify(DBTablePartBase *partition, DBEntryBase *e)
virtual xmps::PeerState GetPeerState() const =0
@ READY
Definition: xmpp_channel.h:17
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
boost::uuids::uuid uuid
const std::string BuildInfo