OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flow_event.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  */
4 #ifndef __AGENT_FLOW_EVENT_H__
5 #define __AGENT_FLOW_EVENT_H__
6 
7 #include <sys/resource.h>
8 #include <ksync/ksync_entry.h>
9 #include "flow_table.h"
10 
11 class FlowTokenPool;
12 
14 // Control events for flow management
16 class FlowEvent {
17 public:
18  enum Event {
20  // Flow add message from VRouter
22  // Message to update a flow
24  // Event to delete a flow entry
26  // Event by audit module to delete a flow
28  // In agent, flow is evicted if index is allocated for another flow
29  // We delete the flow on eviction. There is a corner case where evicted
30  // flow is added in parallel with different index. In that case
31  // we ignore the operation
33  // Revaluate flow due to deletion of a DBEntry. Other than for INET
34  // routes, delete of a DBEntry will result in deletion of flows using
35  // the DBEntry
37  // Revaluate route due to change in a DBEntry. This event is used to
38  // revaluate a flow on add/change of interface, vm, vn etc...
39  // The action typically invovles only re-evaluating ACL lookup actions
41  // Add/Delete of route can result in flow using a next higher/lower
42  // prefix. The event will recompute the complete flow due to change
43  // in route used for flow
45  // Flow entry should be freed from kTaskFlowEvent task context.
46  // Event to ensure flow entry is freed from right context
48  // A DBEntry should be freed from kTaskFlowEvent task context.
49  // Event to ensure DBEntry entry reference is freed from right context
51  // Grow the free-list entries for flow and ksync
53  // Generate KSync event for the flow
55  // Pkt is re-entering processing in new partition
57  // Need to resolve the Flow entry whic is depending on Mirror entry
59  };
60 
62  event_(INVALID), flow_(NULL), pkt_info_(), db_entry_(NULL),
63  gen_id_(0), evict_gen_id_(0),
64  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(0) {
65  }
66 
68  event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
70  }
71 
73  event_(event), flow_(flow), pkt_info_(), db_entry_(NULL),
74  table_index_(0) {
75  }
76 
78  event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
79  gen_id_(0), evict_gen_id_(0),
80  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(table_index) {
81  }
82 
84  uint8_t gen_id) :
85  event_(event), flow_(flow), pkt_info_(), db_entry_(NULL),
86  gen_id_(gen_id), evict_gen_id_(0), flow_handle_(flow_handle),
87  table_index_(0) {
88  }
89 
91  uint8_t gen_id, uint8_t evict_gen_id) :
92  event_(event), flow_(flow), pkt_info_(), db_entry_(NULL),
93  gen_id_(gen_id), evict_gen_id_(evict_gen_id), flow_handle_(flow_handle),
94  table_index_(0) {
95  }
96 
98  event_(event), flow_(flow), pkt_info_(), db_entry_(db_entry),
99  gen_id_(0), evict_gen_id_(0),
100  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(0) {
101  }
102 
104  event_(event), flow_(NULL), pkt_info_(), db_entry_(db_entry),
105  gen_id_(gen_id), evict_gen_id_(0),
106  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(0) {
107  }
108 
110  uint32_t gen_id) :
111  event_(event), flow_(NULL), pkt_info_(), db_entry_(db_entry),
112  gen_id_(gen_id), evict_gen_id_(0),
113  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(table_index) {
114  }
115 
116  FlowEvent(Event event, const FlowKey &key) :
117  event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
118  gen_id_(0), evict_gen_id_(0), flow_key_(key),
119  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(0) {
120  }
121 
122  FlowEvent(Event event, const FlowKey &key, uint32_t flow_handle,
123  uint8_t gen_id) :
124  event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
125  gen_id_(gen_id), evict_gen_id_(0), flow_key_(key),
126  flow_handle_(flow_handle), table_index_(0) {
127  }
128 
130  uint32_t table_index) :
131  event_(event), flow_(flow), pkt_info_(pkt_info), db_entry_(NULL),
132  gen_id_(0), evict_gen_id_(0), flow_key_(),
133  flow_handle_(FlowEntry::kInvalidFlowHandle), table_index_(table_index) {
134  }
135 
136  FlowEvent(const FlowEvent &rhs) :
137  event_(rhs.event_), flow_(rhs.flow()), pkt_info_(rhs.pkt_info_),
138  db_entry_(rhs.db_entry_), gen_id_(rhs.gen_id_),
141  }
142 
143  virtual ~FlowEvent() {
144  }
145 
146  Event event() const { return event_; }
147  FlowEntry *flow() const { return flow_.get(); }
148  FlowEntryPtr &flow_ref() { return flow_; }
150  const DBEntry *db_entry() const { return db_entry_; }
152  uint32_t gen_id() const { return gen_id_; }
153  uint32_t evict_gen_id() const { return evict_gen_id_; }
154  const FlowKey &get_flow_key() const { return flow_key_; }
155  PktInfoPtr pkt_info() const { return pkt_info_; }
156  uint32_t flow_handle() const { return flow_handle_; }
157  uint32_t table_index() const { return table_index_;}
158 private:
163  uint32_t gen_id_;
164  uint32_t evict_gen_id_;
166  uint32_t flow_handle_;
167  uint32_t table_index_;
168 };
169 
171 // Event to process VRouter response for flow operation. VRouter response for
172 // flow is made of two messages,
173 // - vr_flow response which will contains,
174 // - Return code for the operation
175 // - flow-handle allocated for flow
176 // - gen-id for he hash-entry allocated
177 // - stats for the flow being evicted by VRouter
178 // - vr_response
179 // - contains ksync-event to be generated for the flow
180 //
181 // The event combines data from both the messages. The event-handler will
182 // process both the vrouter response messages
183 //
184 // The flow-handle and gen-id are got from base class (FlowEvent)
186 class FlowEventKSync : public FlowEvent {
187 public:
190  uint32_t gen_id, int ksync_error, uint64_t evict_flow_bytes,
191  uint64_t evict_flow_packets, uint64_t evict_flow_oflow,
192  uint32_t transaction_id) :
193  FlowEvent(KSYNC_EVENT, NULL, flow_handle, gen_id),
194  ksync_entry_(ksync_entry), ksync_event_(ksync_event),
195  ksync_error_(ksync_error), evict_flow_bytes_(evict_flow_bytes),
196  evict_flow_packets_(evict_flow_packets),
197  evict_flow_oflow_(evict_flow_oflow),
198  transaction_id_(transaction_id) {
199  }
200 
208  }
209 
210  virtual ~FlowEventKSync() { }
211 
212  KSyncEntry *ksync_entry() const { return ksync_entry_.get(); }
214  int ksync_error() const { return ksync_error_; }
215  uint64_t evict_flow_bytes() const { return evict_flow_bytes_; }
216  uint64_t evict_flow_packets() const { return evict_flow_packets_; }
217  uint64_t evict_flow_oflow() const { return evict_flow_oflow_; }
218  uint32_t transaction_id() const { return transaction_id_; }
219 private:
226  uint32_t transaction_id_;
227 };
228 
230 // FlowProto uses following queues,
231 //
232 // - FlowEventQueue
233 // This queue contains events for flow add, flow eviction etc...
234 // See FlowProto::FlowEventHandler for events handled in this queue
235 // - KSyncFlowEventQueue
236 // This queue contains events generated from KSync response for a flow
237 // - DeleteFlowEventQueue
238 // This queue contains events generated for flow-ageing
239 // - UpdateFlowEventQueue
240 // This queue contains events generated as result of config changes such
241 // as add/delete/change of interface, vn, vm, acl, nh, route etc...
242 //
243 // All queues are defined from a base class FlowEventQueueBase.
244 // FlowEventQueueBase implements a wrapper around the WorkQueues with following
245 // additional functionality,
246 //
247 // - Rate Control using Tokens
248 // All the queues give above can potentially add/change/delete flows in the
249 // vrouter. So, the queues given above acts as producer and VRouter acts as
250 // consumer. VRouter is a slow consumer of events. To provide fairness
251 // across queues, a "token" based scheme is used. See flow_token.h for more
252 // information
253 //
254 // The queue will stop the WorkQueue when it runs out of tokens. The queue
255 // is started again after a minimum number of tokens become available
256 //
257 // - Time limits
258 // Intermittently, it is observed that some of the queues take large amount
259 // of time. Latencies in queue such as KSync queue or delete-queue can result
260 // in flow-setup latencies. So, we want to impose an upper bound on the
261 // amount of time taken in single run of WorkQueue.
262 //
263 // We take timestamp at start of queue, and check latency for every 8
264 // events processed in the queue. If the latency goes beyond a limit, the
265 // WorkQueue run is aborted.
268 public:
270 
271  FlowEventQueueBase(FlowProto *proto, const std::string &name,
272  uint32_t task_id, int task_instance,
273  FlowTokenPool *pool, uint16_t latency_limit,
274  uint32_t max_iterations);
275  virtual ~FlowEventQueueBase();
276  virtual bool HandleEvent(FlowEvent *event) = 0;
277  virtual bool Handler(FlowEvent *event);
278 
279  void Shutdown();
280  void Enqueue(FlowEvent *event);
281  bool TokenCheck();
282  bool TaskEntry();
283  void TaskExit(bool done);
284  void set_disable(bool val) { queue_->set_disable(val); }
285  uint32_t Length() { return queue_->Length(); }
287  Queue *queue() const { return queue_; }
288  uint64_t events_processed() const { return events_processed_; }
289  uint64_t events_enqueued() const { return queue_->NumEnqueues(); }
290 
291 protected:
292  bool CanEnqueue(FlowEvent *event);
293  bool CanProcess(FlowEvent *event);
294  void ProcessDone(FlowEvent *event, bool update_rev_flow);
295 
299  uint64_t task_start_;
300  // Number of entries processed in single run of WorkQueue
301  uint32_t count_;
302  // Number of events processed. Skips event that are state-compressed
303  // due to Flow PendingActions
305  uint16_t latency_limit_;
306  struct rusage rusage_;
307 };
308 
310 public:
311  FlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table,
312  FlowTokenPool *pool, uint16_t latency_limit,
313  uint32_t max_iterations);
314  virtual ~FlowEventQueue();
315 
316  bool HandleEvent(FlowEvent *event);
317 private:
319 };
320 
322 public:
323  DeleteFlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table,
324  FlowTokenPool *pool, uint16_t latency_limit,
325  uint32_t max_iterations);
326  virtual ~DeleteFlowEventQueue();
327 
328  bool HandleEvent(FlowEvent *event);
329 private:
331 };
332 
334 public:
335  KSyncFlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table,
336  FlowTokenPool *pool, uint16_t latency_limit,
337  uint32_t max_iterations);
338  virtual ~KSyncFlowEventQueue();
339 
340  bool HandleEvent(FlowEvent *event);
341 private:
343 };
344 
346 public:
347  UpdateFlowEventQueue(Agent *agent, FlowProto *proto,
348  FlowTokenPool *pool, uint16_t latency_limit,
349  uint32_t max_iterations);
350  virtual ~UpdateFlowEventQueue();
351 
352  bool HandleEvent(FlowEvent *event);
353 };
354 
355 #endif // __AGENT_FLOW_EVENT_H__
UpdateFlowEventQueue(Agent *agent, FlowProto *proto, FlowTokenPool *pool, uint16_t latency_limit, uint32_t max_iterations)
Definition: flow_event.cc:290
FlowKey flow_key_
Definition: flow_event.h:165
FlowEntryPtr flow_
Definition: flow_event.h:160
KSyncFlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table, FlowTokenPool *pool, uint16_t latency_limit, uint32_t max_iterations)
Definition: flow_event.cc:271
FlowEventKSync(const KSyncEntry::KSyncEntryPtr ksync_entry, KSyncEntry::KSyncEvent ksync_event, uint32_t flow_handle, uint32_t gen_id, int ksync_error, uint64_t evict_flow_bytes, uint64_t evict_flow_packets, uint64_t evict_flow_oflow, uint32_t transaction_id)
Definition: flow_event.h:188
uint64_t evict_flow_bytes() const
Definition: flow_event.h:215
DeleteFlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table, FlowTokenPool *pool, uint16_t latency_limit, uint32_t max_iterations)
Definition: flow_event.cc:252
virtual bool Handler(FlowEvent *event)
Definition: flow_event.cc:96
bool HandleEvent(FlowEvent *event)
Definition: flow_event.cc:248
uint16_t latency_limit_
Definition: flow_event.h:305
uint64_t evict_flow_oflow() const
Definition: flow_event.h:217
PktInfoPtr pkt_info_
Definition: flow_event.h:161
const FlowKey & get_flow_key() const
Definition: flow_event.h:154
uint64_t evict_flow_oflow_
Definition: flow_event.h:225
virtual bool HandleEvent(FlowEvent *event)=0
uint32_t table_index_
Definition: flow_event.h:167
bool HandleEvent(FlowEvent *event)
Definition: flow_event.cc:267
uint32_t flow_handle() const
Definition: flow_event.h:156
FlowEvent(Event event, FlowEntry *flow, const DBEntry *db_entry)
Definition: flow_event.h:97
bool HandleEvent(FlowEvent *event)
Definition: flow_event.cc:286
FlowEvent(const FlowEvent &rhs)
Definition: flow_event.h:136
uint64_t evict_flow_packets() const
Definition: flow_event.h:216
FlowProto * flow_proto_
Definition: flow_event.h:297
void TaskExit(bool done)
Definition: flow_event.cc:73
KSyncEntry::KSyncEvent ksync_event_
Definition: flow_event.h:221
uint64_t evict_flow_bytes_
Definition: flow_event.h:223
bool CanProcess(FlowEvent *event)
Definition: flow_event.cc:147
void ProcessDone(FlowEvent *event, bool update_rev_flow)
Definition: flow_event.cc:188
uint32_t flow_handle_
Definition: flow_event.h:166
virtual ~DeleteFlowEventQueue()
Definition: flow_event.cc:264
uint32_t table_index() const
Definition: flow_event.h:157
KSyncEntry::KSyncEvent ksync_event() const
Definition: flow_event.h:213
Definition: agent.h:358
size_t Length() const
Definition: queue_task.h:356
FlowEventQueue(Agent *agent, FlowProto *proto, FlowTable *table, FlowTokenPool *pool, uint16_t latency_limit, uint32_t max_iterations)
Definition: flow_event.cc:234
uint64_t task_start_
Definition: flow_event.h:299
virtual ~FlowEventQueue()
Definition: flow_event.cc:245
FlowEventQueueBase(FlowProto *proto, const std::string &name, uint32_t task_id, int task_instance, FlowTokenPool *pool, uint16_t latency_limit, uint32_t max_iterations)
Definition: flow_event.cc:20
FlowEvent(Event event)
Definition: flow_event.h:67
KSyncEntry::KSyncEntryPtr ksync_entry_
Definition: flow_event.h:220
boost::intrusive_ptr< KSyncEntry > KSyncEntryPtr
Definition: ksync_entry.h:68
PktInfoPtr pkt_info() const
Definition: flow_event.h:155
void MayBeStartRunner()
Definition: flow_event.h:286
uint32_t gen_id() const
Definition: flow_event.h:152
uint32_t transaction_id() const
Definition: flow_event.h:218
bool CanEnqueue(FlowEvent *event)
Definition: flow_event.cc:110
uint32_t Length()
Definition: flow_event.h:285
uint64_t evict_flow_packets_
Definition: flow_event.h:224
FlowTable * flow_table_
Definition: flow_event.h:342
uint64_t events_processed_
Definition: flow_event.h:304
uint32_t evict_gen_id_
Definition: flow_event.h:164
FlowEvent(Event event, const FlowKey &key)
Definition: flow_event.h:116
FlowEvent(Event event, PktInfoPtr pkt_info, FlowEntry *flow, uint32_t table_index)
Definition: flow_event.h:129
void MayBeStartRunner()
Definition: queue_task.h:281
const DBEntry * db_entry() const
Definition: flow_event.h:150
uint32_t transaction_id_
Definition: flow_event.h:226
FlowEvent(Event event, uint32_t table_index)
Definition: flow_event.h:77
FlowEvent(Event event, FlowEntry *flow, uint32_t flow_handle, uint8_t gen_id)
Definition: flow_event.h:83
FlowEvent(Event event, const FlowKey &key, uint32_t flow_handle, uint8_t gen_id)
Definition: flow_event.h:122
void set_disable(bool disabled)
Definition: queue_task.h:319
void set_disable(bool val)
Definition: flow_event.h:284
uint32_t gen_id_
Definition: flow_event.h:163
int ksync_error() const
Definition: flow_event.h:214
FlowEvent(Event event, FlowEntry *flow)
Definition: flow_event.h:72
FlowEvent(Event event, const DBEntry *db_entry, uint32_t gen_id)
Definition: flow_event.h:103
bool HandleEvent(FlowEvent *event)
Definition: flow_event.cc:302
FlowEntryPtr & flow_ref()
Definition: flow_event.h:148
void Enqueue(FlowEvent *event)
Definition: flow_event.cc:54
FlowEntry * flow() const
Definition: flow_event.h:147
FlowEventKSync(const FlowEventKSync &rhs)
Definition: flow_event.h:201
virtual ~FlowEvent()
Definition: flow_event.h:143
virtual ~FlowEventQueueBase()
Definition: flow_event.cc:46
FlowEvent(Event event, uint16_t table_index, const DBEntry *db_entry, uint32_t gen_id)
Definition: flow_event.h:109
void set_db_entry(const DBEntry *db_entry)
Definition: flow_event.h:151
KSyncEntry * ksync_entry() const
Definition: flow_event.h:212
uint64_t events_processed() const
Definition: flow_event.h:288
virtual ~FlowEventKSync()
Definition: flow_event.h:210
size_t NumEnqueues() const
Definition: queue_task.h:360
Queue * queue() const
Definition: flow_event.h:287
virtual ~KSyncFlowEventQueue()
Definition: flow_event.cc:283
FlowTokenPool * token_pool_
Definition: flow_event.h:298
WorkQueue< FlowEvent * > Queue
Definition: flow_event.h:269
const DBEntry * db_entry_
Definition: flow_event.h:162
Event event() const
Definition: flow_event.h:146
FlowEvent(Event event, FlowEntry *flow, uint32_t flow_handle, uint8_t gen_id, uint8_t evict_gen_id)
Definition: flow_event.h:90
uint32_t evict_gen_id() const
Definition: flow_event.h:153
Event event_
Definition: flow_event.h:159
FlowTable * flow_table_
Definition: flow_event.h:330
boost::shared_ptr< PktInfo > PktInfoPtr
Definition: pkt_handler.h:61
virtual ~UpdateFlowEventQueue()
Definition: flow_event.cc:299
void set_flow(FlowEntry *flow)
Definition: flow_event.h:149
struct rusage rusage_
Definition: flow_event.h:306
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
Definition: flow_entry.h:125
FlowTable * flow_table_
Definition: flow_event.h:318
uint64_t events_enqueued() const
Definition: flow_event.h:289