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 
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 *>
399  if (!intf || !intf->physical_interface()) {
400  return NULL;
401  }
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_control_ip(param->mgmt_ip().to_string());
562 
563  vhost_cfg.set_name(param->vhost_name());
564  if (agent_->is_l3mh() == false) {
565  vhost_cfg.set_ip(param->vhost_addr().to_string());
566  vhost_cfg.set_ip_prefix_len(param->vhost_plen());
567  if (param->gateway_list().empty() == false) {
568  vhost_cfg.set_gateway(param->gateway_list()[0].to_string());
569  }
570  }
571  vrouter_agent.set_vhost_cfg(vhost_cfg);
572 
573  vrouter_agent.set_eth_name(param->eth_port_list());
574 
575  if (param->isKvmMode()) {
576  hypervisor = "kvm";
577  } else if (param->isXenMode()) {
578  hypervisor = "xen";
579  xen_cfg.set_xen_ll_port(param->xen_ll_name());
580  xen_cfg.set_xen_ll_ip(param->xen_ll_addr().to_string());
581  xen_cfg.set_xen_ll_prefix_len(param->xen_ll_plen());
582  vrouter_agent.set_xen_cfg(xen_cfg);
583  } else if (param->isVmwareMode()) {
584  hypervisor = "vmware";
585  vmware_cfg.set_vmware_port(param->vmware_physical_port());
586  vrouter_agent.set_vmware_cfg(vmware_cfg);
587  }
588  vrouter_agent.set_hypervisor(hypervisor);
589 
591  VirtualGatewayConfigTable::Table::iterator it = table->table().begin();
592  while (it != table->table().end()) {
593  AgentVgwConfig gw_cfg;
594  VirtualGatewayConfig::SubnetList subnet_list = it->subnets();
595  VirtualGatewayConfig::SubnetList route_list = it->routes();
596  vector<string> ip_blocks_list;
597  vector<string> route_str_list;
598 
599  SubnetToStringList(subnet_list, ip_blocks_list);
600  SubnetToStringList(route_list, route_str_list);
601 
602  gw_cfg.set_interface_name(it->interface_name());
603  gw_cfg.set_vrf_name(it->vrf_name());
604  gw_cfg.set_ip_blocks_list(ip_blocks_list);
605  gw_cfg.set_route_list(route_str_list);
606 
607  gw_cfg_list.push_back(gw_cfg);
608  ++it;
609  }
610  vrouter_agent.set_gateway_cfg_list(gw_cfg_list);
611  vrouter_agent.set_headless_mode_cfg(true);
612  vrouter_agent.set_collector_server_list_cfg(param->collector_server_list());
613  vrouter_agent.set_bgpaas_enabled(
615  vrouter_agent.set_port_mirror_enabled(MirrorTable::GetInstance()->IsConfigured());
616  vrouter_agent.set_loopback_ip(param->loopback_ip().to_string());
617  std::vector<string> gateway_list;
618  for (std::vector<Ip4Address>::const_iterator iter = param->gateway_list().begin();
619  iter != param->gateway_list().end(); ++iter) {
620  gateway_list.push_back((*iter).to_string());
621  }
622  vrouter_agent.set_gateway_list(gateway_list);
623 }
624 
625 
627  VrouterAgent vrouter_agent;
628  bool changed = false, bgp_aas, port_mirror;
629  static bool first = true, build_info = false;
630  vrouter_agent.set_name(agent_->agent_name());
631  Ip4Address rid = agent_->router_id();
632  vector<string> ip_list;
633  vector<string> dns_list;
634 
635  if (first) {
636  //Physical interface list
637  vnsConstants vnsVrouterType;
638  //vhost attributes
639  const Interface *vhost = agent_->vhost_interface();
640  if (vhost) {
641  AgentInterface vitf;
642  vitf.set_name(vhost->name());
643  vitf.set_mac_address(GetMacAddress(vhost->mac()));
644  vrouter_agent.set_vhost_if(vitf);
645  }
646 
647  //Configuration. Needs to be sent only once because whenever config
648  //changes agent will be restarted
649  BuildAgentConfig(vrouter_agent);
650 
651  //Set the Agent mode
652  if (agent_->tor_agent_enabled()) {
653  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
654  (VrouterAgentType::VROUTER_AGENT_TOR));
655  } else if (agent_->tsn_enabled()) {
656  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
657  (VrouterAgentType::VROUTER_AGENT_TSN));
658  } else {
659  vrouter_agent.set_mode(vnsVrouterType.VrouterAgentTypeMap.at
660  (VrouterAgentType::VROUTER_AGENT_EMBEDDED));
661  }
662 
663  if (agent_->vrouter_on_nic_mode()) {
664  vrouter_agent.set_platform(vnsVrouterType.
665  VrouterAgentPlatformTypeMap.at
666  (VrouterAgentPlatformType::
667  VROUTER_AGENT_ON_NIC));
668  } else if (agent_->vrouter_on_host_dpdk()) {
669  vrouter_agent.set_platform(vnsVrouterType.
670  VrouterAgentPlatformTypeMap.at
671  (VrouterAgentPlatformType::
672  VROUTER_AGENT_ON_HOST_DPDK));
673  } else if (agent_->vrouter_on_host()) {
674  vrouter_agent.set_platform(vnsVrouterType.
675  VrouterAgentPlatformTypeMap.at
676  (VrouterAgentPlatformType::
677  VROUTER_AGENT_ON_HOST));
678  }
679 
680  vrouter_agent.set_subcluster_name(agent_->subcluster_name());
681  vrouter_agent.set_vr_high_watermark(agent_->vr_limit_high_watermark());
682  vrouter_agent.set_vr_low_watermark(agent_->vr_limit_low_watermark());
683  first = false;
684  changed = true;
685  }
686 
687  VrouterObjectLimits vr_limits = agent_->GetVrouterObjectLimits();
688  VrouterObjectLimits prev_vr_limits = prev_vrouter_.get_vr_limits();
689  if (vr_limits != prev_vr_limits) {
690  vrouter_agent.set_vr_limits(vr_limits);
691  prev_vrouter_.set_vr_limits(vr_limits);
692  changed = true;
693  }
694 
695  if (!build_info) {
696  string build_info_str;
697  build_info = GetBuildInfo(build_info_str);
698  if (prev_vrouter_.get_build_info() != build_info_str) {
699  vrouter_agent.set_build_info(build_info_str);
700  prev_vrouter_.set_build_info(build_info_str);
701  changed = true;
702  }
703 
704  }
705 
706  bgp_aas = agent_->oper_db()->bgp_as_a_service()->IsConfigured();
707  if (prev_vrouter_.get_bgpaas_enabled() != bgp_aas) {
708  vrouter_agent.set_bgpaas_enabled(bgp_aas);
709  prev_vrouter_.set_bgpaas_enabled(bgp_aas);
710  changed = true;
711  }
712 
713  port_mirror = MirrorTable::GetInstance()->IsConfigured();
714  if (prev_vrouter_.get_port_mirror_enabled() != port_mirror) {
715  vrouter_agent.set_port_mirror_enabled(port_mirror);
716  prev_vrouter_.set_port_mirror_enabled(port_mirror);
717  changed = true;
718  }
719 
720  vector<AgentInterface> phy_if_list;
721  PhysicalInterfaceSet::iterator it = phy_intf_set_.begin();
722  while (it != phy_intf_set_.end()) {
723  AgentInterface pitf;
724  const Interface *intf = *it;
725  const PhysicalInterface *port = static_cast
726  <const PhysicalInterface *>(intf);
727  pitf.set_name(intf->name());
728  pitf.set_mac_address(GetMacAddress(port->mac()));
729  phy_if_list.push_back(pitf);
730  ++it;
731  }
732  if (prev_vrouter_.get_phy_if() != phy_if_list) {
733  vrouter_agent.set_phy_if(phy_if_list);
734  prev_vrouter_.set_phy_if(phy_if_list);
735  changed = true;
736  }
737 
738  std::vector<AgentXmppPeer> xmpp_list;
739  for (int count = 0; count < MAX_XMPP_SERVERS; count++) {
740  AgentXmppPeer peer;
741  if (!agent_->controller_ifmap_xmpp_server(count).empty()) {
742  peer.set_ip(agent_->controller_ifmap_xmpp_server(count));
744  if (ch == NULL) {
745  continue;
746  }
747  XmppChannel *xc = ch->GetXmppChannel();
748  if (xc == NULL) {
749  continue;
750  }
751  if (ch->bgp_peer_id() && xc->GetPeerState() == xmps::READY) {
752  peer.set_status(true);
753  } else {
754  peer.set_status(false);
755  }
756  peer.set_setup_time(agent_->controller_xmpp_channel_setup_time(count));
757  if (agent_->ifmap_active_xmpp_server_index() == count) {
758  peer.set_primary(true);
759  } else {
760  peer.set_primary(false);
761  }
762  xmpp_list.push_back(peer);
763  }
764  }
765 
766  if (!prev_vrouter_.__isset.xmpp_peer_list ||
767  prev_vrouter_.get_xmpp_peer_list() != xmpp_list) {
768  vrouter_agent.set_xmpp_peer_list(xmpp_list);
769  prev_vrouter_.set_xmpp_peer_list(xmpp_list);
770  changed = true;
771  }
772  /* Self IP list should be populated only if router_id is configured */
773  if (agent_->router_id_configured()) {
774  ip_list.push_back(rid.to_string());
775  if (!prev_vrouter_.__isset.self_ip_list ||
776  prev_vrouter_.get_self_ip_list() != ip_list) {
777 
778  vrouter_agent.set_self_ip_list(ip_list);
779  prev_vrouter_.set_self_ip_list(ip_list);
780  changed = true;
781  }
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
bool GetBuildInfo(std::string &build_info_str)
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
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
XmppChannel * GetXmppChannel()
BgpPeer * bgp_peer_id()
Definition: agent.h:360
InterfaceTable * interface_table() const
Definition: agent.h:467
const std::string & subcluster_name() const
Definition: agent.h:755
bool vrouter_on_nic_mode() const
Definition: agent.cc:1056
VmTable * vm_table() const
Definition: agent.h:492
AgentXmppChannel * controller_xmpp_channel(uint8_t idx) const
Definition: agent.h:811
OperDB * oper_db() const
Definition: agent.cc:1016
VrLimitExceeded & get_vr_limits_exceeded_map()
Definition: agent.h:1387
const std::string & dns_server(uint8_t idx) const
Definition: agent.h:859
const uint64_t controller_xmpp_channel_setup_time(uint8_t idx) const
Definition: agent.h:803
bool vrouter_on_host() const
Definition: agent.cc:1064
AgentParam * params() const
Definition: agent.h:1226
const std::string & agent_name() const
Definition: agent.h:880
bool tsn_enabled() const
Definition: agent.h:1164
bool router_id_configured()
Definition: agent.h:678
bool is_l3mh() const
Definition: agent.h:727
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:732
float vr_limit_high_watermark()
Definition: agent.h:1399
bool vrouter_on_host_dpdk() const
Definition: agent.cc:1060
static const std::string & NullString()
Definition: agent.h:439
VnTable * vn_table() const
Definition: agent.h:497
PhysicalDeviceTable * physical_device_table() const
Definition: agent.h:630
bool tor_agent_enabled() const
Definition: agent.h:1166
const Interface * vhost_interface() const
Definition: agent.h:937
Ip4Address router_id() const
Definition: agent.h:668
const int8_t & ifmap_active_xmpp_server_index() const
Definition: agent.h:782
float vr_limit_low_watermark()
Definition: agent.h:1407
VrouterObjectLimits GetVrouterObjectLimits()
Definition: agent.cc:1169
static void FillCpuInfo(CpuLoadInfo &info, bool system)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
static const int kInvalidId
Definition: db_table.h:64
void Unregister(ListenerId listener)
Definition: db_table.cc:186
DBTableBase * parent()
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:631
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:613
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:619
@ VM_INTERFACE
Definition: interface.h:35
@ PHYSICAL
Definition: interface.h:29
@ REMOTE_PHYSICAL
Definition: interface.h:31
const MacAddress & mac() const
Definition: interface.h:131
bool os_oper_state() const
Definition: interface.h:132
const std::string & name() const
Definition: interface.h:114
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
Type type() const
Definition: interface.h:112
bool IsUveActive() const
Definition: interface.cc:1486
Interface * physical_interface() const
std::string ToString() const
Definition: mac_address.cc:53
bool IsConfigured()
static MirrorTable * GetInstance()
Definition: mirror_table.h:156
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
bool master() const
const BondChildIntfMap & getBondChildIntfMap() const
SubType subtype() const
std::map< const std::string, Bond_ChildIntf > BondChildIntfMap
BondChildIntfMap::const_iterator BondChildIntfMapIterator
PhysicalDevice * physical_device() const
PhysicalDevice * physical_device() const
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
bool Cancel()
Definition: timer.cc:150
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
const Table & table() const
Definition: cfg_vgw.h:129
std::vector< Subnet > SubnetList
Definition: cfg_vgw.h:30
Definition: vm.h:32
const boost::uuids::uuid & GetUuid() const
Definition: vm.h:46
const boost::uuids::uuid & logical_interface() const
const std::string & cfg_name() const
Definition: vm.h:78
Definition: vn.h:151
const string & GetName() const
Definition: vn.h:162
Definition: vn.h:332
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