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