OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
controller_route_path.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-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/lexical_cast.hpp>
8 
9 #include <cmn/agent_cmn.h>
10 #include <route/route.h>
11 
12 #include <cmn/agent_cmn.h>
13 #include <oper/ecmp_load_balance.h>
14 #include <oper/ecmp.h>
15 #include <oper/route_common.h>
16 #include <oper/vrf.h>
17 #include <oper/tunnel_nh.h>
18 #include <oper/mpls.h>
19 #include <oper/mirror_table.h>
20 #include <oper/peer.h>
21 #include <oper/agent_route.h>
26 #include <controller/controller_types.h>
28 #include <oper/agent_sandesh.h>
29 #include <xmpp/xmpp_channel.h>
30 #include <xmpp_enet_types.h>
31 #include <xmpp_unicast_types.h>
32 
33 using namespace std;
34 using namespace boost::asio;
35 
37  AgentRouteData(AgentRouteData::ADD_DEL_CHANGE, false, 0), peer_(peer) {
38  sequence_number_ = 0;
39  if (peer)
42 }
43 
45  bool ret = false;
46 
48  if (path->ecmp_load_balance() != ecmp_load_balance_) {
50  nh_req_);
51  ret = true;
52  }
53 
54  return ret;
55 }
56 
58  const AgentRoute *rt) {
59  bool path_unresolved = false;
61 
62  // check if tunnel type is mpls and vrf is non default
63  if ((tunnel_bmap_ == (1 << TunnelType::MPLS_OVER_MPLS)) &&
64  (vrf_name_ != agent->fabric_vrf_name())) {
65 
66  // this path depends on inet.3 route table,
67  // update dependent_table if it is not set already.
68  if (!path->GetDependentTable()) {
69  InetUnicastAgentRouteTable *table = NULL;
70  table = static_cast<InetUnicastAgentRouteTable *>
71  (agent->fabric_inet4_mpls_table());
72  assert(table != NULL);
73  path->SetDependentTable(table);
74  }
77  assert(table != NULL);
79  ComponentNHKeyList comp_nh_list;
80  bool comp_nh_policy = false;
81  for (uint32_t i = 0; i < tunnel_dest_list_.size(); i++) {
82  // step1: update ecmpcomponent list
83  IpAddress addr = tunnel_dest_list_[i];
84  uint32_t label = label_list_[i];
86  addr, label, path->GetParentRoute()));
87  InetUnicastRouteEntry *uc_rt = table->FindRoute(addr);
88  const NextHop *anh;
89  if (uc_rt == NULL || uc_rt->prefix_length() == 0 || (anh = uc_rt->GetActiveNextHop()) == NULL) {
90  member->SetUnresolved(true);
91  if (!path_unresolved) {
92  path_unresolved = true;
95  NextHopKey *nh_key =
96  static_cast<NextHopKey *>(key.release());
97  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
98  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
99  std::move(nh_key_ptr)));
100  comp_nh_list.push_back(component_nh_key);
101  }
102  } else {
103  DBEntryBase::KeyPtr key =
104  anh->GetDBRequestKey();
105  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
106  if (nh_key->GetType() != NextHop::COMPOSITE) {
107  //By default all component members of composite NH
108  //will be policy disabled, except for component NH
109  //of type composite
110  nh_key->SetPolicy(false);
111  }
112  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
113  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
114  std::move(nh_key_ptr)));
115  comp_nh_list.push_back(component_nh_key);
116  //Reset to new gateway route, no nexthop for indirect route
117  member->UpdateDependentRoute(uc_rt);
118  member->SetUnresolved(false);
119  }
120  new_list.push_back(member);
121  }
123  nh_req.key.reset(new CompositeNHKey(Composite::ECMP, comp_nh_policy,
124  comp_nh_list, vrf_name_));
125  nh_req.data.reset(new CompositeNHData());
126  nh_req_.Swap(&nh_req);
127  path->ResetEcmpMemberList(new_list);
128  }
129  path->set_vrf_name(vrf_name_);
130 
131  CompositeNHKey *comp_key = static_cast<CompositeNHKey *>(nh_req_.key.get());
132  bool ret = false;
133 
134  if (tunnel_bmap_ == TunnelType::VxlanType() && vxlan_id_ != 0) {
135  path->set_vxlan_id(vxlan_id_);
136  }
137 
138  //Reorder the component NH list, and add a reference to local composite mpls
139  //label if any
140  bool comp_nh_policy = comp_key->GetPolicy();
141  bool new_comp_nh_policy = false;
142  if (path->ReorderCompositeNH(agent, comp_key, new_comp_nh_policy,
143  rt->FindLocalVmPortPath()) == false) {
144  return false;
145  }
146  if (!comp_nh_policy) {
147  comp_key->SetPolicy(new_comp_nh_policy);
148  }
149  ret |= CopyToPath(path);
150 
151  EcmpData ecmp_data(agent, rt->vrf()->GetName(), rt->ToString(),
152  path, false);
153  ret |= ecmp_data.UpdateWithParams(sg_list_, tag_list_, CommunityList(),
156  path->set_unresolved(path_unresolved);
157 
158  // Set dest vn
159  path->set_dest_vn_list(vn_list_);
160 
161  return ret;
162 }
163 
164 template <typename TYPE>
166  const VnListType &vn_list,
167  const EcmpLoadBalance &ecmp_load_balance,
168  const TagList &tag_list,
169  const TYPE *item,
170  const AgentRouteTable *rt_table,
171  const std::string &prefix_str) :
172  ControllerPeerPath(peer), vn_list_(vn_list),
173  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
174  copy_local_path_(false), vxlan_id_(0) {
175  const AgentXmppChannel *channel = peer->GetAgentXmppChannel();
176  std::string bgp_peer_name = channel->GetBgpPeerName();
177  std::string vrf_name = rt_table->vrf_name();
178  agent_ = rt_table->agent();
179  vrf_name_ = vrf_name;
180  uint32_t label = item->entry.next_hops.next_hop[0].label;
181  Composite::Type composite_nh_type = Composite::ECMP;
182 
183  // use LOW PathPreference if local preference attribute is not set
184  uint32_t preference = PathPreference::LOW;
185  TunnelType::TypeBmap encap = TunnelType::AllType(); //default
186  if (item->entry.local_preference != 0) {
187  preference = item->entry.local_preference;
188  }
189 
190  //Override encap type for fabric VRF routes
191  //only type supported is underlay
192  if (vrf_name == agent_->fabric_vrf_name()) {
193  encap = TunnelType::NativeType();
194  }
195 
196  const bool is_routing_vrf = VxlanRoutingManager::IsVxlanAvailable(agent_)
198  // Override encap type for routing VRF routes
199  if (is_routing_vrf) {
200  encap = TunnelType::VxlanType();
201  vxlan_id_ = label;
202  }
203 
204  PathPreference rp(item->entry.sequence_number, preference, false, false);
205  path_preference_ = rp;
206 
207  sg_list_ = item->entry.security_group_list.security_group;
208 
209  ComponentNHKeyList comp_nh_list;
210  bool intf_exist = false;
211  bool tun_exist = false;
212  bool comp_nh_policy = false;
213  for (uint32_t i = 0; i < item->entry.next_hops.next_hop.size(); i++) {
214  std::string nexthop_addr =
215  item->entry.next_hops.next_hop[i].address;
216  boost::system::error_code ec;
217  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
218  if (ec.value() != 0) {
219  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name,
220  "Error parsing nexthop ip address");
221  continue;
222  }
223  if (!addr.is_v4()) {
224  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name,
225  "Non IPv4 address not supported as nexthop");
226  continue;
227  }
228 
229  if (comp_nh_list.size() >= maximum_ecmp_paths) {
230  std::stringstream msg;
231  msg << "Nexthop paths for prefix "
232  << prefix_str
233  << " (" << item->entry.next_hops.next_hop.size()
234  << ") exceed the maximum supported, ignoring them";
235  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name, msg.str());
236  break;
237  }
238 
239  uint32_t label = item->entry.next_hops.next_hop[i].label;
240  if (agent_->router_id() == addr.to_v4()) {
241  encap = agent_->controller()->GetTypeBitmap
242  (item->entry.next_hops.next_hop[i].tunnel_encapsulation_list);
243  //Get local list of interface and append to the list
244  MplsLabel *mpls =
245  agent_->mpls_table()->FindMplsLabel(label);
246  if (mpls != NULL && !is_routing_vrf) {
247  if (mpls->nexthop()->GetType() == NextHop::VRF) {
248  ClonedLocalPath *data =
249  new ClonedLocalPath(label, vn_list,
250  item->entry.security_group_list.security_group,
251  tag_list, sequence_number());
252  cloned_data_list_.push_back(data);
253  continue;
254  }
255 
256  const NextHop *mpls_nh = mpls->nexthop();
257  DBEntryBase::KeyPtr key = mpls_nh->GetDBRequestKey();
258  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
259  if (nh_key->GetType() != NextHop::COMPOSITE) {
260  //By default all component members of composite NH
261  //will be policy disabled, except for component NH
262  //of type composite
263  nh_key->SetPolicy(false);
264  }
265  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
266  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
267  std::move(nh_key_ptr)));
268  comp_nh_list.push_back(component_nh_key);
269  if (!comp_nh_policy) {
270  comp_nh_policy = mpls_nh->NexthopToInterfacePolicy();
271  }
272  tunnel_dest_list_.push_back(addr);
273  label_list_.push_back(label);
274  } else {
275  if (label == 0) {
276  copy_local_path_ = true;
277  }
278  if (is_routing_vrf) {
279  encap = TunnelType::VxlanType();
280  VxlanRoutingManager::AddInterfaceComponentToList(item->entry.nlri.address,
281  vrf_name,
282  item->entry.next_hops.next_hop[i],
283  comp_nh_list);
284  intf_exist = true;
285  }
286  }
287  } else {
288  encap = agent_->controller()->GetTypeBitmap
289  (item->entry.next_hops.next_hop[i].tunnel_encapsulation_list);
290  if (is_routing_vrf){
291  encap = TunnelType::VxlanType();
292  }
293  if (vrf_name == agent_->fabric_vrf_name()) {
294  if (label != MplsTable::kInvalidLabel &&
296  encap = TunnelType::MplsoMplsType();
297  } else {
298  encap = TunnelType::NativeType();
299  }
300  }
302  (item->entry.next_hops.next_hop[i]);
303  if (encap == TunnelType::MplsoMplsType() &&
304  vrf_name == agent_->fabric_vrf_name()) {
305  composite_nh_type = Composite::LU_ECMP;
308  agent_->router_id(),
309  addr.to_v4(),
310  false,
312  mac,
313  label);
314  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
315  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
316  std::move(nh_key_ptr)));
317  comp_nh_list.push_back(component_nh_key);
318  } else if (encap == TunnelType::MplsoMplsType()) {
319  // copy ecmp nexthop list
320  tunnel_dest_list_.push_back(addr);
321  label_list_.push_back(label);
322  } else {
323  TunnelNHKey *nh_key = NULL;
324  if (is_routing_vrf) {
325  nh_key = agent_->oper_db()->vxlan_routing_manager()->
326  AllocateTunnelNextHopKey(addr, mac);
327  tun_exist = true;
328  } else {
329  nh_key = new TunnelNHKey(agent_->fabric_vrf_name(),
330  agent_->router_id(),
331  addr.to_v4(),
332  false,
334  mac);
335  }
336 
337  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
338  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
339  std::move(nh_key_ptr)));
340  comp_nh_list.push_back(component_nh_key);
341  }
342  }
343  }
344 
345  if (intf_exist && tun_exist) {
346  for (auto &comp_nh_ptr : comp_nh_list) {
347  if (comp_nh_ptr == nullptr) {
348  continue;
349  }
350  if (comp_nh_ptr->nh_key()->GetType() != NextHop::INTERFACE)
351  {
352  comp_nh_ptr.reset();
353  }
354  }
355  }
356  if (intf_exist) {
357  comp_nh_policy = true;
358  }
359 
360  tunnel_bmap_ = encap;
361  if ((encap != TunnelType::MplsoMplsType()) ||
362  ((encap == TunnelType::MplsoMplsType()) &&
363  (vrf_name_ == agent_->fabric_vrf_name()))) {
364  // Build the NH request and then create route data to be passed
366  nh_req.key.reset(new CompositeNHKey(composite_nh_type, comp_nh_policy,
367  comp_nh_list, vrf_name));
368  nh_req.data.reset(new CompositeNHData());
369  nh_req_.Swap(&nh_req);
370  }
371  }
372 
374  const VnListType &vn_list,
375  const EcmpLoadBalance &ecmp_load_balance,
376  const TagList &tag_list,
377  const SecurityGroupList &sg_list,
378  const PathPreference &path_pref,
379  TunnelType::TypeBmap tunnel_bmap,
380  DBRequest &nh_req,
381  const std::string &prefix_str,
382  const std::string vrf_name) :
383  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
384  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
385  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
386  copy_local_path_(false), vxlan_id_(0) {
387  nh_req_.Swap(&nh_req);
388  agent_ = peer->agent();
389  if (vrf_name.size() == 0) {
391  } else {
392  vrf_name_ = vrf_name;
393  }
394  const bool is_routing_vrf = VxlanRoutingManager::IsVxlanAvailable(agent_) && VxlanRoutingManager::IsRoutingVrf(vrf_name,
395  agent_);
396  if (is_routing_vrf || tunnel_bmap == TunnelType::VxlanType()) {
398  vxlan_id_ = agent_->vrf_table()->
399  FindVrfFromName(vrf_name)->vxlan_id();
400  }
401 }
402 
404  const VnListType &vn_list,
405  const EcmpLoadBalance &ecmp_load_balance,
406  const TagList &tag_list,
407  const SecurityGroupList &sg_list,
408  const PathPreference &path_pref,
409  TunnelType::TypeBmap tunnel_bmap,
410  std::vector<IpAddress> &tunnel_dest_list,
411  std::vector<uint32_t> &label_list,
412  const std::string &prefix_str,
413  const std::string &vrf_name):
414  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
415  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
416  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
417  copy_local_path_(false), tunnel_dest_list_(tunnel_dest_list),
418  label_list_(label_list), vrf_name_(vrf_name), vxlan_id_(0) {
419  agent_ = peer->agent();
420 }
421 
423  const BgpPeer *bgp_peer,
424  const string &default_vrf,
425  const Ip4Address &router_id,
426  const string &vrf_name,
427  const Ip4Address &tunnel_dest,
429  uint32_t label,
430  const MacAddress rewrite_dmac,
431  const VnListType &dest_vn_list,
432  const SecurityGroupList &sg_list,
433  const TagList &tag_list,
434  const PathPreference &path_preference,
435  bool ecmp_suppressed,
436  const EcmpLoadBalance &ecmp_load_balance,
437  bool etree_leaf) {
438 
440  // Make Tunnel-NH request
441  nh_req.key.reset(new TunnelNHKey(default_vrf, router_id, tunnel_dest, false,
443  rewrite_dmac));
444  nh_req.data.reset(new TunnelNHData());
445 
446  // Make route request pointing to Tunnel-NH created above
447  ControllerVmRoute *data =
448  new ControllerVmRoute(bgp_peer, default_vrf, tunnel_dest, label,
449  dest_vn_list, bmap, sg_list, tag_list, path_preference,
450  nh_req, ecmp_suppressed,
451  ecmp_load_balance, etree_leaf, rewrite_dmac);
452  return data;
453 }
454 
456  const BgpPeer *bgp_peer,
457  const string &default_vrf,
458  const Ip4Address &router_id,
459  const string &vrf_name,
460  const Ip4Address &tunnel_dest,
462  uint32_t label,
463  const MacAddress rewrite_dmac,
464  const VnListType &dest_vn_list,
465  const SecurityGroupList &sg_list,
466  const TagList &tag_list,
467  const PathPreference &path_preference,
468  bool ecmp_suppressed,
469  const EcmpLoadBalance &ecmp_load_balance,
470  bool etree_leaf) {
471 
473  // Make Labelled Tunnel-NH request
474  nh_req.key.reset(new LabelledTunnelNHKey(default_vrf, router_id, tunnel_dest, false,
476  rewrite_dmac, label));
477  nh_req.data.reset(new LabelledTunnelNHData());
478 
479  // Make route request pointing to Labelled Tunnel-NH created above
480  ControllerMplsRoute *data =
481  new ControllerMplsRoute(bgp_peer, default_vrf, tunnel_dest, label,
482  dest_vn_list, bmap, sg_list, tag_list, path_preference,
483  nh_req, ecmp_suppressed,
484  ecmp_load_balance, etree_leaf, rewrite_dmac);
485  return data;
486 }
488  bool ret = false;
489  // For IP subnet routes with Tunnel NH, update arp_flood_ and
490  // local_host_flag_ flags
491  if ((rt->GetTableType() == Agent::INET4_UNICAST) ||
492  (rt->GetTableType() == Agent::INET6_UNICAST)) {
493  InetUnicastRouteEntry *inet_rt =
494  static_cast<InetUnicastRouteEntry *>(rt);
495  //If its the IPAM route then no change required neither
496  //super net needs to be searched.
497  if (inet_rt->ipam_subnet_route())
498  return ret;
499 
500  bool ipam_subnet_route = inet_rt->IpamSubnetRouteAvailable();
501  ret = inet_rt->UpdateIpamHostFlags(ipam_subnet_route);
502  }
503  return ret;
504 }
505 
507  const AgentRoute *rt) {
508  bool ret = false;
509  NextHop *nh = NULL;
510  SecurityGroupList path_sg_list;
511 
513  if (path->tunnel_bmap() != tunnel_bmap_) {
515  ret = true;
516  }
517 
519  if (new_tunnel_type == TunnelType::MPLS_OVER_MPLS) {
520  // this path depends on inet.3 route table,
521  // update dependent_table if it is not set already.
522  if (!path->GetDependentTable()) {
523  InetUnicastAgentRouteTable *table = NULL;
524  table = static_cast<InetUnicastAgentRouteTable *>
525  (agent->fabric_inet4_mpls_table());
526  assert(table != NULL);
527  path->SetDependentTable(table);
528  }
531 
535  path->GetParentRoute()));
537  const NextHop *anh;
538  if (uc_rt == NULL || uc_rt->prefix_length() == 0 || (anh = uc_rt->GetActiveNextHop()) == NULL) {
539  path->set_unresolved(true);
540  member->SetUnresolved(false);
541  } else {
542  path->set_unresolved(false);
544  const NextHopKey *nh_key =
545  static_cast<const NextHopKey*>(key.get());
546  nh = static_cast<NextHop *>(agent->nexthop_table()->
547  FindActiveEntry(nh_key));
548  assert(nh !=NULL);
549  //Reset to new gateway route, no nexthop for indirect route
550  member->UpdateDependentRoute(uc_rt);
551  member->SetUnresolved(false);
552  path->set_gw_ip(tunnel_dest_);
553  path->set_nexthop(NULL);
554  }
555  new_list.push_back(member);
556  path->ResetEcmpMemberList(new_list);
557 
558  } else {
559 
560  if ((tunnel_bmap_ == (1 << TunnelType::VXLAN) &&
561  (new_tunnel_type != TunnelType::VXLAN)) ||
562  (tunnel_bmap_ != (1 << TunnelType::VXLAN) &&
563  (new_tunnel_type == TunnelType::VXLAN))) {
564  new_tunnel_type = TunnelType::INVALID;
565  nh_req_.key.reset(new TunnelNHKey(agent->fabric_vrf_name(),
566  agent->router_id(), tunnel_dest_,
567  false, new_tunnel_type,
568  rewrite_dmac_));
569  }
570  agent->nexthop_table()->Process(nh_req_);
571  TunnelNHKey key(agent->fabric_vrf_name(), agent->router_id(), tunnel_dest_,
572  false, new_tunnel_type, rewrite_dmac_);
573  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
574 
575  path->set_unresolved(false);
576  }
578 
579  if (path->tunnel_type() != new_tunnel_type) {
580  path->set_tunnel_type(new_tunnel_type);
581  ret = true;
582  }
583 
584  //Interpret label sent by control node
586  // Only VXLAN encap is sent, so label is VXLAN
587  // For vxlan routing vn external route label can change , add path change
588  if (rt->vrf() && rt->vrf()->vn() &&
589  rt->vrf()->vn()->vxlan_routing_vn() && path->vxlan_id() != label_) {
590  ret = true;
591  }
592  path->set_vxlan_id(label_);
593  if (path->label() != MplsTable::kInvalidLabel) {
595  ret = true;
596  }
597  } else if ((tunnel_bmap_ == TunnelType::MplsType())||
599  //MPLS (GRE/UDP) is the only encap sent,
600  //so label is MPLS.
601  if (path->label() != label_) {
602  path->set_label(label_);
603  ret = true;
604  }
606  } else {
607  //Got a mix of Vxlan and Mpls, so interpret label
608  //as per the computed tunnel type.
609  if (new_tunnel_type == TunnelType::VXLAN) {
610  if (path->vxlan_id() != label_) {
611  path->set_vxlan_id(label_);
613  ret = true;
614  }
615  } else {
616  if (path->label() != label_) {
617  path->set_label(label_);
619  ret = true;
620  }
621  }
622  }
623 
624  if (path->dest_vn_list() != dest_vn_list_) {
626  ret = true;
627  }
628 
629  if (nh != NULL) {
630  if (path->ChangeNH(agent, nh) == true)
631  ret = true;
632  }
633 
634  path_sg_list = path->sg_list();
635  if (path_sg_list != sg_list_) {
636  path->set_sg_list(sg_list_);
637  ret = true;
638  }
639 
640  if (tag_list_ != path->tag_list()) {
641  path->set_tag_list(tag_list_);
642  ret = true;
643  }
644 
645  if (path->path_preference() != path_preference_) {
647  ret = true;
648  }
649 
650  //If a transition of path happens from ECMP to non ECMP
651  //reset local mpls label reference and composite nh key
652  if (path->composite_nh_key()) {
653  path->set_composite_nh_key(NULL);
654  path->set_local_ecmp_mpls_label(NULL);
655  }
656 
657  if (path->ecmp_suppressed() != ecmp_suppressed_) {
659  ret = true;
660  }
661 
662  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
664  ret = true;
665  }
666 
667  if (path->etree_leaf() != etree_leaf_) {
669  ret = true;
670  }
671 
672  return ret;
673 }
675  const AgentRoute *rt) {
676  bool ret = false;
677  NextHop *nh = NULL;
678  SecurityGroupList path_sg_list;
679 
681  if (path->tunnel_bmap() != tunnel_bmap_) {
683  ret = true;
684  }
685 
686  agent->nexthop_table()->Process(nh_req_);
689  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
691 
692  if (path->label() != label_) {
693  path->set_label(label_);
694  ret = true;
695  }
696 
697  if (path->dest_vn_list() != dest_vn_list_) {
699  ret = true;
700  }
701 
702  path->set_unresolved(false);
703  if (path->ChangeNH(agent, nh) == true)
704  ret = true;
705 
706  path_sg_list = path->sg_list();
707  if (path_sg_list != sg_list_) {
708  path->set_sg_list(sg_list_);
709  ret = true;
710  }
711 
712  if (tag_list_ != path->tag_list()) {
713  path->set_tag_list(tag_list_);
714  ret = true;
715  }
716 
717  if (path->path_preference() != path_preference_) {
719  ret = true;
720  }
721 
722  //If a transition of path happens from ECMP to non ECMP
723  //reset local mpls label reference and composite nh key
724  if (path->composite_nh_key()) {
725  path->set_composite_nh_key(NULL);
726  path->set_local_ecmp_mpls_label(NULL);
727  }
728 
729  if (path->ecmp_suppressed() != ecmp_suppressed_) {
731  ret = true;
732  }
733 
734  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
736  ret = true;
737  }
738 
739  if (path->etree_leaf() != etree_leaf_) {
741  ret = true;
742  }
743 
744  return ret;
745 }
746 
748  const AgentRoute *rt) {
749  bool ret = false;
750 
751  AgentPath *local_path = NULL;
753  local_path = rt->FindPath(agent->fabric_rt_export_peer());
754  if (local_path == NULL) {
755  local_path = rt->FindLocalVmPortPath();
756  }
757  path->set_copy_local_path(true);
758  } else {
759  MplsLabel *mpls = agent->mpls_table()->FindMplsLabel(mpls_label_);
760  if (!mpls) {
761  return ret;
762  }
763 
764  assert(mpls->nexthop()->GetType() == NextHop::VRF);
765  const VrfNH *vrf_nh = static_cast<const VrfNH *>(mpls->nexthop());
766  const InetUnicastRouteEntry *uc_rt =
767  static_cast<const InetUnicastRouteEntry *>(rt);
768  const AgentRoute *mpls_vrf_uc_rt =
769  vrf_nh->GetVrf()->GetUcRoute(uc_rt->prefix_address());
770  if (mpls_vrf_uc_rt == NULL) {
771  return ret;
772  }
773  local_path = mpls_vrf_uc_rt->FindLocalVmPortPath();
774  }
775 
777 
778  if (!local_path) {
779  return ret;
780  }
781 
782  if (path->dest_vn_list() != vn_list_) {
783  path->set_dest_vn_list(vn_list_);
784  ret = true;
785  }
786  path->set_unresolved(false);
787 
788  if (path->sg_list() != sg_list_) {
789  path->set_sg_list(sg_list_);
790  ret = true;
791  }
792 
793  path->set_tunnel_bmap(local_path->tunnel_bmap());
794  TunnelType::Type new_tunnel_type =
796  if (new_tunnel_type == TunnelType::VXLAN &&
797  local_path->vxlan_id() == VxLanTable::kInvalidvxlan_id) {
798  new_tunnel_type = TunnelType::ComputeType(TunnelType::MplsType());
799  }
800 
801  if (path->tunnel_type() != new_tunnel_type) {
802  path->set_tunnel_type(new_tunnel_type);
803  ret = true;
804  }
805 
806  // If policy force-enabled in request, enable policy
807  path->set_force_policy(local_path->force_policy());
808 
809  if (path->label() != local_path->label()) {
810  path->set_label(local_path->label());
811  ret = true;
812  }
813 
814  if (path->vxlan_id() != local_path->vxlan_id()) {
815  path->set_vxlan_id(local_path->vxlan_id());
816  ret = true;
817  }
818 
819  if (path->path_preference() != local_path->path_preference()) {
820  path->set_path_preference(local_path->path_preference());
821  ret = true;
822  }
823 
824  NextHop *nh = const_cast<NextHop *>(local_path->ComputeNextHop(agent));
825  if (path->ChangeNH(agent, nh) == true) {
826  ret = true;
827  }
829  CompositeNHKey *nh_key = dynamic_cast<CompositeNHKey *>(key.release());
830  path->set_composite_nh_key(nh_key);
831 
832  return ret;
833 }
834 
836  const AgentRoute *route) {
837  if (path->peer_sequence_number() >= sequence_number_)
838  return false;
839 
840  if (route->IsDeleted())
841  return false;
842 
843  //Delete old stale path
845  AgentRouteKey *key = (static_cast<AgentRouteKey *>(route->
846  GetDBRequestKey().get()))->Clone();
847  key->set_peer(path->peer());
848  req.key.reset(key);
849  req.data.reset();
850  AgentRouteTable *table = static_cast<AgentRouteTable *>(route->get_table());
851  table->Process(req);
852  return true;
853 }
854 
856  const AgentRoute *route) const {
857  if (path->peer_sequence_number() >= sequence_number_)
858  return false;
859  return true;
860 }
861 
862 //Force instantiation
864  const VnListType &vn_list,
865  const EcmpLoadBalance &ecmp_load_balance,
866  const TagList &tag_list, const autogen::ItemType *item,
867  const AgentRouteTable *rt_table, const std::string &prefix_str);
869  const VnListType &vn_list,
870  const EcmpLoadBalance &ecmp_load_balance,
871  const TagList &tag_list, const autogen::EnetItemType *item,
872  const AgentRouteTable *rt_table, const std::string &prefix_str);
uint8_t prefix_length() const
!
uint64_t sequence_number() const
Definition: agent_route.h:78
uint32_t TypeBmap
Definition: nexthop.h:248
uint64_t sequence_number_
Definition: agent_route.h:82
AgentPath * FindLocalVmPortPath() const
Definition: agent_route.cc:742
void set_path_preference(const PathPreference &rp)
Definition: agent_path.h:331
SecurityGroupList sg_list_
const VnListType & dest_vn_list() const
Definition: agent_path.h:258
PathPreference path_preference_
void SetDependentTable(AgentRouteTable *table)
Definition: agent_path.h:433
bool ChangeNH(Agent *agent, NextHop *nh)
Definition: agent_path.cc:119
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
void set_gw_ip(const IpAddress &addr)
Definition: agent_path.h:286
void set_unresolved(bool unresolved)
Definition: agent_path.h:285
const std::string & vrf_name() const
Definition: agent_route.cc:455
const TagList & tag_list() const
Definition: agent_path.h:249
const PathPreference & path_preference() const
Definition: agent_path.h:329
TunnelType::TypeBmap tunnel_bmap_
bool force_policy() const
Definition: agent_path.h:270
ClonedLocalPathList cloned_data_list_
void set_local_ecmp_mpls_label(MplsLabel *mpls)
Definition: agent_path.cc:1805
NextHopTable * nexthop_table() const
Definition: agent.h:475
DBTableBase * get_table() const
Definition: db_entry.cc:119
bool ipam_subnet_route() const
TunnelType::Type tunnel_type() const
Definition: agent_path.h:266
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
Definition: agent_route.h:109
void set_sg_list(const SecurityGroupList &sg)
Definition: agent_path.h:291
const NextHop * nexthop() const
Definition: mpls.h:80
bool IsDeleted() const
Definition: db_entry.h:49
boost::asio::ip::address IpAddress
Definition: address.h:13
void set_vxlan_id(uint32_t vxlan_id)
Definition: agent_path.h:281
ControllerMplsRoute(const BgpPeer *peer, const string &vrf_name, const Ip4Address &addr, uint32_t label, const VnListType &dest_vn_list, int bmap, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, DBRequest &req, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf, const MacAddress &rewrite_dmac=MacAddress())
PathPreference path_preference_
boost::shared_ptr< AgentPathEcmpComponent > AgentPathEcmpComponentPtr
Definition: agent_path.h:228
std::vector< int > SecurityGroupList
Definition: agent.h:201
static const uint32_t kInvalidExportLabel
Definition: mpls.h:102
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
InetUnicastAgentRouteTable * fabric_inet4_mpls_table() const
Definition: agent.h:589
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
static TypeBmap MplsType()
Definition: nexthop.h:312
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
ControllerEcmpRoute(const BgpPeer *peer, const VnListType &vn_list, const EcmpLoadBalance &ecmp_load_balance, const TagList &tag_list, const TYPE *item, const AgentRouteTable *rt_table, const std::string &prefix_str)
InetUnicastRouteEntry * FindRoute(const IpAddress &ip)
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
Definition: nexthop.h:1639
const string & GetName() const
Definition: vrf.h:100
bool NexthopToInterfacePolicy() const
Definition: nexthop.cc:262
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
MplsTable * mpls_table() const
Definition: agent.h:510
VxlanRoutingManager * vxlan_routing_manager() const
Definition: operdb_init.h:98
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
bool ReorderCompositeNH(Agent *agent, CompositeNHKey *nh, bool &comp_nh_policy, const AgentPath *local_path)
Definition: agent_path.cc:1851
Type GetType() const
Definition: nexthop.h:405
Base class for all Route entries in agent.
Definition: agent_route.h:224
void Swap(DBRequest *rhs)
Definition: db_table.cc:43
bool GetPolicy() const
Definition: nexthop.h:500
CompositeNHKey * composite_nh_key()
Definition: agent_path.h:335
OperDB * oper_db() const
Definition: agent.cc:1013
void ResetEcmpMemberList(AgentPathEcmpComponentPtrList list)
Definition: agent_path.h:429
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
Definition: ecmp.h:15
static TypeBmap MplsoMplsType()
Definition: nexthop.h:313
NextHop::Type GetType() const
Definition: nexthop.h:499
const std::string & fabric_vrf_name() const
Definition: agent.h:903
bool UpdateWithParams(const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &community_list, const PathPreference &path_preference, const TunnelType::TypeBmap bmap, const EcmpLoadBalance &ecmp_load_balance, const VnListType &vn_list, DBRequest &nh_req)
Definition: ecmp.cc:61
void set_tunnel_bmap(TunnelType::TypeBmap bmap)
Definition: agent_path.h:289
virtual Agent::RouteTableType GetTableType() const =0
static void AddInterfaceComponentToList(const std::string &prefix_str, const std::string &vrf_name, const NhType &nh_item, ComponentNHKeyList &comp_nh_list)
Adds an interface or a composite of interfaces nexthops to the list of components NH keys needed for ...
static bool IsRoutingVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of routing type.
static const uint32_t kInvalidvxlan_id
Definition: vxlan.h:141
MacAddress GetTunnelMac(const autogen::EnetNextHopType &nh)
void set_ecmp_suppressed(bool suppresed)
Definition: agent_path.h:358
virtual bool CanDeletePath(Agent *agent, AgentPath *path, const AgentRoute *rt) const
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
static ControllerVmRoute * MakeControllerVmRoute(const BgpPeer *peer, const string &default_vrf, const Ip4Address &router_id, const string &vrf_name, const Ip4Address &tunnel_dest, TunnelType::TypeBmap bmap, uint32_t label, MacAddress rewrite_dmac, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf)
ControllerVmRoute(const BgpPeer *peer, const string &vrf_name, const Ip4Address &addr, uint32_t label, const VnListType &dest_vn_list, int bmap, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, DBRequest &req, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf, const MacAddress &rewrite_dmac=MacAddress())
TunnelType::TypeBmap GetTypeBitmap(const autogen::EnetTunnelEncapsulationListType &encap)
Definition: agent.h:358
PathPreference path_preference_
bool IpamSubnetRouteAvailable() const
std::vector< uint32_t > label_list_
const NextHop * GetActiveNextHop() const
Definition: agent_route.cc:881
uint32_t label() const
Definition: agent_path.h:264
Ip4Address router_id() const
Definition: agent.h:666
void set_vrf_name(const std::string &vrf_name)
Definition: agent_path.h:288
VNController * controller() const
Definition: agent.cc:981
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
bool vxlan_routing_vn() const
Definition: vn.h:255
void set_copy_local_path(bool copy_local_path)
Definition: agent_path.h:307
Definition: trace.h:220
static TypeBmap AllType()
Definition: nexthop.h:321
const Peer * peer() const
Definition: agent_path.h:263
static const uint32_t maximum_ecmp_paths
NextHop * discard_nh() const
Definition: nexthop.h:1971
bool etree_leaf() const
Definition: agent_path.h:388
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
AgentXmppChannel * GetAgentXmppChannel() const
Definition: peer.cc:331
const SecurityGroupList sg_list_
void set_peer_sequence_number(uint64_t sequence_number)
Definition: agent_path.h:416
uint64_t peer_sequence_number() const
Definition: agent_path.h:415
std::set< std::string > VnListType
Definition: agent.h:212
virtual KeyPtr GetDBRequestKey() const =0
void set_tunnel_dest(const Ip4Address &tunnel_dest)
Definition: agent_path.h:297
static TypeBmap NativeType()
Definition: nexthop.h:325
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
ControllerPeerPath(const BgpPeer *peer)
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
std::vector< AgentPathEcmpComponentPtr > AgentPathEcmpComponentPtrList
Definition: agent_path.h:229
static const uint32_t kInvalidLabel
Definition: mpls.h:101
VrfTable * vrf_table() const
Definition: agent.h:485
virtual AgentRouteKey * Clone() const =0
std::vector< IpAddress > tunnel_dest_list_
EcmpLoadBalance ecmp_load_balance_
bool CopyToPath(AgentPath *path)
void UpdateEcmpHashFields(const Agent *agent, const EcmpLoadBalance &ecmp_load_balance, DBRequest &nh_req)
Definition: agent_path.cc:2006
void set_tag_list(const TagList &tag)
Definition: agent_path.h:292
void set_nexthop(NextHop *nh)
Definition: agent_path.cc:578
virtual std::string ToString() const =0
static ControllerMplsRoute * MakeControllerMplsRoute(const BgpPeer *peer, const string &default_vrf, const Ip4Address &router_id, const string &vrf_name, const Ip4Address &tunnel_dest, TunnelType::TypeBmap bmap, uint32_t label, MacAddress rewrite_dmac, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf)
SecurityGroupList sg_list_
TunnelType::TypeBmap tunnel_bmap_
void Process(DBRequest &req)
Definition: nexthop.cc:367
Definition: mpls.h:52
VnEntry * vn() const
Definition: vrf.h:101
void set_etree_leaf(bool leaf)
Definition: agent_path.h:392
static bool IsVxlanAvailable(const Agent *agent)
Checks whether VxLAN routing manager is enabled or not.
void set_composite_nh_key(CompositeNHKey *key)
Definition: agent_path.h:332
AgentRoute * GetParentRoute()
Definition: agent_path.h:428
VrfEntry * vrf() const
Definition: agent_route.h:275
MplsLabel * FindMplsLabel(uint32_t label)
Definition: mpls.cc:399
bool ecmp_suppressed() const
Definition: agent_path.h:357
void set_label(uint32_t label)
Definition: agent_path.h:282
Agent * agent() const
Definition: agent_route.h:159
void Process(DBRequest &req)
Definition: agent_route.cc:186
void set_dest_vn_list(const VnListType &dest_vn_list)
Definition: agent_path.h:283
EcmpLoadBalance ecmp_load_balance_
virtual const NextHop * ComputeNextHop(Agent *agent) const
Definition: agent_path.cc:91
SecurityGroupList sg_list_
const VnListType vn_list_
void SetPolicy(bool policy)
Definition: nexthop.h:495
const Peer * fabric_rt_export_peer() const
Definition: agent.h:1037
bool UpdateIpamHostFlags(bool ipam_host_route)
Agent * agent() const
Definition: peer.cc:327
uint32_t tunnel_bmap() const
Definition: agent_path.h:267
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:864
void set_tunnel_type(TunnelType::Type type)
Definition: agent_path.h:290
void set_force_policy(bool force_policy)
Definition: agent_path.h:287
TunnelType::TypeBmap tunnel_bmap_
EcmpLoadBalance ecmp_load_balance_
static TypeBmap VxlanType()
Definition: nexthop.h:311
#define CONTROLLER_TRACE(obj,...)
virtual bool UpdateRoute(AgentRoute *route)
const SecurityGroupList & sg_list() const
Definition: agent_path.h:248
uint32_t vxlan_id() const
Definition: agent_path.h:265
const EcmpLoadBalance & ecmp_load_balance() const
Definition: agent_path.h:365
void set_ecmp_load_balance(const EcmpLoadBalance &ecmp_load_balance)
Definition: agent_path.h:368
void set_peer(const Peer *peer)
Definition: agent_route.h:48
AgentRouteTable * GetDependentTable() const
Definition: agent_path.h:432
std::vector< int > TagList
Definition: agent.h:202
std::string GetBgpPeerName() const