OpenSDN source code
ifmap_dependency_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <cmn/agent_cmn.h>
6 #include <vnc_cfg_types.h>
7 #include <agent_types.h>
8 
9 #include "oper/oper_db.h"
11 #include "oper/vn.h"
12 #include "oper/sg.h"
13 #include "oper/tag.h"
14 #include "oper/interface_common.h"
15 #include "oper/health_check.h"
16 #include "oper/vrf.h"
17 #include "oper/vm.h"
18 #include "oper/physical_device.h"
19 #include "filter/acl.h"
20 #include "oper/qos_queue.h"
21 #include "oper/forwarding_class.h"
22 #include "oper/qos_config.h"
23 #include "oper/config_manager.h"
24 #include "oper/vrouter.h"
25 #include "oper/bgp_router.h"
26 #include "oper/global_qos_config.h"
28 #include "oper/global_vrouter.h"
29 #include "oper/bridge_domain.h"
30 #include "filter/policy_set.h"
31 #include "cfg/cfg_init.h"
33 #include "oper/multicast_policy.h"
34 
35 #include <boost/assign/list_of.hpp>
36 #include <boost/bind/bind.hpp>
37 
38 #include "base/task.h"
39 #include "base/task_trigger.h"
40 #include "db/db.h"
41 #include "db/db_table_partition.h"
42 #include "db/db_entry.h"
45 #include "ifmap/ifmap_link.h"
46 #include "ifmap/ifmap_node.h"
47 #include "ifmap/ifmap_table.h"
48 
49 using namespace boost::assign;
50 using namespace std;
51 using namespace boost::placeholders;
52 
56 
58  ++state->refcount_;
59 }
60 
62  if (--state->refcount_ == 0) {
63  assert(state->object_ == NULL);
64  state->manager_->IFMapNodeReset(state->node_);
65  delete state;
66  }
67 }
68 
70  : database_(database),
71  graph_(graph) {
72  tracker_.reset(
74  database, graph,
75  boost::bind(&IFMapDependencyManager::ChangeListAdd, this, _1)));
76  int task_id = TaskScheduler::GetInstance()->GetTaskId("db::DBTable");
77  trigger_.reset(
78  new TaskTrigger(
80  task_id, 0));
81 }
82 
84  // TODO: Unregister from all tables.
85 }
86 
88  agent_ = agent;
89  static const char *ifmap_types[] = {
90  "access-control-list",
91  "address-group",
92  "alias-ip",
93  "alias-ip-pool",
94  "application-policy-set",
95  "application-policy-set-firewall-policy",
96  "bgp-as-a-service",
97  "bgpaas-control-node-zone",
98  "bgp-router",
99  "control-node-zone",
100  "firewall-policy",
101  "firewall-rule",
102  "floating-ip",
103  "floating-ip-pool",
104  "forwarding-class",
105  "global-qos-config",
106  "global-system-config",
107  "instance-ip",
108  "logical-interface",
109  "logical-router",
110  "network-ipam",
111  "physical-interface",
112  "physical-router",
113  "policy-management",
114  "project",
115  "qos-config",
116  "qos-queue",
117  "routing-instance",
118  "security-group",
119  "security-logging-object",
120  "service-group",
121  "service-health-check",
122  "service-instance",
123  "service-template",
124  "subnet",
125  "sub-cluster",
126  "tag",
127  "virtual-ip",
128  "virtual-machine",
129  "virtual-machine-interface",
130  "virtual-machine-interface-routing-instance",
131  "virtual-network",
132  "virtual-network-network-ipam",
133  "virtual-port-group",
134  "virtual-port-group-physical-interface",
135  "virtual-DNS",
136  "global-vrouter-config",
137  "virtual-router",
138  "interface-route-table",
139  "bridge-domain",
140  "virtual-machine-interface-bridge-domain",
141  "firewall-policy-firewall-rule",
142  "port-tuple",
143  "multicast-policy"
144  };
145 
146  // Link table
147  DBTable *link_table = static_cast<DBTable *>(
149  assert(link_table != NULL);
150 
151  DBTable::ListenerId id = link_table->Register(
152  boost::bind(&IFMapDependencyManager::LinkObserver, this, _1, _2));
153  table_map_.insert(make_pair(link_table->name(), id));
154 
155  // Identifier tables
156  const int n_types = sizeof(ifmap_types) / sizeof(const char *);
157  for (int i = 0; i < n_types; i++) {
158  const char *id_typename = ifmap_types[i];
159  IFMapTable *table = IFMapTable::FindTable(database_, id_typename);
160  assert(table);
161  DBTable::ListenerId id = table->Register(
162  boost::bind(&IFMapDependencyManager::NodeObserver, this, _1, _2));
163  table_map_.insert(make_pair(table->name(), id));
164  }
165 
166  // Policy definition
167  IFMapDependencyTracker::NodeEventPolicy *policy = tracker_->policy_map();
168 
169  ReactionMap react_si = map_list_of<string, PropagateList>
170  ("service-instance-service-template", list_of("self")
171  .convert_to_container<PropagateList>())
172  ("virtual-machine-service-instance", list_of("self")
173  .convert_to_container<PropagateList>())
174  ("self", list_of("self").convert_to_container<PropagateList>());
175  policy->insert(make_pair("service-instance", react_si));
176 
177  ReactionMap react_tmpl = map_list_of<string, PropagateList>
178  ("self", list_of("service-instance-service-template"));
179  policy->insert(make_pair("service-template", react_tmpl));
180 
181  ReactionMap react_vm = map_list_of<string, PropagateList>
182  ("self", list_of("virtual-machine-service-instance")
183  .convert_to_container<PropagateList>())
184  ("virtual-machine-virtual-machine-interface",
185  list_of("virtual-machine-service-instance")
186  .convert_to_container<PropagateList>())
187  ("virtual-machine-interface-virtual-machine",
188  list_of("virtual-machine-service-instance")
189  .convert_to_container<PropagateList>());
190  policy->insert(make_pair("virtual-machine", react_vm));
191 
192  ReactionMap react_vmi = map_list_of<string, PropagateList>
193  ("self", list_of("virtual-machine-interface-virtual-machine")
194  ("logical-interface-virtual-machine-interface")
195  .convert_to_container<PropagateList>())
196  ("instance-ip-virtual-machine-interface",
197  list_of("virtual-machine-interface-virtual-machine")
198  .convert_to_container<PropagateList>())
199  ("virtual-machine-interface-virtual-network",
200  list_of("virtual-machine-interface-virtual-machine")
201  ("logical-interface-virtual-machine-interface")
202  .convert_to_container<PropagateList>());
203  policy->insert(make_pair("virtual-machine-interface", react_vmi));
204 
205  ReactionMap react_ip = map_list_of<string, PropagateList>
206  ("self", list_of("instance-ip-virtual-machine-interface"));
207  policy->insert(make_pair("instance-ip", react_ip));
208 
209  ReactionMap react_subnet = map_list_of<string, PropagateList>
210  ("self", list_of("virtual-network-network-ipam")
211  .convert_to_container<PropagateList>())
212  ("virtual-network-network-ipam", list_of("nil")
213  .convert_to_container<PropagateList>());
214  policy->insert(make_pair("virtual-network-network-ipam", react_subnet));
215 
216  ReactionMap react_ipam = map_list_of<string, PropagateList>
217  ("virtual-network-network-ipam", list_of("nil"));
218  policy->insert(make_pair("network-ipam", react_ipam));
219 
220  ReactionMap react_bgpaas = map_list_of<string, PropagateList>
221  ("bgpaas-control-node-zone",
222  list_of("bgpaas-virtual-machine-interface"));
223  policy->insert(make_pair("bgp-as-a-service", react_bgpaas));
224 
226 }
227 
229 (const char *node_name, const IFMapDependencyTracker::ReactionMap &react) {
230  // Register to the IFMap table
231  IFMapTable *table = IFMapTable::FindTable(database_, node_name);
232  assert(table);
233  DBTable::ListenerId id = table->Register
234  (boost::bind(&IFMapDependencyManager::NodeObserver, this, _1, _2));
235  table_map_.insert(make_pair(table->name(), id));
236 
237  // Add Policy
238  tracker_->policy_map()->insert(make_pair(node_name, react));
239 }
240 
242  for (TableMap::iterator iter = table_map_.begin();
243  iter != table_map_.end(); ++iter) {
244  DBTable *table = static_cast<DBTable *>(
245  database_->FindTable(iter->first));
246  table->Unregister(iter->second);
247  }
248  table_map_.clear();
249  event_map_.clear();
250 }
251 
253  tracker_->PropagateChanges();
254  tracker_->Clear();
255 
256  for (ChangeList::iterator iter = change_list_.begin();
257  iter != change_list_.end(); ++iter) {
258  IFMapNodeState *state = iter->get();
259  IFMapTable *table = state->node()->table();
260  EventMap::iterator loc = event_map_.find(table->Typename());
261  if (loc == event_map_.end()) {
262  continue;
263  }
264 
265  if (state->notify() == true) {
266  loc->second(state->node(), state->object());
267  }
268  }
269  change_list_.clear();
270  return true;
271 }
272 
274  DBTablePartBase *root, DBEntryBase *db_entry) {
275 
276  IFMapNode *node = static_cast<IFMapNode *>(db_entry);
277  tracker_->NodeEvent(node);
278  trigger_->Set();
279 }
280 
282  tracker_->NodeEvent(node, false);
283  trigger_->Set();
284 }
285 
287 
288  tracker_->NodeEvent(node);
289 
291  iter != node->edge_list_end(graph_); ++iter) {
292  IFMapLink *link = static_cast<IFMapLink *>(iter.operator->());
293  IFMapNode *target = static_cast<IFMapNode *>(iter.target());
294  tracker_->LinkEvent(link->metadata(), node, target);
295  }
296 
297  trigger_->Set();
298 }
299 
301  DBTablePartBase *root, DBEntryBase *db_entry) {
302  IFMapLink *link = static_cast<IFMapLink *>(db_entry);
303  IFMapNode *left = link->LeftNode(database_);
304  IFMapNode *right = link->RightNode(database_);
305  bool set = false;
306  if (left) {
307  EventMap::iterator loc = event_map_.find(left->table()->Typename());
308  if (loc != event_map_.end()) {
309  ChangeListAdd(left);
310  set = true;
311  }
312  }
313 
314  if (right) {
315  EventMap::iterator loc = event_map_.find(right->table()->Typename());
316  if (loc != event_map_.end()) {
317  ChangeListAdd(right);
318  set = true;
319  }
320  }
321 
322  set |= tracker_->LinkEvent(link->metadata(), left, right);
323  if (set) {
324  trigger_->Set();
325  }
326 }
327 
329  IFMapNodeState *state = IFMapNodeGet(node);
330  if (state == NULL) {
331  if (node->IsDeleted() == false)
332  change_list_.push_back(SetState(node));
333  } else {
334  change_list_.push_back(IFMapNodePtr(state));
335  }
336 }
337 
340  IFMapTable *table = node->table();
341  TableMap::const_iterator loc = table_map_.find(table->name());
342  if (loc == table_map_.end()) {
343  return NULL;
344  }
345  IFMapNodeState *state =
346  static_cast<IFMapNodeState *>(node->GetState(table, loc->second));
347  return state;
348 }
349 
351  IFMapTable *table = node->table();
352  TableMap::const_iterator loc = table_map_.find(table->name());
353  assert(loc != table_map_.end());
354  node->ClearState(node->table(), loc->second);
355 }
356 
357 /*
358  * Associate an IFMapNode with an object in the operational database.
359  *
360  * IFMapNodes that do not have an object mapping do not receive notifications.
361  * This method checks whether the DBState exists and delegates the
362  * responsibility to create a new mapping to IFMapNodeSet (private).
363  */
365 
366  IFMapNodeState *state = IFMapNodeGet(node);
367  assert(state);
368 
369  DBEntry *old_entry = state->object();
370 
371  if (old_entry)
372  state->clear_object();
373 
374  if (entry) {
375  state->set_object(entry);
376  tracker_->NodeEvent(node);
377  trigger_->Set();
378  }
379 }
380 
381 void IFMapDependencyManager::SetNotify(IFMapNode *node, bool notify_flag) {
382 
383  IFMapNodeState *state = IFMapNodeGet(node);
384  assert(state);
385 
386  state->set_notify(notify_flag);
387 }
388 
390  bool oper_db_request_enqueued) {
391 
392  IFMapNodeState *state = IFMapNodeGet(node);
393  assert(state);
394 
395  state->set_oper_db_request_enqueued(oper_db_request_enqueued);
396 }
397 
400  IFMapTable *table = node->table();
401  TableMap::const_iterator loc = table_map_.find(table->name());
402  if (loc == table_map_.end())
403  return NULL;
404 
405  IFMapNodeState *state =
406  static_cast<IFMapNodeState *>(node->GetState(table, loc->second));
407 
408  if (!state) {
409  state = new IFMapNodeState(this, node);
410  node->SetState(table, loc->second, state);
411  }
412  return IFMapNodePtr(state);
413 }
414 
416  IFMapTable *table = node->table();
417  TableMap::const_iterator loc = table_map_.find(table->name());
418  if (loc == table_map_.end())
419  return NULL;
420 
421  IFMapNodeState *state =
422  static_cast<IFMapNodeState *>(node->GetState(table, loc->second));
423  if (state == NULL)
424  return NULL;
425 
426  return state->object();
427 }
428 
429 /*
430  * Register a notification callback.
431  */
433  const string &type, ChangeEventHandler handler) {
434  event_map_.insert(std::make_pair(type, handler));
435 }
436 
437 /*
438  * Unregister a notification callback.
439  */
441  event_map_.erase(type);
442 }
443 
444 // Check if a IFMapNode type is registerd with dependency manager
446  EventMap::iterator it = event_map_.find(node->table()->Typename());
447  return (it != event_map_.end());
448 }
449 
451  return (strcmp(node->table()->Typename(), "routing-instance") != 0);
452 }
453 
455 (const char *link1, const char *node1, bool interest1,
456  const char *link2 = NULL, const char *node2 = NULL, bool interest2 = false,
457  const char *link3 = NULL, const char *node3 = NULL, bool interest3 = false,
458  const char *link4 = NULL, const char *node4 = NULL, bool interest4 = false,
459  const char *link5 = NULL, const char *node5 = NULL, bool interest5 = false,
460  const char *link6 = NULL, const char *node6 = NULL, bool interest6 = false) {
461  if (link2) assert(node2);
462  if (link3) assert(node3);
463  if (link4) assert(node4);
464  if (link5) assert(node5);
465  if (link6) assert(node6);
466 
468  path.push_back(IFMapDependencyManager::Link(link1, node1, interest1));
469  if (link2)
470  path.push_back(IFMapDependencyManager::Link(link2, node2, interest2));
471  if (link3)
472  path.push_back(IFMapDependencyManager::Link(link3, node3, interest3));
473  if (link4)
474  path.push_back(IFMapDependencyManager::Link(link4, node4, interest4));
475  if (link5)
476  path.push_back(IFMapDependencyManager::Link(link5, node5, interest5));
477  if (link6)
478  path.push_back(IFMapDependencyManager::Link(link6, node6, interest6));
479  return path;
480 }
481 
482 static NodeEventPolicy::iterator LocateNodeEventPolicy(NodeEventPolicy *policy,
483  const string &node) {
484  NodeEventPolicy::iterator it = policy->find(node);
485  if (it != policy->end()) {
486  return it;
487  }
488  ReactionMap react = map_list_of<string, PropagateList>
489  ("self", PropagateList());
490  policy->insert(make_pair(node, react));
491  return policy->find(node);
492 }
493 
494 static ReactionMap::iterator LocateReactionMap(ReactionMap *react,
495  const string &event) {
496  ReactionMap::iterator it = react->find(event);
497  if (it != react->end()) {
498  return it;
499  }
500  react->insert(make_pair(event, PropagateList()));
501  return react->find(event);
502 }
503 
505 // The IFMap dependency tracker accepts rules in the form or "Reactor Map"
506 // Reactor map is not natural way of defining references between IFMap nodes
507 // in agent.
508 //
509 // When agent builds data for an oper-db entry, the IFNodeToReq API will keep
510 // the IFMapNode for oper-db entry as starting node and traverses the graph
511 // to build all realvent data for the entry. So, it is more natural in agent
512 // to specify relation between nodes in a way IFMapNodeToReq traverses the
513 // graph
514 //
515 // The routine AddDependencyPath takes the graph path between two vertices
516 // and then creates "Reactor Map" for them.
517 //
518 // The API takes IFMapNode for object being built as "node" and then a graph
519 // path to reach another IFMapNode of interest.
520 //
521 // Example: VMI refers to RI with following path to support floating-ip
522 // VMI <----> FIP <----> FIP-POOL <----> VN <----> RI
523 //
524 // node is specified as "virtual-machine-interface"
525 // path is specified as,
526 // <string(link-metadata), string(vertex), bool(vertex-attr-interest)>
527 //
528 // vertex specifies name of the adjacent node in the path
529 // link-metadata specifies metadata of the link connecting the vertex
530 // vertex-attr-interest
531 // If "node" is interested in any attribute of vertex, this value
532 // is set to TRUE else its set to FALSE
533 // When value is set to TRUE, it will generate an event of type
534 // "self" in the reactor-map
535 //
536 // The path from virtual-machine-interface to "routing-instance" above
537 // is given as below,
538 //
539 // <"virtual-machine-interface-floating-ip", "floating-ip", true>
540 // <"floating-ip-floating-ip-pool", "floating-ip-pool", false>
541 // <"floating-ip-pool-virtual-network", "virtual-network", true>
542 // <"virtual-network-routing-instance", "routing-instance", true>
543 //
544 // AddDependencyPath will "APPEND" following Reactor rules,
545 // node(virtual-machine-interface)
546 // event(virtual-machine-floating-ip) => Rectors(self)
547 //
548 // node(routing-instance)
549 // event(self) => Reactors(virtual-network-routing-instance)
550 //
551 // node(virtual-network)
552 // event(virtual-network-routing-instance) => Reactors(floating-ip-pool-virtual-network)
553 //
554 // node(floating-ip-pool)
555 // event(self) => Reactors(virtual-machine-interface-virtual-network)
556 // event(floating-ip-pool-virtual-network) => Reactors(floating-ip-floating-ip-pool)
557 //
558 // node(floating-ip)
559 // event(self) => Reactors(virtual-machine-interface-floating-ip)
560 // event(floating-ip-floating-ip-pool) => Reactors(virtual-machine-interface-floating-ip)
561 //
563 void IFMapDependencyManager::AddDependencyPath(const std::string &node,
564  Path path) {
565  NodeEventPolicy *policy = tracker_->policy_map();
566  assert(policy);
567 
568  NodeEventPolicy::iterator node_it;
569  node_it = LocateNodeEventPolicy(policy, node);
570  ReactionMap::iterator react_it = LocateReactionMap(&node_it->second,
571  path[0].edge_);
572  LOG(DEBUG, "Updating dependency tacker rules for " << node);
573  react_it->second.insert("self");
574  LOG(DEBUG, "Adding ReactorMap " << node_it->first << " : " <<
575  react_it->first << " -> " << "self");
576 
577  for (size_t i = 0; i < path.size(); i++) {
578  node_it = LocateNodeEventPolicy(policy, path[i].vertex_);
579  if (path[i].vertex_interest_) {
580  react_it = LocateReactionMap(&node_it->second, "self");
581  react_it->second.insert(path[i].edge_);
582  LOG(DEBUG, "Adding ReactorMap " << node_it->first << " : " <<
583  react_it->first << " -> " << path[i].edge_);
584  }
585 
586  if (i < (path.size() - 1)) {
587  react_it = LocateReactionMap(&node_it->second, path[i+1].edge_);
588  react_it->second.insert(path[i].edge_);
589  LOG(DEBUG, "Adding ReactorMap " << node_it->first << " : " <<
590  react_it->first << " -> " << path[i].edge_);
591  } else {
592  react_it = LocateReactionMap(&node_it->second, path[i].edge_);
593  react_it->second.insert("nil");
594  LOG(DEBUG, "Adding ReactorMap " << node_it->first << " : " <<
595  react_it->first << " -> " << "nil");
596  }
597  }
598 
599  return;
600 }
601 
602 // Register callback for ifmap node not having corresponding oper-dbtable
604  const char *name, OperIFMapTable *table) {
605  if (table)
606  dep->Register(name, boost::bind(&OperIFMapTable::ConfigEventHandler,
607  table, _1, _2));
608 }
609 
611  const char *name, AgentOperDBTable *table) {
612  if (table)
613  dep->Register(name, boost::bind(&AgentOperDBTable::ConfigEventHandler,
614  table, _1, _2));
615 }
616 
618 
619  RegisterConfigHandler(this, "virtual-machine",
620  agent ? agent->vm_table() : NULL);
621 
622  RegisterConfigHandler(this, "access-control-list",
623  agent ? agent->acl_table() : NULL);
624 
625  RegisterConfigHandler(this, "multicast-policy",
626  agent ? agent->mp_table() : NULL);
627 
629  // VN <----> RI
630  // <----> ACL
631  // <----> VN-IPAM <----> IPAM
632  // <----> SecurityLoggingObject
633  // <----> Multicast Policy
635  AddDependencyPath("virtual-network",
636  MakePath("virtual-network-routing-instance",
637  "routing-instance", true));
638  AddDependencyPath("virtual-network",
639  MakePath("virtual-network-access-control-list",
640  "access-control-list", true));
641  AddDependencyPath("virtual-network",
642  MakePath("virtual-network-network-ipam",
643  "virtual-network-network-ipam", true,
644  "virtual-network-network-ipam",
645  "network-ipam", false));
646  AddDependencyPath("virtual-network",
647  MakePath("virtual-network-qos-config",
648  "qos-config", true));
649  AddDependencyPath("virtual-network",
650  MakePath("virtual-network-security-logging-object",
651  "security-logging-object", true));
652  AddDependencyPath("virtual-network",
653  MakePath("logical-router-virtual-network",
654  "logical-router-virtual-network", true,
655  "logical-router-virtual-network",
656  "logical-router", true));
657  AddDependencyPath("virtual-network",
658  MakePath("virtual-network-multicast-policy",
659  "multicast-policy", true));
660  RegisterConfigHandler(this, "virtual-network",
661  agent ? agent->vn_table() : NULL);
662 
664  // RI <----> VN
666  AddDependencyPath("routing-instance",
667  MakePath("virtual-network-routing-instance",
668  "virtual-network", true,
669  "virtual-network-provider-network",
670  "virtual-network", true));
671  RegisterConfigHandler(this, "routing-instance",
672  agent ? agent->vrf_table() : NULL);
673 
675  // SG <----> ACL
677  AddDependencyPath("security-group",
678  MakePath("security-group-access-control-list",
679  "access-control-list", true));
680  RegisterConfigHandler(this, "security-group",
681  agent ? agent->sg_table() : NULL);
682 
683  RegisterConfigHandler(this, "tag",
684  agent ? agent->tag_table() : NULL);
685  AddDependencyPath("tag",
686  MakePath("application-policy-set-tag",
687  "application-policy-set", true,
688  "policy-management-application-policy-set",
689  "policy-management", false));
691  // VMI <----> VN
692  // <----> VM
693  // <----> VMI-RI <----> RI
694  // <----> SG
695  // //<----> FIP <----> FIP-POOL <----> VN <----> RI
696  // <----> FIP <----> FIP-POOL <----> VN
697  // <----> FIP <----> Instance-IP <----> VN
698  // <----> Instance-IP
699  // <----> interface-route-table
700  // <----> subnet
701  // //<----> vn <----> VN-IPAM <----> IPAM
702  // <----> LI <----> physical-interface <----> physical-router
703  // <----> SecurityLoggingObject
705  AddDependencyPath("virtual-machine-interface",
706  MakePath("virtual-machine-interface-virtual-network",
707  "virtual-network", true,
708  "virtual-network-network-ipam",
709  "virtual-network-network-ipam", true));
710  AddDependencyPath("virtual-machine-interface",
711  MakePath("virtual-machine-interface-virtual-machine",
712  "virtual-machine", true));
713  AddDependencyPath("virtual-machine-interface",
714  MakePath("virtual-machine-interface-sub-interface",
715  "virtual-machine-interface", true));
716 
717  AddDependencyPath("virtual-machine-interface",
718  MakePath("virtual-machine-interface-virtual-network",
719  "virtual-network", true,
720  "virtual-network-provider-network",
721  "virtual-network", true));
722 
723  AddDependencyPath("virtual-machine-interface",
724  MakePath("virtual-machine-interface-routing-instance",
725  "virtual-machine-interface-routing-instance",
726  true,
727  "virtual-machine-interface-routing-instance",
728  "routing-instance", true));
729 
730  AddDependencyPath("virtual-machine-interface",
731  MakePath("virtual-machine-interface-security-group",
732  "security-group", true));
733  AddDependencyPath("virtual-machine-interface",
734  MakePath("alias-ip-virtual-machine-interface",
735  "alias-ip", true,
736  "alias-ip-pool-alias-ip",
737  "alias-ip-pool", false,
738  "virtual-network-alias-ip-pool",
739  "virtual-network", true));
740  AddDependencyPath("virtual-machine-interface",
741  MakePath("floating-ip-virtual-machine-interface",
742  "floating-ip", true,
743  "floating-ip-pool-floating-ip",
744  "floating-ip-pool", false,
745  "virtual-network-floating-ip-pool",
746  "virtual-network", true,
747  "virtual-network-provider-network",
748  "virtual-network", true));
749  AddDependencyPath("virtual-machine-interface",
750  MakePath("floating-ip-virtual-machine-interface",
751  "floating-ip", true,
752  "floating-ip-pool-floating-ip",
753  "floating-ip-pool", false,
754  "virtual-network-floating-ip-pool",
755  "virtual-network", true,
756  "virtual-network-routing-instance",
757  "routing-instance", true));
758  AddDependencyPath("virtual-machine-interface",
759  MakePath("floating-ip-virtual-machine-interface",
760  "floating-ip", true,
761  "instance-ip-floating-ip",
762  "instance-ip", false,
763  "instance-ip-virtual-network",
764  "virtual-network", true));
765  AddDependencyPath("virtual-machine-interface",
766  MakePath("instance-ip-virtual-machine-interface",
767  "instance-ip", true));
768  AddDependencyPath("virtual-machine-interface",
769  MakePath("virtual-machine-interface-route-table",
770  "interface-route-table", true));
771  AddDependencyPath("virtual-machine-interface",
772  MakePath("subnet-virtual-machine-interface",
773  "subnet", true));
774  AddDependencyPath("virtual-machine-interface",
775  MakePath("logical-interface-virtual-machine-interface",
776  "logical-interface", false,
777  "physical-interface-logical-interface",
778  "physical-interface", false,
779  "physical-router-physical-interface",
780  "physical-router", true));
781  AddDependencyPath("virtual-machine-interface",
782  MakePath("virtual-port-group-virtual-machine-interface",
783  "virtual-port-group", false,
784  "virtual-port-group-physical-interface",
785  "physical-interface", false,
786  "physical-router-physical-interface",
787  "physical-router", true));
788  AddDependencyPath("virtual-machine-interface",
789  MakePath("bgpaas-virtual-machine-interface",
790  "bgp-as-a-service", true,
791  "bgpaas-bgp-router",
792  "bgp-router", true,
793  "instance-bgp-router",
794  "routing-instance", true));
795  AddDependencyPath("virtual-machine-interface",
796  MakePath("bgpaas-virtual-machine-interface",
797  "bgp-as-a-service", true,
798  "bgpaas-health-check",
799  "service-health-check", true));
800  AddDependencyPath("virtual-machine-interface",
801  MakePath("virtual-machine-interface-qos-config",
802  "qos-config", true));
803  AddDependencyPath("virtual-machine-interface",
804  MakePath("virtual-machine-interface-security-logging-object",
805  "security-logging-object", true));
806 
807  AddDependencyPath("virtual-machine-interface",
808  MakePath("virtual-machine-interface-bridge-domain",
809  "virtual-machine-interface-bridge-domain",
810  true,
811  "virtual-machine-interface-bridge-domain",
812  "bridge-domain", true,
813  "virtual-network-bridge-domain",
814  "virtual-network", true));
815  //Above rule should suffice for VMI to act on bridge domain
816  //"virtual-machine-interface-bridge-domain" link is used to
817  //link both VMI and bridge domain, so this link could notify
818  //bridge-domain which doesnt have any reaction list as bridge-domain
819  //is not intererested in "virtual-machine-interface-bridge-domain".
820  //VMI ---> VMI-BD Link ---> VMI-BD node ----> VMI-BD link ---> BD
821  //Note that link name is same in above graph
822  //Add the below dummy rule so that VMI-BD link triggers
823  //bridge-domain evaluation its ignored and avoids assert
824  AddDependencyPath("virtual-machine-interface",
825  MakePath("virtual-machine-interface-bridge-domain",
826  "virtual-machine-interface-bridge-domain",
827  true,
828  "virtual-machine-interface-bridge-domain",
829  "bridge-domain", true));
830 
831  AddDependencyPath("virtual-machine-interface",
832  MakePath("virtual-machine-interface-tag",
833  "tag", true,
834  "application-policy-set-tag",
835  "application-policy-set", true,
836  "application-policy-set-firewall-policy",
837  "application-policy-set-firewall-policy", true,
838  "application-policy-set-firewall-policy",
839  "firewall-policy", true));
840 
841  AddDependencyPath("virtual-machine-interface",
842  MakePath("virtual-machine-interface-virtual-network",
843  "virtual-network", true,
844  "virtual-network-tag", "tag", true,
845  "application-policy-set-tag",
846  "application-policy-set", true,
847  "application-policy-set-firewall-policy",
848  "application-policy-set-firewall-policy", true,
849  "application-policy-set-firewall-policy",
850  "firewall-policy", true));
851 
852 
853  AddDependencyPath("virtual-machine-interface",
854  MakePath("virtual-machine-interface-virtual-machine",
855  "virtual-machine", true,
856  "virtual-machine-tag", "tag", true,
857  "application-policy-set-tag",
858  "application-policy-set", true,
859  "application-policy-set-firewall-policy",
860  "application-policy-set-firewall-policy", true,
861  "application-policy-set-firewall-policy",
862  "firewall-policy", true));
863 
864  AddDependencyPath("virtual-machine-interface",
865  MakePath("virtual-machine-interface-sub-interface",
866  "virtual-machine-interface", true,
867  "virtual-machine-interface-virtual-machine",
868  "virtual-machine", true,
869  "virtual-machine-tag", "tag", true,
870  "application-policy-set-tag",
871  "application-policy-set", true,
872  "application-policy-set-firewall-policy",
873  "application-policy-set-firewall-policy", true,
874  "application-policy-set-firewall-policy",
875  "firewall-policy", true));
876 
877  AddDependencyPath("virtual-machine-interface",
878  MakePath("project-virtual-machine-interface",
879  "project", true,
880  "project-tag", "tag", true,
881  "application-policy-set-tag",
882  "application-policy-set", true,
883  "application-policy-set-firewall-policy",
884  "application-policy-set-firewall-policy", true,
885  "application-policy-set-firewall-policy",
886  "firewall-policy", true));
887 
888  /* Trigger change on virtual-machine-interface, if there is change in
889  * port-tuple configuration */
890  AddDependencyPath("virtual-machine-interface",
891  MakePath("port-tuple-interface",
892  "port-tuple", true,
893  "port-tuple-interface",
894  "virtual-machine-interface", true));
895  AddDependencyPath("virtual-machine-interface",
896  MakePath("logical-router-interface",
897  "logical-router", true));
898 
899  RegisterConfigHandler(this, "virtual-machine-interface",
900  agent ? agent->interface_table() : NULL);
902  // physical-interface <----> physical-router
904  AddDependencyPath("physical-interface",
905  MakePath("physical-router-physical-interface",
906  "physical-router", true));
908  // physical-interface <----> virtual-port-group
910  AddDependencyPath("physical-interface",
911  MakePath("virtual-port-group-physical-interface",
912  "virtual-port-group-physical-interface", true,
913  "virtual-port-group-physical-interface",
914  "virtual-port-group", true));
915  RegisterConfigHandler(this, "physical-interface",
916  agent ? agent->interface_table() : NULL);
917 
919  // logical-interface <----> physical-interface <----> physical-router
920  // <----> virtual-machine-interface <---> virtual-network
921  //
923  AddDependencyPath("logical-interface",
924  MakePath("physical-interface-logical-interface",
925  "physical-interface", true,
926  "physical-router-physical-interface",
927  "physical-router", true));
928  AddDependencyPath("logical-interface",
929  MakePath("logical-interface-virtual-machine-interface",
930  "virtual-machine-interface", true));
931  AddDependencyPath("logical-interface",
932  MakePath("physical-router-logical-interface",
933  "physical-router", true));
934  RegisterConfigHandler(this, "logical-interface",
935  agent ? agent->interface_table() : NULL);
936 
938  // physical-router <----> physical-interface
940  AddDependencyPath("physical-router",
941  MakePath("physical-router-physical-interface",
942  "physical-interface", true));
943  RegisterConfigHandler(this, "physical-router",
944  agent ? agent->physical_device_table() : NULL);
945 
947  // virtual-machine-interface <----> service-health-check
949  AddDependencyPath("service-health-check",
950  MakePath("service-port-health-check",
951  "virtual-machine-interface", true,
952  "virtual-machine-interface-virtual-network",
953  "virtual-network", false,
954  "virtual-network-network-ipam",
955  "virtual-network-network-ipam", true));
956  AddDependencyPath("service-health-check",
957  MakePath("service-port-health-check",
958  "virtual-machine-interface", true,
959  "port-tuple-interface",
960  "port-tuple", true,
961  "port-tuple-interface",
962  "virtual-machine-interface", true,
963  "virtual-machine-interface-virtual-network",
964  "virtual-network", false,
965  "virtual-network-network-ipam",
966  "virtual-network-network-ipam", true));
967  RegisterConfigHandler(this, "service-health-check",
968  agent ? agent->health_check_table() : NULL);
969 
970  AddDependencyPath("qos-config",
971  MakePath("global-qos-config-qos-config",
972  "global-qos-config", false));
973  RegisterConfigHandler(this, "qos-config",
974  agent ? agent->qos_config_table() : NULL);
975 
976  RegisterConfigHandler(this, "qos-queue",
977  agent ? agent->qos_queue_table() : NULL);
978 
979  AddDependencyPath("forwarding-class",
980  MakePath("forwarding-class-qos-queue",
981  "qos-queue", true));
982  RegisterConfigHandler(this, "forwarding-class",
983  agent ? agent->forwarding_class_table() : NULL);
984 
986  // security-logging-object <----> network-policy
987  // <----> security-group
989  AddDependencyPath("security-logging-object",
990  MakePath("security-logging-object-network-policy",
991  "network-policy", true));
992  AddDependencyPath("security-logging-object",
993  MakePath("security-logging-object-security-group",
994  "security-group", true));
995  AddDependencyPath("security-logging-object",
996  MakePath("firewall-policy-security-logging-object",
997  "firewall-policy-security-logging-object", true,
998  "firewall-policy-security-logging-object",
999  "firewall-policy", false));
1000  AddDependencyPath("security-logging-object",
1001  MakePath("firewall-rule-security-logging-object",
1002  "firewall-rule-security-logging-object", true,
1003  "firewall-rule-security-logging-object",
1004  "firewall-rule", false));
1005  RegisterConfigHandler(this, "security-logging-object",
1006  agent ? agent->slo_table() : NULL);
1007 
1009  // VR <----> Subcluster <----> bgp-router
1011  AddDependencyPath("virtual-router",
1012  MakePath("virtual-router-sub-cluster",
1013  "sub-cluster", true,
1014  "bgp-router-sub-cluster",
1015  "bgp-router", true));
1016 
1017  // Register callback for ifmap node not having corresponding oper-dbtable
1018  RegisterConfigHandler(this, "virtual-router", agent->oper_db()->vrouter());
1019  RegisterConfigHandler(this, "global-qos-config",
1020  agent->oper_db()->global_qos_config());
1021  RegisterConfigHandler(this, "global-system-config",
1022  agent->oper_db()->global_system_config());
1023  RegisterConfigHandler(this, "network-ipam",
1024  agent->oper_db()->network_ipam());
1025  RegisterConfigHandler(this, "virtual-DNS",
1026  agent->oper_db()->virtual_dns());
1027  RegisterConfigHandler(this, "global-vrouter-config",
1028  agent->oper_db()->global_vrouter());
1029  RegisterConfigHandler(this, "bgp-router",
1030  agent->oper_db()->bgp_router_config());
1031  AddDependencyPath("bridge-domain",
1032  MakePath("virtual-network-bridge-domain",
1033  "virtual-network", true,
1034  "virtual-network-routing-instance",
1035  "routing-instance", true));
1036  AddDependencyPath("bridge-domain",
1037  MakePath("virtual-network-bridge-domain",
1038  "virtual-network", true));
1039 
1040  RegisterConfigHandler(this, "bridge-domain",
1041  agent ? agent->bridge_domain_table() : NULL);
1042 
1043  AddDependencyPath("application-policy-set",
1044  MakePath("application-policy-set-firewall-policy",
1045  "application-policy-set-firewall-policy", true,
1046  "application-policy-set-firewall-policy",
1047  "firewall-policy", true));
1048  RegisterConfigHandler(this, "application-policy-set",
1049  agent ? agent->policy_set_table() : NULL);
1050 
1051  AddDependencyPath("firewall-policy",
1052  MakePath("firewall-policy-firewall-rule",
1053  "firewall-policy-firewall-rule", true,
1054  "firewall-policy-firewall-rule",
1055  "firewall-rule", true,
1056  "firewall-rule-service-group",
1057  "service-group", true));
1058  AddDependencyPath("firewall-policy",
1059  MakePath("firewall-policy-firewall-rule",
1060  "firewall-policy-firewall-rule", true,
1061  "firewall-policy-firewall-rule",
1062  "firewall-rule", true,
1063  "firewall-rule-address-group",
1064  "address-group", true,
1065  "address-group-tag", "tag", "true"));
1066 
1067  AddDependencyPath("firewall-policy",
1068  MakePath("firewall-policy-firewall-rule",
1069  "firewall-policy-firewall-rule", true,
1070  "firewall-policy-firewall-rule",
1071  "firewall-rule", true,
1072  "firewall-rule-tag",
1073  "tag", true));
1074 
1075  AddDependencyPath("firewall-policy",
1076  MakePath("firewall-policy-firewall-rule",
1077  "firewall-policy-firewall-rule", true,
1078  "firewall-policy-firewall-rule",
1079  "firewall-rule", true));
1080 
1081  RegisterConfigHandler(this, "firewall-policy",
1082  agent ? agent->acl_table() : NULL);
1083 }
1084 
1085 void IFMapNodePolicyReq::HandleRequest() const {
1086  Agent *agent = Agent::GetInstance();
1087  IFMapNodePolicyResp *resp = new IFMapNodePolicyResp();
1088 
1090  agent->oper_db()->dependency_manager()->tracker()->policy_map();
1091  NodeEventPolicy::iterator it1 = policy_list->begin();
1092  std::vector<IFMapNodePolicy> resp_policy_list;
1093  while (it1 != policy_list->end()) {
1094  if (it1->first.find(get_node()) == string::npos) {
1095  it1++;
1096  continue;
1097  }
1098 
1099  ReactionMap::iterator it2 = it1->second.begin();
1100  vector<IFMapReactEvent> resp_event_list;
1101  while(it2 != it1->second.end()) {
1102  IFMapReactEvent resp_event;
1103  vector<string> resp_reactor_list;
1104  PropagateList::iterator it3 = it2->second.begin();
1105  while (it3 != it2->second.end()) {
1106  resp_reactor_list.push_back((*it3));
1107  it3++;
1108  }
1109  resp_event.set_event(it2->first);
1110  resp_event.set_reactors(resp_reactor_list);
1111  resp_event_list.push_back(resp_event);
1112  it2++;
1113  }
1114 
1115  IFMapNodePolicy policy;
1116  policy.set_node(it1->first);
1117  policy.set_events(resp_event_list);
1118  resp_policy_list.push_back(policy);
1119  it1++;
1120  }
1121 
1122  resp->set_policies(resp_policy_list);
1123  resp->set_context(context());
1124  resp->set_more(false);
1125  resp->Response();
1126  return;
1127 }
virtual void ConfigEventHandler(IFMapNode *node, DBEntry *entry)
Definition: oper_db.h:120
Definition: agent.h:360
InterfaceTable * interface_table() const
Definition: agent.h:467
VmTable * vm_table() const
Definition: agent.h:492
ForwardingClassTable * forwarding_class_table() const
Definition: agent.h:542
TagTable * tag_table() const
Definition: agent.h:507
OperDB * oper_db() const
Definition: agent.cc:1016
QosQueueTable * qos_queue_table() const
Definition: agent.h:564
VrfTable * vrf_table() const
Definition: agent.h:487
AgentQosConfigTable * qos_config_table() const
Definition: agent.h:556
AclTable * acl_table() const
Definition: agent.h:517
SecurityLoggingObjectTable * slo_table() const
Definition: agent.h:549
MulticastPolicyTable * mp_table() const
Definition: agent.h:644
BridgeDomainTable * bridge_domain_table() const
Definition: agent.cc:944
VnTable * vn_table() const
Definition: agent.h:497
PhysicalDeviceTable * physical_device_table() const
Definition: agent.h:630
static Agent * GetInstance()
Definition: agent.h:438
SgTable * sg_table() const
Definition: agent.h:502
HealthCheckTable * health_check_table() const
Definition: agent.cc:936
PolicySetTable * policy_set_table() const
Definition: agent.h:522
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:48
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
edge_iterator edge_list_begin(DBGraph *graph)
edge_iterator edge_list_end(DBGraph *graph)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:207
void Unregister(ListenerId listener)
Definition: db_table.cc:212
int ListenerId
Definition: db_table.h:62
const std::string & name() const
Definition: db_table.h:110
Definition: db.h:24
DBTableBase * FindTable(const std::string &name)
Definition: db.cc:68
void SetRequestEnqueued(IFMapNode *node, bool oper_db_request_enqueued)
DBEntry * GetObject(IFMapNode *node)
void SetNotify(IFMapNode *node, bool notfiy_flag)
void Unregister(const std::string &type)
void InitializeDependencyRules(Agent *agent)
IFMapNodeState * IFMapNodeGet(IFMapNode *node)
void RegisterReactionMap(const char *node_name, const IFMapDependencyTracker::ReactionMap &react)
bool IsRegistered(const IFMapNode *node)
void AddDependencyPath(const std::string &node, Path path)
void PropogateNodeChange(IFMapNode *node)
bool IsNodeIdentifiedByUuid(const IFMapNode *node)
IFMapDependencyManager(DB *database, DBGraph *graph)
boost::intrusive_ptr< IFMapNodeState > IFMapNodePtr
void ChangeListAdd(IFMapNode *node)
IFMapNodePtr SetState(IFMapNode *node)
void PropogateNodeAndLinkChange(IFMapNode *node)
std::unique_ptr< IFMapDependencyTracker > tracker_
boost::function< void(IFMapNode *, DBEntry *)> ChangeEventHandler
std::unique_ptr< TaskTrigger > trigger_
void Register(const std::string &type, ChangeEventHandler handler)
IFMapDependencyTracker * tracker() const
void SetObject(IFMapNode *node, DBEntry *entry)
void IFMapNodeReset(IFMapNode *node)
void LinkObserver(DBTablePartBase *root, DBEntryBase *db_entry)
void NodeObserver(DBTablePartBase *root, DBEntryBase *db_entry)
std::set< std::string > PropagateList
std::map< std::string, PropagateList > ReactionMap
NodeEventPolicy * policy_map()
std::map< std::string, ReactionMap > NodeEventPolicy
void set_notify(bool flag)
void set_oper_db_request_enqueued(bool oper_db_request_enqueued)
void set_object(DBEntry *object)
IFMapDependencyManager * manager_
IFMapTable * table()
Definition: ifmap_node.h:29
static IFMapTable * FindTable(DB *db, const std::string &element_type)
Definition: ifmap_table.cc:39
virtual const char * Typename() const =0
OperNetworkIpam * network_ipam() const
Definition: operdb_init.h:89
OperVirtualDns * virtual_dns() const
Definition: operdb_init.h:90
GlobalVrouter * global_vrouter() const
Definition: operdb_init.h:54
GlobalSystemConfig * global_system_config() const
Definition: operdb_init.h:85
BgpRouterConfig * bgp_router_config() const
Definition: operdb_init.h:55
GlobalQosConfig * global_qos_config() const
Definition: operdb_init.h:81
IFMapDependencyManager * dependency_manager()
Definition: operdb_init.h:61
VRouter * vrouter() const
Definition: operdb_init.h:76
void ConfigEventHandler(IFMapNode *node, DBEntry *entry)
Definition: oper_db.h:250
Definition: path.h:10
int GetTaskId(const std::string &name)
Definition: task.cc:861
static TaskScheduler * GetInstance()
Definition: task.cc:554
#define IFMAP_AGENT_LINK_DB_NAME
static NodeEventPolicy::iterator LocateNodeEventPolicy(NodeEventPolicy *policy, const string &node)
IFMapDependencyTracker::PropagateList PropagateList
void intrusive_ptr_release(IFMapNodeState *state)
IFMapDependencyTracker::ReactionMap ReactionMap
IFMapDependencyTracker::NodeEventPolicy NodeEventPolicy
static ReactionMap::iterator LocateReactionMap(ReactionMap *react, const string &event)
IFMapDependencyManager::Path MakePath(const char *link1, const char *node1, bool interest1, const char *link2=NULL, const char *node2=NULL, bool interest2=false, const char *link3=NULL, const char *node3=NULL, bool interest3=false, const char *link4=NULL, const char *node4=NULL, bool interest4=false, const char *link5=NULL, const char *node5=NULL, bool interest5=false, const char *link6=NULL, const char *node6=NULL, bool interest6=false)
static void RegisterConfigHandler(IFMapDependencyManager *dep, const char *name, OperIFMapTable *table)
void intrusive_ptr_add_ref(IFMapNodeState *state)
uint8_t type
Definition: load_balance.h:2
#define LOG(_Level, _Msg)
Definition: logging.h:34