OpenSDN source code
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 
8 #include <atomic>
9 #include <boost/intrusive_ptr.hpp>
10 #include <vnc_cfg_types.h>
11 
12 namespace autogen {
13  struct EcmpHashingIncludeFields;
14 }
15 
16 static const std::string HashingFieldsStr[] = {
17  "l3-source-address",
18  "l3-destination-address",
19  "l4-protocol",
20  "l4-source-port",
21  "l4-destination-port"
22 };
23 static const std::string LoadBalanceDecision = "field-hash";
24 
26 public:
34  };
35 
37  SetAll();
38  }
39  virtual ~EcmpLoadBalance() { }
40 
41  const std::string &source_ip_str() const {
43  }
44  const std::string &destination_ip_str() const {
46  }
47  const std::string &source_port_str() const {
49  }
50  const std::string &destination_port_str() const {
52  }
53  const std::string &ip_protocol_str() const {
55  }
56 
57  void GetStringVector (std::vector<std::string> &string_vector) const {
58  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
59  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
60  field_type++) {
61  if (hash_fields_to_use_[field_type])
62  string_vector.push_back(HashingFieldsStr[field_type]);
63  }
64  }
65 
66  bool operator!=(const EcmpLoadBalance &rhs) const {
67  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
68  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
69  field_type++) {
70  if (hash_fields_to_use_[field_type] !=
71  rhs.hash_fields_to_use_[field_type])
72  return true;
73  }
74  return false;
75  }
76 
77  virtual void Copy(const EcmpLoadBalance &rhs) {
78  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
79  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
80  field_type++) {
81  hash_fields_to_use_[field_type] =
82  rhs.hash_fields_to_use_[field_type];
83  }
84  }
85 
86  void SetAll() {
87  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
88  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
89  field_type++) {
90  hash_fields_to_use_[field_type] = true;
91  }
92  }
93 
94  void ResetAll() {
95  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
96  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
97  field_type++) {
98  hash_fields_to_use_[field_type] = false;
99  }
100  }
101 
102  bool AllSet() const {
103  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
104  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
105  field_type++) {
106  if (hash_fields_to_use_[field_type] == false)
107  return false;
108  }
109  return true;
110  }
111  void set_source_ip() {
113  }
116  }
119  }
122  }
125  }
128  }
131  }
134  }
137  }
140  }
141 
142  bool is_source_ip_set() const {
143  return (hash_fields_to_use_[SOURCE_IP]);
144  }
145  bool is_destination_ip_set() const {
147  }
148  bool is_source_port_set() const {
150  }
151  bool is_destination_port_set() const {
153  }
154  bool is_ip_protocol_set() const {
156  }
157 
158  void reset() {
159  for (uint8_t field_type = ((uint8_t) EcmpLoadBalance::SOURCE_IP);
160  field_type < ((uint8_t) EcmpLoadBalance::NUM_HASH_FIELDS);
161  field_type++) {
162  hash_fields_to_use_[field_type] = false;
163  }
164  }
165 
167  (const autogen::EcmpHashingIncludeFields &ecmp_hashing_fields) {
168  bool ret = false;
169 
170  if (hash_fields_to_use_[SOURCE_IP] != ecmp_hashing_fields.source_ip) {
171  hash_fields_to_use_[SOURCE_IP] = ecmp_hashing_fields.source_ip;
172  ret = true;
173  }
175  ecmp_hashing_fields.destination_ip) {
177  ecmp_hashing_fields.destination_ip;
178  ret = true;
179  }
181  ecmp_hashing_fields.source_port) {
182  hash_fields_to_use_[SOURCE_PORT] = ecmp_hashing_fields.source_port;
183  ret = true;
184  }
186  ecmp_hashing_fields.destination_port) {
188  ecmp_hashing_fields.destination_port;
189  ret = true;
190  }
192  ecmp_hashing_fields.ip_protocol) {
193  hash_fields_to_use_[IP_PROTOCOL] = ecmp_hashing_fields.ip_protocol;
194  ret = true;
195  }
196  return ret;
197  }
198 
199 private:
201 };
202 
204 public:
206  virtual ~VmiEcmpLoadBalance() { }
207 
211  }
212  virtual void Copy(const VmiEcmpLoadBalance &rhs) {
215  }
216 
217 private:
219 };
220 
221 class EcmpField {
222 public:
224  ref_count_= 0;
225  }
226 
227  uint32_t RefCount() const {
228  return ref_count_;
229  }
230 private:
231  friend void intrusive_ptr_add_ref(EcmpField* ptr);
232  friend void intrusive_ptr_release(EcmpField* ptr);
233  mutable std::atomic<uint32_t> ref_count_;
234 };
235 
236 inline void intrusive_ptr_add_ref(EcmpField* ptr) {
237  ptr->ref_count_++;
238 }
239 
240 inline void intrusive_ptr_release(EcmpField* ptr) {
241  uint32_t prev = ptr->ref_count_.fetch_sub(1);
242  if (prev == 1) {
243  delete ptr;
244  }
245 }
246 
248 public:
249  typedef boost::intrusive_ptr<EcmpField> EcmpFieldPtr;
250 
252  }
253 
254  EcmpHashFields(const uint8_t hash_fields_to_use ) {
255  hash_fields_to_use_ = hash_fields_to_use;
256  }
257  void operator = (const uint8_t hash_fields_to_use) {
258  hash_fields_to_use_ = hash_fields_to_use;
259  }
260 
262  sip_ = new EcmpField;
263  dip_ = new EcmpField;
264  proto_ = new EcmpField;
265  sport_ = new EcmpField;
266  dport_ = new EcmpField;
267  }
268 
269  uint8_t HashFieldsToUse() const {
270  return hash_fields_to_use_;
271  }
272 
273  void SetHashFieldtoUse(EcmpField *ptr, uint8_t key) {
274  if (ptr && ptr->RefCount() == 1) {
275  comp_hash_fields_to_use_ |= 1 << key;
276  }
277  }
278  // If the field is not set create intrusive pointer
279  // else release the pointer.
280  void SetChangeInHashField(bool is_field_set, EcmpFieldPtr& fieldPtr,
281  EcmpFieldPtr &objFieldPtr) {
282  if (!is_field_set) {
283  if (!objFieldPtr.get()) {
284  objFieldPtr = fieldPtr;
285  }
286  } else {
287  objFieldPtr.reset();
288  }
289  }
290  // This function will be called to ge intersection of ecmp fields
299  }
300  //This function used to calculate the Change in ecmp fields
301  void CalculateChangeInEcmpFields(const EcmpLoadBalance &ecmp_load_balance,
302  EcmpHashFields& ecmp_hash_fields) {
303  SetChangeInHashField(ecmp_load_balance.is_source_ip_set(),
304  ecmp_hash_fields.sip_, sip_);
305  SetChangeInHashField(ecmp_load_balance.is_destination_ip_set(),
306  ecmp_hash_fields.dip_, dip_);
307  SetChangeInHashField(ecmp_load_balance.is_ip_protocol_set(),
308  ecmp_hash_fields.proto_, proto_);
309  SetChangeInHashField(ecmp_load_balance.is_source_port_set(),
310  ecmp_hash_fields.sport_, sport_);
311  SetChangeInHashField(ecmp_load_balance.is_destination_port_set(),
312  ecmp_hash_fields.dport_, dport_);
313  }
314 
317  }
318 
321  }
322 
323  void Reset() {
324  sip_ = NULL;
325  dip_ = NULL;
326  proto_ = NULL;
327  sport_ = NULL;
328  dport_ = NULL;
329  }
330 
331 private:
332  // This will have latest computed value
341 };
342 #endif
uint32_t RefCount() const
friend void intrusive_ptr_add_ref(EcmpField *ptr)
friend void intrusive_ptr_release(EcmpField *ptr)
std::atomic< uint32_t > ref_count_
void CalculateChangeInEcmpFields(const EcmpLoadBalance &ecmp_load_balance, EcmpHashFields &ecmp_hash_fields)
uint8_t comp_hash_fields_to_use_
EcmpFieldPtr sip_
void SetChangeInHashField(bool is_field_set, EcmpFieldPtr &fieldPtr, EcmpFieldPtr &objFieldPtr)
boost::intrusive_ptr< EcmpField > EcmpFieldPtr
uint8_t HashFieldsToUse() const
DISALLOW_COPY_AND_ASSIGN(EcmpHashFields)
EcmpHashFields(const uint8_t hash_fields_to_use)
uint8_t CalculateHashFieldsToUse()
void SetHashFieldtoUse(EcmpField *ptr, uint8_t key)
EcmpFieldPtr sport_
EcmpFieldPtr dip_
void operator=(const uint8_t hash_fields_to_use)
uint8_t hash_fields_to_use_
EcmpFieldPtr dport_
EcmpFieldPtr proto_
bool UpdateFields(const autogen::EcmpHashingIncludeFields &ecmp_hashing_fields)
virtual ~EcmpLoadBalance()
bool is_ip_protocol_set() const
virtual void Copy(const EcmpLoadBalance &rhs)
bool is_destination_port_set() const
bool AllSet() const
const std::string & destination_port_str() const
const std::string & source_port_str() const
const std::string & ip_protocol_str() const
bool is_destination_ip_set() const
const std::string & source_ip_str() const
bool hash_fields_to_use_[NUM_HASH_FIELDS]
bool is_source_ip_set() const
bool operator!=(const EcmpLoadBalance &rhs) const
const std::string & destination_ip_str() const
bool is_source_port_set() const
void GetStringVector(std::vector< std::string > &string_vector) const
bool use_global_vrouter() const
void set_use_global_vrouter(bool use_global_vrouter)
virtual void Copy(const VmiEcmpLoadBalance &rhs)
static const std::string LoadBalanceDecision
static const std::string HashingFieldsStr[]
void intrusive_ptr_add_ref(EcmpField *ptr)
void intrusive_ptr_release(EcmpField *ptr)