OpenSDN source code
port_subscribe_table.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3  */
4 #include <string>
5 #include <sandesh/sandesh_trace.h>
6 #include <port_ipc/port_ipc_types.h>
7 #include <cmn/agent_cmn.h>
8 #include <init/agent_param.h>
11 #include "port_subscribe_table.h"
12 #include "port_ipc_handler.h"
13 
14 using namespace autogen;
15 using boost::uuids::nil_uuid;
16 
18 // Init/Shutdown routines
21  // Register with config DB table for vm-port UUID to IFNode mapping
22  vmi_config_table_ = (static_cast<IFMapAgentTable *>
23  (IFMapTable::FindTable(agent_->db(),
24  "virtual-machine-interface")));
25  vmi_config_listener_id_ = vmi_config_table_->Register
26  (boost::bind(&PortSubscribeTable::Notify, this, _1, _2));
27 }
28 
30  DBTable::DBStateClear(vmi_config_table_, vmi_config_listener_id_);
31  vmi_config_table_->Unregister(vmi_config_listener_id_);
32 }
33 
35 // PortSubscribeEntry routines
38  int32_t version) :
39  type_(type), ifname_(ifname), version_(version) {
40 }
41 
43 }
44 
45 // Only version number is modifiable
47  version_ = rhs->version_;
48 }
49 
51  switch (type) {
52  case VMPORT:
53  return "VM Port";
54  break;
55 
56  case NAMESPACE:
57  return "Namespace Port";
58  break;
59 
60  case REMOTE_PORT:
61  return "Remote Port";
62  break;
63 
64  default:
65  break;
66  }
67 
68  return "Invalid";
69 }
70 
72 // VmiSubscribeEntry routines
75  const std::string &ifname,
76  uint32_t version,
77  const boost::uuids::uuid &vmi_uuid,
78  const boost::uuids::uuid vm_uuid,
79  const std::string &vm_name,
80  const boost::uuids::uuid &vn_uuid,
81  const boost::uuids::uuid &project_uuid,
82  const Ip4Address &ip4_addr,
83  const Ip6Address &ip6_addr,
84  const std::string &mac_addr,
85  uint16_t tx_vlan_id, uint16_t rx_vlan_id,
86  uint8_t vhostuser_mode, uint8_t link_state) :
87  PortSubscribeEntry(type, ifname, version), vmi_uuid_(vmi_uuid),
88  vm_uuid_(vm_uuid), vm_name_(vm_name), vn_uuid_(vn_uuid),
89  project_uuid_(project_uuid), ip4_addr_(ip4_addr), ip6_addr_(ip6_addr),
90  mac_addr_(mac_addr), tx_vlan_id_(tx_vlan_id), rx_vlan_id_(rx_vlan_id),
91  vhostuser_mode_(vhostuser_mode), link_state_(link_state) {
92 }
93 
95 }
96 
99 }
100 
102  uint16_t tx_vlan_id_p = VmInterface::kInvalidVlanId;
103  uint16_t rx_vlan_id_p = VmInterface::kInvalidVlanId;
104  string port = Agent::NullString();
106  if (agent->params()->isVmwareMode()) {
107  tx_vlan_id_p = tx_vlan_id_;
108  rx_vlan_id_p = rx_vlan_id_;
109  if (tx_vlan_id_p != VmInterface::kInvalidVlanId ||
110  rx_vlan_id_p != VmInterface::kInvalidVlanId) {
111  // In case of netns instance transport mode and
112  // parent interface shouldnt be set
113  port = agent->params()->vmware_physical_port();
114  transport = Interface::TRANSPORT_VIRTUAL;
115  }
116  }
117 
118  if ((agent->vrouter_on_nic_mode() == true ||
119  agent->vrouter_on_host_dpdk() == true) &&
121  transport = Interface::TRANSPORT_PMD;
122  }
123 
124  // Add the interface
127  tx_vlan_id_p, rx_vlan_id_p, port, ip6_addr_,
128  vhostuser_mode_, transport, link_state_);
129 
130  // Notify controller module about new port
132  return;
133 
135  data(new ControllerVmiSubscribeData(false, vmi_uuid_, vm_uuid_));
136  agent->controller()->Enqueue(data);
137 }
138 
140  const {
144  return;
145 
148  agent->controller()->Enqueue(data);
149 }
150 
152  return vn_uuid_ == u;
153 }
154 
156  return vm_uuid_ == u;
157 }
158 
160 // VmVnPortSubscribeEntry routines
163 (PortSubscribeEntry::Type type, const std::string &ifname, uint32_t version,
164  const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid,
165  const boost::uuids::uuid &vmi_uuid, const std::string &vm_name,
166  const std::string &vm_identifier, const std::string &vm_ifname,
167  const std::string &vm_namespace) :
168  PortSubscribeEntry(type, ifname, version), vm_uuid_(vm_uuid),
169  vn_uuid_(vn_uuid), vm_name_(vm_name), vm_identifier_(vm_identifier),
170  vm_ifname_(vm_ifname), vm_namespace_(vm_namespace), vmi_uuid_(vmi_uuid) {
171 }
172 
174 }
175 
178 }
179 
181  const {
183 
184 }
185 
187  const {
189 }
190 
192  if (vn_uuid_ == nil_uuid())
193  return true;
194 
195  return vn_uuid_ == u;
196 }
197 
199  return vm_uuid_ == u;
200 }
201 
203 // PortSubscribeTable routines
206  agent_(agent), interface_table_(agent->interface_table()),
207  controller_(agent->controller()),
208  vmi_config_table_(NULL), vmi_config_listener_id_(DBTableBase::kInvalidId) {
209 }
210 
212  assert(vmi_tree_.size() == 0);
213 }
214 
216  PortSubscribeEntryPtr entry) {
217  tbb::mutex::scoped_lock lock(mutex_);
218  std::pair<VmiTree::iterator, bool> ret =
219  vmi_tree_.insert(std::make_pair(u, entry));
220  if (ret.second == false) {
221  // Could be a port add for an exisiting VMI with a different VM.
222  // If so need to handle as a del and add.
223  VmiSubscribeEntry *new_entry =
224  dynamic_cast<VmiSubscribeEntry *>(entry.get());
225  VmiSubscribeEntry *old_entry =
226  dynamic_cast<VmiSubscribeEntry *>(ret.first->second.get());
227  if (old_entry->vm_uuid() != new_entry->vm_uuid()) {
228  ret.first->second->OnDelete(agent_, this);
229  vmi_tree_.erase(ret.first);
230  ret = vmi_tree_.insert(std::make_pair(u, entry));
231  } else {
232  ret.first->second->Update(entry.get());
233  }
234  }
235 
236  ret.first->second->OnAdd(agent_, this);
237 }
238 
240  tbb::mutex::scoped_lock lock(mutex_);
241  VmiTree::iterator it = vmi_tree_.find(u);
242  if (it == vmi_tree_.end())
243  return;
244 
245  it->second->OnDelete(agent_, this);
246  vmi_tree_.erase(it);
247 }
248 
250  const {
251  tbb::mutex::scoped_lock lock(mutex_);
252  VmiTree::const_iterator it = vmi_tree_.find(u);
253  if (it == vmi_tree_.end())
254  return PortSubscribeEntryPtr();
255 
256  return it->second;
257 }
258 
259 /*
260  * Process add of vm-vn subscribe entry.
261  * Add an entry to vmvn_subscribe_tree_
262  * If VMI config was already received for port then
263  * - find vmi-uuid from * vmvn_to_vmi_tree_
264  * - ifmap config resync will be done once vmi is added
265  */
267  const boost::uuids::uuid &vn_uuid,
268  const boost::uuids::uuid &vmi_uuid,
269  PortSubscribeEntryPtr entry) {
270  tbb::mutex::scoped_lock lock(mutex_);
271  std::pair<VmVnTree::iterator, bool> ret = vmvn_subscribe_tree_.insert
272  (make_pair(VmVnUuidEntry(vm_uuid, vn_uuid, vmi_uuid),entry));
273  if (ret.second == false) {
274  ret.first->second->Update(entry.get());
275  }
276 
277  // Find VMI for the vm-vn
278  //boost::uuids::uuid vmi_uuid = VmVnToVmiNoLock(vm_uuid);
279  if (vmi_uuid.is_nil())
280  return;
281 
282  // If entry is found, it means IFNode for VMI already present
283  // Enqueue vm-add request
284  VmVnPortSubscribeEntry *vmvn_entry =
285  static_cast<VmVnPortSubscribeEntry *>(entry.get());
286  vmvn_entry->set_vmi_uuid(vmi_uuid);
287  vmvn_entry->OnAdd(agent_, this);
288 }
289 
291 (const boost::uuids::uuid &vm_uuid,
292 const boost::uuids::uuid &vn_uuid,
293 const boost::uuids::uuid &vmi_uuid) {
294  tbb::mutex::scoped_lock lock(mutex_);
295  VmVnTree::iterator it =
296  vmvn_subscribe_tree_.find(VmVnUuidEntry(vm_uuid, vn_uuid, vmi_uuid));
297  if (it == vmvn_subscribe_tree_.end())
298  return;
299 
300  it->second->OnDelete(agent_, this);
301  vmvn_subscribe_tree_.erase(it);
302 }
303 
305 (const boost::uuids::uuid &vm_uuid,
306  const boost::uuids::uuid &vn_uuid,
307  const boost::uuids::uuid &vmi_uuid) {
308  VmVnTree::iterator it =
309  vmvn_subscribe_tree_.find(VmVnUuidEntry(vm_uuid, vn_uuid, vmi_uuid));
310  if (it == vmvn_subscribe_tree_.end())
311  return PortSubscribeEntryPtr();
312 
313  return it->second;
314 }
315 
317 (const boost::uuids::uuid &vm_uuid,
318  const boost::uuids::uuid &vn_uuid,
319  const boost::uuids::uuid &vmi_uuid) {
320  tbb::mutex::scoped_lock lock(mutex_);
321  return GetVmVnPortNoLock(vm_uuid, vn_uuid, vmi_uuid);
322 }
323 
325 // virtual-machine-interface table handler
328  IFMapNode *node = static_cast<IFMapNode *>(e);
329  State *state = static_cast<State *>(e->GetState(partition->parent(),
331  if (node->IsDeleted()) {
332  if (state == NULL)
333  return;
334  if (state->uuid_ != nil_uuid())
335  uuid_ifnode_tree_.erase(state->uuid_);
336  node->ClearState(partition->parent(), vmi_config_listener_id_);
337  delete state;
338  return;
339  }
340 
341  // Allocate DBState
342  if (state == NULL) {
343  state = new State();
344  node->SetState(partition->parent(), vmi_config_listener_id_, state);
345  }
346 
348  VirtualMachineInterface *cfg =
349  static_cast <VirtualMachineInterface *> (node->GetObject());
350  if (cfg != NULL) {
351  autogen::IdPermsType id_perms = cfg->id_perms();
352  CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
353  }
354 
355  // Update UUID tree
356  if (state->uuid_ != u) {
357  // Remove old-uuid
358  if (state->uuid_ != nil_uuid()) {
359  uuid_ifnode_tree_.erase(state->uuid_);
360  state->uuid_ = nil_uuid();
361  }
362 
363  // Set new-uuid
364  if (u != nil_uuid()) {
365  state->uuid_ = u;
366  uuid_ifnode_tree_.insert(std::make_pair(u, node));
367  }
368  }
369 }
370 
372  UuidToIFNodeTree::const_iterator it;
373  it = uuid_ifnode_tree_.find(u);
374  if (it == uuid_ifnode_tree_.end()) {
375  return NULL;
376  }
377  return it->second;
378 }
379 
381 (const boost::uuids::uuid &vmi_uuid) const {
382  VmiToVmVnTree::const_iterator it = vmi_to_vmvn_tree_.find(vmi_uuid);
383  if (it == vmi_to_vmvn_tree_.end())
384  return NULL;
385 
386  return &it->second;
387 }
388 
390  const VmInterfaceConfigData *data) {
391  entry->vm_uuid_ = data->vm_uuid_;
392  entry->vn_uuid_ = data->vn_uuid_;
393  entry->sub_interface_ = (entry->parent_vmi_.is_nil() == false);
394  entry->parent_vmi_ = data->parent_vmi_;
395  entry->vlan_tag_ = data->rx_vlan_id_;
396  entry->vhostuser_mode_ = data->vhostuser_mode_;
397  entry->mac_ = data->vm_mac_;
398  entry->vmi_cfg = data->GetVmiCfg();
399 }
400 
401 /*
402  * Update config tables built from VMI IFnode
403  * - Adds entry into vmi_to_vmvn_tree_
404  * - Adds entry to vmvn_to_vmi_tree_
405  */
407 (const boost::uuids::uuid &vmi_uuid, const VmInterfaceConfigData *data) {
408  // Find entry from vmi to vm-vn tree first
409  VmiToVmVnTree::iterator it;
410  it = vmi_to_vmvn_tree_.find(vmi_uuid);
411 
412  if (it != vmi_to_vmvn_tree_.end()) {
413  // Nothing to do if entry already present and vm/vn match
414  if (it->second.vm_uuid_ != data->vm_uuid_ ||
415  it->second.vn_uuid_ != data->vn_uuid_) {
416  // If an entry already present and VM/VN are different, remove the
417  // reverse entry first and then update with new entry
418  vmvn_to_vmi_tree_.erase(VmVnUuidEntry(it->second.vm_uuid_,
419  it->second.vn_uuid_,
420  vmi_uuid));
421  VmVnUuidEntry entry(data->vm_uuid_, data->vn_uuid_, vmi_uuid);
422  vmvn_to_vmi_tree_.insert(std::make_pair(entry, vmi_uuid));
423  }
424 
425  // Update data fields
426  CopyVmiConfigToInfo(&it->second, data);
427  } else {
428  // Entry not present add to vmi_to_vmvn_tree_ and vmvn_to_vmi_tree_
429  VmVnUuidEntry entry(data->vm_uuid_, data->vn_uuid_, vmi_uuid);
430  vmvn_to_vmi_tree_.insert(std::make_pair(entry, vmi_uuid));
431  VmiEntry vmi_entry;
432  CopyVmiConfigToInfo(&vmi_entry, data);
433  vmi_to_vmvn_tree_.insert(std::make_pair(vmi_uuid, vmi_entry));
434  }
435 }
436 
437 /*
438  * VMI IFNode config added. Build vmi_to_vmvn_tree_ and vmvn_to_vmi_tree from
439  * interface configuration. It will be used for vm-vn based subscriptions
440  *
441  * If the vm-vn port subscription is already received, the message would have
442  * been ignored since vmi-uuid was not known. Process the vm-vn port
443  * subscription now
444  */
446  const VmInterfaceConfigData *data) {
447  tbb::mutex::scoped_lock lock(mutex_);
448  UpdateVmiIfnodeInfo(vmi_uuid, data);
449  // Add vm-interface if possible
450  PortSubscribeEntryPtr entry_ref =
451  GetVmVnPortNoLock(data->vm_uuid_, data->vn_uuid_, vmi_uuid);
452  if (entry_ref.get() == NULL)
453  return;
454 
455  VmVnPortSubscribeEntry *entry =
456  dynamic_cast<VmVnPortSubscribeEntry *>(entry_ref.get());
457  // Nothing to do if vmi-uuid doesnt change
458  if (entry->vmi_uuid() == vmi_uuid) {
459  return;
460  }
461 
462  // vmi-uuid for vmvn-port entry changed. Delete old VMI and add new VMI
463  if (entry->vmi_uuid().is_nil() == false) {
464  entry->OnDelete(agent_, this);
465  }
466  entry->set_vmi_uuid(vmi_uuid);
467  if (entry->vmi_uuid().is_nil() == false) {
468  entry->OnAdd(agent_, this);
469  }
470 }
471 
472 /*
473  * Update config tables built from VMI IFnode
474  * - Deletes entry from vmi_to_vmvn_tree_
475  * - Deletes entry from vmvn_to_vmi_tree_
476  */
478 (const boost::uuids::uuid &vmi_uuid) {
479  VmiToVmVnTree::iterator it;
480  it = vmi_to_vmvn_tree_.find(vmi_uuid);
481  if (it == vmi_to_vmvn_tree_.end()) {
482  return;
483  }
484 
485  // If an entry already present in vm-vn entry, delete entries from
486  // vmi_to_vmvn_tree_ and vmvn_to_vmi_tree_
487  vmvn_to_vmi_tree_.erase(VmVnUuidEntry(it->second.vm_uuid_,
488  it->second.vn_uuid_,
489  vmi_uuid));
490  vmi_to_vmvn_tree_.erase(it);
491 }
492 
493 /*
494  * VMI IFNode config deleted. Remove entries from vmi_to_vmvn_tree_ and
495  * vmvn_to_vmi_tree from interface configuration.
496  *
497  * VMI deletion happens only on deletion of vm-vn port subscription. So, dont
498  * enqueue any VMI delete from here
499  */
501 (const boost::uuids::uuid &vmi_uuid) {
502  tbb::mutex::scoped_lock lock(mutex_);
503  DeleteVmiIfnodeInfo(vmi_uuid);
504 }
505 
507  // TODO : The tree can be modified in parallel. Must ensure synchronization
509  if (!pih) {
510  return;
511  }
512  VmiTree::iterator it = vmi_tree_.begin();
513  while (it != vmi_tree_.end()) {
514  VmiSubscribeEntry *entry =
515  dynamic_cast<VmiSubscribeEntry *>(it->second.get());
516  it++;
517  if (entry->type() == PortSubscribeEntry::NAMESPACE)
518  continue;
519 
520  if (entry->version() >= version) {
521  continue;
522  }
523 
524  std::string msg;
525  pih->DeleteVmiUuidEntry(entry->vmi_uuid(), msg);
526  }
527 
528  // Audit vm-vn port subscription entries
529  VmVnTree::iterator vmvn_it = vmvn_subscribe_tree_.begin();
530  while (vmvn_it != vmvn_subscribe_tree_.end()) {
531  VmVnPortSubscribeEntry *entry =
532  dynamic_cast<VmVnPortSubscribeEntry *>(vmvn_it->second.get());
533  vmvn_it++;
534  if (entry->type() == PortSubscribeEntry::NAMESPACE)
535  continue;
536 
537  if (entry->version() >= version) {
538  continue;
539  }
540 
541  std::string msg;
542  pih->DeleteVmVnPort(entry->vm_uuid(), msg);
543  }
544 }
545 
546 // Get port-subscribe-entry for a VMI
547 // First looks at VMI subscription table. If not found, looks into
548 // vmvn-port-subscribe table
550 (const boost::uuids::uuid &vmi_uuid,
551  const boost::uuids::uuid &vm_uuid,
552  const boost::uuids::uuid &vn_uuid) const {
553  tbb::mutex::scoped_lock lock(mutex_);
554  VmiTree::const_iterator it = vmi_tree_.find(vmi_uuid);
555  if (it != vmi_tree_.end())
556  return it->second;
557 
558  VmVnTree::const_iterator it1 =
559  vmvn_subscribe_tree_.find(VmVnUuidEntry(vm_uuid, vn_uuid, vmi_uuid));
560  if (it1 != vmvn_subscribe_tree_.end())
561  return it1->second;
562 
563  return PortSubscribeEntryPtr();
564 }
565 
567 (const boost::uuids::uuid &vm_uuid,
568  std::set<boost::uuids::uuid> &vmi_uuid_set) const {
569  VmVnToVmiTree::const_iterator it =
570  vmvn_to_vmi_tree_.lower_bound(
571  VmVnUuidEntry(vm_uuid, nil_uuid(), nil_uuid()));
572 
573  while (it != vmvn_to_vmi_tree_.end()) {
574  if (it->first.vm_uuid_ == vm_uuid)
575  vmi_uuid_set.insert(it->second);
576  it++;
577  }
578 
579  if (vmi_uuid_set.empty())
580  return false;
581 
582  return true;
583 }
584 
586 (const boost::uuids::uuid &vm_uuid,
587  std::set<boost::uuids::uuid> &vmi_uuid_set) const {
588  tbb::mutex::scoped_lock lock(mutex_);
589  return VmVnToVmiSetNoLock(vm_uuid, vmi_uuid_set);
590 }
591 
593 // Introspect routines
596 public:
597  SandeshPortSubscribeTask(Agent *agent, const std::string &context) :
598  Task(agent->task_scheduler()->GetTaskId(kTaskHttpRequstHandler), 0),
599  agent_(agent),
600  table_(agent->port_ipc_handler()->port_subscribe_table()),
601  context_(context) {
602  }
604 
605 protected:
608  std::string context_;
610 };
611 
612 // vmi_tree_ routes
614 public:
615  SandeshVmiPortSubscribeTask(Agent *agent, const std::string &context,
616  const std::string &ifname,
617  const boost::uuids::uuid &vmi_uuid) :
618  SandeshPortSubscribeTask(agent, context),
619  ifname_(ifname), vmi_uuid_(vmi_uuid) {
620  }
622 
623  virtual bool Run();
624  std::string Description() const { return "SandeshVmiPortSubscribeTask"; }
625 private:
626  std::string ifname_;
629 };
630 
632  SandeshVmiPortSubscriptionResp *resp = new SandeshVmiPortSubscriptionResp();
633 
634  PortSubscribeTable::VmiTree::const_iterator it = table_->vmi_tree_.begin();
635  std::vector<SandeshVmiPortSubscriptionInfo> port_list;
636  while (it != table_->vmi_tree_.end()) {
637  const VmiSubscribeEntry *entry =
638  dynamic_cast<const VmiSubscribeEntry *> (it->second.get());
639  it++;
640 
641  if ((ifname_.empty() == false) &&
642  (entry->ifname().find(ifname_) == string::npos) ) {
643  continue;
644  }
645 
646  if (vmi_uuid_.is_nil() == false && entry->vmi_uuid() != vmi_uuid_) {
647  continue;
648  }
649 
650  SandeshVmiPortSubscriptionInfo info;
651  info.set_ifname(entry->ifname());
652  info.set_version(entry->version());
653  info.set_vmi_uuid(UuidToString(entry->vmi_uuid()));
654  info.set_vm_uuid(UuidToString(entry->vm_uuid()));
655  info.set_vn_uuid(UuidToString(entry->vn_uuid()));
656  info.set_vm_name(entry->vm_name());
657  info.set_ip4_addr(entry->ip4_addr().to_string());
658  info.set_ip6_addr(entry->ip6_addr().to_string());
659  info.set_mac(entry->mac_addr());
660  info.set_tx_vlan(entry->tx_vlan_id());
661  info.set_rx_vlan(entry->rx_vlan_id());
662  info.set_vhostuser_mode(entry->vhostuser_mode());
663 
664  port_list.push_back(info);
665  }
666  resp->set_port_list(port_list);
667 
668  resp->set_context(context_);
669  resp->set_more(false);
670  resp->Response();
671  return true;
672 }
673 
674 void FetchVmiPortSubscriptionReq::HandleRequest() const {
675  Agent *agent = Agent::GetInstance();
676  boost::uuids::uuid u = StringToUuid(get_vmi_uuid());
678  new SandeshVmiPortSubscribeTask(agent, context(), get_ifname(), u);
679  agent->task_scheduler()->Enqueue(t);
680 }
681 
682 // vmvn_subscribe_tree_ routes
684 public:
685  SandeshVmVnPortSubscribeTask(Agent *agent, const std::string &context,
686  const std::string &ifname,
687  const boost::uuids::uuid &vm_uuid) :
688  SandeshPortSubscribeTask(agent, context),
689  ifname_(ifname), vm_uuid_(vm_uuid) {
690  }
692 
693  virtual bool Run();
694  std::string Description() const { return "SandeshVmVnPortSubscribeTask"; }
695 private:
696  std::string ifname_;
699 };
700 
702  SandeshVmVnPortSubscriptionResp *resp =
703  new SandeshVmVnPortSubscriptionResp();
704 
705  PortSubscribeTable::VmVnTree::const_iterator it =
706  table_->vmvn_subscribe_tree_.begin();
707  std::vector<SandeshVmVnPortSubscriptionInfo> port_list;
708  while (it != table_->vmvn_subscribe_tree_.end()) {
709  const VmVnPortSubscribeEntry *entry =
710  dynamic_cast<const VmVnPortSubscribeEntry *> (it->second.get());
711  it++;
712 
713  if ((ifname_.empty() == false) &&
714  (entry->ifname().find(ifname_) == string::npos) ) {
715  continue;
716  }
717 
718  if (vm_uuid_.is_nil() == false && entry->vm_uuid() != vm_uuid_) {
719  continue;
720  }
721 
722  SandeshVmVnPortSubscriptionInfo info;
723  info.set_ifname(entry->ifname());
724  info.set_version(entry->version());
725  info.set_vm_uuid(UuidToString(entry->vm_uuid()));
726  info.set_vn_uuid(UuidToString(nil_uuid()));
727  info.set_vm_name(entry->vm_name());
728  info.set_vm_identifier(entry->vm_identifier());
729  info.set_vm_ifname(entry->vm_ifname());
730  info.set_vm_namespace(entry->vm_namespace());
731  info.set_vmi_uuid(UuidToString(entry->vmi_uuid()));
732  port_list.push_back(info);
733  }
734  resp->set_port_list(port_list);
735 
736  resp->set_context(context_);
737  resp->set_more(false);
738  resp->Response();
739  return true;
740 }
741 
742 void FetchVmVnPortSubscriptionReq::HandleRequest() const {
743  Agent *agent = Agent::GetInstance();
744  boost::uuids::uuid u = StringToUuid(get_vm_uuid());
746  new SandeshVmVnPortSubscribeTask(agent, context(), get_ifname(), u);
747  agent->task_scheduler()->Enqueue(t);
748 }
749 
750 // vmi_to_vmvn_tree_ routes
752 public:
753  SandeshVmiToVmVnTask(Agent *agent, const std::string &context,
754  const boost::uuids::uuid &vmi_uuid) :
755  SandeshPortSubscribeTask(agent, context),
756  vmi_uuid_(vmi_uuid) {
757  }
758  virtual ~SandeshVmiToVmVnTask() { }
759 
760  virtual bool Run();
761  std::string Description() const { return "SandeshVmiToVmVnTask"; }
762 private:
765 };
766 
768  SandeshVmiToVmVnResp *resp = new SandeshVmiToVmVnResp();
769 
770  PortSubscribeTable::VmiToVmVnTree::const_iterator it =
771  table_->vmi_to_vmvn_tree_.begin();
772  std::vector<SandeshVmiToVmVnInfo> port_list;
773  while (it != table_->vmi_to_vmvn_tree_.end()) {
774  boost::uuids::uuid vmi_uuid = it->first;
775  const PortSubscribeTable::VmiEntry *vmi_entry = &it->second;
776  boost::uuids::uuid vm_uuid = vmi_entry->vm_uuid_;
777  boost::uuids::uuid vn_uuid = vmi_entry->vn_uuid_;
778  it++;
779 
780  if (vmi_uuid_.is_nil() == false && vmi_uuid != vmi_uuid_) {
781  continue;
782  }
783 
784  SandeshVmiToVmVnInfo info;
785  info.set_vmi_uuid(UuidToString(vmi_uuid));
786  info.set_vm_uuid(UuidToString(vm_uuid));
787  info.set_vn_uuid(UuidToString(vn_uuid));
788  if (vmi_entry->sub_interface_)
789  info.set_sub_interface("True");
790  else
791  info.set_sub_interface("False");
792  info.set_vlan_tag(vmi_entry->vlan_tag_);
793  info.set_parent_uuid(UuidToString(vmi_entry->parent_vmi_));
794  info.set_mac(vmi_entry->mac_);
795  port_list.push_back(info);
796  }
797  resp->set_port_list(port_list);
798 
799  resp->set_context(context_);
800  resp->set_more(false);
801  resp->Response();
802  return true;
803 }
804 
805 void FetchVmiToVmVnUuidReq::HandleRequest() const {
806  Agent *agent = Agent::GetInstance();
807  boost::uuids::uuid u = StringToUuid(get_vmi_uuid());
808  agent->task_scheduler()->Enqueue(new SandeshVmiToVmVnTask(agent, context(),
809  u));
810 }
811 
812 // vmvn_to_vmi_tree_ routes
814 public:
815  SandeshVmVnToVmiTask(Agent *agent, const std::string &context,
816  const boost::uuids::uuid &vm_uuid,
817  const boost::uuids::uuid &vn_uuid) :
818  SandeshPortSubscribeTask(agent, context),
819  vm_uuid_(vm_uuid), vn_uuid_(vn_uuid) {
820  }
821  virtual ~SandeshVmVnToVmiTask() { }
822 
823  virtual bool Run();
824  std::string Description() const { return "SandeshVmVnToVmiTask"; }
825 private:
829 };
830 
832  SandeshVmVnToVmiResp *resp = new SandeshVmVnToVmiResp();
833 
834  PortSubscribeTable::VmVnToVmiTree::const_iterator it =
835  table_->vmvn_to_vmi_tree_.begin();
836  std::vector<SandeshVmVnToVmiInfo> port_list;
837  while (it != table_->vmvn_to_vmi_tree_.end()) {
838  boost::uuids::uuid vm_uuid = it->first.vm_uuid_;
839  boost::uuids::uuid vn_uuid = it->first.vn_uuid_;
840  boost::uuids::uuid vmi_uuid = it->second;
841  it++;
842 
843  if (vm_uuid_.is_nil() == false && vm_uuid != vm_uuid_) {
844  continue;
845  }
846 
847  if (vn_uuid_.is_nil() == false && vn_uuid != vn_uuid_) {
848  continue;
849  }
850 
851  SandeshVmVnToVmiInfo info;
852  info.set_vmi_uuid(UuidToString(vmi_uuid));
853  info.set_vm_uuid(UuidToString(vm_uuid));
854  info.set_vn_uuid(UuidToString(vn_uuid));
855  port_list.push_back(info);
856  }
857  resp->set_port_list(port_list);
858 
859  resp->set_context(context_);
860  resp->set_more(false);
861  resp->Response();
862  return true;
863 }
864 
865 void FetchVmVnToVmiUuidReq::HandleRequest() const {
866  Agent *agent = Agent::GetInstance();
867  boost::uuids::uuid u1 = StringToUuid(get_vm_uuid());
868  boost::uuids::uuid u2 = StringToUuid(get_vn_uuid());
869  agent->task_scheduler()->Enqueue(new SandeshVmVnToVmiTask(agent, context(),
870  u1, u2));
871 }
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
#define kTaskHttpRequstHandler
Definition: agent.h:340
static void CfgUuidSet(uint64_t ms_long, uint64_t ls_long, boost::uuids::uuid &u)
Definition: agent_cmn.h:67
const std::string & vmware_physical_port() const
Definition: agent_param.h:331
bool isVmwareMode() const
Definition: agent_param.h:339
Definition: agent.h:360
InterfaceTable * interface_table() const
Definition: agent.h:467
bool vrouter_on_nic_mode() const
Definition: agent.cc:1056
VNController * controller() const
Definition: agent.cc:984
PortIpcHandler * port_ipc_handler() const
Definition: agent.cc:1008
AgentParam * params() const
Definition: agent.h:1226
bool vrouter_on_host_dpdk() const
Definition: agent.cc:1060
static const std::string & NullString()
Definition: agent.h:439
TaskScheduler * task_scheduler() const
Definition: agent.h:1122
static Agent * GetInstance()
Definition: agent.h:438
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 Delete()
Definition: db_entry.cc:131
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
DBTableBase * parent()
static void DBStateClear(DBTable *table, ListenerId id)
Definition: db_table.cc:550
IFMapObject * GetObject()
Definition: ifmap_node.cc:63
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
@ TRANSPORT_VIRTUAL
Definition: interface.h:64
@ TRANSPORT_PMD
Definition: interface.h:67
@ TRANSPORT_ETHERNET
Definition: interface.h:65
bool DeleteVmVnPort(const boost::uuids::uuid &vmi_uuid, string &err_msg)
void DeleteVmiUuidEntry(const boost::uuids::uuid &u, std::string &err_str)
uint32_t version() const
const std::string & ifname() const
static const char * TypeToString(Type type)
virtual void Update(const PortSubscribeEntry *rhs)
PortSubscribeEntry(Type type, const std::string &ifname, int32_t version)
PortSubscribeEntryPtr Get(const boost::uuids::uuid &vmi_uuid, const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid) const
void AddVmi(const boost::uuids::uuid &u, PortSubscribeEntryPtr entry)
PortSubscribeEntryPtr GetVmVnPort(const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &vmi_uuid)
void DeleteVmVnPort(const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &vmi_uuid)
VmiToVmVnTree vmi_to_vmvn_tree_
const VmiEntry * VmiToEntry(const boost::uuids::uuid &vmi_uuid) const
bool VmVnToVmiSet(const boost::uuids::uuid &vm_uuid, std::set< boost::uuids::uuid > &vmi_uuid_set) const
PortSubscribeEntryPtr GetVmi(const boost::uuids::uuid &u) const
void HandleVmiIfnodeDelete(const boost::uuids::uuid &vmi_uuid)
void DeleteVmiIfnodeInfo(const boost::uuids::uuid &vmi_uuid)
void AddVmVnPort(const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &vmi_uuid, PortSubscribeEntryPtr entry)
PortSubscribeEntryPtr GetVmVnPortNoLock(const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &vmi_uuid)
void DeleteVmi(const boost::uuids::uuid &u)
void HandleVmiIfnodeAdd(const boost::uuids::uuid &vmi_uuid, const VmInterfaceConfigData *data)
PortSubscribeTable(Agent *agent)
void UpdateVmiIfnodeInfo(const boost::uuids::uuid &vmi_uuid, const VmInterfaceConfigData *data)
bool VmVnToVmiSetNoLock(const boost::uuids::uuid &vm_uuid, std::set< boost::uuids::uuid > &vmi_uuid_set) const
void Notify(DBTablePartBase *partition, DBEntryBase *e)
VmVnToVmiTree vmvn_to_vmi_tree_
DBTableBase::ListenerId vmi_config_listener_id_
UuidToIFNodeTree uuid_ifnode_tree_
void StaleWalk(uint64_t version)
IFMapNode * UuidToIFNode(const boost::uuids::uuid &u) const
const PortSubscribeTable * table_
SandeshPortSubscribeTask(Agent *agent, const std::string &context)
DISALLOW_COPY_AND_ASSIGN(SandeshPortSubscribeTask)
DISALLOW_COPY_AND_ASSIGN(SandeshVmVnPortSubscribeTask)
virtual bool Run()
Code to execute. Returns true if task is completed. Return false to reschedule the task.
SandeshVmVnPortSubscribeTask(Agent *agent, const std::string &context, const std::string &ifname, const boost::uuids::uuid &vm_uuid)
virtual bool Run()
Code to execute. Returns true if task is completed. Return false to reschedule the task.
boost::uuids::uuid vm_uuid_
SandeshVmVnToVmiTask(Agent *agent, const std::string &context, const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid)
boost::uuids::uuid vn_uuid_
std::string Description() const
DISALLOW_COPY_AND_ASSIGN(SandeshVmVnToVmiTask)
SandeshVmiPortSubscribeTask(Agent *agent, const std::string &context, const std::string &ifname, const boost::uuids::uuid &vmi_uuid)
DISALLOW_COPY_AND_ASSIGN(SandeshVmiPortSubscribeTask)
virtual bool Run()
Code to execute. Returns true if task is completed. Return false to reschedule the task.
virtual bool Run()
Code to execute. Returns true if task is completed. Return false to reschedule the task.
boost::uuids::uuid vmi_uuid_
DISALLOW_COPY_AND_ASSIGN(SandeshVmiToVmVnTask)
SandeshVmiToVmVnTask(Agent *agent, const std::string &context, const boost::uuids::uuid &vmi_uuid)
std::string Description() const
void Enqueue(Task *task)
Enqueues a task for running. Starts task if all policy rules are met else puts task in waitq....
Definition: task.cc:636
Task is a wrapper over tbb::task to support policies.
Definition: task.h:86
int GetTaskId() const
Definition: task.h:118
boost::shared_ptr< ControllerWorkQueueData > ControllerWorkQueueDataType
void Enqueue(ControllerWorkQueueDataType data)
static void DeleteIfNameReq(InterfaceTable *table, const boost::uuids::uuid &uuid)
static void NovaAdd(InterfaceTable *table, const boost::uuids::uuid &intf_uuid, const std::string &os_name, const Ip4Address &addr, const std::string &mac, const std::string &vn_name, const boost::uuids::uuid &vm_project_uuid, uint16_t tx_vlan_id, uint16_t rx_vlan_id, const std::string &parent, const Ip6Address &ipv6, uint8_t vhostuser_mode, Interface::Transport transport, uint8_t link_state)
static const uint32_t kInvalidVlanId
Definition: vm_interface.h:360
static void SetIfNameReq(InterfaceTable *table, const boost::uuids::uuid &uuid, const std::string &ifname)
virtual void Update(const PortSubscribeEntry *rhs)
const std::string & vm_name() const
void OnAdd(Agent *agent, PortSubscribeTable *table) const
virtual const boost::uuids::uuid & vm_uuid() const
boost::uuids::uuid vn_uuid_
boost::uuids::uuid vmi_uuid_
virtual bool MatchVn(const boost::uuids::uuid &u) const
void set_vmi_uuid(const boost::uuids::uuid &u)
const std::string & vm_identifier() const
const std::string & vm_ifname() const
virtual bool MatchVm(const boost::uuids::uuid &u) const
boost::uuids::uuid vm_uuid_
void OnDelete(Agent *agent, PortSubscribeTable *table) const
const std::string & vm_namespace() const
VmVnPortSubscribeEntry(PortSubscribeEntry::Type type, const std::string &ifname, uint32_t version, const boost::uuids::uuid &vm_uuid, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &vmi_uuid, const std::string &vm_name, const std::string &vm_identifier, const std::string &vm_ifname, const std::string &vm_namespace)
const boost::uuids::uuid & vmi_uuid() const
uint16_t rx_vlan_id() const
boost::uuids::uuid vn_uuid_
const Ip4Address & ip4_addr() const
virtual bool MatchVn(const boost::uuids::uuid &u) const
const Ip6Address & ip6_addr() const
virtual bool MatchVm(const boost::uuids::uuid &u) const
const std::string & vm_name() const
uint16_t tx_vlan_id() const
const boost::uuids::uuid & vn_uuid() const
boost::uuids::uuid vm_uuid_
uint8_t vhostuser_mode() const
virtual void Update(const PortSubscribeEntry *rhs)
const boost::uuids::uuid & vmi_uuid() const
boost::uuids::uuid project_uuid_
void OnAdd(Agent *agent, PortSubscribeTable *table) const
const std::string & mac_addr() const
void OnDelete(Agent *agent, PortSubscribeTable *table) const
VmiSubscribeEntry(PortSubscribeEntry::Type type, const std::string &ifname, uint32_t version, const boost::uuids::uuid &vmi_uuid, const boost::uuids::uuid vm_uuid, const std::string &vm_name, const boost::uuids::uuid &vn_uuid, const boost::uuids::uuid &project_uuid, const Ip4Address &ip4_addr, const Ip6Address &ip6_addr, const std::string &mac_addr, uint16_t tx_vlan_id, uint16_t rx_vlan_id, uint8_t vhostuser_mode, uint8_t link_state)
const boost::uuids::uuid & vm_uuid() const
boost::uuids::uuid vmi_uuid_
uint8_t type
Definition: load_balance.h:2
boost::shared_ptr< PortSubscribeEntry > PortSubscribeEntryPtr
static void CopyVmiConfigToInfo(PortSubscribeTable::VmiEntry *entry, const VmInterfaceConfigData *data)
static boost::uuids::uuid StringToUuid(const std::string &str)
Definition: string_util.h:145
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
autogen::VirtualMachineInterface * vmi_cfg
boost::uuids::uuid vm_uuid_
boost::uuids::uuid vn_uuid_
autogen::VirtualMachineInterface * GetVmiCfg() const
boost::uuids::uuid parent_vmi_
boost::uuids::uuid uuid