OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
nexthop.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2024 Juniper Networks, Inc. All rights reserved.
3  * Copyright (c) 2024 Elena Zizganova
4  */
5 
6 #include <boost/uuid/uuid_io.hpp>
7 #include <boost/foreach.hpp>
8 #include <cmn/agent_cmn.h>
9 #include "ifmap/ifmap_node.h"
10 #include <vnc_cfg_types.h>
11 #include "base/task_annotations.h"
12 #include <base/logging.h>
13 #include <oper/route_common.h>
14 #include <oper/interface_common.h>
15 #include <oper/nexthop.h>
16 #include <oper/mirror_table.h>
17 #include <oper/multicast.h>
18 #include <oper/tunnel_nh.h>
19 #include <oper/vrf.h>
20 #include <oper/agent_sandesh.h>
21 #include <oper/crypt_tunnel.h>
22 
23 using namespace std;
24 
26 
28 // TunnelTyperoutines
32 
34  for (PriorityList::const_iterator it = priority_list_.begin();
35  it != priority_list_.end(); it++) {
36  if (bmap & (1 << *it)) {
37  return *it;
38  }
39  }
40 
41  //There is no match found in priority list of config,
42  //pick the advertised Tunnel type according to the order.
43  if (bmap & (1 << MPLS_GRE))
44  return MPLS_GRE;
45  else if (bmap & (1 << MPLS_UDP))
46  return MPLS_UDP;
47  else if (bmap & (1 << VXLAN))
48  return VXLAN;
49  else if (bmap & (1 << NATIVE))
50  return NATIVE;
51  else if (bmap & (1 << MPLS_OVER_MPLS))
52  return MPLS_OVER_MPLS;
53 
54  return DefaultType();
55 }
56 
57 // Confg triggers for change in encapsulation priority
58 bool TunnelType::EncapPrioritySync(const std::vector<std::string> &cfg_list) {
59  PriorityList l;
60 
61  for (std::vector<std::string>::const_iterator it = cfg_list.begin();
62  it != cfg_list.end(); it++) {
63  if (*it == "MPLSoGRE")
64  l.push_back(MPLS_GRE);
65  if (*it == "MPLSoUDP")
66  l.push_back(MPLS_UDP);
67  if (*it == "VXLAN")
68  l.push_back(VXLAN);
69  }
70 
71  bool encap_changed = (priority_list_ != l);
72  priority_list_ = l;
73 
74  return encap_changed;
75 }
76 
78  priority_list_.clear();
79 }
80 
82 // NextHop routines
85  AgentLogEvent::type event) const {
86  NextHopObjectLogInfo info;
87 
88  FillObjectLog(event, info);
89  OPER_TRACE_ENTRY(NextHop, table, info);
90 }
91 
93  if (id_ != kInvalidIndex) {
94  static_cast<NextHopTable *>(get_table())->FreeInterfaceId(id_);
95  }
96 }
97 
98 void NextHop::SetKey(const DBRequestKey *key) {
99  const NextHopKey *nh_key = static_cast<const NextHopKey *>(key);
100  type_ = nh_key->type_;
101  policy_ = nh_key->policy_;
102 };
103 
104 // Allocate label for nexthop
106  return agent->mpls_table()->AllocLabel(key);
107 }
108 
109 void NextHop::Add(Agent *agent, const DBRequest *req) {
110  ChangeEntry(req);
111 }
112 
113 void NextHop::Change(const DBRequest *req) {
114  Agent *agent = static_cast<NextHopTable *>(get_table())->agent();
115  // Allocate mpls label if required
116  if (NeedMplsLabel() && (mpls_label() == NULL)) {
117  const NextHopKey *key =
118  static_cast<const NextHopKey *>(req->key.get());
119  mpls_label_ = AllocateLabel(agent, key);
120  }
121 }
122 
124  Agent *agent = static_cast<NextHopTable *>(get_table())->agent();
125  DBEntryBase::KeyPtr key = GetDBRequestKey();
126  const NextHopKey *key1 = static_cast<const NextHopKey *>(key.get());
127  // Mpls Label stores a pointer to NH oper db entry. It uses db table Find
128  // api to retrieve NH db entry. Hence Allocate Mpls label if required
129  // in PostAdd api which ensures presence of NH db entry in db table.
130  if (NeedMplsLabel()) {
131  mpls_label_ = AllocateLabel(agent, key1);
132  }
133 }
134 
137  req.key = GetDBRequestKey();
138  (static_cast<NextHopKey *>(req.key.get()))->sub_op_ = AgentKey::RESYNC;
139  get_table()->Enqueue(&req);
140 }
141 
143  NextHopObjectLogInfo &info) const {
144  string type_str, policy_str("Disabled"), valid_str("Invalid"), str;
145  switch (type_) {
146  case NextHop::DISCARD:
147  type_str.assign("DISCARD");
148  break;
149 
150  case NextHop::RECEIVE:
151  type_str.assign("RECEIVE");
152  break;
153 
154  case NextHop::RESOLVE:
155  type_str.assign("RESOLVE");
156  break;
157 
158  case NextHop::ARP:
159  type_str.assign("ARP");
160  break;
161 
162  case NextHop::NDP:
163  type_str.assign("NDP");
164  break;
165 
166  case NextHop::INTERFACE:
167  type_str.assign("INTERFACE");
168  break;
169 
170  case NextHop::VRF:
171  type_str.assign("VRF");
172  break;
173 
174  case NextHop::TUNNEL:
175  type_str.assign("TUNNEL");
176  break;
177 
178  case NextHop::MIRROR:
179  type_str.assign("MIRROR");
180  break;
181 
182  case NextHop::VLAN:
183  type_str.assign("VLAN");
184  break;
185 
186  case NextHop::COMPOSITE:
187  type_str.assign("COMPOSITE");
188  break;
189 
190  case NextHop::PBB:
191  type_str.assign("PBB_INDIRECT");
192  break;
193 
194  default:
195  type_str.assign("unknown");
196  }
197  if (policy_) {
198  policy_str.assign("Enabled");
199  }
200  if (valid_) {
201  valid_str.assign("Valid");
202  }
203  switch (event) {
204  case AgentLogEvent::ADD:
205  str.assign("Addition ");
206  break;
207  case AgentLogEvent::DEL:
208  str.assign("Deletion ");
209  break;
210  case AgentLogEvent::CHANGE:
211  str.assign("Modification ");
212  break;
213  case AgentLogEvent::RESYNC:
214  str.assign("Resync ");
215  break;
216  default:
217  str.assign("unknown");
218  }
219  info.set_event(str);
220  info.set_type(type_str);
221  info.set_policy(policy_str);
222  info.set_valid(valid_str);
223  info.set_id(id_);
224 }
225 
227  NextHopObjectLogInfo &info) {
228  if (intf) {
229  string if_type_str;
230  switch(intf->type()) {
232  if_type_str.assign("VM_INTERFACE");
233  break;
234  case Interface::PHYSICAL:
235  if_type_str.assign("ETH");
236  break;
237  case Interface::INET:
238  if_type_str.assign("VIRTUAL_HOST");
239  break;
240  case Interface::PACKET:
241  if_type_str.assign("PKT");
242  break;
243  default:
244  if_type_str.assign("Invalid");
245  break;
246  }
247  info.set_intf_type(if_type_str);
248  info.set_intf_uuid(UuidToString(intf->GetUuid()));
249  info.set_intf_name(intf->name());
250  }
251 }
252 
253 void NextHop::FillObjectLogMac(const unsigned char *m,
254  NextHopObjectLogInfo &info) {
255  char mstr[32];
256  snprintf(mstr, 32, "%02x:%02x:%02x:%02x:%02x:%02x",
257  m[0], m[1], m[2], m[3], m[4], m[5]);
258  string mac(mstr);
259  info.set_mac(mac);
260 }
261 
263  if (GetType() == NextHop::INTERFACE) {
264  const InterfaceNH *intf_nh =
265  static_cast<const InterfaceNH *>(this);
266  const VmInterface *intf = dynamic_cast<const VmInterface *>
267  (intf_nh->GetInterface());
268  if (intf && intf->policy_enabled()) {
269  return true;
270  }
271  }
272  return false;
273 }
274 
276 // NextHopTable routines
278 NextHopTable::NextHopTable(DB *db, const string &name) : AgentDBTable(db, name){
279  // nh-index 0 is reserved by vrouter. So, pre-allocate the first index so
280  // that nh added by agent use index 1 and above
281  int id = index_table_.Insert(NULL);
282  assert(id == 0);
283 }
284 
286  FreeInterfaceId(0);
287 }
288 
290  return index_table_.Insert(NULL);
291 }
292 
293 std::unique_ptr<DBEntry> NextHopTable::AllocEntry(const DBRequestKey *k) const {
294  return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(AllocWithKey(k)));
295 }
296 
298  const NextHopKey *key = static_cast<const NextHopKey *>(k);
299  return key->AllocEntry();
300 }
301 
302 std::unique_ptr<DBEntry> NextHopTable::GetEntry(const DBRequestKey *key) const {
303  return std::unique_ptr<DBEntry>(AllocWithKey(key));
304 }
305 
307  const NextHopKey *key = static_cast<const NextHopKey *>(req->key.get());
308  NextHop *nh = AllocWithKey(key);
309 
310  if (nh->CanAdd() == false) {
311  delete nh;
312  return NULL;
313  }
315  nh->set_id(index_table_.Insert(nh));
316  nh->Add(agent(), req);
317  nh->SendObjectLog(this, AgentLogEvent::ADD);
318  return static_cast<DBEntry *>(nh);
319 }
320 
321 bool NextHopTable::OnChange(DBEntry *entry, const DBRequest *req) {
322  NextHop *nh = static_cast<NextHop *>(entry);
323  bool delcleared = false;
324  //Since as part of label addition later, active nh entries are looked
325  //up. So makes sense to clear delete now so as to allow proper label
326  //binding.
327  if (entry->IsDeleted()) {
328  entry->ClearDelete();
329  delcleared = true;
330  }
331  nh->Change(req);
332  bool ret = nh->ChangeEntry(req);
333  nh->SendObjectLog(this, AgentLogEvent::CHANGE);
334  return (ret | delcleared);
335 }
336 
337 bool NextHopTable::Resync(DBEntry *entry, const DBRequest *req) {
338  NextHop *nh = static_cast<NextHop *>(entry);
339  bool ret = nh->ChangeEntry(req);
340  nh->SendObjectLog(this, AgentLogEvent::RESYNC);
341  return ret;
342 }
343 
344 bool NextHopTable::Delete(DBEntry *entry, const DBRequest *req) {
345  NextHop *nh = static_cast<NextHop *>(entry);
346  nh->Delete(req);
347  nh->SendObjectLog(this, AgentLogEvent::DEL);
349  return true;
350 }
351 
352 DBTableBase *NextHopTable::CreateTable(DB *db, const std::string &name) {
353  nexthop_table_ = new NextHopTable(db, name);
354  nexthop_table_->Init();
355  return nexthop_table_;
356 };
357 
359  return static_cast<Interface *>
361 }
362 
364  return static_cast<VrfEntry *>(Agent::GetInstance()->vrf_table()->FindActiveEntry(&key));
365 }
366 
368  agent()->ConcurrencyCheck();
369  DBTablePartition *tpart =
370  static_cast<DBTablePartition *>(GetTablePartition(req.key.get()));
371  tpart->Process(NULL, &req);
372 }
373 
375  agent()->ConcurrencyCheck();
376  DBTablePartition *tpart =
377  static_cast<DBTablePartition *>(GetTablePartition(entry));
378  tpart->RemoveWithoutDelete(entry);
379 }
380 
382  agent()->ConcurrencyCheck();
383  DBTablePartition *tpart =
384  static_cast<DBTablePartition *>(GetTablePartition(entry));
385  tpart->AddWithoutAlloc(entry);
386 }
387 
389  NextHop *nh = static_cast<NextHop *>(e);
390 
391  // Release mpls db entry reference
392  nh->ResetMplsRef();
393  if (nh->DeleteOnZeroRefCount() == false) {
394  return;
395  }
396 
397  agent()->ConcurrencyCheck();
398  nh->OnZeroRefCount();
399 
400  DBRequest req;
403  req.key = std::move(key);
404  req.data.reset(NULL);
405  Process(req);
406 }
407 
410  VrLimitExceeded::iterator vr_limit_itr = vr_limits.find("vr_nexthops");
411  if (vr_limit_itr->second == "Normal") {
413  agent()->vrouter_max_nexthops())/100) ) {
414  vr_limit_itr->second.assign(std::string("Exceeded"));
415  LOG(ERROR, "Vrouter Nexthop Index Exceeded.");
416  }
417  } else if ( vr_limit_itr->second == "Exceeded") {
419  vr_limit_itr->second.assign(std::string("TableLimit"));
420  LOG(ERROR, "Vrouter Nexthop Table Limit Reached. Skip NH Add.");
422  agent()->vrouter_max_nexthops())/100) ) {
423  vr_limit_itr->second.assign(std::string("Normal"));
424  }
425  } else if ( vr_limit_itr->second == "TableLimit" ) {
427  ((agent()->vrouter_max_nexthops()*95)/100) ) {
428  vr_limit_itr->second.assign(std::string("Exceeded"));
429  LOG(ERROR, "Vrouter Nexthop Index Exceeded.");
430  }
431  }
432  agent()->set_vr_limits_exceeded_map(vr_limits);
433 }
434 
436 // ARP NH routines
439  VrfEntry *vrf = static_cast<VrfEntry *>
440  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
441  return new ArpNH(vrf, dip_);
442 }
443 
444 bool ArpNH::CanAdd() const {
445  if (vrf_ == NULL) {
446  LOG(ERROR, "Invalid VRF in ArpNH. Skip Add");
447  return false;
448  }
449 
450  return true;
451 }
452 
453 bool ArpNH::NextHopIsLess(const DBEntry &rhs) const {
454  const ArpNH &a = static_cast<const ArpNH &>(rhs);
455 
456  if (vrf_.get() != a.vrf_.get()) {
457  return vrf_.get() < a.vrf_.get();
458  }
459 
460  return (ip_ < a.ip_);
461 }
462 
463 void ArpNH::SetKey(const DBRequestKey *k) {
464  const ArpNHKey *key = static_cast<const ArpNHKey *>(k);
465 
466  NextHop::SetKey(k);
468  ip_ = key->dip_;
469 }
470 
471 bool ArpNH::ChangeEntry(const DBRequest *req) {
472  bool ret= false;
473  //const ArpNHKey *key = static_cast<const ArpNHKey *>(req->key.get());
474  const ArpNHData *data = static_cast<const ArpNHData *>(req->data.get());
475  if (valid_ != data->resolved_) {
476  valid_ = data->resolved_;
477  ret = true;
478  }
479 
481  (*data->intf_key_.get());
482  if (interface_.get() != pinterface) {
483  interface_ = pinterface;
484  ret = true;
485  }
486 
487  if (!data->valid_) {
488  mac_.Zero();
489  return ret;
490  }
491 
492  if (data->resolved_ != true) {
493  // If ARP is not resolved mac will be invalid
494  return ret;
495  }
496 
497  if (mac_.CompareTo(data->mac_) != 0) {
498  mac_ = data->mac_;
499  ret = true;
500  }
501 
502  return ret;
503 }
504 
505 const uint32_t ArpNH::vrf_id() const {
506  return vrf_->vrf_id();
507 }
508 
510  NextHopKey *key = new ArpNHKey(vrf_->GetName(), ip_, policy_);
511  return DBEntryBase::KeyPtr(key);
512 }
513 
515  return interface_->GetUuid();
516 }
517 
519  AgentLogEvent::type event) const {
520  NextHopObjectLogInfo info;
521 
522  FillObjectLog(event, info);
523 
524  const Interface *intf = GetInterface();
525  FillObjectLogIntf(intf, info);
526 
527  const VrfEntry *vrf = GetVrf();
528  if (vrf) {
529  info.set_vrf(vrf->GetName());
530  }
531  const Ip4Address *ip = GetIp();
532  info.set_dest_ip(ip->to_string());
533 
534  const unsigned char *m = GetMac().GetData();
535  FillObjectLogMac(m, info);
536 
537  OPER_TRACE_ENTRY(NextHop, table, info);
538 }
539 
541 // NDP NH routines
544  VrfEntry *vrf = static_cast<VrfEntry *>
545  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
546  return new NdpNH(vrf, dip_);
547 }
548 
549 bool NdpNH::CanAdd() const {
550  if (vrf_ == NULL) {
551  LOG(ERROR, "Invalid VRF in NdpNH. Skip Add");
552  return false;
553  }
554 
555  return true;
556 }
557 
558 bool NdpNH::NextHopIsLess(const DBEntry &rhs) const {
559  const NdpNH &a = static_cast<const NdpNH &>(rhs);
560 
561  if (vrf_.get() != a.vrf_.get()) {
562  return vrf_.get() < a.vrf_.get();
563  }
564 
565  return (ip_ < a.ip_);
566 }
567 
568 void NdpNH::SetKey(const DBRequestKey *k) {
569  const NdpNHKey *key = static_cast<const NdpNHKey *>(k);
570 
571  NextHop::SetKey(k);
573  ip_ = key->dip_;
574 }
575 
576 bool NdpNH::ChangeEntry(const DBRequest *req) {
577  bool ret= false;
578  //const NdpNHKey *key = static_cast<const NdpNHKey *>(req->key.get());
579  const NdpNHData *data = static_cast<const NdpNHData *>(req->data.get());
580  if (valid_ != data->resolved_) {
581  valid_ = data->resolved_;
582  ret = true;
583  }
584 
586  (*data->intf_key_.get());
587  if (interface_.get() != pinterface) {
588  interface_ = pinterface;
589  ret = true;
590  }
591 
592  if (!data->valid_) {
593  mac_.Zero();
594  return ret;
595  }
596 
597  if (data->resolved_ != true) {
598  // If ARP is not resolved mac will be invalid
599  return ret;
600  }
601 
602  if (mac_.CompareTo(data->mac_) != 0) {
603  mac_ = data->mac_;
604  ret = true;
605  }
606 
607  return ret;
608 }
609 
610 const uint32_t NdpNH::vrf_id() const {
611  return vrf_->vrf_id();
612 }
613 
615  NextHopKey *key = new NdpNHKey(vrf_->GetName(), ip_, policy_);
616  return DBEntryBase::KeyPtr(key);
617 }
618 
620  return interface_->GetUuid();
621 }
622 
624  AgentLogEvent::type event) const {
625  NextHopObjectLogInfo info;
626 
627  FillObjectLog(event, info);
628 
629  const Interface *intf = GetInterface();
630  FillObjectLogIntf(intf, info);
631 
632  const VrfEntry *vrf = GetVrf();
633  if (vrf) {
634  info.set_vrf(vrf->GetName());
635  }
636  const IpAddress *ip = GetIp();
637  info.set_dest_ip(ip->to_string());
638 
639  const unsigned char *m = GetMac().GetData();
640  FillObjectLogMac(m, info);
641 
642  OPER_TRACE_ENTRY(NextHop, table, info);
643 }
644 
646 // Interface NH routines
649  Interface *intf = static_cast<Interface *>
650  (Agent::GetInstance()->interface_table()->Find(intf_key_.get(), true));
651  if (intf && intf->IsDeleted() && intf->GetRefCount() == 0) {
652  //Ignore interface which are deleted, and there are no reference to it
653  //taking reference on deleted interface with refcount 0, would result
654  //in DB state set on deleted interface entry
655  intf = NULL;
656  }
657  return new InterfaceNH(intf, policy_, flags_, dmac_);
658 }
659 
660 bool InterfaceNH::CanAdd() const {
661  if (interface_ == NULL) {
662  LOG(ERROR, "Invalid Interface in InterfaceNH. Skip Add");
663  return false;
664  }
665 
666  return true;
667 }
668 
669 bool InterfaceNH::NextHopIsLess(const DBEntry &rhs) const {
670  const InterfaceNH &a = static_cast<const InterfaceNH &>(rhs);
671 
672  if (interface_.get() != a.interface_.get()) {
673  return interface_.get() < a.interface_.get();
674  }
675 
676  if (flags_ != a.flags_) {
677  return flags_ < a.flags_;
678  }
679 
680  return dmac_ < a.dmac_;
681 }
682 
684  NextHopKey *key =
685  new InterfaceNHKey(static_cast<InterfaceKey *>(
686  interface_->GetDBRequestKey().release()),
687  policy_, flags_, dmac_);
688  return DBEntryBase::KeyPtr(key);
689 }
690 
692  const InterfaceNHKey *key = static_cast<const InterfaceNHKey *>(k);
693 
694  NextHop::SetKey(k);
696  flags_ = key->flags_;
697  dmac_ = key->dmac_;
698 }
699 
701  const InterfaceNHData *data =
702  static_cast<const InterfaceNHData *>(req->data.get());
703  bool ret = false;
704 
705  VrfEntry *vrf = static_cast<VrfEntry *>
707  if (vrf_.get() != vrf) {
708  vrf_ = vrf;
709  ret = true;
710  }
711 
712  if (learning_enabled_ != data->learning_enabled_) {
714  ret = true;
715  }
716 
717  if (etree_leaf_ != data->etree_leaf_) {
718  etree_leaf_ = data->etree_leaf_;
719  ret = true;
720  }
721 
724  ret = true;
725  }
726 
727  return ret;
728 }
729 
731  return interface_->GetUuid();
732 }
733 
734 static void AddInterfaceNH(const boost::uuids::uuid &intf_uuid,
735  const MacAddress &dmac, uint8_t flags,
736  bool policy, const string vrf_name,
737  bool learning_enabled, bool etree_leaf,
738  bool layer2_control_word, const string &name) {
740  req.key.reset(new InterfaceNHKey
741  (new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, intf_uuid, name),
742  policy, flags, dmac));
743  req.data.reset(new InterfaceNHData(vrf_name, learning_enabled,
744  etree_leaf, layer2_control_word));
746 }
747 
748 // Create 3 InterfaceNH for every Vm interface. One with policy another without
749 // policy, third one is for multicast.
751  const MacAddress &dmac,
752  const string &vrf_name,
753  bool learning_enabled,
754  const string &intf_name) {
755  AddInterfaceNH(intf_uuid, dmac, InterfaceNHFlags::INET4, true, vrf_name,
756  learning_enabled, false, false, intf_name);
757  AddInterfaceNH(intf_uuid, dmac, InterfaceNHFlags::INET4, false, vrf_name,
758  learning_enabled, false, false, intf_name);
759 }
760 
762  const MacAddress &mac,
763  const string &intf_name) {
764  DeleteNH(intf_uuid, false, InterfaceNHFlags::INET4, mac, intf_name);
765  DeleteNH(intf_uuid, true, InterfaceNHFlags::INET4, mac, intf_name);
766 }
767 
769  const MacAddress &dmac,
770  const string &vrf_name,
771  bool learning_enabled,
772  bool etree_leaf,
773  bool layer2_control_word,
774  const string &intf_name) {
775  AddInterfaceNH(intf_uuid, dmac, InterfaceNHFlags::BRIDGE, false, vrf_name,
776  learning_enabled, etree_leaf, layer2_control_word, intf_name);
777  AddInterfaceNH(intf_uuid, dmac, InterfaceNHFlags::BRIDGE, true, vrf_name,
778  learning_enabled, etree_leaf, layer2_control_word, intf_name);
779 }
780 
782  const MacAddress &dmac,
783  const string &intf_name) {
784  DeleteNH(intf_uuid, false, InterfaceNHFlags::BRIDGE, dmac, intf_name);
785  DeleteNH(intf_uuid, true, InterfaceNHFlags::BRIDGE, dmac, intf_name);
786 }
787 
789  const MacAddress &dmac,
790  const string &vrf_name,
791  const string &intf_name) {
792  AddInterfaceNH(intf_uuid, dmac, (InterfaceNHFlags::INET4 |
794  vrf_name, false, false, false, intf_name);
795 }
796 
798  const MacAddress &dmac,
799  const string &intf_name) {
800  DeleteNH(intf_uuid, false, (InterfaceNHFlags::INET4 |
802  dmac, intf_name);
803 }
804 
805 void InterfaceNH::DeleteNH(const boost::uuids::uuid &intf_uuid, bool policy,
806  uint8_t flags, const MacAddress &mac,
807  const string &intf_name) {
809  req.key.reset(new InterfaceNHKey
811  intf_name),
812  policy, flags, mac));
813  req.data.reset(NULL);
815 }
816 
817 void InterfaceNH::CreateInetInterfaceNextHop(const string &ifname,
818  const string &vrf_name,
819  const MacAddress &mac) {
820  DBRequest req;
822 
823  NextHopKey *key = new InterfaceNHKey(new InetInterfaceKey(ifname),
825  mac);
826  req.key.reset(key);
827 
828  InterfaceNHData *data = new InterfaceNHData(vrf_name);
829  req.data.reset(data);
831 }
832 
833 void InterfaceNH::DeleteInetInterfaceNextHop(const string &ifname,
834  const MacAddress &mac) {
835  DBRequest req;
837 
838  NextHopKey *key = new InterfaceNHKey
839  (new InetInterfaceKey(ifname), false,
841  req.key.reset(key);
842 
843  req.data.reset(NULL);
845 }
846 
847 void InterfaceNH::CreatePacketInterfaceNh(Agent *agent, const string &ifname) {
849 
850  // create nexthop without policy
851  req.key.reset(new InterfaceNHKey(
852  new PacketInterfaceKey(boost::uuids::nil_uuid(), ifname), false,
854  req.data.reset(new InterfaceNHData(""));
855  agent->nexthop_table()->Process(req);
856 
857  // create nexthop with relaxed policy
858  req.key.reset(new InterfaceNHKey(
859  new PacketInterfaceKey(boost::uuids::nil_uuid(), ifname), true,
861  req.data.reset(new InterfaceNHData(""));
862  agent->nexthop_table()->Process(req);
863 }
864 
865 void InterfaceNH::CreatePhysicalInterfaceNh(const string &ifname,
866  const MacAddress &mac) {
868  req.key.reset(new InterfaceNHKey(new PhysicalInterfaceKey(ifname),
869  false, InterfaceNHFlags::INET4, mac));
870  req.data.reset(new InterfaceNHData(Agent::GetInstance()->fabric_vrf_name()));
872 }
873 
874 void InterfaceNH::DeletePhysicalInterfaceNh(const string &ifname,
875  const MacAddress &mac) {
877  req.key.reset(new InterfaceNHKey(new PhysicalInterfaceKey(ifname),
878  false, InterfaceNHFlags::INET4, mac));
879  req.data.reset(NULL);
881 }
882 
884  AgentLogEvent::type event) const {
885  NextHopObjectLogInfo info;
886 
887  FillObjectLog(event, info);
888 
889  const Interface *intf = GetInterface();
890  FillObjectLogIntf(intf, info);
891 
892  const unsigned char *m = (unsigned char *)GetDMac().GetData();
893  FillObjectLogMac(m, info);
894 
895  OPER_TRACE_ENTRY(NextHop, table, info);
896 }
897 
899  const Interface *itf = GetInterface();
900  //Label is required only for VMInterface and InetInterface
901  if (dynamic_cast<const VmInterface *>(itf) ||
902  dynamic_cast<const InetInterface *>(itf)) {
903  return true;
904  }
905  return false;
906 }
907 
909 // VRF NH routines
911 bool VrfNH::CanAdd() const {
912  if (vrf_ == NULL) {
913  LOG(ERROR, "Invalid VRF in VrfNH. Skip Add");
914  return false;
915  }
916 
917  return true;
918 }
919 
921  VrfEntry *vrf = static_cast<VrfEntry *>
922  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
923  return new VrfNH(vrf, policy_, bridge_nh_);
924 }
925 
926 bool VrfNH::NextHopIsLess(const DBEntry &rhs) const {
927  const VrfNH &a = static_cast<const VrfNH &>(rhs);
928 
929  if (vrf_.get() != a.vrf_.get()) {
930  return (vrf_.get() < a.vrf_.get());
931  }
932 
933  return bridge_nh_ < a.bridge_nh_;
934 }
935 
936 void VrfNH::SetKey(const DBRequestKey *k) {
937  const VrfNHKey *key = static_cast<const VrfNHKey *>(k);
938  NextHop::SetKey(k);
940  bridge_nh_ = key->bridge_nh_;
941 }
942 
944  NextHopKey *key = new VrfNHKey(vrf_->GetName(), policy_, bridge_nh_);
945  return DBEntryBase::KeyPtr(key);
946 }
947 
948 bool VrfNH::ChangeEntry(const DBRequest *req) {
949  bool ret = false;
950  const VrfNHData *data = static_cast<const VrfNHData *>(req->data.get());
951 
954  ret = true;
955  }
956 
957  if (learning_enabled_ != data->learning_enabled_) {
959  ret = true;
960  }
961 
964  ret = true;
965  }
966 
967  return ret;
968 }
969 
971  AgentLogEvent::type event) const {
972  NextHopObjectLogInfo info;
973  FillObjectLog(event, info);
974 
975  const VrfEntry *vrf = GetVrf();
976  if (vrf) {
977  info.set_vrf(vrf->GetName());
978  }
979  OPER_TRACE_ENTRY(NextHop, table, info);
980 }
981 
983 // Tunnel NH routines
985 TunnelNH::TunnelNH(VrfEntry *vrf, const Ip4Address &sip, const Ip4Address &dip,
986  bool policy, TunnelType type, const MacAddress &rewrite_dmac) :
987  NextHop(NextHop::TUNNEL, false, policy), vrf_(vrf, this), sip_(sip),
988  dip_(dip), tunnel_type_(type), tunnel_dst_rt_(NULL), crypt_(false),
989  crypt_tunnel_available_(false), crypt_interface_(NULL), rewrite_dmac_(rewrite_dmac) {
990 
991  for (size_t i = 0;
992  i < Agent::GetInstance()->vhost_default_gateway().size(); i++) {
993  EncapDataPtr data(new EncapData(this, NULL));
994  encap_list_.push_back(data);
995  }
996 }
997 
999 }
1000 
1001 bool TunnelNH::CanAdd() const {
1002  if (vrf_ == NULL) {
1003  LOG(ERROR, "Invalid VRF in TunnelNH. Skip Add");
1004  return false;
1005  }
1006 
1007  if (dip_.to_ulong() == 0) {
1008  LOG(ERROR, "Invalid tunnel-destination in TunnelNH");
1009  }
1010 
1011  return true;
1012 }
1013 
1015  VrfEntry *vrf = static_cast<VrfEntry *>
1016  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
1017  return new TunnelNH(vrf, sip_, dip_, policy_, tunnel_type_,
1018  rewrite_dmac_);
1019 }
1020 
1021 bool TunnelNH::NextHopIsLess(const DBEntry &rhs) const {
1022  const TunnelNH &a = static_cast<const TunnelNH &>(rhs);
1023 
1024  bool ret;
1025  if (vrf_.get() != a.vrf_.get()) {
1026  return vrf_.get() < a.vrf_.get();
1027  }
1028 
1029  if (sip_ != a.sip_) {
1030  return sip_ < a.sip_;
1031  }
1032 
1033  if (dip_ != a.dip_) {
1034  return dip_ < a.dip_;
1035  }
1036 
1037  if (!tunnel_type_.Compare(a.tunnel_type_)) {
1038  return tunnel_type_.IsLess(a.tunnel_type_);
1039  }
1040 
1041  if (rewrite_dmac_ != a.rewrite_dmac_) {
1042  return rewrite_dmac_ < a.rewrite_dmac_;
1043  }
1044  ret = TunnelNextHopIsLess(rhs);
1045  return ret;
1046 }
1047 
1049  const TunnelNHKey *key = static_cast<const TunnelNHKey *>(k);
1050  NextHop::SetKey(k);
1052  sip_ = key->sip_;
1053  dip_ = key->dip_;
1054  tunnel_type_ = key->tunnel_type_;
1055  policy_ = key->policy_;
1057 }
1058 
1060  NextHopKey *key = new TunnelNHKey(vrf_->GetName(), sip_, dip_, policy_,
1062  return DBEntryBase::KeyPtr(key);
1063 }
1064 
1065 const uint32_t TunnelNH::vrf_id() const {
1066  return vrf_->vrf_id();
1067 }
1068 
1070  bool ret = false;
1071  bool valid = false;
1072 
1073  InetUnicastAgentRouteTable *rt_table =
1075  InetUnicastRouteEntry *rt = rt_table->FindLPM(dip_);
1076  const NextHop *anh;
1077  if (!rt) {
1078  //No route to reach destination, add to unresolved list
1079  valid = false;
1080  rt_table->AddUnresolvedNH(this);
1081  } else if ((anh = rt->GetActiveNextHop()) == NULL) {
1082  valid = false;
1083  rt_table->AddUnresolvedNH(this);
1084  } else if (anh->GetType() == NextHop::RESOLVE) {
1085  //Trigger ARP resolution
1086  valid = false;
1087  rt_table->AddUnresolvedNH(this);
1088 
1089  const ResolveNH *nh = static_cast<const ResolveNH *>(anh);
1090  std::string nexthop_vrf = nh->get_interface()->vrf()->GetName();
1091  if (nh->get_interface()->vrf()->forwarding_vrf()) {
1092  nexthop_vrf = nh->get_interface()->vrf()->forwarding_vrf()->GetName();
1093  }
1094 
1096  nexthop_vrf,
1097  nh->get_interface(),
1098  nh->PolicyEnabled(),
1099  rt->GetActivePath()->dest_vn_list(),
1100  rt->GetActivePath()->sg_list(),
1101  rt->GetActivePath()->tag_list());
1102  rt = NULL;
1103  } else {
1104  valid = anh->IsValid();
1105  }
1106 
1107  if (valid != valid_) {
1108  valid_ = valid;
1109  ret = true;
1110  }
1111 
1112  if (tunnel_dst_rt_ != rt) {
1113  tunnel_dst_rt_ = rt;
1114  ret = true;
1115  }
1116 
1117  if (encap_list_[0]->arp_rt_.get() != rt) {
1118  encap_list_[0]->arp_rt_.reset(rt);
1119  ret = true;
1120  }
1121 
1122  Agent *agent = Agent::GetInstance();
1123  if (agent->crypt_interface() != crypt_interface_) {
1124  crypt_interface_ = agent->crypt_interface();
1125  ret = true;
1126  }
1127  bool crypt, crypt_tunnel_available;
1128  agent->crypt_tunnel_table()->CryptAvailability(dip_.to_string(),
1129  crypt, crypt_tunnel_available);
1130  if (crypt_tunnel_available != crypt_tunnel_available_) {
1131  crypt_tunnel_available_ = crypt_tunnel_available;
1132  ret = true;
1133  }
1134  if (crypt != crypt_) {
1135  crypt_ = crypt;
1136  ret = true;
1137  }
1138 
1139  //If route is present, check if the interface or mac
1140  //address changed for the dependent route
1141  if (valid_ && rt) {
1142  //Check if the interface or mac
1143  //of the dependent route has changed
1144  //only then notify the route
1145  const NextHop *active_nh = rt->GetActiveNextHop();
1146  if (active_nh == NULL) {
1147  return ret;
1148  }
1149  const Interface *intf = NULL;
1150  MacAddress dmac;
1151  if (active_nh->GetType() == NextHop::ARP) {
1152  const ArpNH *arp_nh = static_cast<const ArpNH *>(active_nh);
1153  dmac = arp_nh->GetMac();
1154  intf = arp_nh->GetInterface();
1155  } else if (active_nh->GetType() == NextHop::NDP) {
1156  const NdpNH *ndp_nh = static_cast<const NdpNH *>(active_nh);
1157  dmac = ndp_nh->GetMac();
1158  intf = ndp_nh->GetInterface();
1159  } else if (active_nh->GetType() == NextHop::INTERFACE) {
1160  const InterfaceNH *intf_nh =
1161  static_cast<const InterfaceNH *>(active_nh);
1162  intf = intf_nh->GetInterface();
1163  encap_list_[0]->dmac_.Zero();
1164  }
1165 
1166  if (encap_list_[0]->dmac_ != dmac) {
1167  encap_list_[0]->dmac_ = dmac;
1168  ret = true;
1169  }
1170 
1171  if (encap_list_[0]->interface_ != intf) {
1172  encap_list_[0]->interface_ = intf;
1173  ret = true;
1174  }
1175 
1176  if (active_nh->GetType() == NextHop::COMPOSITE) {
1177  valid_ = false;
1178  const CompositeNH *cnh = dynamic_cast<const CompositeNH*>(active_nh);
1179  ComponentNHList::const_iterator component_nh_it =
1180  cnh->begin();
1181  int i = 0;
1182  while (component_nh_it != cnh->end()) {
1183  const NextHop *component_nh = NULL;
1184  if (*component_nh_it) {
1185  component_nh = (*component_nh_it)->nh();
1186  if (component_nh->GetType() == NextHop::ARP) {
1187  const ArpNH *anh = dynamic_cast<const ArpNH*>(component_nh);
1188  encap_list_[i]->dmac_ = anh->GetMac();
1189  encap_list_[i]->interface_ = anh->GetInterface();
1190  encap_list_[i]->valid_ = anh->IsValid();
1191  rt = rt_table->FindLPM(agent->vhost_default_gateway()[i]);
1192  encap_list_[i]->arp_rt_.reset(rt);
1193  /* if any single encap is valid then set tunnel flag to valid */
1194  if (encap_list_[i]->valid_) {
1195  valid_ = true;
1196  }
1197  ret = true;
1198  i++;
1199  }
1200  }
1201  component_nh_it++;
1202  }
1203  return ret;
1204  }
1205  }
1206 
1207  return ret;
1208 }
1209 
1210 void TunnelNH::Delete(const DBRequest *req) {
1211  InetUnicastAgentRouteTable *rt_table =
1213  if (rt_table)
1214  rt_table->RemoveUnresolvedNH(this);
1215 }
1216 
1218  AgentLogEvent::type event) const {
1219  NextHopObjectLogInfo info;
1220  FillObjectLog(event, info);
1221 
1222  const VrfEntry *vrf = GetVrf();
1223  if (vrf) {
1224  info.set_vrf(vrf->GetName());
1225  }
1226  const Ip4Address *sip = GetSip();
1227  info.set_source_ip(sip->to_string());
1228  const Ip4Address *dip = GetDip();
1229  info.set_dest_ip(dip->to_string());
1230  info.set_tunnel_type(tunnel_type_.ToString());
1231  if (crypt_)
1232  info.set_crypt_traffic("All");
1234  info.set_crypt_tunnel_available("Yes");
1235  if (crypt_interface_)
1236  info.set_crypt_interface(GetCryptInterface()->name());
1237  info.set_rewrite_dmac(rewrite_dmac_.ToString());
1238  OPER_TRACE_ENTRY(NextHop, table, info);
1239 }
1240 
1242 // Labelled Tunnel NH routines
1244 
1246  bool policy, TunnelType type, const MacAddress &rewrite_dmac,
1247  uint32_t label) :
1248  TunnelNH(vrf, sip, dip, policy, type, rewrite_dmac), transport_mpls_label_(label) {
1249 }
1250 
1252 }
1253 
1255  VrfEntry *vrf = static_cast<VrfEntry *>
1256  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
1257  return new LabelledTunnelNH(vrf, sip_, dip_, policy_, tunnel_type_,
1259 }
1260 
1262  NextHopKey *key = new LabelledTunnelNHKey(vrf_->GetName(), sip_, dip_,
1264  return DBEntryBase::KeyPtr(key);
1265 }
1266 
1268  const LabelledTunnelNH &a = static_cast<const LabelledTunnelNH &>(rhs);
1269 
1271 }
1272 
1274  bool ret = false;
1275  ret = TunnelNH::ChangeEntry(req);
1276  TunnelType::Type transport_tunnel_type =
1278  if (transport_tunnel_type != transport_tunnel_type_) {
1279  transport_tunnel_type_ = transport_tunnel_type;
1280  ret = true;
1281  }
1282  return ret;
1283 }
1284 
1286  AgentLogEvent::type event) const {
1287  NextHopObjectLogInfo info;
1288  FillObjectLog(event, info);
1289 
1290  const VrfEntry *vrf = GetVrf();
1291  if (vrf) {
1292  info.set_vrf(vrf->GetName());
1293  }
1294  const Ip4Address *sip = GetSip();
1295  info.set_source_ip(sip->to_string());
1296  const Ip4Address *dip = GetDip();
1297  info.set_dest_ip(dip->to_string());
1298  info.set_tunnel_type(tunnel_type_.ToString());
1299  if (crypt_)
1300  info.set_crypt_traffic("All");
1302  info.set_crypt_tunnel_available("Yes");
1303  if (crypt_interface_)
1304  info.set_crypt_interface(GetCryptInterface()->name());
1305  info.set_rewrite_dmac(rewrite_dmac_.ToString());
1306  info.set_transport_mpls_label(transport_mpls_label_);
1307  OPER_TRACE_ENTRY(NextHop, table, info);
1308 }
1310 // Mirror NH routines
1312 MirrorNH::MirrorNH(const VrfKey &vkey, const IpAddress &sip, uint16_t sport,
1313  const IpAddress &dip, uint16_t dport):
1314  NextHop(NextHop::MIRROR, false, false), vrf_name_(vkey.name_),
1315  sip_(sip), sport_(sport), dip_(dip), dport_(dport), arp_rt_(this),
1316  interface_(NULL), dmac_() {
1317  VrfEntry *vrf = static_cast<VrfEntry *>
1318  (Agent::GetInstance()->vrf_table()->Find(&vkey, true));
1319  vrf_ = VrfEntryRef(vrf, this);
1320 }
1321 
1322 bool MirrorNH::CanAdd() const {
1323  /* For service-chain based mirroring, vrf will always be empty. In this
1324  * case we should create MirrorNH even when VRF is NULL */
1325  if (!vrf_name_.empty() && vrf_ == NULL) {
1326  LOG(ERROR, "Invalid VRF in mirror NH");
1327  return false;
1328  }
1329 
1330  return true;
1331 }
1332 
1334  return new MirrorNH(vrf_key_, sip_, sport_, dip_, dport_);
1335 }
1336 
1337 bool MirrorNH::NextHopIsLess(const DBEntry &rhs) const {
1338  const MirrorNH &a = static_cast<const MirrorNH &>(rhs);
1339 
1340  if ((vrf_.get() != a.vrf_.get())) {
1341  return vrf_.get() < a.vrf_.get();
1342  }
1343 
1344  if (dip_ != a.dip_) {
1345  return dip_ < a.dip_;
1346  }
1347 
1348  return (dport_ < a.dport_);
1349 }
1350 
1351 const uint32_t MirrorNH::vrf_id() const {
1352  return (vrf_ ? vrf_->vrf_id() : (uint32_t)-1);
1353 }
1354 
1356  const MirrorNHKey *key = static_cast<const MirrorNHKey *>(k);
1357  NextHop::SetKey(k);
1359  sip_ = key->sip_;
1360  sport_ = key->sport_;
1361  dip_ = key->dip_;
1362  dport_ = key->dport_;
1363 }
1364 
1366  NextHopKey *key = new MirrorNHKey((vrf_ ? vrf_->GetName() : ""),
1367  sip_, sport_, dip_, dport_);
1368  return DBEntryBase::KeyPtr(key);
1369 }
1370 
1372  InetUnicastAgentRouteTable *rt_table = NULL;
1373  if (dip_.is_v4()) {
1374  rt_table = GetVrf()->GetInet4UnicastRouteTable();
1375  } else {
1376  rt_table = GetVrf()->GetInet6UnicastRouteTable();
1377  }
1378  return rt_table;
1379 }
1380 
1382  bool ret = false;
1383  bool valid = false;
1384 
1385  if (GetVrf() == NULL) {
1386  valid_ = true;
1387  return true;
1388  }
1390  InetUnicastRouteEntry *rt = rt_table->FindLPM(dip_);
1391  const NextHop *anh;
1392  if (!rt) {
1393  //No route to reach destination, add to unresolved list
1394  valid = false;
1395  rt_table->AddUnresolvedNH(this);
1396  } else if ((anh = rt->GetActiveNextHop()) == NULL) {
1397  valid = false;
1398  rt_table->AddUnresolvedNH(this);
1399  } else if ((anh->GetType() == NextHop::RESOLVE) &&
1401  //Trigger ARP resolution
1402  valid = false;
1403  rt_table->AddUnresolvedNH(this);
1404 
1405  const ResolveNH *nh = static_cast<const ResolveNH *>(anh);
1406  std::string nexthop_vrf = nh->get_interface()->vrf()->GetName();
1407  if (nh->get_interface()->vrf()->forwarding_vrf()) {
1408  nexthop_vrf = nh->get_interface()->vrf()->forwarding_vrf()->GetName();
1409  }
1410 
1411  InetUnicastAgentRouteTable::AddArpReq(GetVrf()->GetName(), dip_.to_v4(),
1412  nexthop_vrf,
1413  nh->get_interface(),
1414  nh->PolicyEnabled(),
1415  rt->GetActivePath()->dest_vn_list(),
1416  rt->GetActivePath()->sg_list(),
1417  rt->GetActivePath()->tag_list());
1418  rt = NULL;
1419  } else {
1420  valid = anh->IsValid();
1421  }
1422 
1423  if (valid != valid_) {
1424  valid_ = valid;
1425  ret = true;
1426  }
1427 
1428  if (dip_.is_v4() && (arp_rt_.get() != rt)) {
1429  arp_rt_.reset(rt);
1430  ret = true;
1431  }
1432 
1433  //If route is present, check if the interface or mac
1434  //address changed for the dependent route
1435  if (valid_ && rt) {
1436  //Check if the interface or mac
1437  //of the dependent route has changed
1438  //only then notify the route
1439  const NextHop *active_nh = rt->GetActiveNextHop();
1440  const Interface *intf = NULL;
1441  MacAddress dmac;
1442  if (active_nh->GetType() == NextHop::ARP) {
1443  const ArpNH *arp_nh = static_cast<const ArpNH *>(active_nh);
1444  dmac = arp_nh->GetMac();
1445  intf = arp_nh->GetInterface();
1446  } else if (active_nh->GetType() == NextHop::NDP) {
1447  const NdpNH *ndp_nh = static_cast<const NdpNH *>(active_nh);
1448  dmac = ndp_nh->GetMac();
1449  intf = ndp_nh->GetInterface();
1450  } else if (active_nh->GetType() == NextHop::INTERFACE) {
1451  const InterfaceNH *intf_nh =
1452  static_cast<const InterfaceNH *>(active_nh);
1453  intf = intf_nh->GetInterface();
1454  dmac_.Zero();
1455  }
1456 
1457  if (dmac_ != dmac) {
1458  dmac_ = dmac;
1459  ret = true;
1460  }
1461 
1462  if (interface_ != intf) {
1463  interface_ = intf;
1464  ret = true;
1465  }
1466  }
1467 
1468  return ret;
1469 }
1470 
1471 void MirrorNH::Delete(const DBRequest *req) {
1472  if (!GetVrf()) {
1473  return;
1474  }
1476  rt_table->RemoveUnresolvedNH(this);
1477 }
1478 
1480  AgentLogEvent::type event) const {
1481  NextHopObjectLogInfo info;
1482 
1483  FillObjectLog(event, info);
1484 
1485  const VrfEntry *vrf = GetVrf();
1486  if (vrf) {
1487  info.set_vrf(vrf->GetName());
1488  }
1489  const IpAddress *sip = GetSip();
1490  info.set_source_ip(sip->to_string());
1491  const IpAddress *dip = GetDip();
1492  info.set_dest_ip(dip->to_string());
1493  info.set_source_port((short int)GetSPort());
1494  info.set_dest_port((short int)GetDPort());
1495  OPER_TRACE_ENTRY(NextHop, table, info);
1496 }
1497 
1499 // ReceiveNH routines
1501 bool ReceiveNH::CanAdd() const {
1502  if (interface_ == NULL) {
1503  LOG(ERROR, "Invalid Interface in ReceiveNH. Skip Add");
1504  return false;
1505  }
1506 
1507  return true;
1508 }
1509 
1511  Interface *intf = static_cast<Interface *>
1512  (Agent::GetInstance()->interface_table()->Find(intf_key_.get(), true));
1513  if (intf && intf->IsDeleted() && intf->GetRefCount() == 0) {
1514  // Ignore interface which are deleted, and there are no reference to it
1515  // taking reference on deleted interface with refcount 0, would result
1516  // in DB state set on deleted interface entry
1517  intf = NULL;
1518  }
1519  return new ReceiveNH(intf, policy_);
1520 }
1521 
1523  const ReceiveNHKey *nh_key = static_cast<const ReceiveNHKey *>(key);
1524  NextHop::SetKey(key);
1526 };
1527 
1528 // Create 2 ReceiveNH for every VPort. One with policy another without
1529 // policy
1530 void ReceiveNH::Create(NextHopTable *table, const Interface *intf,
1531  bool policy) {
1533  InterfaceKey *key =
1534  static_cast<InterfaceKey *>(intf->GetDBRequestKey().get())->Clone();
1535  req.key.reset(new ReceiveNHKey(key, policy));
1536  req.data.reset(new ReceiveNHData());
1537  table->Process(req);
1538 
1539  key = static_cast<InterfaceKey *>(intf->GetDBRequestKey().get())->Clone();
1540  req.key.reset(new ReceiveNHKey(key, true));
1541  table->Process(req);
1542 }
1543 
1544 void ReceiveNH::Delete(NextHopTable *table, const Interface *intf,
1545  bool policy) {
1547  InterfaceKey *key =
1548  static_cast<InterfaceKey *>(intf->GetDBRequestKey().get())->Clone();
1549  req.key.reset(new ReceiveNHKey(key, policy));
1550  req.data.reset(NULL);
1551  table->Process(req);
1552 
1553  key = static_cast<InterfaceKey *>(intf->GetDBRequestKey().get())->Clone();
1554  req.key.reset(new ReceiveNHKey(key, true));
1555  table->Process(req);
1556 }
1557 
1559  AgentLogEvent::type event) const {
1560  NextHopObjectLogInfo info;
1561 
1562  FillObjectLog(event, info);
1563 
1564  const Interface *intf = GetInterface();
1565  FillObjectLogIntf(intf, info);
1566 
1567  OPER_TRACE_ENTRY(NextHop, table, info);
1568 }
1569 
1571 // ResolveNH routines
1574  Interface *intf = static_cast<Interface *>
1575  (Agent::GetInstance()->interface_table()->Find(intf_key_.get(), true));
1576  return new ResolveNH(intf, policy_);
1577 }
1578 
1579 bool ResolveNH::CanAdd() const {
1580  return true;
1581 }
1582 
1583 void ResolveNH::Create(const InterfaceKey *intf, bool policy) {
1585  req.key.reset(new ResolveNHKey(intf, policy));
1586  req.data.reset(new ResolveNHData());
1588 }
1589 
1590 void ResolveNH::CreateReq(const InterfaceKey *intf, bool policy) {
1592  req.key.reset(new ResolveNHKey(intf, policy));
1593  req.data.reset(new ResolveNHData());
1595 }
1596 
1598 // DiscardNH routines
1601  return new DiscardNH();
1602 }
1603 
1604 bool DiscardNH::CanAdd() const {
1605  return true;
1606 }
1607 
1610  req.key.reset(new DiscardNHKey());
1611  req.data.reset(new DiscardNHData());
1613 }
1614 
1616 // L2ReceiveNH routines
1619  return new L2ReceiveNH();
1620 }
1621 
1622 bool L2ReceiveNH::CanAdd() const {
1623  return true;
1624 }
1625 
1628  req.key.reset(new L2ReceiveNHKey());
1629  req.data.reset(new L2ReceiveNHData());
1631 }
1632 
1634 // VLAN NH routines
1636 bool VlanNH::CanAdd() const {
1637  if (interface_ == NULL) {
1638  LOG(ERROR, "Invalid Interface in VlanNH. Skip Add");
1639  return false;
1640  }
1641 
1642  return true;
1643 }
1644 
1646  Interface *intf = static_cast<Interface *>
1647  (Agent::GetInstance()->interface_table()->Find(intf_key_.get(), true));
1648  return new VlanNH(intf, vlan_tag_);
1649 }
1650 
1651 bool VlanNH::NextHopIsLess(const DBEntry &rhs) const {
1652  const VlanNH &a = static_cast<const VlanNH &>(rhs);
1653 
1654  if (interface_.get() != a.interface_.get()) {
1655  return interface_.get() < a.interface_.get();
1656  }
1657 
1658  return vlan_tag_ < a.vlan_tag_;
1659 }
1660 
1662  VlanNHKey *key = new VlanNHKey(interface_->GetUuid(), vlan_tag_);
1663  return DBEntryBase::KeyPtr(key);
1664 }
1665 
1667  const VlanNHKey *key = static_cast<const VlanNHKey *>(k);
1668 
1669  NextHop::SetKey(k);
1671  vlan_tag_ = key->vlan_tag_;
1672 }
1673 
1674 bool VlanNH::ChangeEntry(const DBRequest *req) {
1675  const VlanNHData *data = static_cast<const VlanNHData *>(req->data.get());
1676  bool ret = false;
1677 
1678  VrfEntry *vrf = static_cast<VrfEntry *>
1680  if (vrf_.get() != vrf) {
1681  vrf_ = vrf;
1682  ret = true;
1683  }
1684 
1685  if (smac_.CompareTo(data->smac_) != 0) {
1686  smac_ = data->smac_;
1687  ret = true;
1688  }
1689 
1690  if (dmac_.CompareTo(data->dmac_) != 0) {
1691  dmac_ = data->dmac_;
1692  ret = true;
1693  }
1694 
1695  return ret;
1696 }
1697 
1699  return interface_->GetUuid();
1700 }
1701 
1702 // Create VlanNH for a VPort
1703 void VlanNH::Create(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag,
1704  const string &vrf_name, const MacAddress &smac,
1705  const MacAddress &dmac) {
1706  DBRequest req;
1708 
1709  NextHopKey *key = new VlanNHKey(intf_uuid, vlan_tag);
1710  req.key.reset(key);
1711 
1712  VlanNHData *data = new VlanNHData(vrf_name, smac, dmac);
1713  req.data.reset(data);
1715 }
1716 
1717 void VlanNH::Delete(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag) {
1718  DBRequest req;
1720 
1721  NextHopKey *key = new VlanNHKey(intf_uuid, vlan_tag);
1722  req.key.reset(key);
1723 
1724  req.data.reset(NULL);
1726 }
1727 
1728 // Create VlanNH for a VPort
1729 void VlanNH::CreateReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag,
1730  const string &vrf_name, const MacAddress &smac,
1731  const MacAddress &dmac) {
1733  req.key.reset(new VlanNHKey(intf_uuid, vlan_tag));
1734  req.data.reset(new VlanNHData(vrf_name, smac, dmac));
1736 }
1737 
1738 void VlanNH::DeleteReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag) {
1739  DBRequest req;
1741 
1742  NextHopKey *key = new VlanNHKey(intf_uuid, vlan_tag);
1743  req.key.reset(key);
1744 
1745  req.data.reset(NULL);
1747 }
1748 
1749 
1750 VlanNH *VlanNH::Find(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag) {
1751  VlanNHKey key(intf_uuid, vlan_tag);
1752  return static_cast<VlanNH *>(NextHopTable::GetInstance()->FindActiveEntry(&key));
1753 }
1754 
1756  AgentLogEvent::type event) const {
1757  NextHopObjectLogInfo info;
1758 
1759  FillObjectLog(event, info);
1760 
1761  const Interface *intf = GetInterface();
1762  FillObjectLogIntf(intf, info);
1763 
1764  const unsigned char *m = GetDMac().GetData();
1765  FillObjectLogMac(m, info);
1766 
1767  info.set_vlan_tag((short int)GetVlanTag());
1768  OPER_TRACE_ENTRY(NextHop, table, info);
1769 }
1770 
1772 // CompositeNH routines
1775  //Clear all local nexthop
1776  for (uint32_t i = 0; i < component_nh_key_list_.size();) {
1778  if ((cnh.get() != NULL) &&
1779  (cnh->nh_key()->GetType() == NextHop::INTERFACE)) {
1781  } else {
1782  i++;
1783  }
1784  }
1785 
1786  component_nh_key_list_.insert(component_nh_key_list_.begin(), lnh.begin(),
1787  lnh.end());
1788 }
1789 
1790 bool CompositeNH::CanAdd() const {
1791  if (vrf_ == NULL || vrf_->IsDeleted()) {
1792  LOG(ERROR, "Invalid VRF in composite NH. Skip Add");
1793  return false;
1794  }
1795  return true;
1796 }
1797 
1799  ComponentNHList::const_iterator comp_nh_it =
1800  component_nh_list_.begin();
1801  for(;comp_nh_it != component_nh_list_.end(); comp_nh_it++) {
1802  if ((*comp_nh_it) == NULL) {
1803  continue;
1804  }
1805 
1806  if ((*comp_nh_it)->nh()->GetType() != NextHop::TUNNEL) {
1807  return (*comp_nh_it)->nh();
1808  }
1809  }
1810  return NULL;
1811 }
1812 
1814  ComponentNHList::const_iterator comp_nh_it =
1815  component_nh_list_.begin();
1816  for(;comp_nh_it != component_nh_list_.end(); comp_nh_it++) {
1817  if ((*comp_nh_it) == NULL) {
1818  continue;
1819  }
1820 
1821  if ((*comp_nh_it)->nh()->GetType() == NextHop::INTERFACE) {
1822  const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
1823  ((*comp_nh_it)->nh());
1824  if (intf_nh->GetInterface() == vmi)
1825  return true;
1826  }
1827  if ((*comp_nh_it)->nh()->GetType() == NextHop::VLAN) {
1828  const VlanNH *vlan_nh = dynamic_cast<const VlanNH *>
1829  ((*comp_nh_it)->nh());
1830  if (vlan_nh->GetInterface() == vmi)
1831  return true;
1832  }
1833  }
1834  return false;
1835 }
1836 
1839  return NULL;
1840  }
1841  ComponentNHList::const_iterator comp_nh_it =
1842  component_nh_list_.begin();
1843  for(;comp_nh_it != component_nh_list_.end(); comp_nh_it++) {
1844  if (*comp_nh_it == NULL) {
1845  continue;
1846  }
1847  if ((*comp_nh_it)->nh()->GetType() == NextHop::INTERFACE) {
1848  const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>
1849  ((*comp_nh_it)->nh());
1850  return (intf_nh->GetInterface());
1851  }
1852  if ((*comp_nh_it)->nh()->GetType() == NextHop::VLAN) {
1853  const VlanNH *vlan_nh = dynamic_cast<const VlanNH *>
1854  ((*comp_nh_it)->nh());
1855  return (vlan_nh->GetInterface());
1856  }
1857  }
1858  return NULL;
1859 }
1860 
1861 uint32_t CompositeNH::PickMember(uint32_t seed, uint32_t affinity_index,
1862  bool ingress) const {
1863  uint32_t idx = kInvalidComponentNHIdx;
1864  size_t size = component_nh_list_.size();
1865  if (size == 0) {
1866  return idx;
1867  }
1868 
1869  if (affinity_index != kInvalidComponentNHIdx) {
1870  const NextHop *nh = GetNH(affinity_index);
1871  if (nh != NULL && nh->IsActive()) {
1872  return affinity_index;
1873  }
1874  }
1875 
1876  idx = seed % size;
1877  if (component_nh_list_[idx].get() == NULL ||
1878  component_nh_list_[idx]->nh() == NULL ||
1879  component_nh_list_[idx]->nh()->IsActive() == false ||
1880  (ingress == false &&
1881  component_nh_list_[idx]->nh()->GetType() == NextHop::TUNNEL)) {
1882 
1883  std::vector<uint32_t> active_list;
1884  for (uint32_t i = 0; i < size; i++) {
1885  if (i == idx)
1886  continue;
1887  if (component_nh_list_[i].get() != NULL &&
1888  component_nh_list_[i]->nh() != NULL &&
1889  component_nh_list_[i]->nh()->IsActive()) {
1890  if (ingress == false) {
1891  if (component_nh_list_[i]->nh()->GetType() != NextHop::TUNNEL) {
1892  active_list.push_back(i);
1893  }
1894  } else {
1895  active_list.push_back(i);
1896  }
1897  }
1898  }
1899  idx = (active_list.size()) ?
1900  active_list.at(seed % active_list.size()) :
1902  }
1903 
1904  return idx;
1905 }
1906 
1908  VrfEntry *vrf = static_cast<VrfEntry *>
1909  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
1911  component_nh_key_list_, vrf);
1912 }
1913 
1915  ComponentNHKeyList::iterator it = component_nh_key_list_.begin();
1916  for (;it != component_nh_key_list_.end(); it++) {
1917  if ((*it) == NULL) {
1918  continue;
1919  }
1920  if ((*it)->nh_key()->GetType() == NextHop::TUNNEL) {
1921  TunnelNHKey *tunnel_nh_key =
1922  static_cast<TunnelNHKey *>((*it)->nh_key()->Clone());
1923  tunnel_nh_key->set_tunnel_type(tunnel_type);
1924  std::unique_ptr<const NextHopKey> nh_key(tunnel_nh_key);
1925  ComponentNHKeyPtr new_tunnel_nh(new ComponentNHKey((*it)->label(),
1926  std::move(nh_key)));
1927  (*it) = new_tunnel_nh;
1928  }
1929  }
1930 }
1931 
1933  bool changed = false;
1934  CompositeNHData *data = static_cast<CompositeNHData *>(req->data.get());
1935  NextHopKey *key = static_cast <NextHopKey *>(req->key.get());
1936  ComponentNHKeyList tmp_component_nh_key_list_;
1937  if (data && data->pbb_nh_ != pbb_nh_) {
1938  pbb_nh_ = data->pbb_nh_;
1939  changed = true;
1940  }
1941 
1942  if (data && data->learning_enabled_ != learning_enabled_) {
1944  changed = true;
1945  }
1946 
1947  if (data && layer2_control_word_ != data->layer2_control_word_) {
1949  changed = true;
1950  }
1951 
1952  if (key->sub_op_ == AgentKey::RESYNC &&
1953  (data && data->component_nh_key_list_.empty() == false) &&
1955  tmp_component_nh_key_list_ = data->component_nh_key_list_;
1956  changed = true;
1957  } else {
1958  tmp_component_nh_key_list_ = component_nh_key_list_;
1959  }
1960 
1962  ComponentNHKeyList::const_iterator it = tmp_component_nh_key_list_.begin();
1963  for (;it != tmp_component_nh_key_list_.end(); it++) {
1964  if ((*it) == NULL) {
1965  ComponentNHPtr nh_key;
1966  nh_key.reset();
1967  component_nh_list.push_back(nh_key);
1968  continue;
1969  }
1970 
1971  const NextHop *nh = static_cast<const NextHop *>
1972  (NextHopTable::GetInstance()->FindActiveEntry((*it)->nh_key()));
1973  if (nh) {
1974  ComponentNHPtr nh_key(new ComponentNH((*it)->label(), nh));
1975  component_nh_list.push_back(nh_key);
1976  } else {
1977  //Nexthop not active
1978  //Insert a empty entry
1979  ComponentNHPtr nh_key;
1980  nh_key.reset();
1981  component_nh_list.push_back(nh_key);
1982  }
1983  }
1984 
1985  //Check if new list and old list are same
1986  ComponentNHList::const_iterator new_comp_nh_it =
1987  component_nh_list.begin();
1988  ComponentNHList::const_iterator old_comp_nh_it =
1989  component_nh_list_.begin();
1990  for(;new_comp_nh_it != component_nh_list.end() &&
1991  old_comp_nh_it != component_nh_list_.end();
1992  new_comp_nh_it++, old_comp_nh_it++) {
1993  //Check if both component NH are NULL
1994  if ((*old_comp_nh_it) == NULL &&
1995  (*new_comp_nh_it) == NULL) {
1996  continue;
1997  }
1998 
1999  //check if one of the component NH is NULL
2000  if ((*old_comp_nh_it) == NULL || (*new_comp_nh_it) == NULL) {
2001  changed = true;
2002  break;
2003  }
2004 
2005  //Check if component NH are same
2006  if ((**old_comp_nh_it) == (**new_comp_nh_it)) {
2007  continue;
2008  }
2009 
2010  changed = true;
2011  break;
2012  }
2013 
2014  if (new_comp_nh_it == component_nh_list.end() &&
2015  old_comp_nh_it == component_nh_list_.end()) {
2016  //No Change
2017  } else {
2018  changed = true;
2019  }
2020 
2023  changed = true;
2024  }
2026 
2027  if (key->sub_op_ == AgentKey::RESYNC &&
2028  (data && data->component_nh_key_list_.empty() == false) &&
2030  /* First remove entry from tree */
2031  Agent::GetInstance()->nexthop_table()->RemoveWithoutDelete(static_cast<DBEntry *>(this));
2032 
2033  /* Now update the key and add it back to tree */
2034  component_nh_key_list_ = tmp_component_nh_key_list_;
2035  Agent::GetInstance()->nexthop_table()->AddWithoutAlloc(static_cast<DBEntry *>(this));
2036  }
2037 
2038  return changed;
2039 }
2040 
2042  AgentLogEvent::type event) const {
2043  NextHopObjectLogInfo info;
2044  FillObjectLog(event, info);
2045 
2046  const VrfEntry *vrf_entry = vrf();
2047  if (vrf_entry) {
2048  info.set_vrf(vrf_entry->GetName());
2049  }
2050 
2051  std::vector<ComponentNHLogInfo> comp_nh_log_list;
2052  ComponentNHList::const_iterator component_nh_it = begin();
2053  for (;component_nh_it != end(); component_nh_it++) {
2054  ComponentNHLogInfo component_nh_info;
2055  const ComponentNH *comp_nh = (*component_nh_it).get();
2056  if (comp_nh == NULL) {
2057  continue;
2058  }
2059  const NextHop *nh = comp_nh->nh();
2060  component_nh_info.set_component_nh_id(nh->id());
2061  switch(nh->GetType()) {
2062  case TUNNEL: {
2063  const TunnelNH *tun_nh = static_cast<const TunnelNH *>(nh);
2064  component_nh_info.set_type("Tunnel");
2065  component_nh_info.set_label(comp_nh->label());
2066  component_nh_info.set_server_ip(tun_nh->GetDip()->to_string());
2067  break;
2068  }
2069 
2070  case INTERFACE: {
2071  const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
2072  component_nh_info.set_type("Interface");
2073  component_nh_info.set_label(comp_nh->label());
2074  const Interface *intf =
2075  static_cast<const Interface *>(intf_nh->GetInterface());
2076  component_nh_info.set_intf_name(intf->name());
2077  break;
2078  }
2079 
2080  case VLAN: {
2081  const VlanNH *vlan_nh = static_cast<const VlanNH *>(nh);
2082  component_nh_info.set_type("Vlan");
2083  component_nh_info.set_label(comp_nh->label());
2084  const Interface *intf =
2085  static_cast<const Interface *>(vlan_nh->GetInterface());
2086  component_nh_info.set_intf_name(intf->name());
2087  break;
2088  }
2089 
2090  case COMPOSITE: {
2091  const CompositeNH *cnh = static_cast<const CompositeNH *>(nh);
2092  std::stringstream str;
2093  str << "Composite; Type: " << cnh->composite_nh_type() <<
2094  " comp_nh_count" << cnh->ComponentNHCount();
2095  component_nh_info.set_type(str.str());
2096  break;
2097  }
2098  default:
2099  break;
2100  }
2101  comp_nh_log_list.push_back(component_nh_info);
2102  }
2103 
2104  info.set_nh_list(comp_nh_log_list);
2105  OPER_TRACE_ENTRY(NextHop, table, info);
2106 }
2107 
2108 //Key for composite NH is list of component NH
2109 //Some of the component NH may be NULL, in case of ECMP, as deletion of
2110 //component NH resulting in addition of invalid component NH at that location,
2111 //so that kernel can trap packet hitting such component NH
2113  const CompositeNHKey *key = static_cast<const CompositeNHKey *>(k);
2114  NextHop::SetKey(k);
2117 }
2118 
2119 bool CompositeNH::NextHopIsLess(const DBEntry &rhs_db) const {
2120  const CompositeNH &rhs = static_cast<const CompositeNH &>(rhs_db);
2123  }
2124 
2125  if (vrf_ != rhs.vrf_) {
2126  return vrf_ < rhs.vrf_;
2127  }
2128 
2129  //Parse thought indivial key entries and compare if they are same
2130  ComponentNHKeyList::const_iterator left_component_nh_it =
2131  component_nh_key_list_.begin();
2132  ComponentNHKeyList::const_iterator right_component_nh_it =
2133  rhs.component_nh_key_list_.begin();
2134 
2135  for (;left_component_nh_it != component_nh_key_list_.end() &&
2136  right_component_nh_it != rhs.component_nh_key_list_.end();
2137  left_component_nh_it++, right_component_nh_it++) {
2138  //If both component NH are empty, nothing to compare
2139  if (*left_component_nh_it == NULL &&
2140  *right_component_nh_it == NULL) {
2141  continue;
2142  }
2143  //One of the component NH is NULL
2144  if ((*left_component_nh_it) == NULL ||
2145  (*right_component_nh_it) == NULL) {
2146  return (*left_component_nh_it) < (*right_component_nh_it);
2147  }
2148 
2149  //Check if the label is different
2150  if ((*left_component_nh_it)->label() !=
2151  (*right_component_nh_it)->label()) {
2152  return (*left_component_nh_it)->label() <
2153  (*right_component_nh_it)->label();
2154  }
2155 
2156  //Check if the nexthop key is different
2157  //Ideally we could find the nexthop and compare pointer alone
2158  //it wont work because this is called from Find context itself,
2159  //and it would result in deadlock
2160  //Hence compare nexthop key alone
2161  const NextHopKey *left_nh = (*left_component_nh_it)->nh_key();
2162  const NextHopKey *right_nh = (*right_component_nh_it)->nh_key();
2163 
2164  if (left_nh->IsEqual(*right_nh) == false) {
2165  return left_nh->IsLess(*right_nh);
2166  }
2167  }
2168 
2169  //Both composite nexthop are same
2170  if (left_component_nh_it == component_nh_key_list_.end() &&
2171  right_component_nh_it == rhs.component_nh_key_list_.end()) {
2172  return false;
2173  }
2174 
2175  //Right composite nexthop entry has more entries, hence
2176  //left composite nexthop is lesser then right composite nh
2177  if (left_component_nh_it == component_nh_key_list_.end()) {
2178  return true;
2179  }
2180  return false;
2181 }
2182 
2185  component_nh_key_list = component_nh_key_list_;
2188  component_nh_key_list,
2189  vrf_->GetName());
2190  return DBEntryBase::KeyPtr(key);
2191 }
2192 
2193 void CompositeNH::Delete(const DBRequest* req) {
2194  component_nh_list_.clear();
2195 }
2196 
2198  TunnelType::Type type) const {
2199  //Create all component NH
2200  for (ComponentNHList::const_iterator it = component_nh_list_.begin();
2201  it != component_nh_list_.end(); it++) {
2202  if ((*it) == NULL) {
2203  continue;
2204  }
2205  const NextHop *nh = (*it)->nh();
2206  switch (nh->GetType()) {
2207  case NextHop::TUNNEL: {
2208  if (type == TunnelType::MPLS_OVER_MPLS) {
2209  const LabelledTunnelNH *tnh =
2210  static_cast<const LabelledTunnelNH *>(nh);
2211  if (tnh->GetTransportTunnelType() !=
2214  tnh_req.key.reset(new LabelledTunnelNHKey(
2215  tnh->GetVrf()->GetName(),
2216  *(tnh->GetSip()),
2217  *(tnh->GetDip()),
2218  tnh->PolicyEnabled(),
2219  type,
2220  tnh->rewrite_dmac(),
2221  tnh->GetTransportLabel()));
2222  tnh_req.data.reset(new LabelledTunnelNHData());
2223  agent->nexthop_table()->Process(tnh_req);
2224  }
2225  } else {
2226  const TunnelNH *tnh = static_cast<const TunnelNH *>(nh);
2227  if (type != tnh->GetTunnelType().GetType()) {
2229  tnh_req.key.reset(new TunnelNHKey(tnh->GetVrf()->GetName(),
2230  *(tnh->GetSip()),
2231  *(tnh->GetDip()),
2232  tnh->PolicyEnabled(),
2233  type,
2234  tnh->rewrite_dmac()));
2235  tnh_req.data.reset(new TunnelNHData());
2236  agent->nexthop_table()->Process(tnh_req);
2237  }
2238  }
2239  break;
2240  }
2241  case NextHop::COMPOSITE: {
2242  const CompositeNH *cnh =
2243  static_cast<const CompositeNH *>(nh);
2244  //Create new composite NH
2245  cnh->ChangeTunnelType(agent, type);
2246  break;
2247  }
2248  default: {
2249  break;
2250  }
2251  }
2252  }
2253 }
2254 
2255 //Changes the component NH key list to contain new NH keys as per new
2256 //tunnel type
2258  ComponentNHKeyList &component_nh_key_list, TunnelType::Type type) const {
2259 
2260  ComponentNHKeyList::iterator it = component_nh_key_list.begin();
2261  TunnelType::Type orig_type = type;
2262  for (;it != component_nh_key_list.end(); it++) {
2263  type = orig_type;
2264  if ((*it) == NULL) {
2265  continue;
2266  }
2267 
2268  if ((*it)->nh_key()->GetType() == NextHop::COMPOSITE) {
2269  CompositeNHKey *composite_nh_key =
2270  static_cast<CompositeNHKey *>((*it)->nh_key()->Clone());
2271  if (composite_nh_key->composite_nh_type() == Composite::TOR) {
2272  type = TunnelType::VXLAN;
2273  }
2274  if (composite_nh_key->composite_nh_type() == Composite::FABRIC ||
2275  composite_nh_key->composite_nh_type() == Composite::L3FABRIC) {
2277  }
2279  composite_nh_key->component_nh_key_list_, type);
2280  std::unique_ptr<const NextHopKey> nh_key(composite_nh_key);
2281  ComponentNHKeyPtr new_comp_nh(new ComponentNHKey((*it)->label(),
2282  std::move(nh_key)));
2283  (*it) = new_comp_nh;
2284  }
2285 
2286  if ((*it)->nh_key()->GetType() == NextHop::TUNNEL) {
2287  TunnelNHKey *tunnel_nh_key =
2288  static_cast<TunnelNHKey *>((*it)->nh_key()->Clone());
2289  tunnel_nh_key->set_tunnel_type(type);
2290  std::unique_ptr<const NextHopKey> nh_key(tunnel_nh_key);
2291  ComponentNHKeyPtr new_tunnel_nh(new ComponentNHKey((*it)->label(),
2292  std::move(nh_key)));
2293  (*it) = new_tunnel_nh;
2294  }
2295  }
2296 }
2297 
2298 //This API recursively goes thru composite NH and creates
2299 //all the component NH upon tunnel type change
2300 //CreateComponentNH() API which creates new tunnel NH and composite NH,
2301 //would call ChangeTunnelType() API which would result in recursion
2303  TunnelType::Type type) const {
2305  type = TunnelType::VXLAN;
2306  }
2310  }
2311  //Create all component NH with new tunnel type
2312  CreateComponentNH(agent, type);
2313 
2314  //Change the tunnel type of all component NH key
2315  ComponentNHKeyList new_component_nh_key_list = component_nh_key_list_;
2316  ChangeComponentNHKeyTunnelType(new_component_nh_key_list, type);
2317  //Create the new nexthop
2320  policy_,
2321  new_component_nh_key_list,
2322  vrf_->GetName());
2324  nh_req.key.reset(comp_nh_key);
2325  nh_req.data.reset(new CompositeNHData(pbb_nh_, learning_enabled_,
2327  agent->nexthop_table()->Process(nh_req);
2328 
2329  CompositeNH *comp_nh = static_cast<CompositeNH *>(
2330  agent->nexthop_table()->FindActiveEntry(comp_nh_key));
2331  assert(comp_nh);
2332  return comp_nh;
2333 }
2334 
2335 bool CompositeNH::GetIndex(ComponentNH &component_nh, uint32_t &idx) const {
2336  idx = 0;
2337  BOOST_FOREACH(ComponentNHPtr it, component_nh_list_) {
2338  if (it.get() == NULL) {
2339  idx++;
2340  continue;
2341  }
2342 
2343  if (it->nh() && component_nh.nh()) {
2344  if (it->nh()->MatchEgressData(component_nh.nh())) {
2345  return true;
2346  } else if (it->nh() == component_nh.nh()) {
2347  return true;
2348  }
2349  }
2350  idx++;
2351  }
2352  return false;
2353 }
2354 
2356  const string &vrf_name) {
2360  NextHopKey *nh_key = static_cast<NextHopKey *>(key.get());
2361  nh_key->sub_op_ = AgentKey::RESYNC;
2362  nh_req.key = std::move(key);
2363  nh_req.data.reset(NULL);
2364  agent->nexthop_table()->Process(nh_req);
2365  }
2366 }
2367 
2369  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key, component_nh_key_list_) {
2370  if (component_nh_key.get() &&
2371  component_nh_key->nh_key()->GetType() == NextHop::TUNNEL) {
2372  DBRequest req;
2373  // First enqueue request to create Tunnel NH
2375  req.key.reset(component_nh_key->nh_key()->Clone());
2376  TunnelNHData *data = new TunnelNHData();
2377  req.data.reset(data);
2378  agent->nexthop_table()->Process(req);
2379  }
2380  }
2381 }
2382 
2384  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key, component_nh_key_list_) {
2385  if (component_nh_key.get() &&
2386  component_nh_key->nh_key()->GetType() == NextHop::TUNNEL) {
2387  DBRequest req;
2388  // First enqueue request to create Tunnel NH
2390  req.key.reset(component_nh_key->nh_key()->Clone());
2391  TunnelNHData *data = new TunnelNHData();
2392  req.data.reset(data);
2393  agent->nexthop_table()->Enqueue(&req);
2394  }
2395  }
2396 }
2397 
2401 }
2402 
2403 bool CompositeNHKey::find(ComponentNHKeyPtr new_component_nh_key) {
2404  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
2406  if (component_nh_key == NULL) {
2407  continue;
2408  }
2409  if (*component_nh_key == *new_component_nh_key) {
2410  return true;
2411  }
2412  }
2413  return false;
2414 }
2415 
2416 void CompositeNHKey::insert(ComponentNHKeyPtr new_component_nh_key) {
2417  if (new_component_nh_key == NULL) {
2418  component_nh_key_list_.push_back(new_component_nh_key);
2419  return;
2420  }
2421 
2422  if (find(new_component_nh_key)) {
2423  return;
2424  }
2425 
2426  ComponentNHKeyList::iterator it;
2427  for (it = component_nh_key_list_.begin();
2428  it != component_nh_key_list_.end(); it++) {
2429  //Insert at empty spot
2430  if ((*it) == NULL) {
2431  *it = new_component_nh_key;
2432  return;
2433  }
2434  }
2435  component_nh_key_list_.push_back(new_component_nh_key);
2436 }
2437 
2439  if (nh_key_ptr==nullptr){
2440  return;
2441  }
2442  for (auto &com_key_ptr : component_nh_key_list_)
2443  {
2444  if (com_key_ptr==nullptr){
2445  continue;
2446  }
2447  if (*com_key_ptr==*nh_key_ptr ){
2448  com_key_ptr.reset();
2449  return;
2450  }
2451  }
2452 }
2453 
2454 bool CompositeNH::UpdateComponentNHKey(uint32_t label, NextHopKey *nh_key,
2455  ComponentNHKeyList &component_nh_key_list, bool &comp_nh_policy) const {
2456  bool ret = false;
2457  comp_nh_policy = false;
2458  BOOST_FOREACH(ComponentNHPtr it, component_nh_list_) {
2459  if (it.get() == NULL) {
2460  ComponentNHKeyPtr dummy_ptr;
2461  dummy_ptr.reset();
2462  component_nh_key_list.push_back(dummy_ptr);
2463  continue;
2464  }
2465  const ComponentNH *component_nh = it.get();
2466  uint32_t new_label = component_nh->label();
2467  DBEntryBase::KeyPtr key = component_nh->nh()->GetDBRequestKey();
2468  NextHopKey *lhs = static_cast<NextHopKey *>(key.release());
2469 
2470  if (new_label != label && lhs->IsEqual(*nh_key)) {
2471  new_label = label;
2472  ret = true;
2473  }
2474  std::unique_ptr<const NextHopKey> nh_key_ptr(lhs);
2475  ComponentNHKeyPtr component_nh_key(
2476  new ComponentNHKey(new_label, std::move(nh_key_ptr)));
2477  component_nh_key_list.push_back(component_nh_key);
2478  if (!comp_nh_policy) {
2479  comp_nh_policy = component_nh->nh()->NexthopToInterfacePolicy();
2480  }
2481  }
2482  return ret;
2483 }
2484 
2486  bool &comp_nh_policy) const {
2487  Agent *agent = static_cast<NextHopTable *>(get_table())->agent();
2488  const NextHop *nh = static_cast<const NextHop *>(agent->nexthop_table()->
2489  FindActiveEntry(cnh->nh_key()));
2490  assert(nh);
2491 
2493  int index = 0;
2494 
2495  comp_nh_policy = false;
2496  bool made_cnh_list = false;
2497  BOOST_FOREACH(ComponentNHPtr it, component_nh_list_) {
2498  const ComponentNH *component_nh = it.get();
2499  if (component_nh == NULL) {
2500  index++;
2501  continue;
2502  }
2503  if (component_nh->nh() == nh) {
2504  if (component_nh->label() == cnh->label()) {
2505  //Entry already present, return old component nh key list
2506  comp_nh_policy = PolicyEnabled();
2507  return component_nh_key_list;
2508  } else {
2509  if (nh->GetType() == NextHop::INTERFACE) {
2510  component_nh_key_list[index] = cnh;
2511  made_cnh_list = true;
2512  }
2513  if (!comp_nh_policy) {
2514  comp_nh_policy = nh->NexthopToInterfacePolicy();
2515  }
2516  }
2517  } else if (!comp_nh_policy) {
2518  comp_nh_policy = component_nh->nh()->NexthopToInterfacePolicy();
2519  }
2520  if (comp_nh_policy && made_cnh_list) {
2521  break;
2522  }
2523  index++;
2524  }
2525 
2526  if (made_cnh_list) {
2527  return component_nh_key_list;
2528  }
2529 
2530  bool inserted = false;
2531  index = 0;
2532  ComponentNHKeyList::const_iterator key_it = component_nh_key_list.begin();
2533  for (;key_it != component_nh_key_list.end(); key_it++, index++) {
2534  //If there is a empty slot, in
2535  //component key list insert the element there.
2536  if ((*key_it) == NULL) {
2537  component_nh_key_list[index] = cnh;
2538  inserted = true;
2539  break;
2540  }
2541  }
2542 
2543  //No empty slots found, insert entry at last
2544  if (inserted == false) {
2545  component_nh_key_list.push_back(cnh);
2546  }
2547  comp_nh_policy = PolicyEnabled();
2548  if (!comp_nh_policy && (nh->GetType() == NextHop::INTERFACE)) {
2549  comp_nh_policy = nh->NexthopToInterfacePolicy();
2550  }
2551  return component_nh_key_list;
2552 }
2553 
2556  bool &comp_nh_new_policy) const {
2557  Agent *agent = static_cast<NextHopTable *>(get_table())->agent();
2558  const NextHop *nh = static_cast<const NextHop *>(agent->nexthop_table()->
2559  Find(cnh->nh_key(), true));
2560  assert(nh);
2561 
2563  ComponentNHKeyPtr component_nh_key;
2564  ComponentNHList::const_iterator it = begin();
2565  comp_nh_new_policy = false;
2566  bool removed = false;
2567  int index = 0;
2568  for (;it != end(); it++, index++) {
2569  ComponentNHKeyPtr dummy_ptr;
2570  dummy_ptr.reset();
2571  if ((*it) && ((*it)->label() == cnh->label() && (*it)->nh() == nh)) {
2572  component_nh_key_list[index] = dummy_ptr;
2573  removed = true;
2574  } else {
2575  /* Go through all the component Interface Nexthops of this
2576  * CompositeNH to figure out the new policy status of this
2577  * CompositeNH. Ignore the component NH being deleted while
2578  * iterating. */
2579  if ((*it) && (*it)->nh() && !comp_nh_new_policy) {
2580  /* If any one of component NH's interface has policy enabled,
2581  * the policy-status of compositeNH is true. So we need to
2582  * look only until we find the first Interface which has
2583  * policy enabled */
2584  comp_nh_new_policy = (*it)->nh()->NexthopToInterfacePolicy();
2585  }
2586  }
2587  if (removed && comp_nh_new_policy) {
2588  /* No need to iterate further if we done with both deleting key and
2589  * figuring out policy-status */
2590  break;
2591  }
2592  }
2593  return component_nh_key_list;
2594 }
2595 
2597  const CompositeNHKey *comp_rhs = static_cast<const CompositeNHKey *>(&rhs);
2598  if (vrf_key_.name_ != comp_rhs->vrf_key_.name_) {
2599  return vrf_key_.name_ < comp_rhs->vrf_key_.name_;
2600  }
2601 
2602  if (composite_nh_type_ != comp_rhs->composite_nh_type_) {
2603  return composite_nh_type_ < comp_rhs->composite_nh_type_;
2604  }
2605 
2606  ComponentNHKeyList::const_iterator key_it = begin();
2607  ComponentNHKeyList::const_iterator rhs_key_it = comp_rhs->begin();
2608  for (;key_it != end() && rhs_key_it != comp_rhs->end();
2609  key_it++, rhs_key_it++) {
2610  const ComponentNHKey *lhs_component_nh_ptr = (*key_it).get();
2611  const ComponentNHKey *rhs_component_nh_ptr = (*rhs_key_it).get();
2612  if (lhs_component_nh_ptr == NULL &&
2613  rhs_component_nh_ptr == NULL) {
2614  continue;
2615  }
2616 
2617  if (lhs_component_nh_ptr == NULL ||
2618  rhs_component_nh_ptr == NULL) {
2619  return lhs_component_nh_ptr < rhs_component_nh_ptr;
2620  }
2621 
2622  if (lhs_component_nh_ptr->label() !=
2623  rhs_component_nh_ptr->label()) {
2624  return lhs_component_nh_ptr->label() < rhs_component_nh_ptr->label();
2625  }
2626 
2627  const NextHopKey *left_nh_key = lhs_component_nh_ptr->nh_key();
2628  const NextHopKey *right_nh_key = rhs_component_nh_ptr->nh_key();
2629  if (left_nh_key->IsEqual(*right_nh_key) == false) {
2630  if (left_nh_key->GetType() != right_nh_key->GetType()) {
2631  return left_nh_key->GetType() < right_nh_key->GetType();
2632  }
2633  return left_nh_key->IsLess(*right_nh_key);
2634  }
2635  }
2636 
2637  if (key_it == end() && rhs_key_it == comp_rhs->end()) {
2638  return false;
2639  }
2640 
2641  if (key_it == end()) {
2642  return true;
2643  }
2644  return false;
2645 }
2646 
2647 // Expand list of local composite members using the MPLS label in
2648 // local-composite key
2649 // Note, another alternative could be to use path created for local-composites
2650 // However, in cases such as service-chain, the MPLS label can point to
2651 // local composite created from different route (route for service-ip)
2653  uint32_t label = MplsTable::kInvalidLabel;
2654  //Find local composite ecmp label
2655  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
2657  if (component_nh_key.get() &&
2658  component_nh_key->nh_key()->GetType() == NextHop::COMPOSITE) {
2659  const CompositeNHKey *composite_nh_key =
2660  static_cast<const CompositeNHKey *>(
2661  component_nh_key->nh_key());
2662  if (composite_nh_key->composite_nh_type() ==
2664  label = component_nh_key->label();
2665  //Erase the entry from list, it will be replaced with
2666  //individual entries of this local composite NH
2667  erase(component_nh_key);
2668  break;
2669  }
2670  }
2671  }
2672 
2673  //In case of ECMP in fabric VRF there is no mpls
2674  //label, hence pick policy flag from corresponding
2675  //interface NH
2676  if (label == MplsTable::kInvalidLabel &&
2677  vrf_key_.IsEqual(VrfKey(agent->fabric_vrf_name()))) {
2678  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
2680  if (component_nh_key.get() &&
2681  component_nh_key->nh_key()->GetType() == NextHop::INTERFACE) {
2682  //Interface NH wouldnt have policy hence pick from VMI
2683  const NextHop *nh = static_cast<const NextHop *>(
2684  agent->nexthop_table()->FindActiveEntry(component_nh_key->nh_key()));
2685  if (nh && nh->NexthopToInterfacePolicy()) {
2686  return true;
2687  }
2688  }
2689  }
2690  }
2691 
2692  //No Local composite NH found
2693  if (label == MplsTable::kInvalidLabel) {
2694  return false;
2695  }
2696 
2697  MplsLabel *mpls = agent->mpls_table()->FindMplsLabel(label);
2698  if (mpls == NULL) {
2699  return false;
2700  }
2701 
2702  const NextHop *mpls_nh = mpls->nexthop();
2703 
2704  // FIXME: Its possible that the label we have got here is re-cycled one
2705  // We dont have a good scheme to handle recycled labels. For now ensure
2706  // that label points to COMPOSITE.
2707  //
2708  // If the label is really recyecled, then we will get a route update
2709  // shortly with new label or route delete
2710  if (mpls_nh->GetType() != NextHop::COMPOSITE) {
2711  component_nh_key_list_.clear();
2712  return false;
2713  }
2714 
2715  assert(mpls_nh->GetType() == NextHop::COMPOSITE);
2716  const CompositeNH *cnh = static_cast<const CompositeNH *>(mpls_nh);
2717 
2718  bool comp_nh_new_policy = false;
2719  BOOST_FOREACH(ComponentNHPtr it, cnh->component_nh_list()) {
2720  if (it.get() == NULL) {
2721  ComponentNHKeyPtr dummy_ptr;
2722  dummy_ptr.reset();
2723  insert(dummy_ptr);
2724  continue;
2725  }
2726  const ComponentNH *component_nh = it.get();
2727  DBEntryBase::KeyPtr key = component_nh->nh()->GetDBRequestKey();
2728  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
2729  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
2730  ComponentNHKeyPtr component_nh_key(
2731  new ComponentNHKey(component_nh->label(), std::move(nh_key_ptr)));
2732  insert(component_nh_key);
2733  if (!comp_nh_new_policy) {
2734  comp_nh_new_policy = component_nh->nh()->NexthopToInterfacePolicy();
2735  }
2736  }
2737  return comp_nh_new_policy;
2738 }
2739 
2741  uint32_t label, const NextHop *nh) {
2742  //Enqueue request to create Tunnel NH
2743  CreateTunnelNH(agent);
2744  //First expand local composite NH, if any
2745  bool policy = ExpandLocalCompositeNH(agent);
2746  //Order the component NH entries, so that previous position of
2747  //component NH are maintained.
2748  //For example, if previous composite NH consisted of A, B and C
2749  //as component NH, and the new array of component NH is B, A and C
2750  //or any combination of the three entries, the result should be A, B and C
2751  //only, so that previous position are mainatined.
2752  //If the new key list is C and A, then the end result would be A <NULL> C,
2753  //so that A and C component NH position are maintained
2754  //
2755  //Example 2
2756  //Let old component NH member be A, B, C
2757  //And new component NH member be D, A, B, C in any of 24 combination
2758  //Then new composite NH has to be A, B, C, D in that order, such that
2759  //A, B, C nexthop retain there position
2760  if (!nh) {
2761  return policy;
2762  }
2763 
2764  if (nh->GetType() != NextHop::COMPOSITE) {
2766  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
2767  nh_key->SetPolicy(false);
2768  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
2769  //Insert exisiting nexthop at first slot
2770  //This ensures that old flows are not disturbed
2771  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
2772  std::move(nh_key_ptr)));
2773  if (find(component_nh_key)) {
2774  //Swap first entry and previous nexthop which
2775  //route would have been pointing to
2776  ComponentNHKeyPtr first_entry = component_nh_key_list_[0];
2777  erase(first_entry);
2778  erase(component_nh_key);
2779  insert(component_nh_key);
2780  insert(first_entry);
2781  }
2782  return policy;
2783  }
2784 
2785  CompositeNHKey *composite_nh_key;
2787  composite_nh_key = static_cast<CompositeNHKey *>(key.get());
2788  // Delete entries not present in the new composite NH key
2789  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
2790  composite_nh_key->component_nh_key_list()) {
2791  if (component_nh_key != NULL &&
2792  find(component_nh_key) == false) {
2793  composite_nh_key->erase(component_nh_key);
2794  }
2795  }
2796 
2797  // Add new entries
2798  BOOST_FOREACH(ComponentNHKeyPtr component_nh_key,
2800  if (component_nh_key != NULL) {
2801  composite_nh_key->insert(component_nh_key);
2802  }
2803  }
2804  // Copy over the list
2805  component_nh_key_list_ = composite_nh_key->component_nh_key_list();
2806  return policy;
2807 }
2808 
2810  const ComponentNHKeyList &component_nh_list, const std::string &vrf_name):
2811  label_(label), nh_key_(new CompositeNHKey(type, policy, component_nh_list,
2812  vrf_name)) {
2813 }
2814 
2815 PBBNH::PBBNH(VrfEntry *vrf, const MacAddress &dest_bmac, uint32_t isid):
2816  NextHop(NextHop::PBB, true, false), vrf_(vrf, this), dest_bmac_(dest_bmac),
2817  isid_(isid), label_(MplsTable::kInvalidLabel), child_nh_(NULL){
2818 }
2819 
2821 }
2822 
2823 bool PBBNH::CanAdd() const {
2824  if (vrf_ == NULL) {
2825  LOG(ERROR, "Invalid VRF in PBBNH. Skip Add");
2826  return false;
2827  }
2828 
2829  if (dest_bmac_ == MacAddress::ZeroMac()) {
2830  LOG(ERROR, "Invalid tunnel-destination in PBBNH");
2831  }
2832 
2833  return true;
2834 }
2835 
2837  VrfEntry *vrf = static_cast<VrfEntry *>
2838  (Agent::GetInstance()->vrf_table()->Find(&vrf_key_, true));
2839  return new PBBNH(vrf, dest_bmac_, isid_);
2840 }
2841 
2842 bool PBBNH::NextHopIsLess(const DBEntry &rhs) const {
2843  const PBBNH &a = static_cast<const PBBNH &>(rhs);
2844 
2845  if (vrf_.get() != a.vrf_.get()) {
2846  return vrf_.get() < a.vrf_.get();
2847  }
2848 
2849  if (dest_bmac_ != a.dest_bmac_) {
2850  return dest_bmac_ < a.dest_bmac_;
2851  }
2852 
2853  return isid_ < a.isid_;
2854 }
2855 
2856 void PBBNH::SetKey(const DBRequestKey *k) {
2857  const PBBNHKey *key = static_cast<const PBBNHKey *>(k);
2858  NextHop::SetKey(k);
2860  dest_bmac_ = key->dest_bmac_;
2861  policy_ = key->policy_;
2862  isid_ = key->isid_;
2863 }
2864 
2866  NextHopKey *key = new PBBNHKey(vrf_->GetName(), dest_bmac_, isid_);
2867  return DBEntryBase::KeyPtr(key);
2868 }
2869 
2870 const uint32_t PBBNH::vrf_id() const {
2871  return vrf_->vrf_id();
2872 }
2873 
2874 bool PBBNH::ChangeEntry(const DBRequest *req) {
2875  bool ret = false;
2876  Agent *agent = Agent::GetInstance();
2877  BridgeAgentRouteTable *rt_table =
2878  static_cast<BridgeAgentRouteTable *>(vrf_->GetBridgeRouteTable());
2879  BridgeRouteEntry *rt = rt_table->FindRouteNoLock(dest_bmac_);
2880 
2881  uint32_t label = MplsTable::kInvalidLabel;
2882  const NextHop *nh = NULL;
2883 
2884  if (!rt) {
2885  DiscardNHKey key;
2886  nh = static_cast<NextHop *>
2887  (agent->nexthop_table()->FindActiveEntry(&key));
2888  } else {
2889  nh = rt->GetActiveNextHop();
2890  label = rt->GetActiveLabel();
2891  }
2892 
2893  if (nh != child_nh_.get()) {
2894  child_nh_ = nh;
2895  ret = true;
2896  }
2897 
2898  if (label_ != label) {
2899  label_ = label;
2900  ret = true;
2901  }
2902  const AgentPath *path;
2903  if (rt && (path = rt->GetActivePath()) != NULL) {
2904  if (etree_leaf_ != path->etree_leaf()) {
2905  etree_leaf_ = path->etree_leaf();
2906  ret = true;
2907  }
2908  }
2909 
2910  return ret;
2911 }
2912 
2913 void PBBNH::Delete(const DBRequest *req) {
2914  child_nh_.reset(NULL);
2915 }
2916 
2918  AgentLogEvent::type event) const {
2919  NextHopObjectLogInfo info;
2920  FillObjectLog(event, info);
2921 
2922  if (vrf_) {
2923  info.set_vrf(vrf_->GetName());
2924  }
2925  info.set_mac(dest_bmac_.ToString());
2926  OPER_TRACE_ENTRY(NextHop, table, info);
2927 }
2928 
2930 // NextHop Sandesh routines
2932 static void FillComponentNextHop(const CompositeNH *comp_nh,
2933  std::vector<McastData> &list)
2934 {
2935  for (ComponentNHList::const_iterator it = comp_nh->begin();
2936  it != comp_nh->end(); it++) {
2937  const ComponentNH *component_nh = (*it).get();
2938  McastData sdata;
2939  if (component_nh == NULL) {
2940  sdata.set_type("NULL");
2941  list.push_back(sdata);
2942  continue;
2943  }
2944  switch (component_nh->nh()->GetType()) {
2945  case NextHop::INTERFACE: {
2946  sdata.set_type("Interface");
2947  const InterfaceNH *sub_nh =
2948  static_cast<const InterfaceNH *>(component_nh->nh());
2949  if (sub_nh && sub_nh->GetInterface())
2950  sdata.set_label(component_nh->label());
2951  sdata.set_itf(sub_nh->GetInterface()->name());
2952  list.push_back(sdata);
2953  break;
2954  }
2955  case NextHop::TUNNEL: {
2956  sdata.set_type("Tunnel");
2957  const TunnelNH *tnh =
2958  static_cast<const TunnelNH *>(component_nh->nh());
2959  sdata.set_dip(tnh->GetDip()->to_string());
2960  sdata.set_sip(tnh->GetSip()->to_string());
2961  sdata.set_label(component_nh->label());
2962  list.push_back(sdata);
2963  break;
2964  }
2965  case NextHop::VLAN: {
2966  sdata.set_type("Vlan");
2967  const VlanNH *vlan_nh =
2968  static_cast<const VlanNH *>(component_nh->nh());
2969  sdata.set_itf(vlan_nh->GetInterface()->name());
2970  sdata.set_vlan_tag(vlan_nh->GetVlanTag());
2971  list.push_back(sdata);
2972  break;
2973  }
2974  case NextHop::COMPOSITE: {
2975  sdata.set_type("Composite");
2976  const CompositeNH *child_component_nh =
2977  static_cast<const CompositeNH *>(component_nh->nh());
2978  std::vector<McastData> comp_list;
2979  FillComponentNextHop(child_component_nh, comp_list);
2980  list.insert(list.begin(), comp_list.begin(), comp_list.end());
2981  break;
2982  }
2983  default:
2984  std::stringstream s;
2985  s << "UNKNOWN<" << component_nh->nh()->GetType()
2986  << ">";
2987  sdata.set_type(s.str());
2988  list.push_back(sdata);
2989  break;
2990  }
2991  }
2992 }
2993 
2994 static void FillL2CompositeNextHop(const CompositeNH *comp_nh,
2995  L2CompositeData &data)
2996 {
2997  std::stringstream str;
2998  str << "L2 Composite, subnh count : "
2999  << comp_nh->ComponentNHCount();
3000  data.set_type(str.str());
3001  if (comp_nh->ComponentNHCount() == 0)
3002  return;
3003  std::vector<McastData> data_list;
3004  FillComponentNextHop(comp_nh, data_list);
3005  data.set_mc_list(data_list);
3006 }
3007 
3008 static void FillL3CompositeNextHop(const CompositeNH *comp_nh,
3009  L3CompositeData &data)
3010 {
3011  std::stringstream str;
3012  str << "L3 Composite, subnh count : "
3013  << comp_nh->ComponentNHCount();
3014  data.set_type(str.str());
3015  if (comp_nh->ComponentNHCount() == 0)
3016  return;
3017  std::vector<McastData> data_list;
3018  FillComponentNextHop(comp_nh, data_list);
3019  data.set_mc_list(data_list);
3020 }
3021 
3022 static void FillMultiProtoCompositeNextHop(const CompositeNH *comp_nh,
3023  NhSandeshData &data)
3024 {
3025  std::stringstream str;
3026  str << "Multi Proto Composite, subnh count : "
3027  << comp_nh->ComponentNHCount();
3028  data.set_type(str.str());
3029  if (comp_nh->ComponentNHCount() == 0)
3030  return;
3031  for (ComponentNHList::const_iterator it = comp_nh->begin();
3032  it != comp_nh->end(); it++) {
3033  const ComponentNH *component_nh = (*it).get();
3034  if (component_nh == NULL) {
3035  continue;
3036  }
3037  const CompositeNH *sub_cnh =
3038  static_cast<const CompositeNH *>(component_nh->nh());
3039  if (sub_cnh->composite_nh_type() == Composite::L2COMP) {
3040  L2CompositeData l2_data;
3041  FillL2CompositeNextHop(sub_cnh, l2_data);
3042  data.set_l2_comp(l2_data);
3043  }
3044  if (sub_cnh->composite_nh_type() == Composite::L3COMP) {
3045  L3CompositeData l3_data;
3046  FillL3CompositeNextHop(sub_cnh, l3_data);
3047  data.set_l3_comp(l3_data);
3048  }
3049  }
3050 }
3051 
3052 static void ExpandCompositeNextHop(const CompositeNH *comp_nh,
3053  NhSandeshData &data)
3054 {
3055  stringstream comp_str;
3056  switch (comp_nh->composite_nh_type()) {
3057  case Composite::EVPN: {
3058  comp_str << "evpn Composite" << " sub nh count: "
3059  << comp_nh->ComponentNHCount();
3060  data.set_type(comp_str.str());
3061  if (comp_nh->ComponentNHCount() == 0)
3062  break;
3063  std::vector<McastData> data_list;
3064  FillComponentNextHop(comp_nh, data_list);
3065  data.set_mc_list(data_list);
3066  break;
3067  }
3068  case Composite::TOR: {
3069  comp_str << "TOR Composite" << " sub nh count: "
3070  << comp_nh->ComponentNHCount();
3071  data.set_type(comp_str.str());
3072  if (comp_nh->ComponentNHCount() == 0)
3073  break;
3074  std::vector<McastData> data_list;
3075  FillComponentNextHop(comp_nh, data_list);
3076  data.set_mc_list(data_list);
3077  break;
3078  }
3079  case Composite::FABRIC: {
3080  comp_str << "fabric Composite" << " sub nh count: "
3081  << comp_nh->ComponentNHCount();
3082  data.set_type(comp_str.str());
3083  if (comp_nh->ComponentNHCount() == 0)
3084  break;
3085  std::vector<McastData> data_list;
3086  FillComponentNextHop(comp_nh, data_list);
3087  data.set_mc_list(data_list);
3088  break;
3089  }
3090  case Composite::L3FABRIC: {
3091  comp_str << "L3 Fabric Composite" << " sub nh count: "
3092  << comp_nh->ComponentNHCount();
3093  data.set_type(comp_str.str());
3094  if (comp_nh->ComponentNHCount() == 0)
3095  break;
3096  std::vector<McastData> data_list;
3097  FillComponentNextHop(comp_nh, data_list);
3098  data.set_mc_list(data_list);
3099  break;
3100  }
3101  case Composite::L3COMP: {
3102  comp_str << "L3 Composite" << " sub nh count: "
3103  << comp_nh->ComponentNHCount();
3104  data.set_type(comp_str.str());
3105  if (comp_nh->ComponentNHCount() == 0)
3106  break;
3107  std::vector<McastData> data_list;
3108  FillComponentNextHop(comp_nh, data_list);
3109  data.set_mc_list(data_list);
3110  break;
3111  }
3112  case Composite::L2COMP: {
3113  comp_str << "L2 Composite" << " sub nh count: "
3114  << comp_nh->ComponentNHCount();
3115  data.set_type(comp_str.str());
3116  if (comp_nh->ComponentNHCount() == 0)
3117  break;
3118  std::vector<McastData> data_list;
3119  FillComponentNextHop(comp_nh, data_list);
3120  data.set_mc_list(data_list);
3121  break;
3122  }
3123  case Composite::L2INTERFACE: {
3124  comp_str << "L2 interface Composite" << " sub nh count: "
3125  << comp_nh->ComponentNHCount();
3126  data.set_type(comp_str.str());
3127  if (comp_nh->ComponentNHCount() == 0)
3128  break;
3129  std::vector<McastData> data_list;
3130  FillComponentNextHop(comp_nh, data_list);
3131  data.set_mc_list(data_list);
3132  break;
3133  }
3134  case Composite::L3INTERFACE: {
3135  comp_str << "L3 interface Composite" << " sub nh count: "
3136  << comp_nh->ComponentNHCount();
3137  data.set_type(comp_str.str());
3138  if (comp_nh->ComponentNHCount() == 0)
3139  break;
3140  std::vector<McastData> data_list;
3141  FillComponentNextHop(comp_nh, data_list);
3142  data.set_mc_list(data_list);
3143  break;
3144  }
3145  case Composite::MULTIPROTO: {
3146  comp_str << "Multiproto Composite" << " sub nh count: "
3147  << comp_nh->ComponentNHCount();
3148  data.set_type(comp_str.str());
3149  FillMultiProtoCompositeNextHop(comp_nh, data);
3150  break;
3151  }
3152  case Composite::ECMP:
3153  case Composite::LOCAL_ECMP:
3154  case Composite::LU_ECMP: {
3155  comp_str << "ECMP Composite" << " sub nh count: "
3156  << comp_nh->ComponentNHCount();
3157  data.set_type(comp_str.str());
3158  std::vector<McastData> data_list;
3159  FillComponentNextHop(comp_nh, data_list);
3160  data.set_mc_list(data_list);
3161  break;
3162  }
3163  default: {
3164  comp_str << "UNKNOWN<" << comp_nh->composite_nh_type()
3165  << ">";
3166  data.set_type(comp_str.str());
3167  break;
3168  }
3169  }
3170 }
3171 
3172 void NextHop::SetNHSandeshData(NhSandeshData &data) const {
3173  data.set_nh_index(id());
3174  data.set_vxlan_flag(false);
3175  data.set_intf_flags(0);
3176  switch (type_) {
3177  case DISCARD:
3178  data.set_type("discard");
3179  break;
3180  case L2_RECEIVE:
3181  data.set_type("l2-receive");
3182  break;
3183  case RECEIVE: {
3184  data.set_type("receive");
3185  const ReceiveNH *nh = static_cast<const ReceiveNH *>(this);
3186  if (nh->GetInterface()) {
3187  data.set_itf(nh->GetInterface()->name());
3188  } else {
3189  data.set_itf("<NULL>");
3190  }
3191  break;
3192  }
3193  case RESOLVE:
3194  data.set_type("resolve");
3195  break;
3196  case ARP: {
3197  data.set_type("arp");
3198  const ArpNH *arp = static_cast<const ArpNH *>(this);
3199  data.set_sip(arp->GetIp()->to_string());
3200  data.set_vrf(arp->GetVrf()->GetName());
3201  if (valid_ == false) {
3202  break;
3203  }
3204  data.set_itf(arp->GetInterface()->name());
3205  const unsigned char *m = arp->GetMac().GetData();
3206  char mstr[32];
3207  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3208  m[0], m[1], m[2], m[3], m[4], m[5]);
3209  std::string mac(mstr);
3210  data.set_mac(std::vector<std::string>(1, mac));
3211  break;
3212  }
3213  case NDP: {
3214  data.set_type("ndp");
3215  const NdpNH *ndp = static_cast<const NdpNH *>(this);
3216  data.set_sip(ndp->GetIp()->to_string());
3217  data.set_vrf(ndp->GetVrf()->GetName());
3218  if (valid_ == false) {
3219  break;
3220  }
3221  data.set_itf(ndp->GetInterface()->name());
3222  const unsigned char *m = ndp->GetMac().GetData();
3223  char mstr[32];
3224  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3225  m[0], m[1], m[2], m[3], m[4], m[5]);
3226  std::string mac(mstr);
3227  data.set_mac(std::vector<std::string>(1, mac));
3228  break;
3229  }
3230  case VRF: {
3231  data.set_type("vrf");
3232  const VrfNH *vrf = static_cast<const VrfNH *>(this);
3233  data.set_vrf(vrf->GetVrf()->GetName());
3234  data.set_vxlan_flag(vrf->bridge_nh());
3235  data.set_flood_unknown_unicast(vrf->flood_unknown_unicast());
3236  data.set_layer2_control_word(vrf->layer2_control_word());
3237  break;
3238  }
3239  case INTERFACE: {
3240  data.set_type("interface");
3241  const InterfaceNH *itf = static_cast<const InterfaceNH *>(this);
3242  data.set_itf(itf->GetInterface()->name());
3243  const unsigned char *m = itf->GetDMac().GetData();
3244  char mstr[32];
3245  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3246  m[0], m[1], m[2], m[3], m[4], m[5]);
3247  std::string mac(mstr);
3248  data.set_mac(std::vector<std::string>(1, mac));
3249  if (itf->is_multicastNH())
3250  data.set_mcast("enabled");
3251  else
3252  data.set_mcast("disabled");
3253  data.set_layer2_control_word(itf->layer2_control_word());
3254  data.set_vxlan_flag(itf->IsVxlanRouting());
3255  data.set_intf_flags(itf->GetFlags());
3256  break;
3257  }
3258  case TUNNEL: {
3259  data.set_type("tunnel");
3260  const TunnelNH *tun = static_cast<const TunnelNH *>(this);
3261  data.set_sip(tun->GetSip()->to_string());
3262  data.set_dip(tun->GetDip()->to_string());
3263  data.set_vrf(tun->GetVrf()->GetName());
3264  data.set_tunnel_type(tun->GetTunnelType().ToString());
3265  if (valid_) {
3266  const NextHop *anh = tun->GetRt()->GetActiveNextHop();
3267  if (anh != NULL) {
3268  const NextHop *nh = static_cast<const NextHop *>(anh);
3269  if (nh->GetType() == NextHop::ARP) {
3270  const ArpNH *arp_nh = static_cast<const ArpNH *>(nh);
3271  const unsigned char *m = arp_nh->GetMac().GetData();
3272  char mstr[32];
3273  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3274  m[0], m[1], m[2], m[3], m[4], m[5]);
3275  std::string mac(mstr);
3276  data.set_mac(std::vector<std::string>(1, mac));
3277  } else if (nh->GetType() == NextHop::NDP) {
3278  const NdpNH *ndp_nh = static_cast<const NdpNH *>(nh);
3279  const unsigned char *m = ndp_nh->GetMac().GetData();
3280  char mstr[32];
3281  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3282  m[0], m[1], m[2], m[3], m[4], m[5]);
3283  std::string mac(mstr);
3284  data.set_mac(std::vector<std::string>(1, mac));
3285  } else if (nh->GetType() == NextHop::COMPOSITE) {
3286  const CompositeNH *cnh = dynamic_cast<const CompositeNH*>(nh);
3287  ComponentNHList::const_iterator component_nh_it =
3288  cnh->begin();
3289  std::vector<std::string> mac_list;
3290  while (component_nh_it != cnh->end()) {
3291  const NextHop *component_nh = NULL;
3292  if (*component_nh_it) {
3293  component_nh = (*component_nh_it)->nh();
3294  if (component_nh->GetType() == NextHop::ARP) {
3295  const ArpNH *arp_nh = dynamic_cast<const ArpNH*>(component_nh);
3296  const unsigned char *m = arp_nh->GetMac().GetData();
3297  char mstr[32];
3298  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3299  m[0], m[1], m[2], m[3], m[4], m[5]);
3300  std::string mac(mstr);
3301  mac_list.push_back(mac);
3302  }
3303  }
3304  component_nh_it++;
3305  }
3306  data.set_mac(mac_list);
3307  }
3308  }
3309  }
3310  data.set_crypt_all_traffic(tun->GetCrypt());
3311  if (tun->GetCryptTunnelAvailable()) {
3312  data.set_crypt_path_available(tun->GetCryptTunnelAvailable());
3313  data.set_crypt_interface(tun->GetCryptInterface()->name());
3314  }
3315  if (tun->rewrite_dmac().IsZero() == false) {
3316  data.set_vxlan_flag(true);
3317  data.set_pbb_bmac(tun->rewrite_dmac().ToString());
3318  }
3319  break;
3320  }
3321  case MIRROR: {
3322  data.set_type("Mirror");
3323  const MirrorNH *mir_nh = static_cast<const MirrorNH *>(this);
3324  data.set_sip(mir_nh->GetSip()->to_string());
3325  data.set_dip(mir_nh->GetDip()->to_string());
3326  data.set_vrf(mir_nh->GetVrf() ? mir_nh->GetVrf()->GetName() : "");
3327  data.set_sport(mir_nh->GetSPort());
3328  data.set_dport(mir_nh->GetDPort());
3329  if (valid_ && mir_nh->GetVrf()) {
3330  const NextHop *mnh = mir_nh->GetRt()->GetActiveNextHop();
3331  if (mnh != NULL) {
3332  const NextHop *nh = static_cast<const NextHop *>(mnh);
3333  if (nh->GetType() == NextHop::ARP) {
3334  const ArpNH *arp_nh = static_cast<const ArpNH *>(nh);
3335  (mir_nh->GetRt()->GetActiveNextHop());
3336  const unsigned char *m = arp_nh->GetMac().GetData();
3337  char mstr[32];
3338  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3339  m[0], m[1], m[2], m[3], m[4], m[5]);
3340  std::string mac(mstr);
3341  data.set_mac(std::vector<std::string>(1, mac));
3342  } else if (nh->GetType() == NextHop::NDP) {
3343  const NdpNH *ndp_nh = static_cast<const NdpNH *>(nh);
3344  (mir_nh->GetRt()->GetActiveNextHop());
3345  const unsigned char *m = ndp_nh->GetMac().GetData();
3346  char mstr[32];
3347  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3348  m[0], m[1], m[2], m[3], m[4], m[5]);
3349  std::string mac(mstr);
3350  data.set_mac(std::vector<std::string>(1, mac));
3351  } else if (nh->GetType() == NextHop::RECEIVE) {
3352  const ReceiveNH *rcv_nh = static_cast<const ReceiveNH*>(nh);
3353  data.set_itf(rcv_nh->GetInterface()->name());
3354  } else if (nh->GetType() == NextHop::COMPOSITE) {
3355  const CompositeNH *cnh = dynamic_cast<const CompositeNH*>(nh);
3356  ComponentNHList::const_iterator component_nh_it =
3357  cnh->begin();
3358  std::vector<std::string> mac_list;
3359  while (component_nh_it != cnh->end()) {
3360  const NextHop *component_nh = NULL;
3361  if (*component_nh_it) {
3362  component_nh = (*component_nh_it)->nh();
3363  if (component_nh->GetType() == NextHop::ARP) {
3364  const ArpNH *arp_nh = dynamic_cast<const ArpNH*>(component_nh);
3365  const unsigned char *m = arp_nh->GetMac().GetData();
3366  char mstr[32];
3367  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3368  m[0], m[1], m[2], m[3], m[4], m[5]);
3369  std::string mac(mstr);
3370  mac_list.push_back(mac);
3371  }
3372  }
3373  component_nh_it++;
3374  }
3375  data.set_mac(mac_list);
3376 
3377  }
3378  }
3379  }
3380  break;
3381  }
3382  case COMPOSITE: {
3383  const CompositeNH *comp_nh = static_cast<const CompositeNH *>(this);
3384  ExpandCompositeNextHop(comp_nh, data);
3385  data.set_layer2_control_word(comp_nh->layer2_control_word());
3386  break;
3387  }
3388 
3389  case PBB: {
3390  data.set_type("PBB Tunnel");
3391  const PBBNH *pbb_nh = static_cast<const PBBNH *>(this);
3392  data.set_pbb_bmac(pbb_nh->dest_bmac().ToString());
3393  data.set_vrf(pbb_nh->vrf()->GetName());
3394  data.set_isid(pbb_nh->isid());
3395  std::vector<McastData> data_list;
3396  const TunnelNH *tnh =
3397  dynamic_cast<const TunnelNH *>(pbb_nh->child_nh());
3398  if (tnh) {
3399  McastData sdata;
3400  sdata.set_type("Tunnel");
3401  sdata.set_dip(tnh->GetDip()->to_string());
3402  sdata.set_sip(tnh->GetSip()->to_string());
3403  sdata.set_label(pbb_nh->label());
3404  data_list.push_back(sdata);
3405  }
3406  data.set_mc_list(data_list);
3407  break;
3408  }
3409 
3410  case VLAN: {
3411  data.set_type("vlan");
3412  const VlanNH *itf = static_cast<const VlanNH *>(this);
3413  data.set_itf(itf->GetInterface()->name());
3414  data.set_vlan_tag(itf->GetVlanTag());
3415  const unsigned char *m = itf->GetDMac().GetData();
3416  char mstr[32];
3417  snprintf(mstr, 32, "%x:%x:%x:%x:%x:%x",
3418  m[0], m[1], m[2], m[3], m[4], m[5]);
3419  std::string mac(mstr);
3420  data.set_mac(std::vector<std::string>(1, mac));
3421  break;
3422  }
3423 
3424  case INVALID:
3425  default:
3426  data.set_type("invalid");
3427  break;
3428  }
3429  if (valid_) {
3430  data.set_valid("true");
3431  } else {
3432  data.set_valid("false");
3433  }
3434 
3435  data.set_learning_enabled(learning_enabled_);
3436  data.set_etree_leaf(etree_leaf_);
3437 
3438  if (policy_) {
3439  data.set_policy("enabled");
3440  } else {
3441  data.set_policy("disabled");
3442  }
3443 
3444  data.set_ref_count(GetRefCount());
3445 }
3446 
3448  NextHop *nh = index_table_.At(index);
3449  if (nh && nh->IsDeleted() != true) {
3450  return nh;
3451  }
3452  return NULL;
3453 }
3454 
3455 bool NextHop::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
3456  NhListResp *resp = static_cast<NhListResp *>(sresp);
3457 
3458  NhSandeshData data;
3459  SetNHSandeshData(data);
3460  std::vector<NhSandeshData> &list =
3461  const_cast<std::vector<NhSandeshData>&>(resp->get_nh_list());
3462  list.push_back(data);
3463 
3464  return true;
3465 }
3466 
3467 void NhListReq::HandleRequest() const {
3468  AgentSandeshPtr sand(new AgentNhSandesh(context(), get_type(),
3469  get_nh_index(), get_policy_enabled()));
3470  sand->DoSandesh(sand);
3471 }
3472 
3474  const std::string &context) {
3475  return AgentSandeshPtr(new AgentNhSandesh(context,
3476  args->GetString("type"), args->GetString("nh_index"),
3477  args->GetString("policy_enabled")));
3478 }
uint32_t PickMember(uint32_t seed, uint32_t affinity_index, bool ingress) const
Definition: nexthop.cc:1861
EntryType At(size_t index) const
Definition: index_vector.h:32
static PriorityList priority_list_
Definition: nexthop.h:332
static const MacAddress & ZeroMac()
Definition: mac_address.h:158
uint32_t TypeBmap
Definition: nexthop.h:248
uint32_t const GetTransportLabel() const
Definition: tunnel_nh.h:100
static void FillL2CompositeNextHop(const CompositeNH *comp_nh, L2CompositeData &data)
Definition: nexthop.cc:2994
IpAddress sip_
Definition: tunnel_nh.h:196
static void FillObjectLogMac(const unsigned char *m, NextHopObjectLogInfo &info)
Definition: nexthop.cc:253
const NextHop * nh() const
Definition: nexthop.h:1623
static void Create()
Definition: nexthop.cc:1626
uint16_t sport_
Definition: tunnel_nh.h:142
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:2874
const Interface * GetInterface() const
Definition: nexthop.h:1293
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:2112
virtual bool CanAdd() const
Definition: nexthop.cc:1322
void ConcurrencyCheck()
Definition: agent.cc:1044
bool IsEqual(const NextHopKey &rhs) const
Definition: nexthop.h:481
bool crypt_
Definition: tunnel_nh.h:78
uint16_t vlan_tag_
Definition: nexthop.h:1509
std::string vrf_name_
Definition: tunnel_nh.h:194
MacAddress rewrite_dmac_
Definition: nexthop.h:1011
Interface * FindInterface(const InterfaceKey &key) const
Definition: nexthop.cc:358
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:943
const VnListType & dest_vn_list() const
Definition: agent_path.h:258
void ReplaceLocalNexthop(const ComponentNHKeyList &new_comp_nh)
Definition: nexthop.cc:1774
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:2842
const Interface * GetFirstLocalEcmpMemberInterface() const
Definition: nexthop.cc:1837
static void CreateReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag, const std::string &vrf_name, const MacAddress &smac, const MacAddress &dmac)
Definition: nexthop.cc:1729
NextHopTable(DB *db, const std::string &name)
Definition: nexthop.cc:278
Type type() const
Definition: interface.h:112
void UpdateEcmpHashFieldsUponRouteDelete(Agent *agent, const string &vrf_name)
Definition: nexthop.cc:2355
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:509
ComponentNHKeyList component_nh_key_list_
Definition: nexthop.h:1932
void Process(DBClient *client, DBRequest *req)
const VrfEntry * GetVrf() const
Definition: tunnel_nh.h:35
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:1674
virtual ~TunnelNH()
Definition: nexthop.cc:998
CompositeNHKey(COMPOSITETYPE type, bool policy, const ComponentNHKeyList &component_nh_key_list, const std::string &vrf_name)
Definition: nexthop.h:1686
friend class VrfNH
Definition: nexthop.h:1404
TunnelType tunnel_type_
Definition: nexthop.h:1010
VrfEntryRef vrf_
Definition: tunnel_nh.h:70
friend class MirrorNH
Definition: tunnel_nh.h:138
static Agent * GetInstance()
Definition: agent.h:436
static void CreateReq(const InterfaceKey *intf, bool policy)
Definition: nexthop.cc:1590
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:970
friend class TunnelNH
Definition: nexthop.h:1006
Definition: vrf.h:86
static Type default_type_
Definition: nexthop.h:333
const TagList & tag_list() const
Definition: agent_path.h:249
uint32_t isid_
Definition: nexthop.h:1174
NextHop * FindNextHop(size_t index)
Definition: nexthop.cc:3447
const uint32_t vrf_id() const
Definition: nexthop.cc:505
static const uint32_t kInvalidComponentNHIdx
Definition: nexthop.h:1777
bool layer2_control_word_
Definition: nexthop.h:1759
VrfKey vrf_key_
Definition: nexthop.h:794
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
COMPOSITETYPE composite_nh_type_
Definition: nexthop.h:1737
virtual bool CanAdd() const
Definition: nexthop.cc:1636
virtual void Add(Agent *agent, const DBRequest *req)
Definition: nexthop.cc:109
static void DeleteReq(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag)
Definition: nexthop.cc:1738
NextHop::Type type_
Definition: nexthop.h:512
bool GetCrypt() const
Definition: tunnel_nh.h:44
void set_id(uint32_t index)
Definition: nexthop.h:409
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:576
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:1755
std::string GetString(const std::string &key) const
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
MplsLabel * AllocateLabel(Agent *agent, const NextHopKey *key)
Definition: nexthop.cc:105
virtual bool CanAdd() const
Definition: nexthop.cc:911
InterfaceRef interface_
Definition: nexthop.h:1570
const VrfEntry * GetVrf() const
Definition: nexthop.h:1444
NextHopTable * nexthop_table() const
Definition: agent.h:475
DBTableBase * get_table() const
Definition: db_entry.cc:119
Ip4Address ip_
Definition: nexthop.h:858
const MacAddress & GetMac() const
Definition: nexthop.h:836
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:453
static void AddArpReq(const string &route_vrf_name, const Ip4Address &ip, const string &nh_vrf_name, const Interface *intf, bool policy, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list)
TunnelType tunnel_type_
Definition: tunnel_nh.h:75
VrfEntryRef vrf_
Definition: nexthop.h:857
virtual bool CanAdd() const
Definition: nexthop.cc:1622
void EnqueueResync() const
Definition: nexthop.cc:135
void CryptAvailability(const std::string &remote_ip, bool &crypt_traffic, bool &crypt_path_available)
Definition: crypt_tunnel.cc:82
virtual bool Delete(DBEntry *entry, const DBRequest *req)
Definition: nexthop.cc:344
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:2041
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:463
bool valid_
Definition: nexthop.h:905
bool layer2_control_word_
Definition: nexthop.h:1937
const MacAddress & GetDMac() const
Definition: nexthop.h:1548
VrfKey vrf_key_
Definition: nexthop.h:1405
virtual bool NextHopKeyIsLess(const NextHopKey &rhs) const
Definition: nexthop.cc:2596
void CreateTunnelNHReq(Agent *agent)
Definition: nexthop.cc:2383
const Interface * GetInterface() const
Definition: nexthop.h:926
const NextHop * nexthop() const
Definition: mpls.h:80
MacAddress mac_
Definition: nexthop.h:949
bool IsDeleted() const
Definition: db_entry.h:49
const IpAddress * GetIp() const
Definition: nexthop.h:929
bool flood_unknown_unicast_
Definition: nexthop.h:1421
bool etree_leaf_
Definition: nexthop.h:452
uint8_t flags_
Definition: nexthop.h:1365
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:619
static DBTableBase * CreateTable(DB *db, const std::string &name)
Definition: nexthop.cc:352
VrfEntryRef vrf_
Definition: nexthop.h:1934
bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:1651
virtual ~PBBNH()
Definition: nexthop.cc:2820
boost::asio::ip::address IpAddress
Definition: address.h:13
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1573
Type GetType() const
Definition: nexthop.h:303
uint8_t sub_op_
Definition: agent_db.h:106
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1645
bool bridge_nh_
Definition: nexthop.h:1407
boost::scoped_ptr< const InterfaceKey > intf_key_
Definition: nexthop.h:714
MacAddress dmac_
Definition: nexthop.h:1522
bool valid_
Definition: nexthop.h:816
Agent * agent() const
Definition: agent_db.h:213
const VrfEntry * GetVrf() const
Definition: nexthop.h:930
bool layer2_control_word() const
Definition: nexthop.h:1918
uint32_t transport_mpls_label_
Definition: nexthop.h:1068
virtual bool TunnelNextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:1267
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:1666
IntrusivePtrRef< VrfEntry > VrfEntryRef
Definition: agent.h:86
std::map< std::string, std::string > VrLimitExceeded
Definition: agent.h:214
const MacAddress & GetMac() const
Definition: nexthop.h:925
bool IsVxlanRouting() const
Definition: nexthop.h:1295
bool policy_
Definition: nexthop.h:513
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:691
IpAddress dip_
Definition: tunnel_nh.h:141
TunnelNH(VrfEntry *vrf, const Ip4Address &sip, const Ip4Address &dip, bool policy, TunnelType type, const MacAddress &rewrite_dmac)
Definition: nexthop.cc:985
const AgentRoute * GetRt() const
Definition: tunnel_nh.h:175
IpAddress ip_
Definition: nexthop.h:947
void CreateComponentNH(Agent *agent, TunnelType::Type type) const
Definition: nexthop.cc:2197
bool validate_mcast_src_
Definition: nexthop.h:1931
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
uint32_t GetRefCount() const
Definition: nexthop.h:395
MacAddress dmac_
Definition: tunnel_nh.h:202
IpAddress sip_
Definition: tunnel_nh.h:140
uint32_t label() const
Definition: nexthop.h:1627
MacAddress dmac_
Definition: nexthop.h:1247
const NextHop * GetLocalNextHop() const
Definition: nexthop.cc:1798
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:936
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:1217
InterfaceTable * interface_table() const
Definition: agent.h:465
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
virtual bool CanAdd() const
Definition: nexthop.cc:444
const Ip4Address * GetDip() const
Definition: tunnel_nh.h:37
VrfKey vrf_key_
Definition: nexthop.h:1007
boost::uuids::uuid uuid
static TypeBmap MplsType()
Definition: nexthop.h:312
static void DeleteMulticastVmInterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &dmac, const std::string &intf_name)
Definition: nexthop.cc:797
bool layer2_control_word() const
Definition: nexthop.h:1359
ObjectType * get() const
Definition: dependency.h:49
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:558
static VlanNH * Find(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag)
Definition: nexthop.cc:1750
virtual DBEntry * Add(const DBRequest *req)
Definition: nexthop.cc:306
friend class LabelledTunnelNH
Definition: nexthop.h:1069
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
Definition: nexthop.h:1639
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
Definition: vrf.cc:338
const string & GetName() const
Definition: vrf.h:100
static void CreateInetInterfaceNextHop(const string &ifname, const string &vrf_name, const MacAddress &mac)
Definition: nexthop.cc:817
bool NexthopToInterfacePolicy() const
Definition: nexthop.cc:262
AddressList vhost_default_gateway() const
Definition: agent.h:656
Ip4Address dip_
Definition: tunnel_nh.h:74
void insert(ComponentNHKeyPtr nh_key)
Definition: nexthop.cc:2416
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
float vr_limit_high_watermark()
Definition: agent.h:1391
uint16_t GetVlanTag() const
Definition: nexthop.h:1544
bool GetCryptTunnelAvailable() const
Definition: tunnel_nh.h:45
static void FillMultiProtoCompositeNextHop(const CompositeNH *comp_nh, NhSandeshData &data)
Definition: nexthop.cc:3022
MacAddress dmac_
Definition: nexthop.h:1573
MacAddress mac_
Definition: nexthop.h:903
size_t InUseIndexCount()
Definition: index_vector.h:89
MplsTable * mpls_table() const
Definition: agent.h:510
VrfEntry * vrf() const
Definition: interface.h:115
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:438
MacAddress dest_bmac_
Definition: nexthop.h:1173
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
friend class CompositeNH
Definition: nexthop.h:1731
MacAddress rewrite_dmac_
Definition: tunnel_nh.h:81
void SetNHSandeshData(NhSandeshData &data) const
Definition: nexthop.cc:3172
Type GetType() const
Definition: nexthop.h:405
const VrfEntry * vrf() const
Definition: nexthop.h:1875
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:683
VrfKey vrf_key_
Definition: nexthop.h:1740
BridgeRouteEntry * FindRouteNoLock(const MacAddress &mac)
Definition: bridge_route.cc:77
virtual bool CanAdd() const
Definition: nexthop.cc:1501
uint32_t GetRefCount() const
Definition: interface.h:102
static void Create()
Definition: nexthop.cc:1608
virtual CompositeNHKey * Clone() const
Definition: nexthop.cc:2398
Ip4Address dip_
Definition: nexthop.h:795
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1510
virtual ~NextHopTable()
Definition: nexthop.cc:285
float vr_limit_low_watermark()
Definition: agent.h:1399
const uint32_t vrf_id() const
Definition: nexthop.cc:610
bool layer2_control_word_
Definition: nexthop.h:1263
uint16_t dport_
Definition: tunnel_nh.h:143
virtual ~LabelledTunnelNH()
Definition: nexthop.cc:1251
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
virtual bool OnChange(DBEntry *entry, const DBRequest *req)
Definition: nexthop.cc:321
std::string ToString() const
Definition: mac_address.cc:53
static bool EncapPrioritySync(const std::vector< std::string > &cfg_list)
Definition: nexthop.cc:58
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:1273
static NextHopTable * nexthop_table_
Definition: nexthop.h:1990
Ip4Address sip_
Definition: nexthop.h:1008
void AddWithoutAlloc(DBEntry *entry)
Definition: nexthop.cc:381
const Ip4Address * GetIp() const
Definition: nexthop.h:840
const Interface * GetInterface() const
Definition: nexthop.h:837
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:471
TunnelType::Type const GetTransportTunnelType() const
Definition: tunnel_nh.h:109
ComponentNHKey(int label, std::unique_ptr< const NextHopKey > key)
Definition: nexthop.h:1645
MacAddress mac_
Definition: nexthop.h:860
uint32_t vrouter_max_nexthops() const
Definition: agent.h:1259
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:1661
MacAddress dmac_
Definition: nexthop.h:1366
NextHop::Type GetType() const
Definition: nexthop.h:499
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:1355
virtual bool TunnelNextHopIsLess(const DBEntry &rhs) const
Definition: tunnel_nh.h:25
static NextHopTable * GetInstance()
Definition: nexthop.h:1968
const std::string & fabric_vrf_name() const
Definition: agent.h:903
Definition: db.h:24
boost::scoped_ptr< InterfaceKey > intf_key_
Definition: nexthop.h:642
virtual bool CanAdd() const
Definition: nexthop.cc:1790
uint32_t label() const
Definition: nexthop.h:1163
static void FillL3CompositeNextHop(const CompositeNH *comp_nh, L3CompositeData &data)
Definition: nexthop.cc:3008
const AgentPath * GetActivePath() const
Definition: agent_route.cc:876
uint8_t GetFlags() const
Definition: nexthop.h:1300
size_t Insert(EntryType entry)
Definition: index_vector.h:40
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:1048
ComponentNHKeyList component_nh_key_list_
Definition: nexthop.h:1760
virtual NextHop * AllocEntry() const =0
void Init()
Definition: db_table.cc:387
uint32_t transport_mpls_label_
Definition: tunnel_nh.h:116
VrfEntryRef vrf_
Definition: nexthop.h:946
string name_
Definition: vrf.h:38
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:1522
MacAddress smac_
Definition: nexthop.h:1572
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:514
bool IsValid() const
Definition: nexthop.h:406
const uint16_t GetSPort() const
Definition: tunnel_nh.h:172
bool resolved_
Definition: nexthop.h:815
boost::scoped_ptr< InterfaceKey > intf_key_
Definition: nexthop.h:902
ComponentNHKeyList::const_iterator end() const
Definition: nexthop.h:1715
bool IsZero() const
Definition: mac_address.cc:29
uint32_t label_
Definition: nexthop.h:1175
static void AddInterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &dmac, uint8_t flags, bool policy, const string vrf_name, bool learning_enabled, bool etree_leaf, bool layer2_control_word, const string &name)
Definition: nexthop.cc:734
std::list< Type > PriorityList
Definition: nexthop.h:249
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:700
uint8_t type
Definition: load_balance.h:109
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:614
static void DeletePriorityList()
Definition: nexthop.cc:77
bool valid_
Definition: nexthop.h:447
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
Definition: nexthop.cc:3473
Definition: agent.h:358
static void CreateMulticastVmInterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &dmac, const string &vrf_name, const string &intf_name)
Definition: nexthop.cc:788
const uint32_t vrf_id() const
Definition: nexthop.cc:1351
MplsLabel * AllocLabel(const NextHopKey *nh_key)
Definition: mpls.cc:405
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:669
static void Create(NextHopTable *table, const Interface *intf, bool policy)
Definition: nexthop.cc:1530
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:1479
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:926
uint8_t flags_
Definition: nexthop.h:1246
Definition: vrf.h:22
const TunnelType & GetTunnelType() const
Definition: tunnel_nh.h:42
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1254
const NextHop * child_nh() const
Definition: nexthop.h:1167
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:948
const NextHop * GetActiveNextHop() const
Definition: agent_route.cc:881
VrfKey vrf_key_
Definition: nexthop.h:883
VrfKey vrf_key_
Definition: nexthop.h:1113
InetUnicastAgentRouteTable * GetRouteTable()
Definition: nexthop.cc:1371
InterfaceConstRef crypt_interface_
Definition: tunnel_nh.h:80
uint32_t isid_
Definition: nexthop.h:1115
NextHop * AllocWithKey(const DBRequestKey *k) const
Definition: nexthop.cc:297
int CompareTo(const MacAddress &rhs, int len=0) const
Definition: mac_address.cc:87
static void ExpandCompositeNextHop(const CompositeNH *comp_nh, NhSandeshData &data)
Definition: nexthop.cc:3052
bool policy_
Definition: nexthop.h:448
void ResetMplsRef()
Definition: nexthop.h:399
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1014
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:518
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:883
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:2865
std::string ToString() const
Definition: nexthop.h:260
uint32_t label() const
Definition: nexthop.h:1676
void PostAdd()
Definition: nexthop.cc:123
Definition: nexthop.h:820
static void FillObjectLogIntf(const Interface *intf, NextHopObjectLogInfo &info)
Definition: nexthop.cc:226
void RemoveWithoutDelete(DBEntry *entry)
Definition: nexthop.cc:374
bool IsEqual(const VrfKey &rhs) const
Definition: vrf.h:31
Definition: nexthop.h:909
DBOperation oper
Definition: db_table.h:42
virtual bool CanAdd() const
Definition: nexthop.cc:1579
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1333
bool IsLess(const NextHopKey &rhs) const
Definition: nexthop.h:501
void ChangeComponentNHKeyTunnelType(ComponentNHKeyList &component_nh_list, TunnelType::Type type) const
Definition: nexthop.cc:2257
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1618
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:568
bool learning_enabled_
Definition: nexthop.h:462
const uint32_t isid() const
Definition: nexthop.h:1148
VrfKey vrf_key_
Definition: tunnel_nh.h:139
uint16_t vlan_tag_
Definition: nexthop.h:1571
void RemoveWithoutDelete(DBEntry *entry)
const VrfEntry * GetVrf() const
Definition: tunnel_nh.h:170
ComponentNHKeyList DeleteComponentNHKey(ComponentNHKeyPtr component_nh_key, bool &comp_nh_new_policy) const
Definition: nexthop.cc:2555
const Interface * GetInterface() const
Definition: nexthop.h:686
virtual bool CanAdd() const
Definition: nexthop.cc:660
friend class VlanNH
Definition: nexthop.h:1507
bool bridge_nh() const
Definition: nexthop.h:1448
bool resolved_
Definition: nexthop.h:904
static void Create(const InterfaceKey *intf, bool policy)
Definition: nexthop.cc:1583
const ComponentNHList & component_nh_list() const
Definition: nexthop.h:1869
bool UpdateComponentNHKey(uint32_t label, NextHopKey *nh_key, ComponentNHKeyList &component_nh_key_list, bool &comp_nh_policy) const
Definition: nexthop.cc:2454
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1907
#define OPER_TRACE_ENTRY(obj, table,...)
Definition: agent_db.h:234
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
Definition: agent_db.h:18
VrfEntryRef vrf_
Definition: nexthop.h:1574
InterfaceRef interface_
Definition: nexthop.h:694
bool etree_leaf() const
Definition: agent_path.h:388
bool policy_enabled() const
const Ip4Address * GetSip() const
Definition: tunnel_nh.h:36
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
InterfaceRef interface_
Definition: nexthop.h:1364
CryptTunnelTable * crypt_tunnel_table() const
Definition: agent.h:480
COMPOSITETYPE composite_nh_type() const
Definition: nexthop.h:1842
COMPOSITETYPE composite_nh_type() const
Definition: nexthop.h:1726
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:1558
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:2836
void ClearDelete()
Definition: db_entry.h:48
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:1021
EncapDataList encap_list_
Definition: tunnel_nh.h:77
virtual bool Resync(DBEntry *entry, const DBRequest *req)
Definition: nexthop.cc:337
bool HasVmInterface(const VmInterface *vmi) const
Definition: nexthop.cc:1813
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:98
virtual KeyPtr GetDBRequestKey() const =0
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:1932
EcmpHashFields comp_ecmp_hash_fields_
Definition: nexthop.h:1935
ComponentNHList component_nh_list_
Definition: nexthop.h:1933
MacAddress smac_
Definition: nexthop.h:1521
bool Compare(const TunnelType &rhs) const
Definition: nexthop.h:253
InterfaceRef interface_
Definition: nexthop.h:948
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
void CreateTunnelNH(Agent *agent)
Definition: nexthop.cc:2368
VrfEntryRef vrf_
Definition: nexthop.h:1172
bool crypt_tunnel_available_
Definition: tunnel_nh.h:79
InterfaceRef interface_
Definition: nexthop.h:859
const MacAddress & rewrite_dmac() const
Definition: tunnel_nh.h:41
virtual void Change(const DBRequest *req)
Definition: nexthop.cc:113
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
const AgentRoute * GetRt() const
Definition: tunnel_nh.h:38
bool policy_
Definition: nexthop.h:1406
DependencyRef< NextHop, AgentRoute > arp_rt_
Definition: tunnel_nh.h:200
virtual bool ChangeEntry(const DBRequest *req)=0
Type type_
Definition: nexthop.h:446
bool flood_unknown_unicast_
Definition: nexthop.h:1470
const IpAddress * GetSip() const
Definition: tunnel_nh.h:171
static const uint32_t kInvalidLabel
Definition: mpls.h:101
static void DeleteNH(const boost::uuids::uuid &intf_uuid, bool policy, uint8_t flags, const MacAddress &mac, const std::string &intf_name)
Definition: nexthop.cc:805
VrfTable * vrf_table() const
Definition: agent.h:485
void Delete()
Definition: db_entry.cc:131
static void FillComponentNextHop(const CompositeNH *comp_nh, std::vector< McastData > &list)
Definition: nexthop.cc:2932
virtual KeyPtr GetDBRequestKey() const =0
ComponentNHList::const_iterator begin() const
Definition: nexthop.h:1807
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:1261
IpAddress dip_
Definition: tunnel_nh.h:198
boost::scoped_ptr< InterfaceKey > intf_key_
Definition: nexthop.h:1508
friend class ArpNH
Definition: nexthop.h:793
virtual DBTablePartBase * GetTablePartition(const DBRequestKey *key)
Definition: db_table.cc:436
Ip4Address dip_
Definition: nexthop.h:1009
virtual std::unique_ptr< DBEntry > GetEntry(const DBRequestKey *key) const
Definition: nexthop.cc:302
bool etree_leaf_
Definition: nexthop.h:465
void set_vr_limits_exceeded_map(VrLimitExceeded &vr_limit_exceed_map)
Definition: agent.h:1383
MirrorNH(const VrfKey &vkey, const IpAddress &sip, uint16_t sport, const IpAddress &dip, uint16_t dport)
Definition: nexthop.cc:1312
Ip4Address sip_
Definition: tunnel_nh.h:73
virtual bool CanAdd() const
Definition: nexthop.cc:1604
static void DeleteL2InterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &mac, const std::string &intf_name)
Definition: nexthop.cc:781
VrfEntryRef vrf_
Definition: nexthop.h:1367
Definition: mpls.h:99
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:543
void set_tunnel_type(TunnelType tunnel_type)
Definition: nexthop.h:996
MacAddress dest_bmac_
Definition: nexthop.h:1114
bool pbb_nh_
Definition: nexthop.h:1936
bool layer2_control_word_
Definition: nexthop.h:1422
bool ExpandLocalCompositeNH(Agent *agent)
Definition: nexthop.cc:2652
PBBNH(VrfEntry *vrf, const MacAddress &dmac, uint32_t isid)
Definition: nexthop.cc:2815
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:648
uint32_t id() const
Definition: nexthop.h:408
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:1600
static void DeletePhysicalInterfaceNh(const string &ifname, const MacAddress &mac)
Definition: nexthop.cc:874
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:2119
TunnelType::Type transport_tunnel_type_
Definition: tunnel_nh.h:117
friend class ResolveNH
Definition: nexthop.h:713
const MacAddress & GetDMac() const
Definition: nexthop.h:1294
friend class ReceiveNH
Definition: nexthop.h:641
bool validate_mcast_src_
Definition: nexthop.h:1738
static void CreatePacketInterfaceNh(Agent *agent, const string &ifname)
Definition: nexthop.cc:847
const uint16_t GetDPort() const
Definition: tunnel_nh.h:174
static void CreatePhysicalInterfaceNh(const string &ifname, const MacAddress &mac)
Definition: nexthop.cc:865
LabelledTunnelNH(VrfEntry *vrf, const Ip4Address &sip, const Ip4Address &dip, bool policy, TunnelType type, const MacAddress &rewrite_dmac, uint32_t label)
Definition: nexthop.cc:1245
const Interface * crypt_interface() const
Definition: agent.h:1141
bool IsLess(const TunnelType &rhs) const
Definition: nexthop.h:256
void RemoveUnresolvedNH(const NextHop *)
Definition: agent_route.cc:393
uint32_t ReserveIndex()
Definition: nexthop.cc:289
virtual bool CanAdd() const
Definition: nexthop.cc:549
static void DeleteInetInterfaceNextHop(const string &ifname, const MacAddress &mac)
Definition: nexthop.cc:833
IndexVector< NextHop * > index_table_
Definition: nexthop.h:1989
const VrfEntry * GetVrf() const
Definition: nexthop.h:841
void Process(DBRequest &req)
Definition: nexthop.cc:367
bool layer2_control_word_
Definition: nexthop.h:1369
ComponentNHKeyList::const_iterator begin() const
Definition: nexthop.h:1711
ComponentNHKeyList AddComponentNHKey(ComponentNHKeyPtr component_nh_key, bool &comp_nh_policy) const
Definition: nexthop.cc:2485
virtual ~NextHop()
Definition: nexthop.cc:92
virtual void Delete(const DBRequest *req)
Definition: nexthop.h:372
static void CreateL2VmInterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &dmac, const string &vrf_name, bool learning_enabled, bool etree_leaf, bool layer2_control_word, const std::string &intf_name)
Definition: nexthop.cc:768
Definition: mpls.h:52
size_t ComponentNHCount() const
Definition: nexthop.h:1815
VrLimitExceeded & get_vr_limits_exceeded_map()
Definition: agent.h:1379
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:1285
void FillObjectLog(AgentLogEvent::type event, NextHopObjectLogInfo &info) const
Definition: nexthop.cc:142
virtual bool CanAdd() const
Definition: nexthop.cc:1001
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:623
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:1059
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:730
friend class NdpNH
Definition: nexthop.h:882
VrfEntry * forwarding_vrf() const
Definition: vrf.h:217
bool Reorder(Agent *agent, uint32_t label, const NextHop *nh)
Definition: nexthop.cc:2740
#define LOG(_Level, _Msg)
Definition: logging.h:33
CompositeNH * ChangeTunnelType(Agent *agent, TunnelType::Type type) const
Definition: nexthop.cc:2302
void AddWithoutAlloc(DBEntry *entry)
virtual bool CanAdd() const =0
MplsLabel * FindMplsLabel(uint32_t label)
Definition: mpls.cc:399
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:84
bool IsActive() const
Definition: agent_db.cc:27
void FreeInterfaceId(size_t index)
Definition: nexthop.h:1976
virtual void OnZeroRefCount()
Definition: nexthop.h:393
bool layer2_control_word_
Definition: nexthop.h:1471
static void CreateL3VmInterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &dmac, const string &vrf_name, bool learning_enabled, const std::string &intf_name)
Definition: nexthop.cc:750
bool layer2_control_word() const
Definition: nexthop.h:1461
boost::shared_ptr< EncapData > EncapDataPtr
Definition: tunnel_nh.h:68
const std::string & name() const
Definition: interface.h:114
const uint8_t * GetData() const
Definition: mac_address.h:143
bool GetIndex(ComponentNH &nh, uint32_t &idx) const
Definition: nexthop.cc:2335
const Interface * get_interface() const
Definition: nexthop.h:754
static const MacAddress & pkt_interface_mac()
Definition: agent.h:440
const uint32_t vrf_id() const
Definition: nexthop.cc:1065
NextHopConstRef child_nh_
Definition: nexthop.h:1176
uint16_t sport_
Definition: tunnel_nh.h:197
bool PolicyEnabled() const
Definition: nexthop.h:407
void erase(ComponentNHKeyPtr nh_key)
Definition: nexthop.cc:2438
const NextHopKey * nh_key() const
Definition: nexthop.h:1677
std::vector< ComponentNHPtr > ComponentNHList
Definition: nexthop.h:1637
void ChangeTunnelType(TunnelType::Type tunnel_type)
Definition: nexthop.cc:1914
friend class PBBNH
Definition: nexthop.h:1112
void SetPolicy(bool policy)
Definition: nexthop.h:495
static void DeleteL3InterfaceNH(const boost::uuids::uuid &intf_uuid, const MacAddress &mac, const std::string &intf_name)
Definition: nexthop.cc:761
uint16_t dport_
Definition: tunnel_nh.h:199
ComponentNHKeyList component_nh_key_list_
Definition: nexthop.h:1739
const NextHop * GetNH(uint32_t idx) const
Definition: nexthop.h:1832
friend class InterfaceNH
Definition: nexthop.h:1244
bool find(ComponentNHKeyPtr nh_key)
Definition: nexthop.cc:2403
ComponentNHList::const_iterator end() const
Definition: nexthop.h:1811
virtual std::unique_ptr< DBEntry > AllocEntry(const DBRequestKey *k) const
Definition: nexthop.cc:293
const VrfEntry * vrf() const
Definition: nexthop.h:1146
void reset(ObjectType *ptr)
Definition: dependency.h:32
void AddUnresolvedNH(const NextHop *)
Definition: agent_route.cc:389
virtual void OnZeroRefcount(AgentDBEntry *e)
Definition: nexthop.cc:388
boost::scoped_ptr< InterfaceKey > intf_key_
Definition: nexthop.h:1245
bool learning_enabled_
Definition: nexthop.h:451
InterfaceConstRef interface_
Definition: tunnel_nh.h:201
boost::shared_ptr< const ComponentNH > ComponentNHPtr
Definition: nexthop.h:1636
void Zero()
Definition: mac_address.h:131
VrfEntryRef vrf_
Definition: tunnel_nh.h:195
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:1365
const IpAddress * GetDip() const
Definition: tunnel_nh.h:173
const Interface * GetInterface() const
Definition: nexthop.h:1543
const ComponentNHKeyList & component_nh_key_list() const
Definition: nexthop.h:1719
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:1381
bool is_multicastNH() const
Definition: nexthop.h:1298
VrfEntry * FindVrfEntry(const VrfKey &key) const
Definition: nexthop.cc:363
virtual void SendObjectLog(const NextHopTable *table, AgentLogEvent::type event) const
Definition: nexthop.cc:2917
COMPOSITETYPE composite_nh_type_
Definition: nexthop.h:1928
VrfKey vrf_key_
Definition: nexthop.h:1523
bool DBEntrySandesh(Sandesh *sresp, std::string &name) const
Definition: nexthop.cc:3455
virtual bool NextHopIsLess(const DBEntry &rhs) const
Definition: nexthop.cc:1337
const Interface * GetCryptInterface() const
Definition: tunnel_nh.h:43
AgentRoute * tunnel_dst_rt_
Definition: tunnel_nh.h:76
void CheckVrNexthopLimit()
Definition: nexthop.cc:408
VrfKey vrf_key_
Definition: nexthop.h:1262
virtual bool NeedMplsLabel()
Definition: nexthop.cc:898
const MacAddress dest_bmac() const
Definition: nexthop.h:1147
virtual bool DeleteOnZeroRefCount() const
Definition: nexthop.h:390
IpAddress dip_
Definition: nexthop.h:884
virtual NextHop * AllocEntry() const
Definition: nexthop.cc:920
boost::scoped_ptr< InterfaceKey > intf_key_
Definition: nexthop.h:813
const SecurityGroupList & sg_list() const
Definition: agent_path.h:248
VrfEntryRef vrf_
Definition: nexthop.h:1467
MacAddress mac_
Definition: nexthop.h:814
const uint32_t vrf_id() const
Definition: nexthop.cc:2870
static void Create(const boost::uuids::uuid &intf_uuid, uint16_t vlan_tag, const std::string &vrf_name, const MacAddress &smac, const MacAddress &dmac)
Definition: nexthop.cc:1703
bool bridge_nh_
Definition: nexthop.h:1469
virtual bool ChangeEntry(const DBRequest *req)
Definition: nexthop.cc:1069
bool flood_unknown_unicast() const
Definition: nexthop.h:1449
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:1698
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:2183
virtual bool CanAdd() const
Definition: nexthop.cc:2823
virtual uint32_t GetActiveLabel() const
const ComponentNHKeyList & component_nh_key_list() const
Definition: nexthop.h:1872
virtual void SetKey(const DBRequestKey *key)
Definition: nexthop.cc:2856