OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flow_mgmt.cc
Go to the documentation of this file.
1 #include <bitset>
2 #include <boost/uuid/uuid_io.hpp>
3 #include "cmn/agent.h"
5 #include "oper/bgp_as_service.h"
6 #include "oper/health_check.h"
7 #include "pkt/flow_proto.h"
8 #include <pkt/flow_mgmt.h>
14 #include "uve/agent_uve_stats.h"
16 
19 // FlowMgmtManager methods
21 FlowMgmtManager::FlowMgmtManager(Agent *agent, uint16_t table_index) :
22  agent_(agent),
23  table_index_(table_index),
24  acl_flow_mgmt_tree_(this),
25  interface_flow_mgmt_tree_(this),
26  vn_flow_mgmt_tree_(this),
27  ip4_route_flow_mgmt_tree_(this),
28  ip6_route_flow_mgmt_tree_(this),
29  bridge_route_flow_mgmt_tree_(this),
30  vrf_flow_mgmt_tree_(this),
31  nh_flow_mgmt_tree_(this),
32  flow_mgmt_dbclient_(new FlowMgmtDbClient(agent, this)),
33  request_queue_(agent_->task_scheduler()->GetTaskId(kTaskFlowMgmt),
34  table_index,
35  boost::bind(&FlowMgmtManager::RequestHandler, this, _1)),
36  db_event_queue_(agent_->task_scheduler()->GetTaskId(kTaskFlowMgmt),
37  table_index,
38  boost::bind(&FlowMgmtManager::DBRequestHandler, this, _1),
39  db_event_queue_.kMaxSize, 1) {
40  request_queue_.set_name("Flow management");
42  db_event_queue_.set_name("Flow DB Event Queue");
43  for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
45  new BgpAsAServiceFlowMgmtTree(this, count));
46  }
47 }
48 
50  flow_mgmt_dbclient_->Init();
52  (boost::bind(&FlowMgmtManager::SetAceSandeshData, this, _1, _2, _3));
54  (boost::bind(&FlowMgmtManager::SetAclFlowSandeshData, this, _1, _2,
55  _3));
56  // If BGP service is deleted then flush off all the flows for the VMI.
58  (&FlowMgmtManager::BgpAsAServiceNotify, this, _1, _2));
59  // If BGP service health check configuration is modified,
60  // update the corresponding flows
63  _1, _2, _3, _4));
64  // If control node goes off delete all flows frmo its tree.
67 }
68 
72  flow_mgmt_dbclient_->Shutdown();
73 }
74 
76  uint32_t task_id = agent->task_scheduler()->GetTaskId(kTaskFlowLogging);
77  log_queue_ = new FlowMgmtQueue(task_id, 0,
78  boost::bind(&FlowMgmtManager::LogHandler,
79  _1));
80  log_queue_->set_name("Flow Log Queue");
81  log_queue_->SetBounded(true);
82 }
83 
86  delete log_queue_;
87 }
88 
90 // BGP as a service callbacks
93  uint32_t source_port) {
95  source_port));
97 }
98 
100  const boost::uuids::uuid &vm_uuid, uint32_t source_port,
101  const boost::uuids::uuid &hc_uuid, bool add) {
106  source_port,
107  hc_uuid, type));
108  request_queue_.Enqueue(req);
109 }
110 
113  request_queue_.Enqueue(req);
114 }
115 
117 // Introspect routines
120  AclFlowCountResp &data,
121  const std::string &ace_id) {
122  AclFlowMgmtKey key(acl, NULL);
123  AclFlowMgmtEntry *entry = static_cast<AclFlowMgmtEntry *>
124  (acl_flow_mgmt_tree_.Find(&key));
125  if (entry == NULL) {
126  return;
127  }
128  entry->FillAceFlowSandeshInfo(acl, data, ace_id);
129 
130 }
131 
133  AclFlowResp &data,
134  const int last_count) {
135  AclFlowMgmtKey key(acl, NULL);
136  AclFlowMgmtEntry *entry = static_cast<AclFlowMgmtEntry *>
137  (acl_flow_mgmt_tree_.Find(&key));
138  if (entry == NULL) {
139  return;
140  }
141  entry->FillAclFlowSandeshInfo(acl, data, last_count, agent_);
142 }
143 
145 // Utility methods to enqueue events into work-queue
148  // Check if there is a flow-mgmt request already pending
149  // Flow mgmt takes care of current state of flow. So, there is no need to
150  // enqueue duplicate requests
151  FlowMgmtRequest *req = flow->flow_mgmt_request();
152  if (req == NULL) {
154  flow->set_flow_mgmt_request(req);
156  }
157 }
158 
160  const RevFlowDepParams &params) {
161  // Check if there is a flow-mgmt request already pending
162  // Flow mgmt takes care of current state of flow. So, there is no need to
163  // enqueue duplicate requests
164  FlowMgmtRequest *req = flow->flow_mgmt_request();
165  if (req == NULL) {
167  flow->set_flow_mgmt_request(req);
169  }
170 
171  req->set_params(params);
172 }
173 
175  uint32_t packets,
176  uint32_t oflow_bytes,
177  const boost::uuids::uuid &u) {
178  if (bytes == 0 && packets == 0 && oflow_bytes == 0) {
179  return;
180  }
181 
182  /* Ignore StatsUpdate request in TSN mode as we don't export flows */
183  if (agent_->tsn_enabled()) {
184  return;
185  }
188  bytes, packets, oflow_bytes, u));
189  request_queue_.Enqueue(req);
190 }
191 
195  request_queue_.Enqueue(req);
196 }
197 
200  request_queue_.Enqueue(req);
201 }
202 
203 void FlowMgmtManager::AddDBEntryEvent(const DBEntry *entry, uint32_t gen_id) {
205  entry, gen_id));
207 }
208 
210  uint32_t gen_id) {
212  entry, gen_id));
214 }
215 
217  uint32_t gen_id) {
219  entry, gen_id));
221 }
222 
224  uint32_t gen_id) {
227  entry, gen_id));
229 }
230 
233 }
234 
236  FlowEntry *flow) {
237  FlowEvent *flow_resp = new FlowEvent(event, flow->key(), true,
239  flow_resp->set_flow(flow);
240  EnqueueFlowEvent(flow_resp);
241 }
242 
244  FlowEntry *flow) {
245  FlowEvent *flow_resp = new FlowEvent(event, NULL, key->db_entry());
246  key->KeyToFlowRequest(flow_resp);
247  flow_resp->set_flow(flow);
248  EnqueueFlowEvent(flow_resp);
249 }
250 
252  uint32_t gen_id) {
253  FlowEvent *flow_resp = new FlowEvent(event, table_index_, key->db_entry(),
254  gen_id);
255  EnqueueFlowEvent(flow_resp);
256 }
257 
259  request_queue_.set_disable(disabled);
260  db_event_queue_.set_disable(disabled);
261 }
262 
264  return request_queue_.Length();
265 }
266 
268  return db_event_queue_.Length();
269 }
271 // Handlers for events from the work-queue
274  FlowMgmtTree *tree) {
275  InetRouteFlowMgmtTree* itree = dynamic_cast<InetRouteFlowMgmtTree*>(tree);
276  switch (req->event()) {
278  tree->OperEntryAdd(req, key);
279  break;
280 
282  tree->OperEntryChange(req, key);
283  break;
284 
287  tree->OperEntryDelete(req, key);
288  break;
289 
291  assert(itree);
292  itree->RouteNHChangeEvent(req, key);
293  break;
294 
295  default:
296  assert(0);
297  break;
298  }
299 
300  return true;
301 }
302 
304  const DBEntry *entry) {
305  const Interface *intf = dynamic_cast<const Interface *>(entry);
306  if (intf) {
307  InterfaceFlowMgmtKey key(intf);
308  return ProcessEvent(req, &key, &interface_flow_mgmt_tree_);
309  }
310 
311  const VnEntry *vn = dynamic_cast<const VnEntry *>(entry);
312  if (vn) {
313  VnFlowMgmtKey key(vn);
314  return ProcessEvent(req, &key, &vn_flow_mgmt_tree_);
315  }
316 
317  const AclDBEntry *acl = dynamic_cast<const AclDBEntry *>(entry);
318  if (acl) {
319  AclFlowMgmtKey key(acl, NULL);
320  return ProcessEvent(req, &key, &acl_flow_mgmt_tree_);
321  }
322 
323  const NextHop *nh = dynamic_cast<const NextHop *>(entry);
324  if (nh) {
325  NhFlowMgmtKey key(static_cast<const NextHop *>(req->db_entry()));
326  return ProcessEvent(req, &key, &nh_flow_mgmt_tree_);
327  }
328 
329  const InetUnicastRouteEntry *inet_uc_rt =
330  dynamic_cast<const InetUnicastRouteEntry *>(entry);
331  if (inet_uc_rt) {
332  InetRouteFlowMgmtKey key(inet_uc_rt);
333  if (inet_uc_rt->prefix_address().is_v4()) {
334  return ProcessEvent(req, &key, &ip4_route_flow_mgmt_tree_);
335  }
336  if (inet_uc_rt->prefix_address().is_v6()) {
337  return ProcessEvent(req, &key, &ip6_route_flow_mgmt_tree_);
338  }
339  }
340 
341  const BridgeRouteEntry *bridge =
342  dynamic_cast<const BridgeRouteEntry *>(entry);
343  if (bridge) {
344  BridgeRouteFlowMgmtKey key(bridge);
345  return ProcessEvent(req, &key, &bridge_route_flow_mgmt_tree_);
346  }
347 
348  const VrfEntry *vrf = dynamic_cast<const VrfEntry *>(entry);
349  if (vrf) {
350  VrfFlowMgmtKey key(vrf);
351  return ProcessEvent(req, &key, &vrf_flow_mgmt_tree_);
352  }
353 
354  assert(0);
355  return true;
356 }
357 
358 bool
360 
361  BgpAsAServiceFlowMgmtRequest *bgp_as_a_service_request =
362  dynamic_cast<BgpAsAServiceFlowMgmtRequest *>(req);
363  if (bgp_as_a_service_request->type() == BgpAsAServiceFlowMgmtRequest::VMI) {
364  //Delete it for for all CN trees
365  for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
366  BgpAsAServiceFlowMgmtKey key(bgp_as_a_service_request->vm_uuid(),
367  bgp_as_a_service_request->source_port(),
368  count, NULL, NULL);
369  bgp_as_a_service_flow_mgmt_tree_[count].get()->
370  BgpAsAServiceDelete(key, req);
371  }
372  } else if (bgp_as_a_service_request->type() ==
374  bgp_as_a_service_flow_mgmt_tree_[bgp_as_a_service_request->index()].get()->
375  DeleteAll();
376  } else if (bgp_as_a_service_request->type() ==
378  bgp_as_a_service_request->type() ==
380  // Health check added to BGPaaS, check if any flows are impacted
381  for (uint8_t count = 0; count < MAX_XMPP_SERVERS; count++) {
382  BgpAsAServiceFlowMgmtKey key(bgp_as_a_service_request->vm_uuid(),
383  bgp_as_a_service_request->source_port(),
384  count, NULL, NULL);
385  bgp_as_a_service_flow_mgmt_tree_[count].get()->
386  BgpAsAServiceHealthCheckUpdate(agent(), key, bgp_as_a_service_request);
387  }
388  }
389 
390  return true;
391 }
392 
394  switch (req->event()) {
396  FlowEntry *flow = req->flow().get();
397  // Before processing event, set the request pointer in flow to
398  // NULL. This ensures flow-entry enqueues new request from now
399  // onwards
400  tbb::mutex::scoped_lock mutex(flow->mutex());
401  flow->set_flow_mgmt_request(NULL);
402 
403  // Update flow-mgmt information based on flow-state
404  if (flow->deleted() == false) {
407  req->flow().get()));
408  log_queue_->Enqueue(log_req);
409 
410  //Enqueue Add request to flow-stats-collector
411  agent_->flow_stats_manager()->AddEvent(req->flow());
412 
413  //Enqueue Add request to UVE module for ACE stats
414  EnqueueUveAddEvent(flow);
415 
416  AddFlow(req->flow());
417 
418  } else {
421  req->flow().get(), req->params()));
422  log_queue_->Enqueue(log_req);
423 
424  //Enqueue Delete request to flow-stats-collector
425  agent_->flow_stats_manager()->DeleteEvent(flow, req->params());
426 
427  //Enqueue Delete request to UVE module for ACE stats
428  EnqueueUveDeleteEvent(flow);
429 
430  DeleteFlow(req->flow(), req->params());
431  }
432  break;
433  }
434 
436  //Handle Flow stats update for flow-mgmt
437  UpdateFlowStats(req->flow(), req->bytes(), req->packets(),
438  req->oflow_bytes(), req->flow_uuid());
439  break;
440  }
441 
443  RetryVrfDelete(req->vrf_id());
444  break;
445  }
446 
448  BgpAsAServiceRequestHandler(req.get());
449  break;
450  }
451 
453  break;
454 
455  default:
456  assert(0);
457 
458  }
459 
460  return true;
461 }
462 
464  switch (req->event()) {
469  DBRequestHandler(req.get(), req->db_entry());
470  break;
471  }
472 
473  default:
474  assert(0);
475 
476  }
477 
478  return true;
479 }
480 
482  FlowEntry *flow = req->flow().get();
483  FlowEntry *rflow = flow->reverse_flow_entry();
484 
485  FLOW_LOCK(flow, rflow, FlowEvent::FLOW_MESSAGE);
486  switch (req->event()) {
488  LogFlowUnlocked(flow, "ADD");
489  break;
490  }
491 
493  LogFlowUnlocked(flow, "DEL");
494  break;
495  }
496 
497  default:
498  assert(0);
499 
500  }
501 
502  return true;
503 }
504 
505 void FlowMgmtManager::RetryVrfDelete(uint32_t vrf_id) {
507 }
508 
509 // Extract all the FlowMgmtKey for a flow
510 void FlowMgmtManager::LogFlowUnlocked(FlowEntry *flow, const std::string &op) {
511  if (flow->trace() == false)
512  return;
513  FlowInfo trace;
514  flow->FillFlowInfo(trace);
515  FLOW_TRACE(Trace, op, trace);
516 }
517 
518 // Extract all the FlowMgmtKey for a flow
520  FlowMgmtKeyTree *tree) {
521  acl_flow_mgmt_tree_.ExtractKeys(flow, tree);
523  vn_flow_mgmt_tree_.ExtractKeys(flow, tree);
527  nh_flow_mgmt_tree_.ExtractKeys(flow, tree);
529  int cn_index = BgpAsAServiceFlowMgmtTree::GetCNIndex(flow);
531  bgp_as_a_service_flow_mgmt_tree_[cn_index].get()->
532  ExtractKeys(flow, tree);
533  }
534  }
535 }
536 
538  AgentUveStats *uve = dynamic_cast<AgentUveStats *>(agent_->uve());
539  if (uve) {
540  const Interface *itf = flow->intf_entry();
541  const VmInterface *vmi = dynamic_cast<const VmInterface *>(itf);
542  const VnEntry *vn = flow->vn_entry();
543  string vn_name = vn? vn->GetName() : "";
544  string itf_name = vmi? vmi->cfg_name() : "";
545  FlowUveVnAcePolicyInfo vn_ace_info;
546  FlowUveFwPolicyInfo fw_policy_info;
547 
548  flow->FillUveVnAceInfo(&vn_ace_info);
549  if (!itf_name.empty()) {
550  flow->FillUveFwStatsInfo(&fw_policy_info, true);
551  }
552  boost::shared_ptr<FlowUveStatsRequest> req(new FlowUveStatsRequest
553  (FlowUveStatsRequest::ADD_FLOW, flow->uuid(), itf_name,
554  flow->sg_rule_uuid(), vn_ace_info, fw_policy_info));
555 
556  if (!req->sg_info_valid() && !req->vn_ace_valid() &&
557  !req->fw_policy_valid()) {
558  return;
559  }
560 
561  uve->stats_manager()->EnqueueEvent(req);
562  }
563 }
564 
566  AgentUveStats *uve = dynamic_cast<AgentUveStats *>(agent_->uve());
567  if (uve) {
568  const Interface *itf = flow->intf_entry();
569  const VmInterface *vmi = dynamic_cast<const VmInterface *>(itf);
570  string itf_name = vmi? vmi->cfg_name() : "";
571  FlowUveFwPolicyInfo fw_policy_info;
572  if (!itf_name.empty()) {
573  flow->FillUveFwStatsInfo(&fw_policy_info, false);
574  }
575  boost::shared_ptr<FlowUveStatsRequest> req(new FlowUveStatsRequest
576  (FlowUveStatsRequest::DELETE_FLOW, flow->uuid(), itf_name,
577  fw_policy_info));
578  uve->stats_manager()->EnqueueEvent(req);
579  }
580 }
581 
583  FlowMgmtKeyTree new_tree;
584  MakeFlowMgmtKeyTree(flow.get(), &new_tree);
585 
586  // Get old FlowMgmtKeyTree
587  FlowEntryInfo *old_info = LocateFlowEntryInfo(flow);
588  FlowMgmtKeyTree *old_tree = &old_info->tree_;
589  assert(old_tree);
590  old_info->count_++;
591 
592  // Apply the difference in old and new key tree
593  FlowMgmtKeyTree::iterator new_it = new_tree.begin();
594  FlowMgmtKeyTree::iterator old_it = old_tree->begin();
595 
596  while (new_it != new_tree.end() && old_it != old_tree->end()) {
597  FlowMgmtKey *new_key = new_it->first;
598  FlowMgmtKey *old_key = old_it->first;
599  if (new_key->IsLess(old_key)) {
600  AddFlowMgmtKey(flow.get(), old_info, new_key, NULL);
601  new_it++;
602  } else if (old_key->IsLess(new_key)) {
603  FlowMgmtKeyNode *node = old_it->second;
604  DeleteFlowMgmtKey(flow.get(), old_info, old_key,
605  node);
606  FlowMgmtKeyTree::iterator tmp = old_it++;
607  FlowMgmtKey *key = tmp->first;
608  old_tree->erase(tmp);
609  delete key;
610  delete node;
611  } else {
612  AddFlowMgmtKey(flow.get(), old_info, new_key, old_key);
613  old_it++;
614  new_it++;
615  }
616  }
617 
618  while (new_it != new_tree.end()) {
619  FlowMgmtKey *new_key = new_it->first;
620  AddFlowMgmtKey(flow.get(), old_info, new_key, NULL);
621  new_it++;
622  }
623 
624  while (old_it != old_tree->end()) {
625  FlowMgmtKey *old_key = old_it->first;
626  FlowMgmtKeyNode *node = old_it->second;
627  DeleteFlowMgmtKey(flow.get(), old_info, old_key, node);
628  FlowMgmtKeyTree::iterator tmp = old_it++;
629  FlowMgmtKey *key = tmp->first;
630  old_tree->erase(tmp);
631  delete key;
632  delete node;
633  }
634 
635  new_it = new_tree.begin();
636  while (new_it != new_tree.end()) {
637  FlowMgmtKeyTree::iterator tmp = new_it++;
638  FlowMgmtKey *key = tmp->first;
639  FlowMgmtKeyNode *node = tmp->second;
640  new_tree.erase(tmp);
641  delete key;
642  delete node;
643  }
644 }
645 
647  const RevFlowDepParams &params) {
648  // Delete entries for flow from the tree
649  FlowEntryInfo *old_info = FindFlowEntryInfo(flow);
650  if (old_info == NULL)
651  return;
652 
653  FlowMgmtKeyTree *old_tree = &old_info->tree_;
654  assert(old_tree);
655  old_info->count_++;
656 
657  FlowMgmtKeyTree::iterator old_it = old_tree->begin();
658  while (old_it != old_tree->end()) {
659  FlowMgmtKeyNode *node = old_it->second;
660  DeleteFlowMgmtKey(flow.get(), old_info, old_it->first, node);
661  FlowMgmtKeyTree::iterator tmp = old_it++;
662  FlowMgmtKey *key = tmp->first;
663  old_tree->erase(tmp);
664  delete key;
665  delete node;
666  }
667 
668  assert(old_tree->size() == 0);
669  DeleteFlowEntryInfo(flow);
670 }
671 
673  uint32_t packets, uint32_t oflow_bytes,
674  const boost::uuids::uuid &u) {
675  //Enqueue Flow Index Update Event request to flow-stats-collector
676  agent_->flow_stats_manager()->UpdateStatsEvent(flow, bytes, packets,
677  oflow_bytes, u);
678 }
679 
680 bool FlowMgmtManager::HasVrfFlows(uint32_t vrf_id) {
682  return true;
683  }
684 
686  return true;
687  }
688 
690  return true;
691  }
692 
693  return false;
694 }
695 
696 void FlowMgmtManager::VnFlowCounters(const VnEntry *vn, uint32_t *ingress_flow_count,
697  uint32_t *egress_flow_count) {
698  vn_flow_mgmt_tree_.VnFlowCounters(vn, ingress_flow_count,
699  egress_flow_count);
700 }
701 
703  uint64_t *created, uint64_t *aged,
704  uint32_t *active_flows) {
706  active_flows);
707 }
708 
711  return flow->flow_mgmt_info();
712 }
713 
716  FlowEntryInfo *info = FindFlowEntryInfo(flow);
717  if (info != NULL)
718  return info;
719  info = new FlowEntryInfo(flow.get());
720  flow->set_flow_mgmt_info(info);
721  return info;
722 }
723 
727  FlowEntryInfo *flow_info = FindFlowEntryInfo(flow);
728  if (flow_info == NULL)
729  return NULL;
730 
731  FlowMgmtKeyTree::iterator key_it = flow_info->tree_.find(&key);
732  if (key_it == flow_info->tree().end())
733  return NULL;
734 
736  static_cast<BgpAsAServiceFlowMgmtKey *>(key_it->first);
737  return bkey;
738 }
739 
741  FlowEntryInfo *info = flow->flow_mgmt_info();
742  if (info == NULL)
743  return;
744 
745  assert(info->tree_.size() == 0);
746  flow->set_flow_mgmt_info(NULL);
747  return;
748 }
749 
751 // Routines to add/delete Flow and FlowMgmtKey in different trees
753 
754 // Add a FlowMgmtKey into FlowMgmtKeyTree for an object
755 // The FlowMgmtKeyTree for object is passed as argument
757  FlowMgmtKey *key, FlowMgmtKey *old_key) {
758  FlowMgmtKey *tmp = key->Clone();
759  FlowMgmtKeyNode *node = new FlowMgmtKeyNode(flow);
760 
761  std::pair<FlowMgmtKeyTree::iterator, bool> ret = info->tree_.insert(
762  make_pair(tmp, node));
763  if (ret.second == false) {
764  delete tmp;
765  delete node;
766  if (key->type() == FlowMgmtKey::ACL) {
767  /* Copy the ACE Id list to existing key from new Key */
768  FlowMgmtKey *existing_key = ret.first->first;
769  AclFlowMgmtKey *akey = static_cast<AclFlowMgmtKey *>(existing_key);
770  AclFlowMgmtKey *new_key = static_cast<AclFlowMgmtKey *>(key);
771  akey->set_ace_id_list(new_key->ace_id_list());
772  }
773  }
774 
775  switch (key->type()) {
777  interface_flow_mgmt_tree_.Add(key, flow,
778  (ret.second)? node : NULL);
779  break;
780 
781  case FlowMgmtKey::ACL:
782  acl_flow_mgmt_tree_.Add(key, flow, old_key,
783  (ret.second)? node : NULL);
784  break;
785 
786  case FlowMgmtKey::VN: {
787  bool new_flow = vn_flow_mgmt_tree_.Add(key, flow,
788  (ret.second)? node : NULL);
789  VnFlowMgmtEntry *entry = static_cast<VnFlowMgmtEntry *>
790  (vn_flow_mgmt_tree_.Find(key));
791  entry->UpdateCounterOnAdd(flow, new_flow, info->local_flow_,
792  info->ingress_);
795  break;
796  }
797 
798  case FlowMgmtKey::INET4:
799  ip4_route_flow_mgmt_tree_.Add(key, flow,
800  (ret.second)? node : NULL);
801  break;
802 
803  case FlowMgmtKey::INET6:
804  ip6_route_flow_mgmt_tree_.Add(key, flow,
805  (ret.second)? node : NULL);
806  break;
807 
808  case FlowMgmtKey::BRIDGE:
810  (ret.second)? node : NULL);
811  break;
812 
813  case FlowMgmtKey::NH:
814  nh_flow_mgmt_tree_.Add(key, flow,
815  (ret.second)? node : NULL);
816  break;
817 
819  BgpAsAServiceFlowMgmtKey *bgp_service_key =
820  static_cast<BgpAsAServiceFlowMgmtKey *>(key);
821  int cn_index = bgp_service_key->cn_index();
823  bgp_as_a_service_flow_mgmt_tree_[cn_index].get()->Add(key, flow,
824  (ret.second)? node : NULL);
825  boost::uuids::uuid hc_uuid;
826  if (agent()->oper_db()->bgp_as_a_service()->GetBgpHealthCheck(
827  static_cast<const VmInterface *>(flow->intf_entry()), &hc_uuid)) {
828  FlowMgmtKey *inserted_key = ret.first->first;
830  static_cast<BgpAsAServiceFlowMgmtKey *>(inserted_key);
831  bkey->StartHealthCheck(agent(), flow, hc_uuid);
832  }
833  }
834  break;
835  }
836 
837  default:
838  assert(0);
839  }
840 }
841 
842 // Delete a FlowMgmtKey from FlowMgmtKeyTree for an object
843 // The FlowMgmtKeyTree for object is passed as argument
845  FlowEntry *flow, FlowEntryInfo *info, FlowMgmtKey *key,
846  FlowMgmtKeyNode *node) {
847 
848  FlowMgmtKeyTree::iterator it = info->tree_.find(key);
849  assert(it != info->tree_.end());
850 
851  switch (key->type()) {
853  interface_flow_mgmt_tree_.Delete(key, flow, node);
854  break;
855 
856  case FlowMgmtKey::ACL:
857  acl_flow_mgmt_tree_.Delete(key, flow, node);
858  break;
859 
860  case FlowMgmtKey::VN: {
861  vn_flow_mgmt_tree_.Delete(key, flow, node);
862  VnFlowMgmtEntry *entry = static_cast<VnFlowMgmtEntry *>
863  (vn_flow_mgmt_tree_.Find(key));
864  if (entry)
865  entry->UpdateCounterOnDel(flow, info->local_flow_, info->ingress_);
868  break;
869  }
870 
871  case FlowMgmtKey::INET4:
872  ip4_route_flow_mgmt_tree_.Delete(key, flow, node);
873  break;
874 
875  case FlowMgmtKey::INET6:
876  ip6_route_flow_mgmt_tree_.Delete(key, flow, node);
877  break;
878 
879  case FlowMgmtKey::BRIDGE:
880  bridge_route_flow_mgmt_tree_.Delete(key, flow, node);
881  break;
882 
883  case FlowMgmtKey::NH:
884  nh_flow_mgmt_tree_.Delete(key, flow, node);
885  break;
886 
889  static_cast<BgpAsAServiceFlowMgmtKey *>(it->first);
890  bkey->StopHealthCheck(flow);
891  BgpAsAServiceFlowMgmtKey *bgp_service_key =
892  static_cast<BgpAsAServiceFlowMgmtKey *>(key);
893  uint8_t count = bgp_service_key->cn_index();
894  bgp_as_a_service_flow_mgmt_tree_[count].get()->Delete(key, flow, node);
895  break;
896  }
897 
898  default:
899  assert(0);
900  }
901 }
bool MeasureQueueDelay()
Definition: agent.cc:1136
StatsManager * stats_manager() const
virtual bool OperEntryDelete(const FlowMgmtRequest *req, FlowMgmtKey *key)
void UpdateFlowStats(FlowEntryPtr &flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
Definition: flow_mgmt.cc:672
void SetBounded(bool bounded)
Definition: queue_task.h:200
const DBEntry * db_entry() const
void DeleteDBEntryEvent(const DBEntry *entry, uint32_t gen_id)
Definition: flow_mgmt.cc:216
FlowMgmtKeyTree tree_
static void LogFlowUnlocked(FlowEntry *flow, const std::string &op)
Definition: flow_mgmt.cc:510
void AddFlow(FlowEntryPtr &flow)
Definition: flow_mgmt.cc:582
bool tsn_enabled() const
Definition: agent.h:1162
void EnqueueUveAddEvent(const FlowEntry *flow) const
Definition: flow_mgmt.cc:537
Definition: vrf.h:86
FlowStatsManager * flow_stats_manager() const
Definition: agent.cc:925
bool DBRequestHandler(FlowMgmtRequestPtr req)
Definition: flow_mgmt.cc:463
void VnFlowCounters(const VnEntry *vn, uint32_t *ingress_flow_count, uint32_t *egress_flow_count)
static bool LogHandler(FlowMgmtRequestPtr req)
Definition: flow_mgmt.cc:481
void Shutdown(bool delete_entries=true)
Definition: queue_task.h:152
WorkQueue< FlowMgmtRequestPtr > FlowMgmtQueue
Definition: flow_mgmt.h:241
VnFlowMgmtTree vn_flow_mgmt_tree_
Definition: flow_mgmt.h:363
const DBEntry * db_entry() const
Definition: flow_mgmt_key.h:65
FlowMgmtEntry * Find(FlowMgmtKey *key)
Type type() const
Definition: flow_mgmt_key.h:64
size_t FlowDBQueueLength()
Definition: flow_mgmt.cc:267
AgentUveBase * uve() const
Definition: agent.cc:909
static const uint32_t kPortNatFlowTableInstance
Definition: flow_table.h:154
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree, uint32_t vrf, const IpAddress &ip, uint8_t plen)
Agent * agent_
Definition: flow_mgmt.h:359
void FreeDBEntryEvent(FlowEvent::Event event, FlowMgmtKey *key, uint32_t gen_id)
Definition: flow_mgmt.cc:251
FlowMgmtQueue db_event_queue_
Definition: flow_mgmt.h:372
void RegisterHealthCheckCb(HealthCheckCb callback)
virtual bool Delete(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKeyNode *node)
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree)
void set_flow_mgmt_request(FlowMgmtRequest *req)
Definition: flow_entry.h:756
void DeleteFlowEntryInfo(FlowEntryPtr &flow)
Definition: flow_mgmt.cc:740
static int GetCNIndex(const FlowEntry *flow)
static bool ProcessEvent(FlowMgmtRequest *req, FlowMgmtKey *key, FlowMgmtTree *tree)
Definition: flow_mgmt.cc:273
bool Add(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKey *old_key, FlowMgmtKeyNode *node)
BgpAsAServiceFlowMgmtKey * FindBgpAsAServiceInfo(FlowEntry *flow, BgpAsAServiceFlowMgmtKey &key)
Definition: flow_mgmt.cc:725
#define FLOW_LOCK(flow, rflow, flow_event)
Definition: flow_table.h:61
boost::uuids::uuid uuid
void NonOperEntryEvent(FlowEvent::Event event, FlowEntry *flow)
Definition: flow_mgmt.cc:235
void UpdateCounterOnDel(FlowEntry *flow, bool local_flow, bool old_ingress)
#define kTaskFlowMgmt
Definition: agent.h:325
virtual bool Delete(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKeyNode *node)
void FillUveFwStatsInfo(FlowUveFwPolicyInfo *info, bool added) const
Definition: flow_entry.cc:3602
void DeleteFlowMgmtKey(FlowEntry *flow, FlowEntryInfo *info, FlowMgmtKey *key, FlowMgmtKeyNode *node)
Definition: flow_mgmt.cc:844
boost::shared_ptr< FlowMgmtRequest > FlowMgmtRequestPtr
Definition: flow_mgmt.h:240
void ChangeDBEntryEvent(const DBEntry *entry, uint32_t gen_id)
Definition: flow_mgmt.cc:209
void EnqueueFlowEvent(FlowEvent *event)
Definition: flow_mgmt.cc:231
void AddEvent(FlowEntry *low)
Definition: flow_mgmt.cc:147
void RetryVrfDeleteEvent(const VrfEntry *vrf)
Definition: flow_mgmt.cc:192
void RegisterControllerChangeCallback(XmppChannelDownCb xmpp_channel_down_cb)
void ControllerNotify(uint8_t index)
Definition: flow_mgmt.cc:111
bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type)
void Shutdown()
Definition: flow_mgmt.cc:69
virtual void KeyToFlowRequest(FlowEvent *req)
Definition: flow_mgmt_key.h:39
static void InitLogQueue(Agent *agent)
Definition: flow_mgmt.cc:75
InterfaceFlowMgmtTree interface_flow_mgmt_tree_
Definition: flow_mgmt.h:362
void RetryDelete(uint32_t vrf_id)
FlowEntryInfo * FindFlowEntryInfo(const FlowEntryPtr &flow)
Definition: flow_mgmt.cc:710
const std::string & sg_rule_uuid() const
Definition: flow_entry.h:633
bool RouteNHChangeEvent(const FlowMgmtRequest *req, FlowMgmtKey *key)
const boost::uuids::uuid & vm_uuid() const
OperDB * oper_db() const
Definition: agent.cc:1013
int GetTaskId(const std::string &name)
Definition: task.cc:856
FlowMgmtRequest * flow_mgmt_request() const
Definition: flow_entry.h:755
virtual bool OperEntryChange(const FlowMgmtRequest *req, FlowMgmtKey *key)
void RouteNHChangeEvent(const DBEntry *entry, uint32_t gen_id)
Definition: flow_mgmt.cc:223
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree)
const AclEntryIDList * ace_id_list() const
Definition: flow_mgmt_key.h:98
void RegisterServiceDeleteCb(ServiceDeleteCb callback)
bool HasVrfFlows(uint32_t vrf_id, Agent::RouteTableType type)
uint16_t table_index_
Definition: flow_mgmt.h:360
const FlowKey & key() const
Definition: flow_entry.h:594
void SetAceSandeshData(const AclDBEntry *acl, AclFlowCountResp &data, const std::string &ace_id)
Definition: flow_mgmt.cc:119
void set_acl_flow_sandesh_data_cb(FlowAclSandeshDataFn fn)
Definition: acl.cc:1580
void SetAclFlowSandeshData(const AclDBEntry *acl, AclFlowResp &data, const int last_count)
Definition: flow_mgmt.cc:132
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
VrfFlowMgmtTree vrf_flow_mgmt_tree_
Definition: flow_mgmt.h:367
void StopHealthCheck(FlowEntry *flow)
FlowEntryInfo * LocateFlowEntryInfo(FlowEntryPtr &flow)
Definition: flow_mgmt.cc:715
bool is_flags_set(const FlowEntryFlags &flags) const
Definition: flow_entry.h:610
TaskScheduler * task_scheduler() const
Definition: agent.h:1120
uint8_t type
Definition: load_balance.h:109
Definition: agent.h:358
size_t Length() const
Definition: queue_task.h:356
const boost::uuids::uuid & uuid() const
Definition: flow_entry.h:631
void FlowUpdateQueueDisable(bool val)
Definition: flow_mgmt.cc:258
void MakeFlowMgmtKeyTree(FlowEntry *flow, FlowMgmtKeyTree *tree)
Definition: flow_mgmt.cc:519
void EnqueueEvent(const boost::shared_ptr< FlowUveStatsRequest > &req)
VNController * controller() const
Definition: agent.cc:981
void BgpAsAServiceNotify(const boost::uuids::uuid &vm_uuid, uint32_t source_port)
Definition: flow_mgmt.cc:92
static const int kInvalidCnIndex
size_t FlowUpdateQueueLength()
Definition: flow_mgmt.cc:263
std::map< FlowMgmtKey *, FlowMgmtKeyNode *, FlowMgmtKeyCmp > FlowMgmtKeyTree
Definition: trace.h:220
BridgeRouteFlowMgmtTree bridge_route_flow_mgmt_tree_
Definition: flow_mgmt.h:366
void AddFlowMgmtKey(FlowEntry *flow, FlowEntryInfo *info, FlowMgmtKey *key, FlowMgmtKey *old_key)
Definition: flow_mgmt.cc:756
void RetryVrfDelete(uint32_t vrf_id)
Definition: flow_mgmt.cc:505
virtual FlowMgmtKey * Clone()=0
static void ShutdownLogQueue()
Definition: flow_mgmt.cc:84
void set_measure_busy_time(bool val) const
Definition: queue_task.h:379
bool HasVrfFlows(uint32_t vrf)
Definition: flow_mgmt.cc:680
void InterfaceFlowCount(const Interface *itf, uint64_t *created, uint64_t *aged, uint32_t *active_flows)
#define FLOW_TRACE(obj,...)
Definition: flow_mgmt.h:377
tbb::mutex & mutex()
Definition: flow_entry.h:650
uint8_t cn_index() const
Agent * agent() const
Definition: flow_mgmt.h:283
void AddEvent(FlowEntryPtr &flow)
FlowMgmtManager(Agent *agent, uint16_t table_index)
Definition: flow_mgmt.cc:21
bool trace() const
Definition: flow_entry.h:752
void BgpAsAServiceHealthCheckNotify(const boost::uuids::uuid &vm_uuid, uint32_t source_port, const boost::uuids::uuid &hc_uuid, bool add)
Definition: flow_mgmt.cc:99
void DeleteEvent(FlowEntry *flow, const RevFlowDepParams &params)
Definition: flow_mgmt.cc:159
void FlowStatsUpdateEvent(FlowEntry *flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
Definition: flow_mgmt.cc:174
void AddDBEntryEvent(const DBEntry *entry, uint32_t gen_id)
Definition: flow_mgmt.cc:203
const FlowMgmtKeyTree & tree() const
void UpdateStatsEvent(const FlowEntryPtr &flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
void DBEntryEvent(FlowEvent::Event event, FlowMgmtKey *key, FlowEntry *flow)
Definition: flow_mgmt.cc:243
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
FlowProto * get_flow_proto() const
Definition: pkt_init.h:43
Definition: vn.h:151
#define MAX_XMPP_SERVERS
Definition: agent.h:291
const Interface * intf_entry() const
Definition: flow_entry.h:652
virtual bool OperEntryAdd(const FlowMgmtRequest *req, FlowMgmtKey *key)
void set_disable(bool disabled)
Definition: queue_task.h:319
bool IsLess(const FlowMgmtKey *rhs) const
Definition: flow_mgmt_key.h:51
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree)
InetRouteFlowMgmtTree ip6_route_flow_mgmt_tree_
Definition: flow_mgmt.h:365
void DeleteEvent(const FlowEntryPtr &flow, const RevFlowDepParams &params)
void UpdateCounterOnAdd(FlowEntry *flow, bool add_flow, bool local_flow, bool old_ingress)
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree, const MatchAclParamsList *acl_list)
virtual bool Add(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKeyNode *node)
bool BgpAsAServiceRequestHandler(FlowMgmtRequest *req)
Definition: flow_mgmt.cc:359
NhFlowMgmtTree nh_flow_mgmt_tree_
Definition: flow_mgmt.h:368
const VnEntry * vn_entry() const
Definition: flow_entry.h:653
Event event() const
void FillAceFlowSandeshInfo(const AclDBEntry *acl, AclFlowCountResp &data, const std::string &ace_id)
const std::string & cfg_name() const
FlowEntry * reverse_flow_entry()
Definition: flow_entry.h:602
void FillAclFlowSandeshInfo(const AclDBEntry *acl, AclFlowResp &data, const int last_count, Agent *agent)
void FillUveVnAceInfo(FlowUveVnAcePolicyInfo *info) const
Definition: flow_entry.cc:3547
#define kTaskFlowLogging
Definition: agent.h:327
void EnqueueFlowEvent(FlowEvent *event)
Definition: flow_proto.cc:307
static FlowMgmtQueue * log_queue_
Definition: flow_mgmt.h:373
void set_params(const RevFlowDepParams &params)
InetRouteFlowMgmtTree ip4_route_flow_mgmt_tree_
Definition: flow_mgmt.h:364
const string & GetName() const
Definition: vn.h:162
std::unique_ptr< FlowMgmtDbClient > flow_mgmt_dbclient_
Definition: flow_mgmt.h:370
bool deleted()
Definition: flow_entry.h:680
void ExtractKeys(FlowEntry *flow, FlowMgmtKeyTree *tree)
void DummyEvent()
Definition: flow_mgmt.cc:198
void DeleteFlow(FlowEntryPtr &flow, const RevFlowDepParams &p)
Definition: flow_mgmt.cc:646
PktModule * pkt() const
Definition: agent.cc:965
void VnFlowCounters(const VnEntry *vn, uint32_t *ingress_flow_count, uint32_t *egress_flow_count)
Definition: flow_mgmt.cc:696
AclTable * acl_table() const
Definition: agent.h:515
void StartHealthCheck(Agent *agent, FlowEntry *flow, const boost::uuids::uuid &hc_uuid)
void InterfaceFlowCount(const Interface *itf, uint64_t *created, uint64_t *aged, uint32_t *active_flows)
Definition: flow_mgmt.cc:702
BgpAsAServiceFlowMgmtRequest::Type type() const
bool Enqueue(QueueEntryT entry)
Definition: queue_task.h:248
void FillFlowInfo(FlowInfo &info) const
Definition: flow_entry.cc:3134
bool Delete(FlowMgmtKey *key, FlowEntry *flow, FlowMgmtKeyNode *node)
void set_name(const std::string &name)
Definition: queue_task.h:307
Definition: acl.h:92
void set_ace_id_list(const AclEntryIDList *list)
bool RequestHandler(FlowMgmtRequestPtr req)
Definition: flow_mgmt.cc:393
boost::scoped_ptr< BgpAsAServiceFlowMgmtTree > bgp_as_a_service_flow_mgmt_tree_[MAX_XMPP_SERVERS]
Definition: flow_mgmt.h:369
FlowMgmtQueue request_queue_
Definition: flow_mgmt.h:371
void set_flow(FlowEntry *flow)
Definition: flow_event.h:149
void set_ace_flow_sandesh_data_cb(FlowAceSandeshDataFn fn)
Definition: acl.cc:1576
AclFlowMgmtTree acl_flow_mgmt_tree_
Definition: flow_mgmt.h:361
void EnqueueUveDeleteEvent(const FlowEntry *flow) const
Definition: flow_mgmt.cc:565
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
Definition: flow_entry.h:125