OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flowtable_ksync.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef __AGENT_FLOWTABLE_KSYNC_H__
6 #define __AGENT_FLOWTABLE_KSYNC_H__
7 
8 #include <boost/asio.hpp>
9 #include <boost/bind.hpp>
10 
11 #include <db/db_entry.h>
12 #include <db/db_table.h>
13 #include <db/db_table_partition.h>
14 #include <ksync/ksync_index.h>
15 #include <ksync/ksync_entry.h>
16 #include <ksync/ksync_object.h>
17 #include <ksync/ksync_netlink.h>
18 #include <vrouter/ksync/agent_ksync_types.h>
20 #include <pkt/flow_proto.h>
21 #include <pkt/flow_table.h>
22 #include <vr_types.h>
23 #include <vr_flow.h>
24 
27 
30  uint32_t flow_handle_;
31  uint8_t gen_id_;
35 
36  void Reset() {
37  ksync_error_ = 0;
39  gen_id_ = 0;
43  }
45  Reset();
46  }
47 };
48 
50 public:
53  uint32_t hash_id);
54  virtual ~FlowTableKSyncEntry();
55 
56  void Reset();
57  void Reset(FlowEntry *flow, uint32_t hash_id);
58 
60  uint32_t hash_id() const {return hash_id_;}
61  void set_hash_id(uint32_t hash_id) {
62  hash_id_ = hash_id;
63  }
64  int Encode(sandesh_op::type op, char *buf, int buf_len);
65  KSyncObject *GetObject() const;
66 
67  std::string ToString() const;
68  bool IsLess(const KSyncEntry &rhs) const;
69  int AddMsg(char *buf, int buf_len);
70  int ChangeMsg(char *buf, int buf_len);
71  int DeleteMsg(char *buf, int buf_len);
72  void SetPcapData(FlowEntryPtr fe, std::vector<int8_t> &data);
73  // For flows allocate buffers in ksync-sock context
74  virtual bool pre_alloc_rx_buffer() const { return true; }
75  // KSync flow responses must be processed in multiple ksync response queues
76  // to support scaling. Distribute the flows based on flow-table index
77  virtual uint32_t GetTableIndex() const;
78  virtual bool Sync();
80  virtual bool ShouldReEvalBackReference() const {
81  // no need to re-eval unresolved reference for flow entries, as they
82  // do not depend on anything
83  return false;
84  }
85  bool AllowDeleteStateComp() {return false;}
86  virtual void ErrorHandler(int, uint32_t, KSyncEvent) const;
87  virtual std::string VrouterError(uint32_t error) const;
88  uint8_t gen_id() { return gen_id_; }
89  void set_gen_id(uint8_t gen_id) { gen_id_ = gen_id; }
90  uint8_t evict_gen_id() { return evict_gen_id_; }
92  uint8_t vrouter_gen_id() { return vrouter_gen_id_; }
93  uint32_t vrouter_hash_id() const { return vrouter_hash_id_; }
95  void ReleaseToken();
98  }
99  void SetKSyncResponseInfo(int ksync_error, uint32_t flow_handle,
100  uint8_t gen_id, uint64_t evict_flow_bytes,
101  uint64_t evict_flow_packets,
102  int32_t evict_flow_oflow) {
103  ksync_response_info_.ksync_error_ = ksync_error;
104  ksync_response_info_.flow_handle_ = flow_handle;
106  ksync_response_info_.evict_flow_bytes_ = evict_flow_bytes;
107  ksync_response_info_.evict_flow_packets_ = evict_flow_packets;
108  ksync_response_info_.evict_flow_oflow_ = evict_flow_oflow;
109  }
111  return &ksync_response_info_;
112  }
113 
114  int ksync_response_error() const {
116  }
117 
120  }
121  void set_transaction_id(uint32_t transaction_id) {
122  transaction_id_ = transaction_id;
123  }
124  uint32_t get_transaction_id() const { return transaction_id_;};
125 
126 private:
127  friend class KSyncFlowEntryFreeList;
128  friend class KSyncFlowIndexManager;
129 
131  uint8_t gen_id_; // contains the last propagated genid from flow module
132  uint8_t evict_gen_id_; // contains current active gen-id in vrouter
133  uint8_t vrouter_gen_id_; // Used to identify the last genid sent to vrouter
134 
135  // used to identify last flow index sent to vrouter
136  // helps in knowing whether the vrouter response is index
137  // allocation or not
139 
140  uint32_t hash_id_;
142  uint32_t old_action_;
148  bool ecmp_;
150  uint32_t src_nh_id_;
152  boost::shared_ptr<Token> token_;
155  boost::intrusive::list_member_hook<> free_list_node_;
156  uint32_t qos_config_idx;
157  uint32_t transaction_id_;
160 };
161 
163 // Class to manage free-list of flow ksync entries
164 // Flow allocation can happen from multiple threads. In scaled scenarios
165 // allocation of flow-entries in multi-thread environment adds overheads.
166 // The KSyncFlowEntryFreeList helps to maintain a per task free-list. Alloc/Free
167 // can happen without lock.
168 //
169 // Alloc and Free happens in a chunk. Alloc/Free are done based on thresholds
170 // in task context of the corresponding flow-table
173 public:
174  static const uint32_t kInitCount = (25 * 1000);
175  static const uint32_t kTestInitCount = (5 * 1000);
176  static const uint32_t kGrowSize = (1 * 1000);
177  static const uint32_t kMinThreshold = (4 * 1000);
178  static const uint32_t kMaxThreshold = (100 * 1000);
179 
180  typedef boost::intrusive::member_hook<FlowTableKSyncEntry,
181  boost::intrusive::list_member_hook<>,
183  typedef boost::intrusive::list<FlowTableKSyncEntry, Node> FreeList;
184 
187  uint32_t hash_id);
188  virtual ~KSyncFlowEntryFreeList();
189 
190  void Reset();
191  void Reset(FlowEntryPtr fe, uint32_t hash_id);
192 
194  void Free(FlowTableKSyncEntry *flow);
195  void Grow();
196  uint32_t max_count() const { return max_count_; }
197  uint32_t free_count() const { return free_list_.size(); }
198  uint32_t alloc_count() const { return (max_count_ - free_list_.size()); }
199  uint32_t total_alloc() const { return total_alloc_; }
200  uint32_t total_free() const { return total_free_; }
201 
202 private:
204  uint32_t max_count_;
206  uint64_t total_alloc_;
207  uint64_t total_free_;
210 };
211 
213 public:
214  // flow dependency timer on mirror entry in msec
215  static const uint32_t kFlowDepSyncTimeout = 1000;
216  static const uint32_t KFlowUnresolvedListYield = 32;
218  FlowTableKSyncObject(KSync *ksync, int max_index);
219  virtual ~FlowTableKSyncObject();
220 
221  void Init();
222  void Shutdown() { }
223 
224  KSyncEntry *Alloc(const KSyncEntry *key, uint32_t index);
225  void Free(KSyncEntry *key);
226  bool DoEventTrace(void) { return false; }
228 
229  vr_flow_req &flow_req() { return flow_req_; }
230  KSync *ksync() const { return ksync_; }
231  void set_flow_table(FlowTable *table) { flow_table_ = table; }
232  FlowTable *flow_table() const { return flow_table_; }
233  void UpdateFlowHandle(FlowTableKSyncEntry *entry, uint32_t flow_handle);
234  void UpdateKey(KSyncEntry *entry, uint32_t flow_handle);
235  uint32_t GetKey(KSyncEntry *entry);
236 
237  void GrowFreeList();
239 
240  void NetlinkAck(KSyncEntry *entry, KSyncEntry::KSyncEvent event);
242  KSyncEntry::KSyncEvent event);
243  void StartTimer();
244  bool TimerExpiry();
246 private:
247  friend class KSyncSandeshContext;
248  friend class FlowTable;
251  vr_flow_req flow_req_;
253  std::list<FlowEntryPtr> unresolved_flow_list_;
256 };
257 
258 #endif /* __AGENT_FLOWTABLE_KSYNC_H__ */
void set_hash_id(uint32_t hash_id)
uint32_t alloc_count() const
int hash_id
FlowTable * flow_table() const
FlowTableKSyncObject(KSync *ksync)
static const uint32_t kTestInitCount
boost::shared_ptr< Token > token_
void set_evict_gen_id(uint8_t gen_id)
KSyncEntry * Alloc(const KSyncEntry *key, uint32_t index)
virtual KSyncEntry * UnresolvedReference()
KSyncFlowEntryFreeList free_list_
uint32_t hash_id() const
virtual bool ShouldReEvalBackReference() const
std::string ToString() const
void SetKSyncResponseInfo(int ksync_error, uint32_t flow_handle, uint8_t gen_id, uint64_t evict_flow_bytes, uint64_t evict_flow_packets, int32_t evict_flow_oflow)
FlowEvent::Event last_event_
boost::intrusive::list_member_hook free_list_node_
FlowTableKSyncObject * object_
static const uint32_t kMaxThreshold
FlowEntryPtr flow_entry_
uint32_t old_first_mirror_index()
void SetPcapData(FlowEntryPtr fe, std::vector< int8_t > &data)
KSyncFlowEntryFreeList * free_list()
uint32_t old_first_mirror_index_
void GenerateKSyncEvent(FlowTableKSyncEntry *entry, KSyncEntry::KSyncEvent event)
void UpdateKey(KSyncEntry *entry, uint32_t flow_handle)
uint32_t GetKey(KSyncEntry *entry)
virtual void ErrorHandler(int, uint32_t, KSyncEvent) const
uint32_t total_free() const
boost::intrusive::list< FlowTableKSyncEntry, Node > FreeList
DISALLOW_COPY_AND_ASSIGN(FlowTableKSyncEntry)
virtual ~FlowTableKSyncEntry()
uint8_t type
Definition: load_balance.h:109
uint32_t total_alloc() const
vr_flow_req & flow_req()
void Free(FlowTableKSyncEntry *flow)
void UpdateUnresolvedFlowEntry(FlowEntryPtr flowptr)
uint32_t get_transaction_id() const
void Free(KSyncEntry *key)
FlowTableKSyncEntry * Allocate(const KSyncEntry *key)
DISALLOW_COPY_AND_ASSIGN(KSyncFlowEntryFreeList)
FlowKSyncResponseInfo ksync_response_info_
uint32_t old_second_mirror_index_
static const uint32_t kMinThreshold
uint32_t max_count() const
const FlowKSyncResponseInfo * ksync_response_info() const
static const uint32_t KFlowUnresolvedListYield
void set_gen_id(uint8_t gen_id)
FlowTableKSyncObject * ksync_obj_
void set_flow_table(FlowTable *table)
KSync * ksync() const
void NetlinkAck(KSyncEntry *entry, KSyncEntry::KSyncEvent event)
virtual std::string VrouterError(uint32_t error) const
int AddMsg(char *buf, int buf_len)
void set_transaction_id(uint32_t transaction_id)
bool IsLess(const KSyncEntry &rhs) const
uint32_t old_component_nh_idx_
uint32_t free_count() const
static const uint32_t kInvalidFlowHandle
Definition: flow_entry.h:521
FlowTableKSyncEntry(FlowTableKSyncObject *obj)
uint32_t vrouter_hash_id() const
virtual uint32_t GetTableIndex() const
FlowEntryPtr flow_entry() const
int DeleteMsg(char *buf, int buf_len)
KSyncFlowEntryFreeList(FlowTableKSyncObject *object)
DISALLOW_COPY_AND_ASSIGN(FlowTableKSyncObject)
static const uint32_t kFlowDepSyncTimeout
int ChangeMsg(char *buf, int buf_len)
Definition: timer.h:54
static const uint32_t kGrowSize
std::list< FlowEntryPtr > unresolved_flow_list_
static const uint32_t kInitCount
int ksync_response_error() const
void UpdateFlowHandle(FlowTableKSyncEntry *entry, uint32_t flow_handle)
boost::intrusive::member_hook< FlowTableKSyncEntry, boost::intrusive::list_member_hook<>,&FlowTableKSyncEntry::free_list_node_ > Node
FlowEvent::Event last_event() const
virtual bool pre_alloc_rx_buffer() const
int Encode(sandesh_op::type op, char *buf, int buf_len)
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
Definition: flow_entry.h:125
KSyncObject * GetObject() const
FlowTableKSyncEntry * Find(FlowEntry *key)