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