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