Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef vnsw_agent_nexthop_hpp
6 : #define vnsw_agent_nexthop_hpp
7 :
8 : #include <netinet/in.h>
9 : #include <net/ethernet.h>
10 :
11 : #include <cmn/agent_cmn.h>
12 : #include <agent_types.h>
13 :
14 : #include <oper/interface_common.h>
15 : #include <oper/vrf.h>
16 : #include <oper/ecmp_load_balance.h>
17 :
18 : class NextHopKey;
19 : class MplsLabel;
20 :
21 : template <typename Member>
22 : class MemberList {
23 : public:
24 : const static uint32_t kInvalidIndex = 0xffff;
25 : MemberList(int max_size) : max_size_(max_size), free_index_(0), hash_id(0) {
26 : }
27 :
28 : MemberList():max_size_(64), free_index_(0), hash_id(0) {
29 : }
30 :
31 : ~MemberList() {
32 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
33 : if (mbr_list_[i]) {
34 : delete mbr_list_[i];
35 : }
36 : }
37 : }
38 :
39 : typedef typename std::vector<Member *>::iterator iterator;
40 : typedef typename std::vector<Member *>::const_iterator const_iterator;
41 :
42 : int insert(const Member &mbr) {
43 : if (mbr_list_.size() >= kInvalidIndex) {
44 : return kInvalidIndex;
45 : }
46 :
47 : if (mbr_list_.size() < free_index_ + 1) {
48 : mbr_list_.resize(free_index_ + 1);
49 : hash_table_.resize(free_index_ + 1);
50 : }
51 :
52 : Member *entry = new Member(mbr);
53 : mbr_list_[free_index_] = entry;
54 : UpdateFreeIndex();
55 : UpdateHashTable();
56 : return free_index_;
57 : }
58 :
59 : bool remove(const Member &mbr) {
60 : uint32_t i = 0;
61 : for (i = 0; i < mbr_list_.size(); i++) {
62 : if (mbr_list_[i] && *mbr_list_[i] == mbr) {
63 : delete mbr_list_[i];
64 : mbr_list_[i] = NULL;
65 : break;
66 : }
67 : }
68 :
69 : if (i == mbr_list_.size()) {
70 : return false;
71 : }
72 : UpdateFreeIndex();
73 : UpdateHashTable();
74 : return true;
75 : }
76 :
77 : bool remove(uint32_t index) {
78 : if (index >= mbr_list_.size()) {
79 : return false;
80 : }
81 : if (mbr_list_[index] != NULL) {
82 : delete mbr_list_[index];
83 : mbr_list_[index] = NULL;
84 : UpdateFreeIndex();
85 : UpdateHashTable();
86 : }
87 : return true;
88 : }
89 :
90 : void UpdateHashTable() {
91 : hash_table_.clear();
92 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
93 : if (mbr_list_[i] == NULL) {
94 : hash_table_.push_back(0xffff);
95 : continue;
96 : }
97 : hash_table_.push_back(i);
98 : }
99 : }
100 :
101 : void UpdateFreeIndex() {
102 : uint32_t i;
103 : for (i = 0; i < mbr_list_.size(); i++) {
104 : if (mbr_list_[i] == NULL) {
105 : free_index_ = i;
106 : return;
107 : }
108 : }
109 : free_index_ = i;
110 : }
111 :
112 : void UpdateFreeIndex(uint32_t index) {
113 : if (index > free_index_) {
114 : return;
115 : }
116 : UpdateFreeIndex();
117 : }
118 :
119 : void replace(std::vector<Member> list) {
120 : //Add new elements, which are not presnet in member list
121 : typename std::vector<Member>::const_iterator it = list.begin();
122 : while (it != list.end()) {
123 : Member mem = *it;
124 : if (!Find(mem)) {
125 : insert(mem);
126 : }
127 : it++;
128 : }
129 :
130 : //Remove elements present member list, but not in new list
131 : iterator mbr_list_iterator = begin();
132 : while (mbr_list_iterator != end()) {
133 : const Member *member = *mbr_list_iterator;
134 : if (!member) {
135 : mbr_list_iterator++;
136 : continue;
137 : }
138 : it = list.begin();
139 : while (it != list.end()) {
140 : const Member *latest_member = &(*it);
141 : if (latest_member && *latest_member == *member) {
142 : break;
143 : }
144 : it++;
145 : }
146 : if (it == list.end()) {
147 : remove(*member);
148 : }
149 : mbr_list_iterator++;
150 : }
151 : }
152 :
153 : void clear() {
154 : hash_table_.clear();
155 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
156 : if (mbr_list_[i]) {
157 : delete mbr_list_[i];
158 : }
159 : }
160 : mbr_list_.clear();
161 : free_index_ = 0;
162 : }
163 :
164 : size_t HashTableSize() const {
165 : return hash_table_.size();
166 : }
167 :
168 : iterator begin() { return iterator(mbr_list_.begin());};
169 : iterator end() { return iterator(mbr_list_.end());};
170 :
171 : const_iterator begin() const {
172 : return const_iterator(mbr_list_.begin());
173 : }
174 : const_iterator end() const {
175 : return const_iterator(mbr_list_.end());
176 : }
177 :
178 : Member* Find(const Member &mem) const {
179 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
180 : if (mbr_list_[i] && *mbr_list_[i] == mem) {
181 : return mbr_list_[i];
182 : }
183 : }
184 : return NULL;
185 : }
186 :
187 : Member* Find(const Member &mem, uint32_t &index) const{
188 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
189 : if (mbr_list_[i] && *mbr_list_[i] == mem) {
190 : index = i;
191 : return mbr_list_[i];
192 : }
193 : }
194 : return NULL;
195 : }
196 :
197 : const Member* Get(uint32_t idx) const {
198 : return mbr_list_[idx];
199 : }
200 :
201 : size_t size() const {
202 : return mbr_list_.size();
203 : }
204 :
205 : uint32_t hash(size_t hash) const {
206 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
207 : if (hash_table_[hash % hash_table_.size()] != 0xffff) {
208 : return hash_table_[hash % hash_table_.size()];
209 : }
210 : hash++;
211 : }
212 : return 0;
213 : }
214 :
215 : uint32_t count() const {
216 : int cnt = 0;
217 : for (uint32_t i = 0; i < mbr_list_.size(); i++) {
218 : if (mbr_list_[i] != NULL)
219 : cnt++;
220 : }
221 :
222 : return cnt;
223 : }
224 :
225 : private:
226 : std::vector<Member *> mbr_list_;
227 : std::vector<uint32_t> hash_table_;
228 : uint32_t max_size_;
229 : uint32_t free_index_;
230 : uint32_t hash_id;
231 : };
232 :
233 : /////////////////////////////////////////////////////////////////////////////
234 : // Class to manage supported tunnel-types
235 : /////////////////////////////////////////////////////////////////////////////
236 : class TunnelType {
237 : public:
238 : // Various tunnel-types supported
239 : enum Type {
240 : INVALID,
241 : MPLS_GRE,
242 : MPLS_UDP,
243 : VXLAN,
244 : NATIVE,
245 : MPLS_OVER_MPLS
246 : };
247 : // Bitmap of supported tunnel types
248 : typedef uint32_t TypeBmap;
249 : typedef std::list<Type> PriorityList;
250 :
251 42050 : TunnelType(Type type) : type_(type) { }
252 42384 : ~TunnelType() { }
253 194 : bool Compare(const TunnelType &rhs) const {
254 194 : return type_ == rhs.type_;
255 : }
256 164 : bool IsLess(const TunnelType &rhs) const {
257 164 : return type_ < rhs.type_;
258 : }
259 :
260 20 : std::string ToString() const {
261 20 : switch (type_) {
262 10 : case MPLS_GRE:
263 10 : return "MPLSoGRE";
264 0 : case MPLS_UDP:
265 0 : return "MPLSoUDP";
266 10 : case VXLAN:
267 10 : return "VXLAN";
268 0 : case NATIVE:
269 0 : return "Native";
270 0 : case MPLS_OVER_MPLS:
271 0 : return "MPLSoMPLS";
272 0 : default:
273 0 : break;
274 : }
275 0 : return "UNKNOWN";
276 : }
277 :
278 0 : static std::string GetString(uint32_t type) {
279 0 : std::ostringstream tunnel_type;
280 0 : if (type & (1 << MPLS_GRE)) {
281 0 : tunnel_type << "MPLSoGRE ";
282 : }
283 :
284 0 : if (type & (1 << MPLS_UDP)) {
285 0 : tunnel_type << "MPLSoUDP ";
286 : }
287 :
288 0 : if (type & ( 1 << VXLAN)) {
289 0 : tunnel_type << "VxLAN";
290 : }
291 :
292 0 : if (type & (1 << NATIVE)) {
293 0 : tunnel_type << "Underlay";
294 : }
295 :
296 0 : if (type & (1 << MPLS_OVER_MPLS)) {
297 0 : tunnel_type << "MPLSoMPLS";
298 : }
299 :
300 0 : return tunnel_type.str();
301 0 : }
302 :
303 214 : Type GetType() const {return type_;}
304 11 : void SetType(TunnelType::Type type) {type_ = type;}
305 :
306 1 : static void SetDefaultType(Type type) {default_type_ = type;}
307 : static Type ComputeType(TypeBmap bmap);
308 : static Type DefaultMplsComputeType();
309 132 : static Type DefaultType() {return default_type_;}
310 : static TypeBmap DefaultTypeBmap() {return (1 << DefaultType());}
311 53 : static TypeBmap VxlanType() {return (1 << VXLAN);};
312 116 : static TypeBmap MplsType() {return ((1 << MPLS_GRE) | (1 << MPLS_UDP));};
313 2075 : static TypeBmap MplsoMplsType() {return (1 << MPLS_OVER_MPLS);};
314 7 : static TypeBmap GetTunnelBmap(TunnelType::Type type) {
315 7 : if (type == MPLS_GRE || type == MPLS_UDP)
316 2 : return TunnelType::MplsType();
317 5 : if (type == VXLAN)
318 5 : return TunnelType::VxlanType();
319 0 : return TunnelType::AllType();
320 : }
321 634 : static TypeBmap AllType() {return ((1 << MPLS_GRE) | (1 << MPLS_UDP) |
322 634 : (1 << VXLAN));}
323 2012 : static TypeBmap GREType() {return (1 << MPLS_GRE);}
324 78 : static TypeBmap UDPType() {return (1 << MPLS_UDP);}
325 56 : static TypeBmap NativeType() {return (1 << NATIVE);}
326 : static TypeBmap MPLSType() {return (1 << MPLS_OVER_MPLS);}
327 : static bool EncapPrioritySync(const std::vector<std::string> &cfg_list);
328 : static void DeletePriorityList();
329 :
330 : private:
331 : Type type_;
332 : static PriorityList priority_list_;
333 : static Type default_type_;
334 : };
335 :
336 : /////////////////////////////////////////////////////////////////////////////
337 : // Base class for NextHop. Implementation of specific NextHop must
338 : // derive from this class
339 : /////////////////////////////////////////////////////////////////////////////
340 : class NextHop : AgentRefCount<NextHop>, public AgentDBEntry {
341 : public:
342 : static const uint32_t kInvalidIndex = 0xFFFFFFFF;
343 : enum Type {
344 : INVALID,
345 : DISCARD,
346 : L2_RECEIVE,
347 : RECEIVE,
348 : RESOLVE,
349 : ARP,
350 : VRF,
351 : INTERFACE,
352 : TUNNEL,
353 : MIRROR,
354 : COMPOSITE,
355 : VLAN,
356 : PBB,
357 : NDP
358 : };
359 :
360 335 : NextHop(Type type, bool policy) :
361 335 : type_(type), valid_(true), policy_(policy), id_(kInvalidIndex),
362 335 : mpls_label_(), learning_enabled_(false), etree_leaf_(false) {}
363 1024 : NextHop(Type type, bool valid, bool policy) :
364 1024 : type_(type), valid_(valid), policy_(policy), id_(kInvalidIndex),
365 1024 : mpls_label_(), learning_enabled_(false), etree_leaf_(false) {}
366 : virtual ~NextHop();
367 :
368 0 : virtual std::string ToString() const { return "NH";}
369 : virtual void Add(Agent *agent, const DBRequest *req);
370 : virtual bool ChangeEntry(const DBRequest *req) = 0;
371 : virtual void Change(const DBRequest *req);
372 0 : virtual void Delete(const DBRequest *req) {};
373 : virtual void SetKey(const DBRequestKey *key);
374 : virtual bool NextHopIsLess(const DBEntry &rhs) const = 0;
375 : virtual void SendObjectLog(const NextHopTable *table,
376 : AgentLogEvent::type event) const;
377 : virtual bool CanAdd() const = 0;
378 10633 : virtual bool IsLess(const DBEntry &rhs) const {
379 10633 : const NextHop &a = static_cast<const NextHop &>(rhs);
380 10633 : if (type_ != a.type_) {
381 3257 : return type_ < a.type_;
382 : }
383 7376 : if (policy_ != a.policy_) {
384 978 : return policy_ < a.policy_;
385 : }
386 6398 : bool ret = NextHopIsLess(rhs);
387 6398 : return ret;
388 : }
389 :
390 4 : virtual bool DeleteOnZeroRefCount() const {
391 4 : return false;
392 : }
393 14 : virtual void OnZeroRefCount() {};
394 :
395 130 : uint32_t GetRefCount() const {
396 130 : return AgentRefCount<NextHop>::GetRefCount();
397 : }
398 :
399 137 : void ResetMplsRef() {
400 137 : if (mpls_label_.get() != NULL) {
401 68 : mpls_label_.reset();
402 : }
403 137 : }
404 :
405 6936 : Type GetType() const {return type_;}
406 1189 : bool IsValid() const {return valid_;};
407 1448 : bool PolicyEnabled() const {return policy_;};
408 2121 : uint32_t id() const { return id_;}
409 130 : void set_id(uint32_t index) { id_ = index;}
410 :
411 : void set_etree_leaf(bool val) {
412 : etree_leaf_ = val;
413 : }
414 :
415 366 : bool etree_leaf() const {
416 366 : return etree_leaf_;
417 : }
418 :
419 : void set_learning_flag(bool val) {
420 : learning_enabled_ = val;
421 : }
422 :
423 1112 : bool learning_enabled() const {
424 1112 : return learning_enabled_;
425 : }
426 :
427 : bool DBEntrySandesh(Sandesh *sresp, std::string &name) const;
428 : void SetNHSandeshData(NhSandeshData &data) const;
429 : static void FillObjectLogIntf(const Interface *intf,
430 : NextHopObjectLogInfo &info);
431 : static void FillObjectLogMac(const unsigned char *m,
432 : NextHopObjectLogInfo &info);
433 : bool NexthopToInterfacePolicy() const;
434 124 : const MplsLabel *mpls_label() const {
435 124 : return mpls_label_.get();
436 : }
437 :
438 : virtual bool MatchEgressData(const NextHop *nh) const = 0;
439 : MplsLabel *AllocateLabel(Agent *agent, const NextHopKey *key);
440 : virtual bool NeedMplsLabel() = 0;
441 : void PostAdd();
442 : void EnqueueResync() const;
443 : protected:
444 : void FillObjectLog(AgentLogEvent::type event,
445 : NextHopObjectLogInfo &info) const;
446 : Type type_;
447 : bool valid_;
448 : bool policy_;
449 : uint32_t id_;
450 : MplsLabelRef mpls_label_;
451 : bool learning_enabled_;
452 : bool etree_leaf_;
453 : private:
454 : DISALLOW_COPY_AND_ASSIGN(NextHop);
455 : };
456 :
457 : class NextHopData : public AgentData {
458 : public:
459 29 : NextHopData() : AgentData(), learning_enabled_(false), etree_leaf_(false) {};
460 224 : NextHopData(bool learning_enabled, bool etree_leaf):
461 224 : learning_enabled_(learning_enabled), etree_leaf_(etree_leaf) {}
462 253 : virtual ~NextHopData() {};
463 : protected:
464 : bool learning_enabled_;
465 : bool etree_leaf_;
466 : DISALLOW_COPY_AND_ASSIGN(NextHopData);
467 : };
468 :
469 : class NextHopKey : public AgentKey {
470 : public:
471 1138 : NextHopKey(NextHop::Type type, bool policy) :
472 1138 : AgentKey(), type_(type), policy_(policy) { }
473 1138 : virtual ~NextHopKey() { };
474 :
475 : virtual NextHop *AllocEntry() const = 0;
476 : virtual NextHopKey *Clone() const = 0;
477 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
478 0 : assert(0);
479 : return false;
480 : }
481 4521 : bool IsEqual(const NextHopKey &rhs) const {
482 4521 : if (type_ != rhs.type_) {
483 0 : return false;
484 : }
485 4521 : if (policy_ != rhs.policy_) {
486 0 : return false;
487 : }
488 8725 : if (NextHopKeyIsLess(rhs) == false &&
489 4204 : rhs.NextHopKeyIsLess(*this) == false) {
490 4072 : return true;
491 : }
492 449 : return false;
493 : }
494 :
495 5 : void SetPolicy(bool policy) {
496 5 : policy_ = policy;
497 5 : };
498 :
499 712 : NextHop::Type GetType() const {return type_;}
500 9 : bool GetPolicy() const {return policy_;}
501 1878 : bool IsLess(const NextHopKey &rhs) const {
502 1878 : if (type_ != rhs.type_) {
503 36 : return type_ < rhs.type_;
504 : }
505 1842 : if (policy_ != rhs.policy_) {
506 174 : return policy_;
507 : }
508 1668 : return NextHopKeyIsLess(rhs);
509 : }
510 : protected:
511 : friend class NextHop;
512 : NextHop::Type type_;
513 : bool policy_;
514 : private:
515 : DISALLOW_COPY_AND_ASSIGN(NextHopKey);
516 : };
517 :
518 : /////////////////////////////////////////////////////////////////////////////
519 : // Discard NH definition
520 : /////////////////////////////////////////////////////////////////////////////
521 : class DiscardNHKey : public NextHopKey {
522 : public:
523 24 : DiscardNHKey() : NextHopKey(NextHop::DISCARD, false) { };
524 39 : virtual ~DiscardNHKey() { };
525 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
526 : // There is single DiscardNH. There is no field to compare
527 0 : return false;
528 : }
529 :
530 8 : virtual NextHopKey *Clone() const { return new DiscardNHKey(); }
531 : private:
532 :
533 : virtual NextHop *AllocEntry() const;
534 : private:
535 : DISALLOW_COPY_AND_ASSIGN(DiscardNHKey);
536 : };
537 :
538 : class DiscardNHData : public NextHopData {
539 : public:
540 1 : DiscardNHData() : NextHopData() {};
541 2 : virtual ~DiscardNHData() {};
542 : private:
543 : DISALLOW_COPY_AND_ASSIGN(DiscardNHData);
544 : };
545 :
546 : class DiscardNH : public NextHop {
547 : public:
548 219 : DiscardNH() : NextHop(DISCARD, true, false) { };
549 237 : virtual ~DiscardNH() { };
550 :
551 0 : virtual std::string ToString() const { return "DISCARD"; };
552 : // No change expected to Discard NH */
553 4 : virtual bool ChangeEntry(const DBRequest *req) { return false; };
554 1 : virtual void Delete(const DBRequest *req) {};
555 438 : virtual bool NextHopIsLess(const DBEntry &rhs) const { return false; };
556 0 : virtual void SetKey(const DBRequestKey *key) { NextHop::SetKey(key); };
557 : virtual bool CanAdd() const;
558 3 : virtual KeyPtr GetDBRequestKey() const {
559 3 : return DBEntryBase::KeyPtr(new DiscardNHKey());
560 : };
561 :
562 0 : virtual bool MatchEgressData(const NextHop *nh) const {
563 0 : return false;
564 : }
565 4 : virtual bool NeedMplsLabel() { return false; }
566 : static void Create();
567 :
568 : private:
569 : DISALLOW_COPY_AND_ASSIGN(DiscardNH);
570 : };
571 :
572 : /////////////////////////////////////////////////////////////////////////////
573 : // Bridge Receive NH definition
574 : /////////////////////////////////////////////////////////////////////////////
575 : class L2ReceiveNHKey : public NextHopKey {
576 : public:
577 5 : L2ReceiveNHKey() : NextHopKey(NextHop::L2_RECEIVE, false) { }
578 9 : virtual ~L2ReceiveNHKey() { }
579 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
580 : // There is single Bridge Receive NH. There is no field to compare
581 0 : return false;
582 : }
583 0 : virtual NextHopKey *Clone() const { return new L2ReceiveNHKey(); }
584 :
585 : private:
586 :
587 : virtual NextHop *AllocEntry() const;
588 : private:
589 : DISALLOW_COPY_AND_ASSIGN(L2ReceiveNHKey);
590 : };
591 :
592 : class L2ReceiveNHData : public NextHopData {
593 : public:
594 1 : L2ReceiveNHData() : NextHopData() {};
595 2 : virtual ~L2ReceiveNHData() {};
596 : private:
597 : DISALLOW_COPY_AND_ASSIGN(L2ReceiveNHData);
598 : };
599 :
600 : class L2ReceiveNH : public NextHop {
601 : public:
602 5 : L2ReceiveNH() : NextHop(L2_RECEIVE, true, false) { };
603 10 : virtual ~L2ReceiveNH() { };
604 :
605 0 : virtual std::string ToString() const { return "L2-Receive"; };
606 : // No change expected to Discard NH */
607 1 : virtual bool ChangeEntry(const DBRequest *req) { return false; };
608 1 : virtual void Delete(const DBRequest *req) {};
609 9 : virtual bool NextHopIsLess(const DBEntry &rhs) const { return false; };
610 0 : virtual void SetKey(const DBRequestKey *key) { NextHop::SetKey(key); };
611 : virtual bool CanAdd() const;
612 3 : virtual KeyPtr GetDBRequestKey() const {
613 3 : return DBEntryBase::KeyPtr(new L2ReceiveNHKey());
614 : };
615 :
616 0 : virtual bool MatchEgressData(const NextHop *nh) const {
617 0 : return false;
618 : }
619 1 : virtual bool NeedMplsLabel() { return false; }
620 : static void Create();
621 :
622 : private:
623 : DISALLOW_COPY_AND_ASSIGN(L2ReceiveNH);
624 : };
625 :
626 : /////////////////////////////////////////////////////////////////////////////
627 : // Receive NH definition
628 : /////////////////////////////////////////////////////////////////////////////
629 : class ReceiveNHKey : public NextHopKey {
630 : public:
631 25 : ReceiveNHKey(InterfaceKey *intf_key, bool policy) :
632 25 : NextHopKey(NextHop::RECEIVE, policy), intf_key_(intf_key) {
633 25 : }
634 39 : virtual ~ReceiveNHKey() { };
635 : virtual NextHop *AllocEntry() const;
636 0 : virtual NextHopKey *Clone() const {
637 0 : return new ReceiveNHKey(intf_key_->Clone(), policy_);
638 : }
639 :
640 : private:
641 : friend class ReceiveNH;
642 : boost::scoped_ptr<InterfaceKey> intf_key_;
643 : DISALLOW_COPY_AND_ASSIGN(ReceiveNHKey);
644 : };
645 :
646 : class ReceiveNHData : public NextHopData {
647 : public:
648 4 : ReceiveNHData() : NextHopData() {};
649 8 : virtual ~ReceiveNHData() {};
650 :
651 : private:
652 : friend class ReceiveNH;
653 : DISALLOW_COPY_AND_ASSIGN(ReceiveNHData);
654 : };
655 :
656 : class ReceiveNH : public NextHop {
657 : public:
658 25 : ReceiveNH(Interface *intf, bool policy) :
659 25 : NextHop(RECEIVE, true, policy), interface_(intf) { };
660 50 : virtual ~ReceiveNH() { };
661 :
662 : virtual void SetKey(const DBRequestKey *key);
663 0 : virtual std::string ToString() const { return "Local Receive"; };
664 : // No change expected to Receive NH */
665 8 : virtual bool ChangeEntry(const DBRequest *req) { return false;};
666 2 : virtual void Delete(const DBRequest *req) {};
667 : virtual void SendObjectLog(const NextHopTable *table,
668 : AgentLogEvent::type event) const;
669 : virtual bool CanAdd() const;
670 48 : virtual bool NextHopIsLess(const DBEntry &rhs) const {
671 48 : const ReceiveNH &a = static_cast<const ReceiveNH &>(rhs);
672 48 : return interface_.get() < a.interface_.get();
673 : };
674 :
675 6 : virtual KeyPtr GetDBRequestKey() const {
676 : return DBEntryBase::KeyPtr
677 12 : (new ReceiveNHKey(dynamic_cast<InterfaceKey *>(interface_->GetDBRequestKey().release()),
678 12 : policy_));
679 : };
680 :
681 : static void CreateReq(const string &interface);
682 : static void Create(NextHopTable *table, const Interface *intf,
683 : bool policy);
684 : static void Delete(NextHopTable *table, const Interface *intf,
685 : bool policy);
686 60 : const Interface *GetInterface() const {return interface_.get();};
687 :
688 0 : virtual bool MatchEgressData(const NextHop *nh) const {
689 0 : return false;
690 : }
691 :
692 8 : virtual bool NeedMplsLabel() { return false; }
693 : private:
694 : InterfaceRef interface_;
695 : DISALLOW_COPY_AND_ASSIGN(ReceiveNH);
696 : };
697 :
698 : /////////////////////////////////////////////////////////////////////////////
699 : // Resolve NH definition
700 : /////////////////////////////////////////////////////////////////////////////
701 : class ResolveNHKey : public NextHopKey {
702 : public:
703 4 : ResolveNHKey(const InterfaceKey *intf_key, bool policy) :
704 : NextHopKey(NextHop::RESOLVE, policy),
705 4 : intf_key_(intf_key->Clone()) { };
706 7 : virtual ~ResolveNHKey() { };
707 :
708 : virtual NextHop *AllocEntry() const;
709 0 : virtual NextHopKey *Clone() const {
710 0 : return new ResolveNHKey(intf_key_->Clone(), policy_);
711 : }
712 : private:
713 : friend class ResolveNH;
714 : boost::scoped_ptr<const InterfaceKey> intf_key_;
715 : DISALLOW_COPY_AND_ASSIGN(ResolveNHKey);
716 : };
717 :
718 : class ResolveNHData : public NextHopData {
719 : public:
720 1 : ResolveNHData() : NextHopData() {};
721 2 : virtual ~ResolveNHData() { };
722 :
723 : private:
724 : friend class ResolveNH;
725 : DISALLOW_COPY_AND_ASSIGN(ResolveNHData);
726 : };
727 :
728 : class ResolveNH : public NextHop {
729 : public:
730 4 : ResolveNH(const Interface *intf, bool policy) :
731 4 : NextHop(RESOLVE, true, policy), interface_(intf) { };
732 8 : virtual ~ResolveNH() { };
733 :
734 0 : virtual std::string ToString() const { return "Resolve"; };
735 : // No change expected to Resolve NH */
736 1 : virtual bool ChangeEntry(const DBRequest *req) { return false;};
737 1 : virtual void Delete(const DBRequest *req) {};
738 0 : virtual void SetKey(const DBRequestKey *key) { NextHop::SetKey(key); };
739 : virtual bool CanAdd() const;
740 8 : virtual bool NextHopIsLess(const DBEntry &rhs) const {
741 8 : const ResolveNH &a = static_cast<const ResolveNH &>(rhs);
742 8 : return interface_.get() < a.interface_.get();
743 : };
744 2 : virtual KeyPtr GetDBRequestKey() const {
745 : boost::scoped_ptr<InterfaceKey> intf_key(
746 2 : static_cast<InterfaceKey *>(interface_->GetDBRequestKey().release()));
747 4 : return DBEntryBase::KeyPtr(new ResolveNHKey(intf_key.get(), policy_));
748 2 : };
749 1 : virtual bool DeleteOnZeroRefCount() const {
750 1 : return true;
751 : }
752 : static void Create(const InterfaceKey *intf, bool policy);
753 : static void CreateReq(const InterfaceKey *intf, bool policy);
754 24 : const Interface* get_interface() const { return interface_.get();}
755 :
756 0 : virtual bool MatchEgressData(const NextHop *nh) const {
757 0 : return false;
758 : }
759 1 : virtual bool NeedMplsLabel() { return false; }
760 :
761 : private:
762 : InterfaceConstRef interface_;
763 : DISALLOW_COPY_AND_ASSIGN(ResolveNH);
764 : };
765 :
766 : /////////////////////////////////////////////////////////////////////////////
767 : // ARP NH definition
768 : /////////////////////////////////////////////////////////////////////////////
769 : class ArpNHKey : public NextHopKey {
770 : public:
771 16 : ArpNHKey(const string &vrf_name, const Ip4Address &ip, bool policy) :
772 16 : NextHopKey(NextHop::ARP, policy), vrf_key_(vrf_name), dip_(ip) {
773 16 : }
774 23 : virtual ~ArpNHKey() { };
775 :
776 : virtual NextHop *AllocEntry() const;
777 0 : virtual NextHopKey *Clone() const {
778 0 : return new ArpNHKey(vrf_key_.name_, dip_, policy_);
779 : }
780 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
781 0 : const ArpNHKey &key = static_cast<const ArpNHKey &>(rhs);
782 0 : if (vrf_key_.IsEqual(key.vrf_key_) == false) {
783 0 : return vrf_key_.IsLess(key.vrf_key_);
784 : }
785 :
786 0 : if (dip_ != key.dip_) {
787 0 : return dip_ < key.dip_;
788 : }
789 :
790 0 : return false;
791 : }
792 : private:
793 : friend class ArpNH;
794 : VrfKey vrf_key_;
795 : Ip4Address dip_;
796 : DISALLOW_COPY_AND_ASSIGN(ArpNHKey);
797 : };
798 :
799 : class ArpNHData : public NextHopData {
800 : public:
801 2 : ArpNHData(InterfaceKey *intf_key) :
802 2 : NextHopData(), intf_key_(intf_key),
803 2 : mac_(), resolved_(false), valid_(false) { };
804 :
805 3 : ArpNHData(const MacAddress &mac, InterfaceKey *intf_key,
806 3 : bool resolved) : NextHopData(), intf_key_(intf_key), mac_(mac),
807 3 : resolved_(resolved), valid_(true) {
808 3 : }
809 10 : virtual ~ArpNHData() { };
810 :
811 : private:
812 : friend class ArpNH;
813 : boost::scoped_ptr<InterfaceKey> intf_key_;
814 : MacAddress mac_;
815 : bool resolved_;
816 : bool valid_;
817 : DISALLOW_COPY_AND_ASSIGN(ArpNHData);
818 : };
819 :
820 : class ArpNH : public NextHop {
821 : public:
822 16 : ArpNH(VrfEntry *vrf, const Ip4Address &ip) :
823 16 : NextHop(ARP, false, false), vrf_(vrf, this), ip_(ip), interface_(), mac_() {};
824 32 : virtual ~ArpNH() { };
825 :
826 0 : virtual std::string ToString() { return "ARP"; }
827 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
828 : virtual void SetKey(const DBRequestKey *key);
829 : virtual bool ChangeEntry(const DBRequest *req);
830 1 : virtual void Delete(const DBRequest *req) {};
831 : virtual KeyPtr GetDBRequestKey() const;
832 : virtual void SendObjectLog(const NextHopTable *table,
833 : AgentLogEvent::type event) const;
834 : virtual bool CanAdd() const;
835 :
836 15 : const MacAddress &GetMac() const {return mac_;};
837 36 : const Interface *GetInterface() const {return interface_.get();};
838 : const boost::uuids::uuid &GetIfUuid() const;
839 : const uint32_t vrf_id() const;
840 22 : const Ip4Address *GetIp() const {return &ip_;};
841 9 : const VrfEntry *GetVrf() const {return vrf_.get();};
842 2 : bool GetResolveState() const {return valid_;}
843 1 : virtual bool DeleteOnZeroRefCount() const {
844 1 : return true;
845 : }
846 :
847 0 : virtual bool MatchEgressData(const NextHop *nh) const {
848 0 : const ArpNH *arp_nh = dynamic_cast<const ArpNH *>(nh);
849 0 : if (arp_nh && vrf_ == arp_nh->vrf_ && ip_ == arp_nh->ip_) {
850 0 : return true;
851 : }
852 0 : return false;
853 : }
854 4 : virtual bool NeedMplsLabel() { return false; }
855 :
856 : private:
857 : VrfEntryRef vrf_;
858 : Ip4Address ip_;
859 : InterfaceRef interface_;
860 : MacAddress mac_;
861 : DISALLOW_COPY_AND_ASSIGN(ArpNH);
862 : };
863 :
864 : /////////////////////////////////////////////////////////////////////////////
865 : // NDP NH definition
866 : /////////////////////////////////////////////////////////////////////////////
867 : class NdpNHKey : public NextHopKey {
868 : public:
869 0 : NdpNHKey(const string &vrf_name, const IpAddress &ip, bool policy) :
870 0 : NextHopKey(NextHop::NDP, policy), vrf_key_(vrf_name), dip_(ip) {
871 0 : }
872 0 : virtual ~NdpNHKey() { };
873 :
874 : virtual NextHop *AllocEntry() const;
875 0 : virtual NextHopKey *Clone() const {
876 0 : return new NdpNHKey(vrf_key_.name_, dip_, policy_);
877 : }
878 : string ToString() {
879 : return vrf_key_.name_ + dip_.to_string();
880 : }
881 : private:
882 : friend class NdpNH;
883 : VrfKey vrf_key_;
884 : IpAddress dip_;
885 : DISALLOW_COPY_AND_ASSIGN(NdpNHKey);
886 : };
887 :
888 : class NdpNHData : public NextHopData {
889 : public:
890 : NdpNHData(InterfaceKey *intf_key) :
891 : NextHopData(), intf_key_(intf_key),
892 : mac_(), resolved_(false), valid_(false) { };
893 :
894 0 : NdpNHData(const MacAddress &mac, InterfaceKey *intf_key,
895 0 : bool resolved) : NextHopData(), intf_key_(intf_key), mac_(mac),
896 0 : resolved_(resolved), valid_(true) {
897 0 : }
898 0 : virtual ~NdpNHData() { };
899 :
900 : private:
901 : friend class NdpNH;
902 : boost::scoped_ptr<InterfaceKey> intf_key_;
903 : MacAddress mac_;
904 : bool resolved_;
905 : bool valid_;
906 : DISALLOW_COPY_AND_ASSIGN(NdpNHData);
907 : };
908 :
909 : class NdpNH : public NextHop {
910 : public:
911 0 : NdpNH(VrfEntry *vrf, const IpAddress &ip) :
912 0 : NextHop(NDP, false, false), vrf_(vrf, this), ip_(ip), interface_(), mac_() {};
913 0 : virtual ~NdpNH() { };
914 :
915 0 : virtual std::string ToString() { return "NDP"; }
916 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
917 : virtual void SetKey(const DBRequestKey *key);
918 : virtual bool ChangeEntry(const DBRequest *req);
919 0 : virtual void Delete(const DBRequest *req) {};
920 : virtual KeyPtr GetDBRequestKey() const;
921 : virtual void SendObjectLog(const NextHopTable *table,
922 : AgentLogEvent::type event) const;
923 : virtual bool CanAdd() const;
924 :
925 0 : const MacAddress &GetMac() const {return mac_;};
926 0 : const Interface *GetInterface() const {return interface_.get();};
927 : const boost::uuids::uuid &GetIfUuid() const;
928 : const uint32_t vrf_id() const;
929 0 : const IpAddress *GetIp() const {return &ip_;};
930 0 : const VrfEntry *GetVrf() const {return vrf_.get();};
931 0 : bool GetResolveState() const {return valid_;}
932 0 : virtual bool DeleteOnZeroRefCount() const {
933 0 : return true;
934 : }
935 :
936 0 : virtual bool MatchEgressData(const NextHop *nh) const {
937 0 : const NdpNH *ndp_nh = dynamic_cast<const NdpNH *>(nh);
938 0 : if (ndp_nh && vrf_ == ndp_nh->vrf_ && ip_ == ndp_nh->ip_) {
939 0 : return true;
940 : }
941 0 : return false;
942 : }
943 0 : virtual bool NeedMplsLabel() { return false; }
944 :
945 : private:
946 : VrfEntryRef vrf_;
947 : IpAddress ip_;
948 : InterfaceRef interface_;
949 : MacAddress mac_;
950 : DISALLOW_COPY_AND_ASSIGN(NdpNH);
951 : };
952 :
953 : /////////////////////////////////////////////////////////////////////////////
954 : // Tunnel NH definition
955 : /////////////////////////////////////////////////////////////////////////////
956 : class TunnelNHKey : public NextHopKey {
957 : public:
958 46 : TunnelNHKey(const string &vrf_name,
959 : const Ip4Address &sip,
960 : const Ip4Address &dip,
961 : bool policy,
962 : TunnelType type,
963 46 : const MacAddress &rewrite_dmac = MacAddress()) :
964 46 : NextHopKey(NextHop::TUNNEL, policy), vrf_key_(vrf_name), sip_(sip),
965 92 : dip_(dip), tunnel_type_(type), rewrite_dmac_(rewrite_dmac) {
966 46 : };
967 83 : virtual ~TunnelNHKey() { };
968 :
969 : virtual NextHop *AllocEntry() const;
970 8 : virtual NextHopKey *Clone() const {
971 8 : return new TunnelNHKey(vrf_key_.name_, sip_, dip_,
972 16 : NextHopKey::GetPolicy(), tunnel_type_,
973 16 : rewrite_dmac_);
974 : }
975 :
976 128 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
977 128 : const TunnelNHKey &key = static_cast<const TunnelNHKey &>(rhs);
978 128 : if (vrf_key_.IsEqual(key.vrf_key_) == false) {
979 0 : return vrf_key_.IsLess(key.vrf_key_);
980 : }
981 :
982 128 : if (sip_ != key.sip_) {
983 0 : return sip_ < key.sip_;
984 : }
985 :
986 128 : if (dip_ != key.dip_) {
987 0 : return dip_ < key.dip_;
988 : }
989 :
990 128 : if (rewrite_dmac_ != key.rewrite_dmac_) {
991 0 : return rewrite_dmac_ < key.rewrite_dmac_;
992 : }
993 :
994 128 : return tunnel_type_.IsLess(key.tunnel_type_);
995 : }
996 6 : void set_tunnel_type(TunnelType tunnel_type) {
997 6 : tunnel_type_ = tunnel_type;
998 6 : }
999 0 : const Ip4Address& dip() const {
1000 0 : return dip_;
1001 : }
1002 0 : const MacAddress& rewrite_dmac() {
1003 0 : return rewrite_dmac_;
1004 : }
1005 : protected:
1006 : friend class TunnelNH;
1007 : VrfKey vrf_key_;
1008 : Ip4Address sip_;
1009 : Ip4Address dip_;
1010 : TunnelType tunnel_type_;
1011 : MacAddress rewrite_dmac_;
1012 : private:
1013 : DISALLOW_COPY_AND_ASSIGN(TunnelNHKey);
1014 : };
1015 :
1016 : class TunnelNHData : public NextHopData {
1017 : public:
1018 11 : TunnelNHData() : NextHopData() {};
1019 22 : virtual ~TunnelNHData() { };
1020 : private:
1021 : friend class TunnelNH;
1022 : DISALLOW_COPY_AND_ASSIGN(TunnelNHData);
1023 : };
1024 :
1025 : /////////////////////////////////////////////////////////////////////////////
1026 : // Labelled Tunnel NH definition
1027 : /////////////////////////////////////////////////////////////////////////////
1028 : class LabelledTunnelNHKey : public TunnelNHKey {
1029 : public:
1030 0 : LabelledTunnelNHKey(const string &vrf_name,
1031 : const Ip4Address &sip,
1032 : const Ip4Address &dip,
1033 : bool policy,
1034 : TunnelType type,
1035 : const MacAddress &rewrite_dmac = MacAddress(),
1036 0 : uint32_t label = 3) :
1037 : TunnelNHKey(vrf_name, sip, dip, policy, type, rewrite_dmac),
1038 0 : transport_mpls_label_(label) {
1039 0 : };
1040 0 : virtual ~LabelledTunnelNHKey() { };
1041 :
1042 : virtual NextHop *AllocEntry() const;
1043 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
1044 0 : const LabelledTunnelNHKey &key = static_cast<const LabelledTunnelNHKey &>(rhs);
1045 0 : if (vrf_key_.IsEqual(key.vrf_key_) == false) {
1046 0 : return vrf_key_.IsLess(key.vrf_key_);
1047 : }
1048 :
1049 0 : if (sip_ != key.sip_) {
1050 0 : return sip_ < key.sip_;
1051 : }
1052 :
1053 0 : if (dip_ != key.dip_) {
1054 0 : return dip_ < key.dip_;
1055 : }
1056 :
1057 0 : if (rewrite_dmac_ != key.rewrite_dmac_) {
1058 0 : return rewrite_dmac_ < key.rewrite_dmac_;
1059 : }
1060 0 : return (transport_mpls_label_ < key.transport_mpls_label_);
1061 : }
1062 0 : virtual NextHopKey *Clone() const {
1063 0 : return new LabelledTunnelNHKey(vrf_key_.name_, sip_, dip_,
1064 0 : NextHopKey::GetPolicy(), tunnel_type_,
1065 0 : rewrite_dmac_, transport_mpls_label_);
1066 : }
1067 : private:
1068 : uint32_t transport_mpls_label_;
1069 : friend class LabelledTunnelNH;
1070 : DISALLOW_COPY_AND_ASSIGN(LabelledTunnelNHKey);
1071 : };
1072 :
1073 : class LabelledTunnelNHData : public TunnelNHData {
1074 : public:
1075 0 : LabelledTunnelNHData() : TunnelNHData() {};
1076 0 : virtual ~LabelledTunnelNHData() { };
1077 : private:
1078 : friend class LabelledTunnelNH;
1079 : DISALLOW_COPY_AND_ASSIGN(LabelledTunnelNHData);
1080 : };
1081 :
1082 : class PBBNHKey : public NextHopKey {
1083 : public:
1084 0 : PBBNHKey(const string &vrf_name, const MacAddress &dest_bmac, uint32_t isid):
1085 0 : NextHopKey(NextHop::PBB, false), vrf_key_(vrf_name),
1086 0 : dest_bmac_(dest_bmac), isid_(isid) {
1087 0 : };
1088 0 : virtual ~PBBNHKey() { };
1089 :
1090 : virtual NextHop *AllocEntry() const;
1091 0 : virtual NextHopKey *Clone() const {
1092 0 : return new PBBNHKey(vrf_key_.name_, dest_bmac_, isid_);
1093 : }
1094 :
1095 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
1096 0 : const PBBNHKey &key = static_cast<const PBBNHKey &>(rhs);
1097 0 : if (vrf_key_.IsEqual(key.vrf_key_) == false) {
1098 0 : return vrf_key_.IsLess(key.vrf_key_);
1099 : }
1100 :
1101 0 : if (dest_bmac_ != key.dest_bmac_) {
1102 0 : return dest_bmac_ < key.dest_bmac_;
1103 : }
1104 :
1105 0 : return isid_ < key.isid_;
1106 : }
1107 :
1108 : const MacAddress dest_bmac() const {
1109 : return dest_bmac_;
1110 : }
1111 : private:
1112 : friend class PBBNH;
1113 : VrfKey vrf_key_;
1114 : MacAddress dest_bmac_;
1115 : uint32_t isid_;
1116 : uint32_t label_;
1117 : NextHopConstRef nh_;
1118 : DISALLOW_COPY_AND_ASSIGN(PBBNHKey);
1119 : };
1120 :
1121 : class PBBNHData : public NextHopData {
1122 : public:
1123 0 : PBBNHData() : NextHopData() {};
1124 0 : virtual ~PBBNHData() { };
1125 : private:
1126 : friend class PBBNH;
1127 : DISALLOW_COPY_AND_ASSIGN(PBBNHData);
1128 : };
1129 :
1130 : class PBBNH : public NextHop {
1131 : public:
1132 : PBBNH(VrfEntry *vrf, const MacAddress &dmac, uint32_t isid);
1133 : virtual ~PBBNH();
1134 :
1135 0 : virtual std::string ToString() const {
1136 0 : return "PBB to " + dest_bmac_.ToString();
1137 : }
1138 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
1139 : virtual void SetKey(const DBRequestKey *key);
1140 : virtual bool ChangeEntry(const DBRequest *req);
1141 : virtual void Delete(const DBRequest *req);
1142 : virtual KeyPtr GetDBRequestKey() const;
1143 : virtual bool CanAdd() const;
1144 :
1145 : const uint32_t vrf_id() const;
1146 0 : const VrfEntry *vrf() const {return vrf_.get();};
1147 0 : const MacAddress dest_bmac() const {return dest_bmac_;};
1148 0 : const uint32_t isid() const { return isid_;};
1149 : virtual void SendObjectLog(const NextHopTable *table,
1150 : AgentLogEvent::type event) const;
1151 0 : virtual bool DeleteOnZeroRefCount() const {
1152 0 : return true;
1153 : }
1154 :
1155 0 : virtual bool MatchEgressData(const NextHop *nh) const {
1156 0 : const PBBNH *pbb_nh = dynamic_cast<const PBBNH *>(nh);
1157 0 : if (pbb_nh && vrf_ == pbb_nh->vrf_ && dest_bmac_ == pbb_nh->dest_bmac_) {
1158 0 : return true;
1159 : }
1160 0 : return false;
1161 : }
1162 :
1163 0 : uint32_t label() const {
1164 0 : return label_;
1165 : }
1166 :
1167 0 : const NextHop *child_nh() const {
1168 0 : return child_nh_.get();
1169 : }
1170 0 : virtual bool NeedMplsLabel() { return false; }
1171 : private:
1172 : VrfEntryRef vrf_;
1173 : MacAddress dest_bmac_;
1174 : uint32_t isid_;
1175 : uint32_t label_;
1176 : NextHopConstRef child_nh_;
1177 : DISALLOW_COPY_AND_ASSIGN(PBBNH);
1178 : };
1179 :
1180 :
1181 : /////////////////////////////////////////////////////////////////////////////
1182 : // Interface NH definition
1183 : /////////////////////////////////////////////////////////////////////////////
1184 : struct InterfaceNHFlags {
1185 : enum Type {
1186 : INVALID,
1187 : INET4 = 1,
1188 : BRIDGE = 2,
1189 : MULTICAST = 4,
1190 : INET6 = 8,
1191 : VXLAN_ROUTING = 16
1192 : };
1193 : };
1194 :
1195 : class InterfaceNHKey : public NextHopKey {
1196 : public:
1197 752 : InterfaceNHKey(InterfaceKey *intf, bool policy, uint8_t flags,
1198 752 : const MacAddress &mac) :
1199 752 : NextHopKey(NextHop::INTERFACE, policy), intf_key_(intf),
1200 752 : flags_(flags), dmac_(mac) {
1201 : //TODO evpn changes remove this, just extra check
1202 752 : assert((flags != (InterfaceNHFlags::INVALID)) ||
1203 : (flags == (InterfaceNHFlags::INET4)) ||
1204 : (flags_ == (InterfaceNHFlags::INET6)) ||
1205 : (flags_ == (InterfaceNHFlags::VXLAN_ROUTING)) ||
1206 : (flags ==
1207 : (InterfaceNHFlags::INET4|InterfaceNHFlags::MULTICAST)));
1208 752 : }
1209 :
1210 1236 : virtual ~InterfaceNHKey() {};
1211 0 : const boost::uuids::uuid &GetUuid() const {return intf_key_->uuid_;};
1212 0 : const std::string& name() const { return intf_key_->name_;};
1213 0 : const Interface::Type &intf_type() const {return intf_key_->type_;}
1214 : const InterfaceKey *intf_key() const { return intf_key_.get(); }
1215 0 : void set_flags(uint8_t flags) {flags_ = flags;}
1216 0 : const uint8_t &flags() const { return flags_; }
1217 0 : const MacAddress &dmac() const { return dmac_; }
1218 :
1219 : virtual NextHop *AllocEntry() const;
1220 130 : virtual NextHopKey *Clone() const {
1221 : //TODO evpn changes remove this, just extra check
1222 130 : assert((flags_ != (InterfaceNHFlags::INVALID)) ||
1223 : (flags_ == (InterfaceNHFlags::INET4)) ||
1224 : (flags_ == (InterfaceNHFlags::INET6)) ||
1225 : (flags_ == (InterfaceNHFlags::VXLAN_ROUTING)) ||
1226 : (flags_ ==
1227 : (InterfaceNHFlags::INET4|InterfaceNHFlags::MULTICAST)));
1228 130 : return new InterfaceNHKey(intf_key_->Clone(), policy_, flags_, dmac_);
1229 : }
1230 8921 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
1231 8921 : const InterfaceNHKey &key = static_cast<const InterfaceNHKey &>(rhs);
1232 8921 : if (intf_key_->IsEqual(*key.intf_key_.get()) == false) {
1233 1225 : return intf_key_->IsLess(*key.intf_key_.get());
1234 : }
1235 :
1236 7696 : if (flags_ != key.flags_) {
1237 288 : return flags_ < key.flags_;
1238 : }
1239 :
1240 7408 : return dmac_ < key.dmac_;
1241 : }
1242 :
1243 : private:
1244 : friend class InterfaceNH;
1245 : boost::scoped_ptr<InterfaceKey> intf_key_;
1246 : uint8_t flags_;
1247 : MacAddress dmac_;
1248 : };
1249 :
1250 : class InterfaceNHData : public NextHopData {
1251 : public:
1252 4 : InterfaceNHData(const string vrf_name) :
1253 4 : NextHopData(), vrf_key_(vrf_name), layer2_control_word_(false) { }
1254 135 : InterfaceNHData(const string vrf_name, bool learning_enabled, bool etree_leaf,
1255 135 : bool layer2_control_word):
1256 135 : NextHopData(learning_enabled, etree_leaf), vrf_key_(vrf_name),
1257 135 : layer2_control_word_(layer2_control_word) {}
1258 278 : virtual ~InterfaceNHData() { }
1259 :
1260 : private:
1261 : friend class InterfaceNH;
1262 : VrfKey vrf_key_;
1263 : bool layer2_control_word_;
1264 : DISALLOW_COPY_AND_ASSIGN(InterfaceNHData);
1265 : };
1266 :
1267 : class InterfaceNH : public NextHop {
1268 : public:
1269 694 : InterfaceNH(Interface *intf, bool policy, uint8_t flags,
1270 694 : const MacAddress &mac) :
1271 694 : NextHop(INTERFACE, true, policy), interface_(intf),
1272 694 : flags_(flags), dmac_(mac), vrf_(NULL, this),
1273 1388 : delete_on_zero_refcount_(false) { };
1274 : InterfaceNH(Interface *intf, bool policy, const MacAddress &mac) :
1275 : NextHop(INTERFACE, true, policy), interface_(intf),
1276 : flags_(InterfaceNHFlags::INET4), dmac_(mac), vrf_(NULL, this),
1277 : delete_on_zero_refcount_(false) {};
1278 1388 : virtual ~InterfaceNH() { };
1279 :
1280 0 : virtual std::string ToString() const {
1281 0 : return "InterfaceNH : " + interface_->name();
1282 : };
1283 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
1284 : virtual void SetKey(const DBRequestKey *key);
1285 : virtual bool ChangeEntry(const DBRequest *req);
1286 70 : virtual void Delete(const DBRequest *req) {};
1287 : virtual KeyPtr GetDBRequestKey() const;
1288 : virtual bool CanAdd() const;
1289 : virtual bool NeedMplsLabel();
1290 : virtual void SendObjectLog(const NextHopTable *table,
1291 : AgentLogEvent::type event) const;
1292 :
1293 3572 : const Interface *GetInterface() const {return interface_.get();};
1294 954 : const MacAddress &GetDMac() const {return dmac_;};
1295 607 : bool IsVxlanRouting() const {
1296 607 : return flags_ & InterfaceNHFlags::VXLAN_ROUTING;
1297 : }
1298 607 : bool is_multicastNH() const { return flags_ & InterfaceNHFlags::MULTICAST; };
1299 615 : bool IsBridge() const { return flags_ & InterfaceNHFlags::BRIDGE; };
1300 0 : uint8_t GetFlags() const {return flags_;};
1301 : const boost::uuids::uuid &GetIfUuid() const;
1302 738 : const VrfEntry *GetVrf() const {return vrf_.get();};
1303 :
1304 : static void CreateMulticastVmInterfaceNH(const boost::uuids::uuid &intf_uuid,
1305 : const MacAddress &dmac,
1306 : const string &vrf_name,
1307 : const string &intf_name);
1308 : static void DeleteMulticastVmInterfaceNH(const boost::uuids::uuid &intf_uuid,
1309 : const MacAddress &dmac,
1310 : const std::string &intf_name);
1311 : static void CreateL2VmInterfaceNH(const boost::uuids::uuid &intf_uuid,
1312 : const MacAddress &dmac,
1313 : const string &vrf_name,
1314 : bool learning_enabled,
1315 : bool etree_leaf,
1316 : bool layer2_control_word,
1317 : const std::string &intf_name);
1318 : static void DeleteL2InterfaceNH(const boost::uuids::uuid &intf_uuid,
1319 : const MacAddress &mac,
1320 : const std::string &intf_name);
1321 : static void CreateL3VmInterfaceNH(const boost::uuids::uuid &intf_uuid,
1322 : const MacAddress &dmac,
1323 : const string &vrf_name,
1324 : bool learning_enabled,
1325 : const std::string &intf_name);
1326 : static void DeleteL3InterfaceNH(const boost::uuids::uuid &intf_uuid,
1327 : const MacAddress &mac,
1328 : const std::string &intf_name);
1329 : static void DeleteNH(const boost::uuids::uuid &intf_uuid,
1330 : bool policy, uint8_t flags,
1331 : const MacAddress &mac, const std::string &intf_name);
1332 : static void CreatePacketInterfaceNh(Agent *agent, const string &ifname);
1333 : static void CreateInetInterfaceNextHop(const string &ifname,
1334 : const string &vrf_name,
1335 : const MacAddress &mac);
1336 : static void DeleteInetInterfaceNextHop(const string &ifname,
1337 : const MacAddress &mac);
1338 : static void CreatePhysicalInterfaceNh(const string &ifname,
1339 : const MacAddress &mac);
1340 : static void DeletePhysicalInterfaceNh(const string &ifname,
1341 : const MacAddress &mac);
1342 76 : virtual bool DeleteOnZeroRefCount() const {
1343 76 : return delete_on_zero_refcount_;
1344 : }
1345 :
1346 0 : void set_delete_on_zero_refcount(bool val) {
1347 0 : delete_on_zero_refcount_ = val;
1348 0 : }
1349 :
1350 0 : virtual bool MatchEgressData(const NextHop *nh) const {
1351 : const InterfaceNH *intf_nh =
1352 0 : dynamic_cast<const InterfaceNH *>(nh);
1353 0 : if (intf_nh && interface_ == intf_nh->interface_) {
1354 0 : return true;
1355 : }
1356 0 : return false;
1357 : }
1358 :
1359 75 : bool layer2_control_word() const {
1360 75 : return layer2_control_word_;
1361 : }
1362 :
1363 : private:
1364 : InterfaceRef interface_;
1365 : uint8_t flags_;
1366 : MacAddress dmac_;
1367 : VrfEntryRef vrf_;
1368 : bool delete_on_zero_refcount_;
1369 : bool layer2_control_word_;
1370 : DISALLOW_COPY_AND_ASSIGN(InterfaceNH);
1371 : };
1372 :
1373 : /////////////////////////////////////////////////////////////////////////////
1374 : // VRF NH definition
1375 : /////////////////////////////////////////////////////////////////////////////
1376 : class VrfNHKey : public NextHopKey {
1377 : public:
1378 18 : VrfNHKey(const string &vrf_name, bool policy, bool bridge_nh) :
1379 36 : NextHopKey(NextHop::VRF, policy), vrf_key_(vrf_name), policy_(policy),
1380 18 : bridge_nh_(bridge_nh) {
1381 18 : }
1382 33 : virtual ~VrfNHKey() { }
1383 :
1384 12 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
1385 12 : const VrfNHKey &key = static_cast<const VrfNHKey &>(rhs);
1386 12 : if (vrf_key_.IsEqual(key.vrf_key_) == false) {
1387 0 : return vrf_key_.IsLess(key.vrf_key_);
1388 : }
1389 :
1390 12 : if (policy_ != key.policy_) {
1391 0 : return policy_ < key.policy_;
1392 : }
1393 12 : return bridge_nh_ < key.bridge_nh_;
1394 : }
1395 :
1396 : virtual NextHop *AllocEntry() const;
1397 6 : virtual NextHopKey *Clone() const {
1398 6 : return new VrfNHKey(vrf_key_.name_, policy_, bridge_nh_);
1399 : }
1400 0 : const std::string &GetVrfName() const { return vrf_key_.name_; }
1401 0 : const bool &GetBridgeNh() const { return bridge_nh_; }
1402 :
1403 : private:
1404 : friend class VrfNH;
1405 : VrfKey vrf_key_;
1406 : bool policy_;
1407 : bool bridge_nh_;
1408 : DISALLOW_COPY_AND_ASSIGN(VrfNHKey);
1409 : };
1410 :
1411 : class VrfNHData : public NextHopData {
1412 : public:
1413 3 : VrfNHData(bool flood_unknown_unicast, bool learning_enabled,
1414 3 : bool layer2_control_word):
1415 : NextHopData(learning_enabled, true),
1416 3 : flood_unknown_unicast_(flood_unknown_unicast),
1417 3 : layer2_control_word_(layer2_control_word) {}
1418 6 : virtual ~VrfNHData() { }
1419 : private:
1420 : friend class VrfNH;
1421 : bool flood_unknown_unicast_;
1422 : bool layer2_control_word_;
1423 : DISALLOW_COPY_AND_ASSIGN(VrfNHData);
1424 : };
1425 :
1426 : class VrfNH : public NextHop {
1427 : public:
1428 15 : VrfNH(VrfEntry *vrf, bool policy, bool bridge_nh_):
1429 30 : NextHop(VRF, true, policy), vrf_(vrf, this), bridge_nh_(bridge_nh_),
1430 15 : flood_unknown_unicast_(false) {}
1431 30 : virtual ~VrfNH() { };
1432 :
1433 0 : virtual std::string ToString() const { return "VrfNH"; };
1434 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
1435 : virtual void SetKey(const DBRequestKey *key);
1436 : // No change expected for VRF Nexthop
1437 : virtual bool ChangeEntry(const DBRequest *req);
1438 3 : virtual void Delete(const DBRequest *req) {};
1439 : virtual KeyPtr GetDBRequestKey() const;
1440 : virtual void SendObjectLog(const NextHopTable *table,
1441 : AgentLogEvent::type event) const;
1442 : virtual bool CanAdd() const;
1443 :
1444 35 : const VrfEntry *GetVrf() const {return vrf_.get();};
1445 3 : virtual bool DeleteOnZeroRefCount() const {
1446 3 : return true;
1447 : }
1448 12 : bool bridge_nh() const { return bridge_nh_; }
1449 5 : bool flood_unknown_unicast() const {
1450 5 : return flood_unknown_unicast_;
1451 : }
1452 :
1453 0 : virtual bool MatchEgressData(const NextHop *nh) const {
1454 0 : const VrfNH *vrf_nh = dynamic_cast<const VrfNH *>(nh);
1455 0 : if (vrf_nh && vrf_ == vrf_nh->vrf_) {
1456 0 : return true;
1457 : }
1458 0 : return false;
1459 : }
1460 :
1461 3 : bool layer2_control_word() const {
1462 3 : return layer2_control_word_;
1463 : }
1464 3 : virtual bool NeedMplsLabel() { return true; }
1465 :
1466 : private:
1467 : VrfEntryRef vrf_;
1468 : // NH created by VXLAN
1469 : bool bridge_nh_;
1470 : bool flood_unknown_unicast_;
1471 : bool layer2_control_word_;
1472 : DISALLOW_COPY_AND_ASSIGN(VrfNH);
1473 : };
1474 :
1475 : /////////////////////////////////////////////////////////////////////////////
1476 : // VLAN NH definition
1477 : /////////////////////////////////////////////////////////////////////////////
1478 : class VlanNHKey : public NextHopKey {
1479 : public:
1480 0 : VlanNHKey(const boost::uuids::uuid &vm_port_uuid, uint16_t vlan_tag) :
1481 : NextHopKey(NextHop::VLAN, false),
1482 0 : intf_key_(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, vm_port_uuid,
1483 0 : "")),
1484 0 : vlan_tag_(vlan_tag) {
1485 0 : }
1486 0 : VlanNHKey(InterfaceKey *key, uint16_t vlan_tag) :
1487 0 : NextHopKey(NextHop::VLAN, false), intf_key_(key), vlan_tag_(vlan_tag) {
1488 0 : }
1489 :
1490 0 : virtual ~VlanNHKey() {}
1491 : virtual NextHop *AllocEntry() const;
1492 0 : virtual NextHopKey *Clone() const {
1493 0 : return new VlanNHKey(intf_key_->Clone(), vlan_tag_);
1494 : }
1495 0 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const {
1496 0 : const VlanNHKey &key = static_cast<const VlanNHKey &>(rhs);
1497 0 : if (intf_key_->IsEqual(*key.intf_key_.get()) == false) {
1498 0 : return intf_key_->IsLess(*key.intf_key_.get());
1499 : }
1500 :
1501 0 : return vlan_tag_ < key.vlan_tag_;
1502 : }
1503 0 : const boost::uuids::uuid& GetUuid() const {return intf_key_->uuid_;}
1504 : const std::string& name() const { return intf_key_->name_;}
1505 0 : const uint16_t vlan_tag() const { return vlan_tag_; }
1506 : private:
1507 : friend class VlanNH;
1508 : boost::scoped_ptr<InterfaceKey> intf_key_;
1509 : uint16_t vlan_tag_;
1510 : DISALLOW_COPY_AND_ASSIGN(VlanNHKey);
1511 : };
1512 :
1513 : class VlanNHData : public NextHopData {
1514 : public:
1515 0 : VlanNHData(const string vrf_name, const MacAddress &smac,
1516 0 : const MacAddress &dmac):
1517 0 : NextHopData(), smac_(smac), dmac_(dmac), vrf_key_(vrf_name) {}
1518 0 : virtual ~VlanNHData() { }
1519 : private:
1520 : friend class VlanNH;
1521 : MacAddress smac_;
1522 : MacAddress dmac_;
1523 : VrfKey vrf_key_;
1524 : DISALLOW_COPY_AND_ASSIGN(VlanNHData);
1525 : };
1526 :
1527 : class VlanNH : public NextHop {
1528 : public:
1529 0 : VlanNH(Interface *intf, uint32_t vlan_tag):
1530 0 : NextHop(VLAN, true, false), interface_(intf), vlan_tag_(vlan_tag),
1531 0 : smac_(), dmac_(), vrf_(NULL, this) { };
1532 0 : virtual ~VlanNH() { };
1533 :
1534 : bool NextHopIsLess(const DBEntry &rhs) const;
1535 : virtual void SetKey(const DBRequestKey *key);
1536 : virtual KeyPtr GetDBRequestKey() const;
1537 0 : virtual void Delete(const DBRequest *req) {};
1538 : virtual bool ChangeEntry(const DBRequest *req);
1539 : virtual void SendObjectLog(const NextHopTable *table,
1540 : AgentLogEvent::type event) const;
1541 : virtual bool CanAdd() const;
1542 :
1543 0 : const Interface *GetInterface() const {return interface_.get();};
1544 0 : uint16_t GetVlanTag() const {return vlan_tag_;};
1545 : const boost::uuids::uuid &GetIfUuid() const;
1546 0 : const VrfEntry *GetVrf() const {return vrf_.get();};
1547 23 : const MacAddress &GetSMac() const {return smac_;};
1548 0 : const MacAddress &GetDMac() const {return dmac_;};
1549 : static VlanNH *Find(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag);
1550 :
1551 : static void Create(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag,
1552 : const std::string &vrf_name, const MacAddress &smac,
1553 : const MacAddress &dmac);
1554 : static void Delete(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag);
1555 : static void CreateReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag,
1556 : const std::string &vrf_name, const MacAddress &smac,
1557 : const MacAddress &dmac);
1558 : static void DeleteReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag);
1559 :
1560 0 : virtual bool MatchEgressData(const NextHop *nh) const {
1561 0 : const VlanNH *vlan_nh = dynamic_cast<const VlanNH *>(nh);
1562 0 : if (vlan_nh && interface_ == vlan_nh->interface_) {
1563 0 : return true;
1564 : }
1565 0 : return false;
1566 : }
1567 0 : virtual bool NeedMplsLabel() { return true; }
1568 :
1569 : private:
1570 : InterfaceRef interface_;
1571 : uint16_t vlan_tag_;
1572 : MacAddress smac_;
1573 : MacAddress dmac_;
1574 : VrfEntryRef vrf_;
1575 : DISALLOW_COPY_AND_ASSIGN(VlanNH);
1576 : };
1577 :
1578 : /////////////////////////////////////////////////////////////////////////////
1579 : // Component NH definition
1580 : /////////////////////////////////////////////////////////////////////////////
1581 : //TODO Shift this to class CompositeNH
1582 : struct Composite {
1583 : enum Type {
1584 : INVALID,
1585 : FABRIC,
1586 : L3FABRIC,
1587 : L2COMP,
1588 : L3COMP,
1589 : MULTIPROTO,
1590 : ECMP,
1591 : L2INTERFACE,
1592 : L3INTERFACE,
1593 : LOCAL_ECMP,
1594 : EVPN,
1595 : TOR,
1596 : LU_ECMP // label unicast ecmp
1597 : };
1598 : };
1599 : //TODO remove defines
1600 : #define COMPOSITETYPE Composite::Type
1601 :
1602 : class ComponentNH {
1603 : public:
1604 125 : ComponentNH(uint32_t label, const NextHop *nh):
1605 125 : label_(label), nh_(nh) {}
1606 : ComponentNH():label_(0), nh_(NULL) {}
1607 :
1608 : ComponentNH(uint32_t label, NextHop *nh): label_(label), nh_(nh) {
1609 : }
1610 :
1611 66 : bool operator == (const ComponentNH &rhs) const {
1612 66 : if (label_ == rhs.label_ && nh_.get() == rhs.nh_.get()) {
1613 66 : return true;
1614 : }
1615 :
1616 0 : return false;
1617 : }
1618 :
1619 : std::string ToString() {
1620 : return nh_->ToString();
1621 : }
1622 :
1623 522 : const NextHop* nh() const {
1624 522 : return nh_.get();
1625 : }
1626 :
1627 459 : uint32_t label() const {
1628 459 : return label_;
1629 : }
1630 : private:
1631 : uint32_t label_;
1632 : NextHopConstRef nh_;
1633 : DISALLOW_COPY_AND_ASSIGN(ComponentNH);
1634 : };
1635 :
1636 : typedef boost::shared_ptr<const ComponentNH> ComponentNHPtr;
1637 : typedef std::vector<ComponentNHPtr> ComponentNHList;
1638 :
1639 : class ComponentNHKey;
1640 : typedef boost::shared_ptr<const ComponentNHKey> ComponentNHKeyPtr;
1641 : typedef std::vector<ComponentNHKeyPtr> ComponentNHKeyList;
1642 :
1643 : class ComponentNHKey {
1644 : public:
1645 47 : ComponentNHKey(int label, std::unique_ptr<const NextHopKey> key) :
1646 47 : label_(label), nh_key_(std::move(key)) { }
1647 : ComponentNHKey(int label, Composite::Type type, bool policy,
1648 : const ComponentNHKeyList &component_nh_list,
1649 : const std::string &vrf_name);
1650 69 : ComponentNHKey(int label, const boost::uuids::uuid &intf_uuid,
1651 69 : uint8_t flags, const MacAddress &mac):
1652 69 : label_(label),
1653 69 : nh_key_(new InterfaceNHKey(
1654 138 : new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, intf_uuid, ""),
1655 138 : false, flags, mac)) {
1656 69 : }
1657 3 : ComponentNHKey(int label, uint8_t tag, const boost::uuids::uuid &intf_uuid):
1658 3 : label_(label), nh_key_(new VlanNHKey(intf_uuid, tag)) {
1659 3 : }
1660 :
1661 2 : ComponentNHKey(int label, const string &vrf_name, const Ip4Address &sip,
1662 2 : const Ip4Address &dip, bool policy, TunnelType::TypeBmap bmap) :
1663 4 : label_(label), nh_key_(new TunnelNHKey(vrf_name, sip, dip, policy,
1664 4 : TunnelType::ComputeType(bmap))) {
1665 2 : }
1666 :
1667 236 : virtual ~ComponentNHKey() { }
1668 :
1669 2 : bool operator == (const ComponentNHKey &rhs) const {
1670 2 : if (label_ != rhs.label_) {
1671 2 : return false;
1672 : }
1673 0 : return nh_key_->IsEqual(*(rhs.nh_key_.get()));
1674 : }
1675 :
1676 9171 : uint32_t label() const { return label_; }
1677 9211 : const NextHopKey* nh_key() const { return nh_key_.get(); }
1678 : private:
1679 : uint32_t label_;
1680 : std::unique_ptr<const NextHopKey> nh_key_;
1681 : DISALLOW_COPY_AND_ASSIGN(ComponentNHKey);
1682 : };
1683 :
1684 : class CompositeNHKey : public NextHopKey {
1685 : public:
1686 41 : CompositeNHKey(COMPOSITETYPE type, bool policy,
1687 : const ComponentNHKeyList &component_nh_key_list,
1688 41 : const std::string &vrf_name) :
1689 : NextHopKey(NextHop::COMPOSITE, policy),
1690 41 : composite_nh_type_(type), component_nh_key_list_(component_nh_key_list),
1691 41 : vrf_key_(vrf_name){
1692 :
1693 41 : validate_mcast_src_ = true;
1694 41 : }
1695 :
1696 207 : CompositeNHKey(COMPOSITETYPE type, bool validate_mcast_src, bool policy,
1697 : const ComponentNHKeyList &component_nh_key_list,
1698 207 : const std::string &vrf_name) :
1699 : NextHopKey(NextHop::COMPOSITE, policy),
1700 207 : composite_nh_type_(type), validate_mcast_src_(validate_mcast_src),
1701 207 : component_nh_key_list_(component_nh_key_list), vrf_key_(vrf_name){
1702 207 : }
1703 :
1704 : virtual CompositeNHKey *Clone() const;
1705 :
1706 496 : virtual ~CompositeNHKey() {
1707 496 : }
1708 : virtual NextHop *AllocEntry() const;
1709 : virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const;
1710 :
1711 2664 : ComponentNHKeyList::const_iterator begin() const {
1712 2664 : return component_nh_key_list_.begin();
1713 : }
1714 :
1715 8564 : ComponentNHKeyList::const_iterator end() const {
1716 8564 : return component_nh_key_list_.end();
1717 : }
1718 :
1719 1 : const ComponentNHKeyList& component_nh_key_list() const {
1720 1 : return component_nh_key_list_;
1721 : }
1722 : bool Reorder(Agent *agent, uint32_t label, const NextHop *nh);
1723 : void CreateTunnelNH(Agent *agent);
1724 : void CreateTunnelNHReq(Agent *agent);
1725 : void ChangeTunnelType(TunnelType::Type tunnel_type);
1726 0 : COMPOSITETYPE composite_nh_type() const {return composite_nh_type_;}
1727 : bool validate_mcast_src() const {return validate_mcast_src_;}
1728 :
1729 : void ReplaceLocalNexthop(const ComponentNHKeyList &new_comp_nh);
1730 : private:
1731 : friend class CompositeNH;
1732 : bool ExpandLocalCompositeNH(Agent *agent);
1733 : void insert(ComponentNHKeyPtr nh_key);
1734 : void erase(ComponentNHKeyPtr nh_key);
1735 : bool find(ComponentNHKeyPtr nh_key);
1736 :
1737 : COMPOSITETYPE composite_nh_type_;
1738 : bool validate_mcast_src_;
1739 : ComponentNHKeyList component_nh_key_list_;
1740 : VrfKey vrf_key_;
1741 : DISALLOW_COPY_AND_ASSIGN(CompositeNHKey);
1742 : };
1743 :
1744 : class CompositeNHData : public NextHopData {
1745 : public:
1746 4 : CompositeNHData() : NextHopData(), pbb_nh_(false),
1747 2 : layer2_control_word_(false),
1748 2 : component_nh_key_list_(ComponentNHKeyList()) {}
1749 86 : CompositeNHData(bool pbb_nh, bool learning_enabled, bool layer2_control_word) :
1750 86 : NextHopData(learning_enabled, true), pbb_nh_(pbb_nh),
1751 86 : layer2_control_word_(layer2_control_word),
1752 86 : component_nh_key_list_(ComponentNHKeyList()) {}
1753 0 : CompositeNHData(const ComponentNHKeyList &component_nh_key_list) :
1754 0 : NextHopData(), pbb_nh_(false), layer2_control_word_(false),
1755 0 : component_nh_key_list_(component_nh_key_list) {}
1756 : private:
1757 : friend class CompositeNH;
1758 : bool pbb_nh_;
1759 : bool layer2_control_word_;
1760 : ComponentNHKeyList component_nh_key_list_;
1761 : DISALLOW_COPY_AND_ASSIGN(CompositeNHData);
1762 : };
1763 :
1764 : //Composite NH
1765 : //* Key of composite NH is list of component NH key(mpls label + Nexthop Key)
1766 : //* In data part we maintain list of component NH(mpls label + Nexthop reference)
1767 : //* In case of ECMP composite NH ordering of component NH is important, since
1768 : // flows would be pointing to one of component NH, and any change in
1769 : // composite NH should not disturb flow which have been already setup.
1770 : // If one of the component NH gets deleted, then a empty component NH
1771 : // would be installed, which would resulting in kernel trapping flow
1772 : // which are pointing to that component NH
1773 : //* In case of multicast composite NH ordering of the component NH is not
1774 : // important
1775 : class CompositeNH : public NextHop {
1776 : public:
1777 : static const uint32_t kInvalidComponentNHIdx = 0xFFFFFFFF;
1778 : CompositeNH(COMPOSITETYPE type, bool policy,
1779 : const ComponentNHKeyList &component_nh_key_list, VrfEntry *vrf):
1780 : NextHop(COMPOSITE, policy), composite_nh_type_(type),
1781 : component_nh_key_list_(component_nh_key_list), vrf_(vrf, this),
1782 : pbb_nh_(false) {
1783 : validate_mcast_src_= true;
1784 : comp_ecmp_hash_fields_.AllocateEcmpFields();
1785 : }
1786 :
1787 335 : CompositeNH(COMPOSITETYPE type, bool validate_mcast_src, bool policy,
1788 335 : const ComponentNHKeyList &component_nh_key_list, VrfEntry *vrf):
1789 335 : NextHop(COMPOSITE, policy), composite_nh_type_(type),
1790 335 : validate_mcast_src_(validate_mcast_src),
1791 335 : component_nh_key_list_(component_nh_key_list), vrf_(vrf, this),
1792 670 : pbb_nh_(false) {
1793 335 : comp_ecmp_hash_fields_.AllocateEcmpFields();
1794 335 : }
1795 :
1796 670 : virtual ~CompositeNH() { };
1797 0 : virtual std::string ToString() const { return "Composite NH"; };
1798 : virtual bool NextHopIsLess(const DBEntry &rhs) const;
1799 : virtual void SetKey(const DBRequestKey *key);
1800 : virtual bool ChangeEntry(const DBRequest *req);
1801 : virtual void Delete(const DBRequest *req);
1802 : virtual KeyPtr GetDBRequestKey() const;
1803 : virtual bool CanAdd() const;
1804 :
1805 : virtual void SendObjectLog(const NextHopTable *table,
1806 : AgentLogEvent::type event) const;
1807 379 : ComponentNHList::const_iterator begin() const {
1808 379 : return component_nh_list_.begin();
1809 : }
1810 :
1811 872 : ComponentNHList::const_iterator end() const {
1812 872 : return component_nh_list_.end();
1813 : }
1814 :
1815 58 : size_t ComponentNHCount() const {
1816 58 : return component_nh_list_.size();
1817 : }
1818 133 : uint32_t ActiveComponentNHCount() const {
1819 133 : uint32_t idx = 0;
1820 133 : uint32_t active_count = 0;
1821 372 : while (idx < component_nh_list_.size()) {
1822 239 : if (component_nh_list_[idx].get() != NULL) {
1823 227 : active_count++;
1824 : }
1825 239 : idx++;
1826 : }
1827 133 : return active_count;
1828 : }
1829 :
1830 : uint32_t PickMember(uint32_t seed, uint32_t affinity_index,
1831 : bool ingress) const;
1832 0 : const NextHop* GetNH(uint32_t idx) const {
1833 0 : if (idx >= component_nh_list_.size()) {
1834 0 : return NULL;
1835 : }
1836 0 : if (component_nh_list_[idx].get() == NULL) {
1837 0 : return NULL;
1838 : }
1839 0 : return (*component_nh_list_[idx]).nh();
1840 : }
1841 :
1842 288 : COMPOSITETYPE composite_nh_type() const {
1843 288 : return composite_nh_type_;
1844 : }
1845 :
1846 36 : void set_validate_mcast_src(bool validate_mcast_src) {
1847 36 : validate_mcast_src_ = validate_mcast_src;
1848 36 : }
1849 :
1850 205 : bool validate_mcast_src() const {
1851 205 : return validate_mcast_src_;
1852 : }
1853 :
1854 : bool GetOldNH(const CompositeNHData *data, ComponentNH &);
1855 :
1856 43 : virtual bool DeleteOnZeroRefCount() const {
1857 43 : return true;
1858 : }
1859 43 : virtual void OnZeroRefCount() {
1860 43 : return;
1861 : }
1862 : ComponentNHKeyList AddComponentNHKey(ComponentNHKeyPtr component_nh_key,
1863 : bool &comp_nh_policy) const;
1864 : ComponentNHKeyList DeleteComponentNHKey(ComponentNHKeyPtr
1865 : component_nh_key,
1866 : bool &comp_nh_new_policy) const;
1867 : bool UpdateComponentNHKey(uint32_t label, NextHopKey *nh_key,
1868 : ComponentNHKeyList &component_nh_key_list, bool &comp_nh_policy) const;
1869 0 : const ComponentNHList& component_nh_list() const {
1870 0 : return component_nh_list_;
1871 : }
1872 205 : const ComponentNHKeyList& component_nh_key_list() const {
1873 205 : return component_nh_key_list_;
1874 : }
1875 336 : const VrfEntry* vrf() const {
1876 336 : return vrf_.get();
1877 : }
1878 0 : uint32_t hash(uint32_t seed, bool ingress) const {
1879 0 : size_t size = component_nh_list_.size();
1880 0 : if (size == 0) {
1881 0 : return kInvalidComponentNHIdx;
1882 : }
1883 0 : uint32_t idx = seed % size;
1884 0 : while (component_nh_list_[idx].get() == NULL ||
1885 0 : component_nh_list_[idx]->nh() == NULL ||
1886 0 : component_nh_list_[idx]->nh()->IsActive() == false ||
1887 0 : (ingress == false &&
1888 0 : component_nh_list_[idx]->nh()->GetType() == NextHop::TUNNEL)) {
1889 0 : idx = (idx + 1) % size;
1890 0 : if (idx == seed % size) {
1891 0 : idx = kInvalidComponentNHIdx;
1892 0 : break;
1893 : }
1894 : }
1895 0 : return idx;
1896 : }
1897 : bool HasVmInterface(const VmInterface *vmi) const;
1898 : bool GetIndex(ComponentNH &nh, uint32_t &idx) const;
1899 72 : const ComponentNH* Get(uint32_t idx) const {
1900 72 : return component_nh_list_[idx].get();
1901 : }
1902 : CompositeNH* ChangeTunnelType(Agent *agent, TunnelType::Type type) const;
1903 : const NextHop *GetLocalNextHop() const;
1904 :
1905 0 : virtual bool MatchEgressData(const NextHop *nh) const {
1906 0 : return false;
1907 : }
1908 88 : virtual bool NeedMplsLabel() { return false; }
1909 173 : uint8_t EcmpHashFieldInUse() const {
1910 173 : return comp_ecmp_hash_fields_.HashFieldsToUse();
1911 : }
1912 205 : EcmpHashFields& CompEcmpHashFields() { return comp_ecmp_hash_fields_; }
1913 : void UpdateEcmpHashFieldsUponRouteDelete(Agent *agent, const string &vrf_name);
1914 79 : bool pbb_nh() const {
1915 79 : return pbb_nh_;
1916 : }
1917 :
1918 43 : bool layer2_control_word() const {
1919 43 : return layer2_control_word_;
1920 : }
1921 :
1922 : const Interface *GetFirstLocalEcmpMemberInterface() const;
1923 :
1924 : private:
1925 : void CreateComponentNH(Agent *agent, TunnelType::Type type) const;
1926 : void ChangeComponentNHKeyTunnelType(ComponentNHKeyList &component_nh_list,
1927 : TunnelType::Type type) const;
1928 : COMPOSITETYPE composite_nh_type_;
1929 : // For relaxing source check in vrouter for mcast data packets
1930 : // in R5.1 where support is for source outside contrail for <*,G>.
1931 : bool validate_mcast_src_;
1932 : ComponentNHKeyList component_nh_key_list_;
1933 : ComponentNHList component_nh_list_;
1934 : VrfEntryRef vrf_;
1935 : EcmpHashFields comp_ecmp_hash_fields_;
1936 : bool pbb_nh_;
1937 : bool layer2_control_word_;
1938 : DISALLOW_COPY_AND_ASSIGN(CompositeNH);
1939 : };
1940 :
1941 : /////////////////////////////////////////////////////////////////////////////
1942 : // NextHop DBTable definition
1943 : /////////////////////////////////////////////////////////////////////////////
1944 : class NextHopTable : public AgentDBTable {
1945 : public:
1946 : static const uint32_t kRpfDisableIndex = 0;
1947 : static const uint32_t kRpfDiscardIndex = 2;
1948 :
1949 : NextHopTable(DB *db, const std::string &name);
1950 : virtual ~NextHopTable();
1951 :
1952 : virtual std::unique_ptr<DBEntry> AllocEntry(const DBRequestKey *k) const;
1953 2044 : virtual size_t Hash(const DBEntry *entry) const {return 0;};
1954 1023 : virtual size_t Hash(const DBRequestKey *key) const {return 0;};
1955 : virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args,
1956 : const std::string &context);
1957 :
1958 : virtual DBEntry *Add(const DBRequest *req);
1959 : virtual bool OnChange(DBEntry *entry, const DBRequest *req);
1960 : virtual bool Resync(DBEntry *entry, const DBRequest *req);
1961 : virtual bool Delete(DBEntry *entry, const DBRequest *req);
1962 :
1963 : virtual void OnZeroRefcount(AgentDBEntry *e);
1964 : void Process(DBRequest &req);
1965 : Interface *FindInterface(const InterfaceKey &key) const;
1966 : VrfEntry *FindVrfEntry(const VrfKey &key) const;
1967 : static DBTableBase *CreateTable(DB *db, const std::string &name);
1968 203 : static NextHopTable *GetInstance() {return nexthop_table_;};
1969 :
1970 2 : void set_discard_nh(NextHop *nh) { discard_nh_ = nh; }
1971 29 : NextHop *discard_nh() const {return discard_nh_;}
1972 :
1973 1 : void set_l2_receive_nh(NextHop *nh) { l2_receive_nh_ = nh; }
1974 16 : NextHop *l2_receive_nh() const {return l2_receive_nh_;}
1975 : // NextHop index managing routines
1976 131 : void FreeInterfaceId(size_t index) { index_table_.Remove(index); }
1977 : NextHop *FindNextHop(size_t index);
1978 : uint32_t ReserveIndex();
1979 : void CheckVrNexthopLimit();
1980 15 : uint32_t NhIndexCount() { return index_table_.InUseIndexCount(); }
1981 : void AddWithoutAlloc(DBEntry *entry);
1982 : void RemoveWithoutDelete(DBEntry *entry);
1983 : private:
1984 : NextHop *AllocWithKey(const DBRequestKey *k) const;
1985 : virtual std::unique_ptr<DBEntry> GetEntry(const DBRequestKey *key) const;
1986 :
1987 : NextHop *discard_nh_;
1988 : NextHop *l2_receive_nh_;
1989 : IndexVector<NextHop *> index_table_;
1990 : static NextHopTable *nexthop_table_;
1991 : DISALLOW_COPY_AND_ASSIGN(NextHopTable);
1992 : };
1993 : #endif // vnsw_agent_nexthop_hpp
|