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