OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
28  : agent_(agent), phy_intf_set_(), prev_stats_(), prev_vrouter_(),
29  cpu_stats_count_(0), do_vn_walk_(false), do_vm_walk_(false),
30  do_interface_walk_(false), vn_walk_ref_(NULL), vm_walk_ref_(NULL),
31  interface_walk_ref_(NULL), vn_listener_id_(DBTableBase::kInvalidId),
32  vm_listener_id_(DBTableBase::kInvalidId),
33  intf_listener_id_(DBTableBase::kInvalidId),
34  physical_device_listener_id_(DBTableBase::kInvalidId),
35  timer_(TimerManager::CreateTimer(
36  *(agent_->event_manager())->io_service(), "UveDBWalkTimer",
37  TaskScheduler::GetInstance()->GetTaskId(kTaskDBExclude), 0)) {
38  StartTimer();
39 
40 }
41 
43 }
44 
46  timer_->Cancel();
48  boost::bind(&VrouterUveEntryBase::TimerExpiry, this));
49 }
50 
52  bool restart = Run();
53  return restart;
54 }
55 
57  /* We don't do vn, vm and interface walks simultaneously to avoid creation
58  * of multiple threads (caused by start of walks). After all the walks are
59  * done we re-start the timer */
60  bool walk_started = StartVnWalk();
61 
62  /* If VN walk is not started, start VM walk */
63  if (!walk_started) {
64  walk_started = StartVmWalk();
65 
66  /* If neither VN nor VM walks have started, start interface walk */
67  if (!walk_started) {
68  walk_started = StartInterfaceWalk();
69 
70  /* If none of the walks are started, return true to trigger
71  * auto restart of timer */
72  if (!walk_started) {
73  return true;
74  }
75  }
76  }
77 
78  return false;
79 }
80 
82  DBEntryBase *e) {
83  const PhysicalDevice *pr = static_cast<const PhysicalDevice *>(e);
85  (e->GetState(partition->parent(), physical_device_listener_id_));
86  if (e->IsDeleted()) {
87  if (state) {
89  delete state;
90  }
91  } else {
92  if (!state) {
93  state = new VrouterPhysicalDeviceState();
95  state);
96  do_interface_walk_ = true;
97  } else {
98  if (state->master_ != pr->master()) {
99  do_interface_walk_ = true;
100  }
101  }
102  state->master_ = pr->master();
103  }
104 }
105 
107  VnTable *vn_table = agent_->vn_table();
108  vn_listener_id_ = vn_table->Register
109  (boost::bind(&VrouterUveEntryBase::VnNotify, this, _1, _2));
110 
111  VmTable *vm_table = agent_->vm_table();
112  vm_listener_id_ = vm_table->Register
113  (boost::bind(&VrouterUveEntryBase::VmNotify, this, _1, _2));
114 
115  InterfaceTable *intf_table = agent_->interface_table();
116  intf_listener_id_ = intf_table->Register
117  (boost::bind(&VrouterUveEntryBase::InterfaceNotify, this, _1, _2));
118 
121  (boost::bind(&VrouterUveEntryBase::PhysicalDeviceNotify, this, _1, _2));
122 }
123 
127  Unregister(physical_device_listener_id_);
134  if (interface_walk_ref_.get() != NULL)
136  if (vn_walk_ref_.get() != NULL)
138  if (vm_walk_ref_.get() != NULL)
140  if (timer_) {
141  timer_->Cancel();
143  timer_ = NULL;
144  }
145  vn_walk_ref_ = NULL;
146  vm_walk_ref_ = NULL;
147  interface_walk_ref_ = NULL;
148 }
149 
150 void VrouterUveEntryBase::DispatchVrouterMsg(const VrouterAgent &uve) {
151  UveVrouterAgent::Send(uve);
152 }
153 
155  VrouterAgent vrouter_agent;
156  vrouter_agent.set_name(agent_->agent_name());
157  vrouter_agent.set_virtual_machine_list(*(list.get()));
158  VrouterAgentObjectCount vm_count;
159  vm_count.set_active(list.get()->size());
160  vrouter_agent.set_vm_count(vm_count);
161  DispatchVrouterMsg(vrouter_agent);
162 
163  /* Start Interface Walk after we are done with Vm Walk */
164  bool walk_started = StartInterfaceWalk();
165 
166  /* If interface walk has not started, restart the timer */
167  if (!walk_started) {
168  StartTimer();
169  }
170  (*list).clear();
171 }
172 
174  StringVectorPtr list) {
175  VmEntry *vm = static_cast<VmEntry *>(entry);
176 
177  if (!vm->IsDeleted()) {
178  std::ostringstream ostr;
179  ostr << vm->GetUuid();
180  list.get()->push_back(ostr.str());
181  }
182  return true;
183 }
184 
186  if (!do_vm_walk_) {
187  /* There is no change in VM list. No need of walk */
188  return false;
189  }
190  if (vm_walk_ref_.get() == NULL) {
191  StringVectorPtr vm_list(new vector<string>());
193  boost::bind(&VrouterUveEntryBase::AppendVm, this, _1, _2, vm_list),
194  boost::bind(&VrouterUveEntryBase::VmWalkDone, this, _2, vm_list));
195  }
197  do_vm_walk_ = false;
198  return true;
199 }
200 
202  DBState *state = static_cast<DBState *>
203  (e->GetState(partition->parent(), vm_listener_id_));
204 
205  if (e->IsDeleted()) {
206  if (state) {
207  do_vm_walk_ = true;
208  e->ClearState(partition->parent(), vm_listener_id_);
209  delete state;
210  }
211  return;
212  }
213 
214  if (!state) {
215  state = new DBState();
216  e->SetState(partition->parent(), vm_listener_id_, state);
217  //Send vrouter object only for a add/delete
218  do_vm_walk_ = true;
219  }
220 }
221 
223  VrouterAgent vrouter_agent;
224  vrouter_agent.set_name(agent_->agent_name());
225  vrouter_agent.set_connected_networks(*(list.get()));
226  vrouter_agent.set_vn_count((*list).size());
227  DispatchVrouterMsg(vrouter_agent);
228 
229  //Update prev_vrouter_ fields. Currently used only in UT
230  prev_vrouter_.set_connected_networks(*(list.get()));
231  prev_vrouter_.set_vn_count((*list).size());
232 
233  /* Start Vm Walk after we are done with Vn Walk */
234  bool walk_started = StartVmWalk();
235 
236  /* If VM walk has not started, start interface walk */
237  if (!walk_started) {
238  walk_started = StartInterfaceWalk();
239 
240  /* If interface walk has not started, restart the timer */
241  if (!walk_started) {
242  StartTimer();
243  }
244  }
245  (*list).clear();
246 }
247 
249  StringVectorPtr list) {
250  VnEntry *vn = static_cast<VnEntry *>(entry);
251 
252  if (!vn->IsDeleted()) {
253  list.get()->push_back(vn->GetName());
254  }
255  return true;
256 }
257 
259  if (!do_vn_walk_) {
260  /* There is no change in VN list. No need of walk */
261  return false;
262  }
263  if (vn_walk_ref_.get() == NULL) {
264  StringVectorPtr vn_list(new vector<string>());
266  boost::bind(&VrouterUveEntryBase::AppendVn, this, _1, _2, vn_list),
267  boost::bind(&VrouterUveEntryBase::VnWalkDone, this, _2, vn_list));
268 
269  }
271  do_vn_walk_ = false;
272  return true;
273 }
274 
276  DBState *state = static_cast<DBState *>
277  (e->GetState(partition->parent(), vn_listener_id_));
278 
279  if (e->IsDeleted()) {
280  if (state) {
281  do_vn_walk_ = true;
282  e->ClearState(partition->parent(), vn_listener_id_);
283  delete state;
284  }
285  return;
286  }
287 
288  if (!state) {
289  state = new DBState();
290  e->SetState(partition->parent(), vn_listener_id_, state);
291  do_vn_walk_ = true;
292  }
293 }
294 
296  StringVectorPtr if_list,
297  StringVectorPtr err_if_list,
298  StringVectorPtr nova_if_list,
299  StringVectorPtr unmanaged_list) {
300  VrouterAgent vrouter_agent;
301  vrouter_agent.set_name(agent_->agent_name());
302  vrouter_agent.set_interface_list(*(if_list.get()));
303  vrouter_agent.set_error_intf_list(*(err_if_list.get()));
304  vrouter_agent.set_no_config_intf_list(*(nova_if_list.get()));
305  if (agent_->tsn_enabled()) {
306  vrouter_agent.set_unmanaged_if_list(*(unmanaged_list.get()));
307  prev_vrouter_.set_unmanaged_if_list(*(unmanaged_list.get()));
308  }
309 
310  VrouterAgentObjectCount vmi_count;
311  vmi_count.set_active((if_list.get()->size() + nova_if_list.get()->size()));
312  vrouter_agent.set_vmi_count(vmi_count);
313  vrouter_agent.set_down_interface_count((err_if_list.get()->size() +
314  nova_if_list.get()->size()));
315  DispatchVrouterMsg(vrouter_agent);
316 
317  //Update prev_vrouter_ fields. This is being used now only for UT
318  prev_vrouter_.set_interface_list(*(if_list.get()));
319  prev_vrouter_.set_error_intf_list(*(err_if_list.get()));
320  prev_vrouter_.set_no_config_intf_list(*(nova_if_list.get()));
321 
322  (*if_list).clear();
323  (*err_if_list).clear();
324  (*nova_if_list).clear();
325  (*unmanaged_list).clear();
326  /* Restart the timer after we are done with the walk */
327  StartTimer();
328 }
329 
331  DBEntryBase *entry,
332  StringVectorPtr intf_list,
333  StringVectorPtr err_if_list,
334  StringVectorPtr nova_if_list,
335  StringVectorPtr unmanaged_list) {
336  Interface *intf = static_cast<Interface *>(entry);
337 
338  if (intf->type() == Interface::VM_INTERFACE) {
339  const VmInterface *port = static_cast<const VmInterface *>(intf);
340  if (!entry->IsDeleted()) {
341  if (port->cfg_name() == agent_->NullString()) {
342  nova_if_list.get()->push_back(UuidToString(port->GetUuid()));
343  } else {
344  if (agent_->tsn_enabled()) {
345  /* For TSN nodes send VMI in interface_list if the VMI's
346  * physical device has tsn_enabled set to true. Otherwise
347  * send the VMI in unmanaged_list */
349  if (!pd || !pd->master()) {
350  unmanaged_list.get()->push_back(port->cfg_name());
351  return true;
352  }
353  AppendInterfaceInternal(port, intf_list, err_if_list);
354  } else {
355  AppendInterfaceInternal(port, intf_list, err_if_list);
356  }
357  }
358  }
359  }
360  else if (intf->type() == Interface::PHYSICAL) {
361  const PhysicalInterface *phy_intf = static_cast<const
362  PhysicalInterface *>(intf);
363  if (phy_intf) {
364  PhysicalInterface::BondChildIntfMap bond_childIntf_map =
365  phy_intf->getBondChildIntfMap();
367  bond_childIntf_map.begin();
368  for(; it != bond_childIntf_map.end(); it++) {
370  bond_intf = it->second;
371  if(!bond_intf.intf_status) {
372  err_if_list.get()->push_back(it->first);
373  }
374  }
375  }
376  }
377  return true;
378 }
379 
381  StringVectorPtr intf_list,
382  StringVectorPtr err_if_list) {
383  intf_list.get()->push_back(port->cfg_name());
384  if (!port->IsUveActive()) {
385  err_if_list.get()->push_back(port->cfg_name());
386  }
387 }
388 
390  (const VmInterface *port) {
391  const boost::uuids::uuid u = port->logical_interface();
392  if (u == boost::uuids::nil_uuid()) {
393  return NULL;
394  }
395  LogicalInterface *intf;
396  VlanLogicalInterfaceKey key(u, "");
397  intf = static_cast<LogicalInterface *>
398  (agent_->interface_table()->FindActiveEntry(&key));
399  if (!intf || !intf->physical_interface()) {
400  return NULL;
401  }
402  return InterfaceToPhysicalDevice(intf->physical_interface());
403 }
404 
406  PhysicalDevice *pde = NULL;
407  const RemotePhysicalInterface *rpintf;
408  const PhysicalInterface *pintf;
409  if (intf->type() == Interface::REMOTE_PHYSICAL) {
410  rpintf = static_cast<const RemotePhysicalInterface *>(intf);
411  pde = rpintf->physical_device();
412  } else if (intf->type() == Interface::PHYSICAL) {
413  pintf = static_cast<const PhysicalInterface *>(intf);
414  pde = pintf->physical_device();
415  }
416  return pde;
417 }
418 
420  if (!do_interface_walk_) {
421  /* There is no change in interface list. No need of walk */
422  return false;
423  }
424  if (interface_walk_ref_.get() == NULL) {
425  StringVectorPtr intf_list(new std::vector<std::string>());
426  StringVectorPtr err_if_list(new std::vector<std::string>());
427  StringVectorPtr nova_if_list(new std::vector<std::string>());
428  StringVectorPtr unmanaged_list(new std::vector<std::string>());
429 
431  boost::bind(&VrouterUveEntryBase::AppendInterface, this, _1, _2,
432  intf_list, err_if_list, nova_if_list, unmanaged_list),
433  boost::bind(&VrouterUveEntryBase::InterfaceWalkDone, this, _2,
434  intf_list, err_if_list, nova_if_list, unmanaged_list));
435 }
437  do_interface_walk_ = false;
438  return true;
439 }
440 
442  DBEntryBase *e) {
443  const Interface *intf = static_cast<const Interface *>(e);
444  bool set_state = false, reset_state = false;
445 
446  VrouterUveInterfaceState *state = static_cast<VrouterUveInterfaceState *>
447  (e->GetState(partition->parent(), intf_listener_id_));
448  bool vmport_active = false;
449  const VmInterface *vm_port = NULL;
450  switch(intf->type()) {
452  vm_port = static_cast<const VmInterface*>(intf);
453  if (!e->IsDeleted() && !state) {
454  set_state = true;
455  vmport_active = vm_port->IsUveActive();
456  do_interface_walk_ = true;
457  } else if (e->IsDeleted()) {
458  if (state) {
459  reset_state = true;
460  do_interface_walk_ = true;
461  }
462  } else {
463  if (state && vm_port->IsUveActive() != state->vmport_active_) {
464  do_interface_walk_ = true;
465  state->vmport_active_ = vm_port->IsUveActive();
466  }
467  }
468  break;
469  case Interface::PHYSICAL:
470  if (e->IsDeleted()) {
471  if (state) {
472  reset_state = true;
473  phy_intf_set_.erase(intf);
474  }
475  } else {
476  const PhysicalInterface* phy_if =
477  static_cast<const PhysicalInterface*>(intf);
478  /* Ignore PhysicalInterface notifications if it is not of subtype
479  * FABRIC */
480  if (phy_if->subtype() != PhysicalInterface::FABRIC) {
481  return;
482  }
483  if (!state) {
484  set_state = true;
485  phy_intf_set_.insert(intf);
486  }
487  if (phy_if) {
488  PhysicalInterface::BondChildIntfMap bond_childIntf_map =
489  phy_if->getBondChildIntfMap();
491  bond_childIntf_map.begin();
492  for(; it != bond_childIntf_map.end(); it++) {
494  bond_intf = it->second;
495  if(!bond_intf.intf_status) {
496  do_interface_walk_ = true;
497  }
498  else {
499  std::vector<std::string> prev_err_if_list =
500  prev_vrouter_.get_error_intf_list();
501  if (std::find(prev_err_if_list.begin(),
502  prev_err_if_list.end(), it->first)
503  != prev_err_if_list.end()) {
504  do_interface_walk_ = true;
505  }
506  }
507  }
508  }
509  }
510  break;
511  default:
512  break;
513  }
514  if (set_state) {
515  state = new VrouterUveInterfaceState(vmport_active);
516  e->SetState(partition->parent(), intf_listener_id_, state);
517  } else if (reset_state) {
518  e->ClearState(partition->parent(), intf_listener_id_);
519  delete state;
520  }
521  return;
522 }
523 
525  (VirtualGatewayConfig::SubnetList &source_list, vector<string> &target_list) {
526  VirtualGatewayConfig::SubnetList::iterator subnet_it =
527  source_list.begin();
528  while (subnet_it != source_list.end()) {
529  string subnet_str = subnet_it->ip_.to_string() + "/" +
530  integerToString(subnet_it->plen_);
531  target_list.push_back(subnet_str);
532  ++subnet_it;
533  }
534 }
535 
536 void VrouterUveEntryBase::BuildAgentConfig(VrouterAgent &vrouter_agent) {
537  AgentVhostConfig vhost_cfg;
538  AgentXenConfig xen_cfg;
539  AgentVmwareConfig vmware_cfg;
540  string hypervisor;
541  vector<AgentVgwConfig> gw_cfg_list;
542 
543  AgentParam *param = agent_->params();
544 
545  vrouter_agent.set_log_file(param->log_file());
546  vrouter_agent.set_config_file(param->config_file());
547  vrouter_agent.set_log_local(param->log_local());
548  vrouter_agent.set_log_flow(param->log_flow());
549  vrouter_agent.set_log_category(param->log_category());
550  vrouter_agent.set_log_level(param->log_level());
551  vrouter_agent.set_sandesh_http_port(param->http_server_port());
552  vrouter_agent.set_tunnel_type(param->tunnel_type());
553  vrouter_agent.set_hostname_cfg(param->host_name());
554  vrouter_agent.set_flow_cache_timeout_cfg(param->flow_cache_timeout());
555 
556  vrouter_agent.set_dns_server_list_cfg(param->dns_server_list());
557  vrouter_agent.set_control_node_list_cfg(param->controller_server_list());
558 
559  vrouter_agent.set_ll_max_system_flows_cfg(param->linklocal_system_flows());
560  vrouter_agent.set_ll_max_vm_flows_cfg(param->linklocal_vm_flows());
561  vrouter_agent.set_max_vm_flows_cfg((uint32_t)param->max_vm_flows());
562  vrouter_agent.set_control_ip(param->mgmt_ip().to_string());
563 
564  vhost_cfg.set_name(param->vhost_name());
565  if (agent_->is_l3mh() == false) {
566  vhost_cfg.set_ip(param->vhost_addr().to_string());
567  vhost_cfg.set_ip_prefix_len(param->vhost_plen());
568  if (param->gateway_list().empty() == false) {
569  vhost_cfg.set_gateway(param->gateway_list()[0].to_string());
570  }
571  }
572  vrouter_agent.set_vhost_cfg(vhost_cfg);
573 
574  vrouter_agent.set_eth_name(param->eth_port_list());
575 
576  if (param->isKvmMode()) {
577  hypervisor = "kvm";
578  } else if (param->isXenMode()) {
579  hypervisor = "xen";
580  xen_cfg.set_xen_ll_port(param->xen_ll_name());
581  xen_cfg.set_xen_ll_ip(param->xen_ll_addr().to_string());
582  xen_cfg.set_xen_ll_prefix_len(param->xen_ll_plen());
583  vrouter_agent.set_xen_cfg(xen_cfg);
584  } else if (param->isVmwareMode()) {
585  hypervisor = "vmware";
586  vmware_cfg.set_vmware_port(param->vmware_physical_port());
587  vrouter_agent.set_vmware_cfg(vmware_cfg);
588  }
589  vrouter_agent.set_hypervisor(hypervisor);
590 
592  VirtualGatewayConfigTable::Table::iterator it = table->table().begin();
593  while (it != table->table().end()) {
594  AgentVgwConfig gw_cfg;
595  VirtualGatewayConfig::SubnetList subnet_list = it->subnets();
596  VirtualGatewayConfig::SubnetList route_list = it->routes();
597  vector<string> ip_blocks_list;
598  vector<string> route_str_list;
599 
600  SubnetToStringList(subnet_list, ip_blocks_list);
601  SubnetToStringList(route_list, route_str_list);
602 
603  gw_cfg.set_interface_name(it->interface_name());
604  gw_cfg.set_vrf_name(it->vrf_name());
605  gw_cfg.set_ip_blocks_list(ip_blocks_list);
606  gw_cfg.set_route_list(route_str_list);
607 
608  gw_cfg_list.push_back(gw_cfg);
609  ++it;
610  }
611  vrouter_agent.set_gateway_cfg_list(gw_cfg_list);
612  vrouter_agent.set_headless_mode_cfg(true);
613  vrouter_agent.set_collector_server_list_cfg(param->collector_server_list());
614  vrouter_agent.set_bgpaas_enabled(
616  vrouter_agent.set_port_mirror_enabled(MirrorTable::GetInstance()->IsConfigured());
617  vrouter_agent.set_loopback_ip(param->loopback_ip().to_string());
618  std::vector<string> gateway_list;
619  for (std::vector<Ip4Address>::const_iterator iter = param->gateway_list().begin();
620  iter != param->gateway_list().end(); ++iter) {
621  gateway_list.push_back((*iter).to_string());
622  }
623  vrouter_agent.set_gateway_list(gateway_list);
624 }
625 
626 
628  VrouterAgent vrouter_agent;
629  bool changed = false, bgp_aas, port_mirror;
630  static bool first = true, build_info = false;
631  vrouter_agent.set_name(agent_->agent_name());
632  Ip4Address rid = agent_->router_id();
633  vector<string> ip_list;
634  vector<string> dns_list;
635 
636  if (first) {
637  //Physical interface list
638  vnsConstants vnsVrouterType;
639  //vhost attributes
640  const Interface *vhost = agent_->vhost_interface();
641  if (vhost) {
642  AgentInterface vitf;
643  vitf.set_name(vhost->name());
644  vitf.set_mac_address(GetMacAddress(vhost->mac()));
645  vrouter_agent.set_vhost_if(vitf);
646  }
647 
648  //Configuration. Needs to be sent only once because whenever config
649  //changes agent will be restarted
650  BuildAgentConfig(vrouter_agent);
651 
652  //Set the Agent mode
653  if (agent_->tor_agent_enabled()) {
654  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
655  (VrouterAgentType::VROUTER_AGENT_TOR));
656  } else if (agent_->tsn_enabled()) {
657  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
658  (VrouterAgentType::VROUTER_AGENT_TSN));
659  } else {
660  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
661  (VrouterAgentType::VROUTER_AGENT_EMBEDDED));
662  }
663 
664  if (agent_->vrouter_on_nic_mode()) {
665  vrouter_agent.set_platform(vnsVrouterType.
666  VrouterAgentPlatformTypeMap.at
667  (VrouterAgentPlatformType::
668  VROUTER_AGENT_ON_NIC));
669  } else if (agent_->vrouter_on_host_dpdk()) {
670  vrouter_agent.set_platform(vnsVrouterType.
671  VrouterAgentPlatformTypeMap.at
672  (VrouterAgentPlatformType::
673  VROUTER_AGENT_ON_HOST_DPDK));
674  } else if (agent_->vrouter_on_host()) {
675  vrouter_agent.set_platform(vnsVrouterType.
676  VrouterAgentPlatformTypeMap.at
677  (VrouterAgentPlatformType::
678  VROUTER_AGENT_ON_HOST));
679  }
680 
681  vrouter_agent.set_subcluster_name(agent_->subcluster_name());
682  vrouter_agent.set_vr_high_watermark(agent_->vr_limit_high_watermark());
683  vrouter_agent.set_vr_low_watermark(agent_->vr_limit_low_watermark());
684  first = false;
685  changed = true;
686  }
687 
688  VrouterObjectLimits vr_limits = agent_->GetVrouterObjectLimits();
689  VrouterObjectLimits prev_vr_limits = prev_vrouter_.get_vr_limits();
690  if (vr_limits != prev_vr_limits) {
691  vrouter_agent.set_vr_limits(vr_limits);
692  prev_vrouter_.set_vr_limits(vr_limits);
693  changed = true;
694  }
695 
696  if (!build_info) {
697  string build_info_str;
698  build_info = GetBuildInfo(build_info_str);
699  if (prev_vrouter_.get_build_info() != build_info_str) {
700  vrouter_agent.set_build_info(build_info_str);
701  prev_vrouter_.set_build_info(build_info_str);
702  changed = true;
703  }
704 
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 
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 }
std::string GetMacAddress(const MacAddress &mac) const
XmppChannel * GetXmppChannel()
const std::string & subcluster_name() const
Definition: agent.h:753
Type type() const
Definition: interface.h:112
bool tsn_enabled() const
Definition: agent.h:1162
void InterfaceWalkDone(DBTableBase *base, StringVectorPtr if_l, StringVectorPtr err_if_l, StringVectorPtr nova_if_l, StringVectorPtr unmanaged_list)
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
const std::string & vhost_name() const
Definition: agent_param.h:183
#define kTaskDBExclude
Definition: agent.h:336
virtual void DispatchComputeCpuStateMsg(const ComputeCpuState &ccs)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
bool tor_agent_enabled() const
Definition: agent.h:1164
DBTable::DBTableWalkRef vm_walk_ref_
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
uint32_t flow_cache_timeout() const
Definition: agent_param.h:257
const std::string & vmware_physical_port() const
Definition: agent_param.h:332
SubType subtype() const
bool IsConfigured()
const Interface * vhost_interface() const
Definition: agent.h:935
bool vrouter_on_host_dpdk() const
Definition: agent.cc:1057
const std::vector< std::string > collector_server_list() const
Definition: agent_param.h:306
PhysicalDeviceTable * physical_device_table() const
Definition: agent.h:628
bool is_l3mh() const
Definition: agent.h:725
bool IsDeleted() const
Definition: db_entry.h:49
VrouterStatsAgent prev_stats_
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
const AddressList & gateway_list() const
Definition: agent_param.h:191
const std::string & dns_server(uint8_t idx) const
Definition: agent.h:857
void PhysicalDeviceNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: vm.h:32
const Ip4Address & loopback_ip() const
Definition: agent_param.h:577
Definition: vm.h:78
const std::vector< std::string > controller_server_list() const
Definition: agent_param.h:217
std::map< std::string, std::string > VrLimitExceeded
Definition: agent.h:214
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:613
DBTableBase * parent()
virtual void DispatchVrouterStatsMsg(const VrouterStatsAgent &uve)
InterfaceTable * interface_table() const
Definition: agent.h:465
boost::uuids::uuid uuid
VnTable * vn_table() const
Definition: agent.h:495
Interface * physical_interface() const
boost::shared_ptr< std::vector< std::string > > StringVectorPtr
void AppendInterfaceInternal(const VmInterface *port, StringVectorPtr intf_list, StringVectorPtr err_if_list)
const MacAddress & mac() const
Definition: interface.h:131
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
float vr_limit_high_watermark()
Definition: agent.h:1391
bool AppendInterface(DBTablePartBase *part, DBEntryBase *entry, StringVectorPtr intf_list, StringVectorPtr err_list, StringVectorPtr nova_if_list, StringVectorPtr unmanaged_list)
const Ip4Address & vhost_addr() const
Definition: agent_param.h:184
const int vhost_plen() const
Definition: agent_param.h:189
static void FillCpuInfo(CpuLoadInfo &info, bool system)
AgentXmppChannel * controller_xmpp_channel(uint8_t idx) const
Definition: agent.h:809
const boost::uuids::uuid & GetUuid() const
Definition: vm.h:46
PhysicalDevice * VmiToPhysicalDevice(const VmInterface *port)
const std::string & xen_ll_name() const
Definition: agent_param.h:195
void VnNotify(DBTablePartBase *partition, DBEntryBase *e)
bool vrouter_on_nic_mode() const
Definition: agent.cc:1053
virtual xmps::PeerState GetPeerState() const =0
void Unregister(ListenerId listener)
Definition: db_table.cc:186
float vr_limit_low_watermark()
Definition: agent.h:1399
bool isXenMode() const
Definition: agent_param.h:337
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:619
OperDB * oper_db() const
Definition: agent.cc:1013
std::string ToString() const
Definition: mac_address.cc:53
void BuildAndSendComputeCpuStateMsg(const CpuLoadInfo &info)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
bool log_flow() const
Definition: agent_param.h:294
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
const std::string & tunnel_type() const
Definition: agent_param.h:240
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
void InterfaceNotify(DBTablePartBase *partition, DBEntryBase *e)
bool isKvmMode() const
Definition: agent_param.h:338
void VnWalkDone(DBTableBase *base, StringVectorPtr list)
const std::vector< std::string > dns_server_list() const
Definition: agent_param.h:221
DBTableBase::ListenerId vn_listener_id_
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
Definition: agent.h:358
const BondChildIntfMap & getBondChildIntfMap() const
PhysicalDevice * InterfaceToPhysicalDevice(Interface *intf)
bool master() const
Ip4Address router_id() const
Definition: agent.h:666
PhysicalDevice * physical_device() const
static const uint32_t kDefaultInterval
void SubnetToStringList(VirtualGatewayConfig::SubnetList &l1, std::vector< std::string > &l2)
uint16_t http_server_port() const
Definition: agent_param.h:312
uint32_t linklocal_system_flows() const
Definition: agent_param.h:255
bool isVmwareMode() const
Definition: agent_param.h:340
static const std::string & NullString()
Definition: agent.h:437
bool os_oper_state() const
Definition: interface.h:132
bool vrouter_on_host() const
Definition: agent.cc:1061
const Table & table() const
Definition: cfg_vgw.h:129
AgentParam * params() const
Definition: agent.h:1218
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:730
const Ip4Address & xen_ll_addr() const
Definition: agent_param.h:199
const std::string & agent_name() const
Definition: agent.h:878
void VmWalkDone(DBTableBase *base, StringVectorPtr list)
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
DBTableBase::ListenerId physical_device_listener_id_
BondChildIntfMap::const_iterator BondChildIntfMapIterator
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
static MirrorTable * GetInstance()
Definition: mirror_table.h:156
const std::string & host_name() const
Definition: agent_param.h:314
bool AppendVm(DBTablePartBase *part, DBEntryBase *e, StringVectorPtr l)
bool Cancel()
Definition: timer.cc:150
Definition: vn.h:151
#define MAX_XMPP_SERVERS
Definition: agent.h:291
float max_vm_flows() const
Definition: agent_param.h:254
Definition: vn.h:331
const boost::uuids::uuid & logical_interface() const
bool router_id_configured()
Definition: agent.h:676
bool AppendVn(DBTablePartBase *part, DBEntryBase *e, StringVectorPtr l)
const int xen_ll_plen() const
Definition: agent_param.h:201
const std::string log_file() const
Definition: agent_param.h:290
bool IsUveActive() const
Definition: interface.cc:1486
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
VrLimitExceeded & get_vr_limits_exceeded_map()
Definition: agent.h:1379
void SendVrouterProuterAssociation(const std::vector< std::string > &list)
const std::string & cfg_name() const
static const int kInvalidId
Definition: db_table.h:64
DBTableBase::ListenerId vm_listener_id_
void VmNotify(DBTablePartBase *partition, DBEntryBase *e)
const std::string & config_file() const
Definition: agent_param.h:288
const std::string & name() const
Definition: interface.h:114
PhysicalDevice * physical_device() const
std::vector< Subnet > SubnetList
Definition: cfg_vgw.h:30
const std::string & log_level() const
Definition: agent_param.h:301
BgpPeer * bgp_peer_id()
uint32_t linklocal_vm_flows() const
Definition: agent_param.h:256
const string & GetName() const
Definition: vn.h:162
void BuildAgentConfig(VrouterAgent &vrouter_agent)
bool log_local() const
Definition: agent_param.h:293
const std::string & log_category() const
Definition: agent_param.h:302
const uint64_t controller_xmpp_channel_setup_time(uint8_t idx) const
Definition: agent.h:801
std::map< const std::string, Bond_ChildIntf > BondChildIntfMap
bool GetBuildInfo(std::string &build_info_str)
DBTable::DBTableWalkRef interface_walk_ref_
const Ip4Address & mgmt_ip() const
Definition: agent_param.h:239
virtual void DispatchVrouterMsg(const VrouterAgent &uve)
const std::vector< std::string > & eth_port_list() const
Definition: agent_param.h:205
VirtualGatewayConfigTable * vgw_config_table() const
Definition: agent_param.h:329
VmTable * vm_table() const
Definition: agent.h:490
PhysicalInterfaceSet phy_intf_set_
const int8_t & ifmap_active_xmpp_server_index() const
Definition: agent.h:780
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
DBTableBase::ListenerId intf_listener_id_
DBTable::DBTableWalkRef vn_walk_ref_
VrouterObjectLimits GetVrouterObjectLimits()
Definition: agent.cc:1157