OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ecmp_load_balance.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef vnsw_agent_ecmp_load_balance_hpp
6 #define vnsw_agent_ecmp_load_balance_hpp
7 #include <boost/intrusive_ptr.hpp>
8 #include <vnc_cfg_types.h>
9 
10 namespace autogen {
11  struct EcmpHashingIncludeFields;
12 }
13 
14 static const std::string HashingFieldsStr[] = {
15  "l3-source-address",
16  "l3-destination-address",
17  "l4-protocol",
18  "l4-source-port",
19  "l4-destination-port"
20 };
21 static const std::string LoadBalanceDecision = "field-hash";
22 
24 public:
32  };
33 
35  SetAll();
36  }
37  virtual ~EcmpLoadBalance() { }
38 
39  const std::string &source_ip_str() const {
41  }
42  const std::string &destination_ip_str() const {
44  }
45  const std::string &source_port_str() const {
47  }
48  const std::string &destination_port_str() const {
50  }
51  const std::string &ip_protocol_str() const {
53  }
54 
55  void GetStringVector (std::vector<std::string> &string_vector) const {
56  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
57  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
58  field_type++) {
59  if (hash_fields_to_use_[field_type])
60  string_vector.push_back(HashingFieldsStr[field_type]);
61  }
62  }
63 
64  bool operator!=(const EcmpLoadBalance &rhs) const {
65  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
66  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
67  field_type++) {
68  if (hash_fields_to_use_[field_type] !=
69  rhs.hash_fields_to_use_[field_type])
70  return true;
71  }
72  return false;
73  }
74 
75  virtual void Copy(const EcmpLoadBalance &rhs) {
76  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
77  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
78  field_type++) {
79  hash_fields_to_use_[field_type] =
80  rhs.hash_fields_to_use_[field_type];
81  }
82  }
83 
84  void SetAll() {
85  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
86  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
87  field_type++) {
88  hash_fields_to_use_[field_type] = true;
89  }
90  }
91 
92  void ResetAll() {
93  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
94  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
95  field_type++) {
96  hash_fields_to_use_[field_type] = false;
97  }
98  }
99 
100  bool AllSet() const {
101  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
102  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
103  field_type++) {
104  if (hash_fields_to_use_[field_type] == false)
105  return false;
106  }
107  return true;
108  }
109  void set_source_ip() {
111  }
114  }
117  }
120  }
123  }
126  }
129  }
132  }
135  }
138  }
139 
140  bool is_source_ip_set() const {
141  return (hash_fields_to_use_[SOURCE_IP]);
142  }
143  bool is_destination_ip_set() const {
145  }
146  bool is_source_port_set() const {
148  }
149  bool is_destination_port_set() const {
151  }
152  bool is_ip_protocol_set() const {
154  }
155 
156  void reset() {
157  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
158  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
159  field_type++) {
160  hash_fields_to_use_[field_type] = false;
161  }
162  }
163 
164  bool UpdateFields
165  (const autogen::EcmpHashingIncludeFields &ecmp_hashing_fields) {
166  bool ret = false;
167 
168  if (hash_fields_to_use_[SOURCE_IP] != ecmp_hashing_fields.source_ip) {
169  hash_fields_to_use_[SOURCE_IP] = ecmp_hashing_fields.source_ip;
170  ret = true;
171  }
173  ecmp_hashing_fields.destination_ip) {
175  ecmp_hashing_fields.destination_ip;
176  ret = true;
177  }
179  ecmp_hashing_fields.source_port) {
180  hash_fields_to_use_[SOURCE_PORT] = ecmp_hashing_fields.source_port;
181  ret = true;
182  }
184  ecmp_hashing_fields.destination_port) {
186  ecmp_hashing_fields.destination_port;
187  ret = true;
188  }
190  ecmp_hashing_fields.ip_protocol) {
191  hash_fields_to_use_[IP_PROTOCOL] = ecmp_hashing_fields.ip_protocol;
192  ret = true;
193  }
194  return ret;
195  }
196 
197 private:
199 };
200 
202 public:
204  virtual ~VmiEcmpLoadBalance() { }
205 
209  }
210  virtual void Copy(const VmiEcmpLoadBalance &rhs) {
213  }
214 
215 private:
217 };
218 
219 class EcmpField {
220 public:
222  ref_count_= 0;
223  }
224 
225  uint32_t RefCount() const {
226  return ref_count_;
227  }
228 private:
229  friend void intrusive_ptr_add_ref(EcmpField* ptr);
230  friend void intrusive_ptr_release(EcmpField* ptr);
231  mutable tbb::atomic<uint32_t> ref_count_;
232 };
233 
234 inline void intrusive_ptr_add_ref(EcmpField* ptr) {
235  ptr->ref_count_.fetch_and_increment();
236 }
237 
238 inline void intrusive_ptr_release(EcmpField* ptr) {
239  uint32_t prev = ptr->ref_count_.fetch_and_decrement();
240  if (prev == 1) {
241  delete ptr;
242  }
243 }
244 
246 public:
247  typedef boost::intrusive_ptr<EcmpField> EcmpFieldPtr;
248 
250  }
251 
252  EcmpHashFields(const uint8_t hash_fields_to_use ) {
253  hash_fields_to_use_ = hash_fields_to_use;
254  }
255  void operator = (const uint8_t hash_fields_to_use) {
256  hash_fields_to_use_ = hash_fields_to_use;
257  }
258 
260  sip_ = new EcmpField;
261  dip_ = new EcmpField;
262  proto_ = new EcmpField;
263  sport_ = new EcmpField;
264  dport_ = new EcmpField;
265  }
266 
267  uint8_t HashFieldsToUse() const {
268  return hash_fields_to_use_;
269  }
270 
271  void SetHashFieldtoUse(EcmpField *ptr, uint8_t key) {
272  if (ptr && ptr->RefCount() == 1) {
273  comp_hash_fields_to_use_ |= 1 << key;
274  }
275  }
276  // If the field is not set create intrusive pointer
277  // else release the pointer.
278  void SetChangeInHashField(bool is_field_set, EcmpFieldPtr& fieldPtr,
279  EcmpFieldPtr &objFieldPtr) {
280  if (!is_field_set) {
281  if (!objFieldPtr.get()) {
282  objFieldPtr = fieldPtr;
283  }
284  } else {
285  objFieldPtr.reset();
286  }
287  }
288  // This function will be called to ge intersection of ecmp fields
297  }
298  //This function used to calculate the Change in ecmp fields
299  void CalculateChangeInEcmpFields(const EcmpLoadBalance &ecmp_load_balance,
300  EcmpHashFields& ecmp_hash_fields) {
301  SetChangeInHashField(ecmp_load_balance.is_source_ip_set(),
302  ecmp_hash_fields.sip_, sip_);
303  SetChangeInHashField(ecmp_load_balance.is_destination_ip_set(),
304  ecmp_hash_fields.dip_, dip_);
305  SetChangeInHashField(ecmp_load_balance.is_ip_protocol_set(),
306  ecmp_hash_fields.proto_, proto_);
307  SetChangeInHashField(ecmp_load_balance.is_source_port_set(),
308  ecmp_hash_fields.sport_, sport_);
309  SetChangeInHashField(ecmp_load_balance.is_destination_port_set(),
310  ecmp_hash_fields.dport_, dport_);
311  }
312 
315  }
316 
319  }
320 
321  void Reset() {
322  sip_ = NULL;
323  dip_ = NULL;
324  proto_ = NULL;
325  sport_ = NULL;
326  dport_ = NULL;
327  }
328 
329 private:
330  // This will have latest computed value
339 };
340 #endif
int intrusive_ptr_add_ref(const AsPath *cpath)
Definition: bgp_aspath.h:147
bool is_source_port_set() const
bool is_destination_ip_set() const
uint8_t CalculateHashFieldsToUse()
const std::string & source_ip_str() const
uint8_t hash_fields_to_use_
bool UpdateFields(const autogen::EcmpHashingIncludeFields &ecmp_hashing_fields)
EcmpFieldPtr dip_
boost::intrusive_ptr< EcmpField > EcmpFieldPtr
uint8_t HashFieldsToUse() const
friend void intrusive_ptr_release(EcmpField *ptr)
EcmpHashFields(const uint8_t hash_fields_to_use)
void operator=(const uint8_t hash_fields_to_use)
bool use_global_vrouter() const
friend void intrusive_ptr_add_ref(EcmpField *ptr)
void GetStringVector(std::vector< std::string > &string_vector) const
virtual void Copy(const VmiEcmpLoadBalance &rhs)
const std::string & source_port_str() const
bool AllSet() const
virtual ~EcmpLoadBalance()
EcmpFieldPtr dport_
uint8_t comp_hash_fields_to_use_
tbb::atomic< uint32_t > ref_count_
void set_use_global_vrouter(bool use_global_vrouter)
bool is_source_ip_set() const
EcmpFieldPtr sip_
static const std::string LoadBalanceDecision
const std::string & destination_port_str() const
void SetHashFieldtoUse(EcmpField *ptr, uint8_t key)
virtual void Copy(const EcmpLoadBalance &rhs)
const std::string & destination_ip_str() const
const std::string & ip_protocol_str() const
DISALLOW_COPY_AND_ASSIGN(EcmpHashFields)
bool hash_fields_to_use_[NUM_HASH_FIELDS]
void intrusive_ptr_release(const AsPath *cpath)
Definition: bgp_aspath.h:155
static const std::string HashingFieldsStr[]
bool is_destination_port_set() const
void SetChangeInHashField(bool is_field_set, EcmpFieldPtr &fieldPtr, EcmpFieldPtr &objFieldPtr)
bool operator!=(const EcmpLoadBalance &rhs) const
EcmpFieldPtr proto_
bool is_ip_protocol_set() const
uint32_t RefCount() const
void CalculateChangeInEcmpFields(const EcmpLoadBalance &ecmp_load_balance, EcmpHashFields &ecmp_hash_fields)
EcmpFieldPtr sport_