OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flow_mgmt_entry.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 #include <pkt/flow_event.h>
8 #include <pkt/flow_mgmt.h>
9 
11  if (node) {
12  flow_list_.push_back(*node);
13  return true;
14  }
15  return false;
16 }
17 
19  flow_list_.erase(flow_list_.iterator_to(*node));
20  return flow_list_.size();
21 }
22 
23 // An entry *cannot* be deleted if
24 // - It contains flows
25 // - It has seen ADD but not seen any DELETE
27  assert(oper_state_ != INVALID);
28  if (flow_list_.size())
29  return false;
30 
31  return (oper_state_ != OPER_ADD_SEEN);
32 }
33 
34 // Handle Add/Change event for DBEntry
36  const FlowMgmtRequest *req, FlowMgmtKey *key) {
38  FlowEvent::Event event = req->GetResponseEvent();
39  if (event == FlowEvent::INVALID)
40  return false;
41 
42  FlowList::iterator it = flow_list_.begin();
43  while (it != flow_list_.end()) {
44  FlowMgmtKeyNode *node = &(*it);
45  mgr->DBEntryEvent(event, key, node->flow_entry());
46  it++;
47  }
48 
49  return true;
50 }
51 
53  const FlowMgmtRequest *req,
54  FlowMgmtKey *key) {
55  return OperEntryAdd(mgr, req, key);
56 }
57 
58 // Handle Delete event for DBEntry
60  const FlowMgmtRequest *req,
61  FlowMgmtKey *key) {
63  //If the delete is implicit there is no DB entry
64  //and hence no free notify should be sent, hence
65  //dont update the state to DEL SEEN
67  gen_id_ = req->gen_id();
68  }
69 
70  FlowEvent::Event event = req->GetResponseEvent();
71  if (event == FlowEvent::INVALID)
72  return false;
73 
74  FlowList::iterator it = flow_list_.begin();
75  while (it != flow_list_.end()) {
76  FlowMgmtKeyNode *node = &(*it);
77  mgr->DBEntryEvent(event, key, node->flow_entry());
78  it++;
79  }
80 
81  return true;
82 }
83 
85  const int last_count) const {
86  string uuid_str = UuidToString(acl->GetUuid());
87  std::stringstream ss;
88  ss << uuid_str << ":";
89  ss << last_count;
90  return ss.str();
91 }
92 
94  const std::string &ace_id) {
95  string uuid_str = UuidToString(acl->GetUuid());
96  std::stringstream ss;
97  ss << uuid_str << ":";
98  ss << ace_id;
99  return ss.str();
100 }
101 
103  AclFlowCountResp &data,
104  const std::string& ace_id) {
105  int count = 0;
106  bool key_set = false;
107  AceIdFlowCntMap::iterator aceid_it = aceid_cnt_map_.upper_bound(ace_id);
108  std::vector<AceIdFlowCnt> id_cnt_l;
109  while (aceid_it != aceid_cnt_map_.end()) {
110  AceIdFlowCnt id_cnt_s;
111  id_cnt_s.ace_id = aceid_it->first;
112  id_cnt_s.flow_cnt = aceid_it->second;
113  id_cnt_l.push_back(id_cnt_s);
114  count++;
115  ++aceid_it;
116  if (count == MaxResponses && aceid_it != aceid_cnt_map_.end()) {
117  data.set_iteration_key(GetAceSandeshDataKey(acl, id_cnt_s.ace_id));
118  key_set = true;
119  break;
120  }
121  }
122  data.set_aceid_cnt_list(id_cnt_l);
123 
124  data.set_flow_count(Size());
125  data.set_flow_miss(flow_miss_);
126 
127  if (!key_set) {
128  data.set_iteration_key(GetAceSandeshDataKey(acl, Agent::NullString()));
129  }
130 }
131 
133  AclFlowResp &data,
134  const int last_count,
135  Agent *agent) {
136  int count = 0;
137  bool key_set = false;
138  FlowList::iterator fe_tree_it = flow_list_.begin();
139  while (fe_tree_it != flow_list_.end() && (count + 1) < last_count) {
140  fe_tree_it++;
141  count++;
142  }
143  data.set_flow_count(Size());
144  data.set_flow_miss(flow_miss_);
145  std::vector<FlowSandeshData> flow_entries_l;
146  while(fe_tree_it != flow_list_.end()) {
147  FlowMgmtKeyNode *node = &(*fe_tree_it);
148  const FlowEntry *fe = node->flow_entry();
149  FlowSandeshData fe_sandesh_data;
150  fe->SetAclFlowSandeshData(acl, fe_sandesh_data, agent);
151 
152  flow_entries_l.push_back(fe_sandesh_data);
153  count++;
154  ++fe_tree_it;
155  if (count == (MaxResponses + last_count) &&
156  fe_tree_it != flow_list_.end()) {
157  data.set_iteration_key(GetAclFlowSandeshDataKey(acl, count));
158  key_set = true;
159  break;
160  }
161  }
162  data.set_flow_entries(flow_entries_l);
163  if (!key_set) {
164  data.set_iteration_key(GetAclFlowSandeshDataKey(acl, 0));
165  }
166 }
167 
169  AclEntryIDList::const_iterator id_it;
170  for (id_it = id_list->begin(); id_it != id_list->end(); ++id_it) {
171  aceid_cnt_map_[id_it->id_] -= 1;
172  }
173 }
174 
175 bool AclFlowMgmtEntry::Add(const AclEntryIDList *id_list, FlowEntry *flow,
176  const AclEntryIDList *old_id_list,
177  FlowMgmtKeyNode *node) {
178  if (old_id_list) {
179  DecrementAceIdCountMap(old_id_list);
180  }
181  if (id_list->size()) {
182  AclEntryIDList::const_iterator id_it;
183  for (id_it = id_list->begin(); id_it != id_list->end(); ++id_it) {
184  aceid_cnt_map_[id_it->id_] += 1;
185  }
186  } else {
187  flow_miss_++;
188  }
189  return FlowMgmtEntry::Add(flow, node);
190 }
191 
193  FlowMgmtKeyNode *node) {
194  if (id_list->size()) {
195  DecrementAceIdCountMap(id_list);
196  }
197  return FlowMgmtEntry::Delete(flow, node);
198 }
199 
201  const FlowMgmtRequest *req,
202  FlowMgmtKey *key) {
204  gen_id_ = req->gen_id();
205  FlowEvent::Event event = req->GetResponseEvent();
206  if (event == FlowEvent::INVALID)
207  return false;
208 
209  FlowList::iterator it = flow_list_.begin();
210  while (it != flow_list_.end()) {
211  FlowMgmtKeyNode *node = &(*it);
212  mgr->NonOperEntryEvent(event, node->flow_entry());
213  it++;
214  }
215  return true;
216 }
217 
218 // Update health check on all the BgpAsAService flows
220  Agent *agent, FlowMgmtManager *mgr,
223  for (FlowList::iterator it = flow_list_.begin();
224  it != flow_list_.end(); ++it) {
225  FlowMgmtKeyNode *node = &(*it);
227  mgr->FindBgpAsAServiceInfo(node->flow_entry(), key);
228  if (bkey == NULL)
229  continue;
230 
232  bkey->StartHealthCheck(agent, node->flow_entry(),
233  req->health_check_uuid());
234  else
235  bkey->StopHealthCheck(node->flow_entry());
236  }
237  return true;
238 }
239 
241  bool local_flow, bool old_ingress) {
242  if (add_flow) {
243  if (flow->is_flags_set(FlowEntry::LocalFlow)) {
246  } else if (flow->is_flags_set(FlowEntry::IngressDir)) {
248  } else {
250  }
251 
252  return;
253  }
254 
255  if (local_flow)
256  return;
257 
258  bool new_ingress = flow->is_flags_set(FlowEntry::IngressDir);
259  if (new_ingress != old_ingress) {
260  if (new_ingress) {
263  } else {
266  }
267  }
268 }
269 
270 void VnFlowMgmtEntry::UpdateCounterOnDel(FlowEntry *flow, bool local_flow,
271  bool old_ingress) {
272  if (local_flow) {
275  return;
276  }
277 
278  if (old_ingress) {
280  } else {
282  }
283 }
284 
286  bool added = FlowMgmtEntry::Add(flow, node);
287  if (added) {
288  flow_created_++;
289  }
290  return added;
291 }
292 
294  flow_aged_++;
295  return FlowMgmtEntry::Delete(flow, node);
296 }
297 
299 (FlowMgmtManager *mgr, InetRouteFlowMgmtKey *covering_route,
300  InetRouteFlowMgmtKey *key){
301  FlowList::iterator it = flow_list_.begin();
302  while (it != flow_list_.end()) {
303  FlowMgmtKeyNode *node = &(*it);
304  // Queue the DB Event only route key matches src or dst ip matches.
305  if (key->NeedsReCompute(node->flow_entry())) {
306  mgr->DBEntryEvent(FlowEvent::RECOMPUTE_FLOW, covering_route,
307  node->flow_entry());
308  }
309  it++;
310  }
311 
312  return true;
313 }
314 
316  const FlowMgmtRequest *req,
317  FlowMgmtKey *key) {
318  assert(req->event() == FlowMgmtRequest::DELETE_LAYER2_FLOW);
319 
320  FlowList::iterator it = flow_list_.begin();
321  while (it != flow_list_.end()) {
322  FlowEvent::Event event;
323  FlowMgmtKeyNode *node = &(*it);
324  it++;
325  FlowEntry *fe = node->flow_entry();
326  if (fe->l3_flow()) {
328  } else {
329  event = FlowEvent::DELETE_FLOW;
330  }
331 
332  mgr->DBEntryEvent(event, key, fe);
333  }
334 
335  return true;
336 }
337 
339  const VrfEntry *vrf) :
340  vrf_(vrf), vrf_id_(vrf->vrf_id()),
341  inet4_(this, vrf, vrf->GetRouteTable(Agent::INET4_UNICAST)),
342  inet6_(this, vrf, vrf->GetRouteTable(Agent::INET6_UNICAST)),
343  bridge_(this, vrf, vrf->GetRouteTable(Agent::BRIDGE)),
344  vrf_tree_(vrf_tree) {
345 }
346 
348  if (FlowMgmtEntry::CanDelete() == false)
349  return false;
350 
351  if (inet4_.deleted() == false || inet6_.deleted() == false ||
352  bridge_.deleted() == false) {
353  return false;
354  }
355 
356  return (vrf_tree_->mgr()->HasVrfFlows(vrf_id_) == false);
357 }
358 
360  const VrfEntry *vrf, AgentRouteTable *table) :
361  deleted_(false), table_ref_(this, NULL),
362  vrf_mgmt_entry_(vrf_mgmt_entry), vrf_(vrf) {
363  if (vrf->IsDeleted() == false) {
364  table_ref_.Reset(table->deleter());
365  } else {
366  deleted_ = true;
367  }
368 }
369 
371  table_ref_.Reset(NULL);
372 }
373 
375  deleted_ = true;
376  vrf_mgmt_entry_->vrf_tree()->mgr()->RetryVrfDeleteEvent(vrf_);
377 }
uint32_t egress_flow_count_
virtual bool OperEntryChange(FlowMgmtManager *mgr, const FlowMgmtRequest *req, FlowMgmtKey *key)
Data(VrfFlowMgmtEntry *vrf_mgmt_entry, const VrfEntry *vrf, AgentRouteTable *table)
virtual bool OperEntryDelete(FlowMgmtManager *mgr, const FlowMgmtRequest *req, FlowMgmtKey *key)
bool HandleNhChange(FlowMgmtManager *mgr, const FlowMgmtRequest *req, FlowMgmtKey *key)
Definition: vrf.h:86
virtual bool HealthCheckUpdate(Agent *agent, FlowMgmtManager *mgr, BgpAsAServiceFlowMgmtKey &key, BgpAsAServiceFlowMgmtRequest *req)
virtual bool OperEntryAdd(FlowMgmtManager *mgr, const FlowMgmtRequest *req, FlowMgmtKey *key)
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
Definition: agent_route.h:109
bool IsDeleted() const
Definition: db_entry.h:49
bool Delete(const AclEntryIDList *ace_id_list, FlowEntry *flow, FlowMgmtKeyNode *node)
BgpAsAServiceFlowMgmtKey * FindBgpAsAServiceInfo(FlowEntry *flow, BgpAsAServiceFlowMgmtKey &key)
Definition: flow_mgmt.cc:725
std::vector< AclEntryID > AclEntryIDList
Definition: acl_entry.h:85
void NonOperEntryEvent(FlowEvent::Event event, FlowEntry *flow)
Definition: flow_mgmt.cc:235
void UpdateCounterOnDel(FlowEntry *flow, bool local_flow, bool old_ingress)
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
const boost::uuids::uuid & GetUuid() const
Definition: acl.h:112
static const int MaxResponses
LifetimeActor * deleter()
Definition: agent_route.cc:451
bool Delete(FlowEntry *flow, FlowMgmtKeyNode *node)
uint32_t Size() const
virtual bool Delete(FlowEntry *flow, FlowMgmtKeyNode *node)
FlowEvent::Event GetResponseEvent() const
bool NeedsReCompute(const FlowEntry *flow)
virtual bool CanDelete() const
void StopHealthCheck(FlowEntry *flow)
bool is_flags_set(const FlowEntryFlags &flags) const
Definition: flow_entry.h:610
Definition: agent.h:358
const VrfEntry * vrf_
FlowList flow_list_
static const std::string & NullString()
Definition: agent.h:437
bool HasVrfFlows(uint32_t vrf)
Definition: flow_mgmt.cc:680
VrfFlowMgmtEntry(VrfFlowMgmtTree *vrf_tree, const VrfEntry *vrf)
void DBEntryEvent(FlowEvent::Event event, FlowMgmtKey *key, FlowEntry *flow)
Definition: flow_mgmt.cc:243
std::string GetAceSandeshDataKey(const AclDBEntry *acl, const std::string &ace_id)
std::string GetAclFlowSandeshDataKey(const AclDBEntry *acl, const int last_count) const
bool l3_flow() const
Definition: flow_entry.h:598
virtual bool NonOperEntryDelete(FlowMgmtManager *mgr, const FlowMgmtRequest *req, FlowMgmtKey *key)
void UpdateCounterOnAdd(FlowEntry *flow, bool add_flow, bool local_flow, bool old_ingress)
LifetimeRef< Data > table_ref_
uint32_t ingress_flow_count_
Event event() const
void SetAclFlowSandeshData(const AclDBEntry *acl, FlowSandeshData &fe_sandesh_data, Agent *agent) const
Definition: flow_entry.cc:3290
void FillAceFlowSandeshInfo(const AclDBEntry *acl, AclFlowCountResp &data, const std::string &ace_id)
bool RecomputeCoveringRouteEntry(FlowMgmtManager *mgr, InetRouteFlowMgmtKey *covering_route, InetRouteFlowMgmtKey *key)
void FillAclFlowSandeshInfo(const AclDBEntry *acl, AclFlowResp &data, const int last_count, Agent *agent)
uint32_t gen_id() const
const boost::uuids::uuid & health_check_uuid() const
void DecrementAceIdCountMap(const AclEntryIDList *id_list)
virtual bool Add(FlowEntry *flow, FlowMgmtKeyNode *node)
VrfFlowMgmtTree * vrf_tree_
void StartHealthCheck(Agent *agent, FlowEntry *flow, const boost::uuids::uuid &hc_uuid)
FlowEntry * flow_entry() const
BgpAsAServiceFlowMgmtRequest::Type type() const
AceIdFlowCntMap aceid_cnt_map_
uint32_t gen_id_
FlowMgmtManager * mgr() const
bool Add(FlowEntry *flow, FlowMgmtKeyNode *node)
Definition: acl.h:92
bool Add(const AclEntryIDList *ace_id_list, FlowEntry *flow, const AclEntryIDList *old_id_list, FlowMgmtKeyNode *node)
bool CanDelete() const