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  std::vector<std::string> peer_sources;
205  for (const auto &peer_addr : item->entry.peers.peer) {
206  peer_sources.push_back(peer_addr);
207  }
208 
209  PathPreference rp(item->entry.sequence_number, preference, false, false);
210  path_preference_ = rp;
211 
212  sg_list_ = item->entry.security_group_list.security_group;
213 
214  ComponentNHKeyList comp_nh_list;
215  bool intf_exist = false;
216  bool tun_exist = false;
217  bool comp_nh_policy = false;
218  for (uint32_t i = 0; i < item->entry.next_hops.next_hop.size(); i++) {
219  std::string nexthop_addr =
220  item->entry.next_hops.next_hop[i].address;
221  boost::system::error_code ec;
222  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
223  if (ec.value() != 0) {
224  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name,
225  "Error parsing nexthop ip address");
226  continue;
227  }
228  if (!addr.is_v4()) {
229  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name,
230  "Non IPv4 address not supported as nexthop");
231  continue;
232  }
233 
234  if (comp_nh_list.size() >= maximum_ecmp_paths) {
235  std::stringstream msg;
236  msg << "Nexthop paths for prefix "
237  << prefix_str
238  << " (" << item->entry.next_hops.next_hop.size()
239  << ") exceed the maximum supported, ignoring them";
240  CONTROLLER_TRACE(Trace, bgp_peer_name, vrf_name, msg.str());
241  break;
242  }
243 
244  uint32_t label = item->entry.next_hops.next_hop[i].label;
245  if (agent_->router_id() == addr.to_v4()) {
246  encap = agent_->controller()->GetTypeBitmap
247  (item->entry.next_hops.next_hop[i].tunnel_encapsulation_list);
248  //Get local list of interface and append to the list
249  MplsLabel *mpls =
250  agent_->mpls_table()->FindMplsLabel(label);
251  if (mpls != NULL && !is_routing_vrf) {
252  if (mpls->nexthop()->GetType() == NextHop::VRF) {
253  ClonedLocalPath *data =
254  new ClonedLocalPath(label, vn_list,
255  item->entry.security_group_list.security_group,
256  tag_list, sequence_number());
257  cloned_data_list_.push_back(data);
258  continue;
259  }
260 
261  const NextHop *mpls_nh = mpls->nexthop();
262  DBEntryBase::KeyPtr key = mpls_nh->GetDBRequestKey();
263  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
264  if (nh_key->GetType() != NextHop::COMPOSITE) {
265  //By default all component members of composite NH
266  //will be policy disabled, except for component NH
267  //of type composite
268  nh_key->SetPolicy(false);
269  }
270  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
271  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
272  std::move(nh_key_ptr)));
273  comp_nh_list.push_back(component_nh_key);
274  if (!comp_nh_policy) {
275  comp_nh_policy = mpls_nh->NexthopToInterfacePolicy();
276  }
277  tunnel_dest_list_.push_back(addr);
278  label_list_.push_back(label);
279  } else {
280  if (label == 0) {
281  copy_local_path_ = true;
282  }
283  if (is_routing_vrf) {
284  encap = TunnelType::VxlanType();
285  VxlanRoutingManager::AddInterfaceComponentToList(item->entry.nlri.address,
286  vrf_name,
287  item->entry.next_hops.next_hop[i],
288  comp_nh_list,
289  peer_sources);
290  intf_exist = true;
291  }
292  }
293  } else {
294  encap = agent_->controller()->GetTypeBitmap
295  (item->entry.next_hops.next_hop[i].tunnel_encapsulation_list);
296  if (is_routing_vrf){
297  encap = TunnelType::VxlanType();
298  }
299  if (vrf_name == agent_->fabric_vrf_name()) {
300  if (label != MplsTable::kInvalidLabel &&
302  encap = TunnelType::MplsoMplsType();
303  } else {
304  encap = TunnelType::NativeType();
305  }
306  }
308  (item->entry.next_hops.next_hop[i]);
309  if (encap == TunnelType::MplsoMplsType() &&
310  vrf_name == agent_->fabric_vrf_name()) {
311  composite_nh_type = Composite::LU_ECMP;
314  agent_->router_id(),
315  addr.to_v4(),
316  false,
318  mac,
319  label);
320  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
321  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
322  std::move(nh_key_ptr)));
323  comp_nh_list.push_back(component_nh_key);
324  } else if (encap == TunnelType::MplsoMplsType()) {
325  // copy ecmp nexthop list
326  tunnel_dest_list_.push_back(addr);
327  label_list_.push_back(label);
328  } else {
329  TunnelNHKey *nh_key = NULL;
330  if (is_routing_vrf) {
331  nh_key = agent_->oper_db()->vxlan_routing_manager()->
332  AllocateTunnelNextHopKey(addr, mac);
333  tun_exist = true;
334  } else {
335  nh_key = new TunnelNHKey(agent_->fabric_vrf_name(),
336  agent_->router_id(),
337  addr.to_v4(),
338  false,
340  mac);
341  }
342 
343  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
344  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(label,
345  std::move(nh_key_ptr)));
346  comp_nh_list.push_back(component_nh_key);
347  }
348  }
349  }
350 
351  if (intf_exist && tun_exist) {
352  for (auto &comp_nh_ptr : comp_nh_list) {
353  if (comp_nh_ptr == nullptr) {
354  continue;
355  }
356  if (comp_nh_ptr->nh_key()->GetType() != NextHop::INTERFACE)
357  {
358  comp_nh_ptr.reset();
359  }
360  }
361  }
362  if (intf_exist) {
363  comp_nh_policy = true;
364  composite_nh_type = Composite::LOCAL_ECMP;
365  }
366 
367  tunnel_bmap_ = encap;
368  if ((encap != TunnelType::MplsoMplsType()) ||
369  ((encap == TunnelType::MplsoMplsType()) &&
370  (vrf_name_ == agent_->fabric_vrf_name()))) {
371  // Build the NH request and then create route data to be passed
373  nh_req.key.reset(new CompositeNHKey(composite_nh_type, comp_nh_policy,
374  comp_nh_list, vrf_name));
375  nh_req.data.reset(new CompositeNHData());
376  nh_req_.Swap(&nh_req);
377  }
378  }
379 
381  const VnListType &vn_list,
382  const EcmpLoadBalance &ecmp_load_balance,
383  const TagList &tag_list,
384  const SecurityGroupList &sg_list,
385  const PathPreference &path_pref,
386  TunnelType::TypeBmap tunnel_bmap,
387  DBRequest &nh_req,
388  const std::string &prefix_str,
389  const std::string vrf_name) :
390  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
391  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
392  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
393  copy_local_path_(false), vxlan_id_(0) {
394  nh_req_.Swap(&nh_req);
395  agent_ = peer->agent();
396  if (vrf_name.size() == 0) {
398  } else {
399  vrf_name_ = vrf_name;
400  }
401  const bool is_routing_vrf = VxlanRoutingManager::IsVxlanAvailable(agent_) && VxlanRoutingManager::IsRoutingVrf(vrf_name,
402  agent_);
403  if (is_routing_vrf || tunnel_bmap == TunnelType::VxlanType()) {
405  vxlan_id_ = agent_->vrf_table()->
406  FindVrfFromName(vrf_name)->vxlan_id();
407  }
408 }
409 
411  const VnListType &vn_list,
412  const EcmpLoadBalance &ecmp_load_balance,
413  const TagList &tag_list,
414  const SecurityGroupList &sg_list,
415  const PathPreference &path_pref,
416  TunnelType::TypeBmap tunnel_bmap,
417  std::vector<IpAddress> &tunnel_dest_list,
418  std::vector<uint32_t> &label_list,
419  const std::string &prefix_str,
420  const std::string &vrf_name):
421  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
422  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
423  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
424  copy_local_path_(false), tunnel_dest_list_(tunnel_dest_list),
425  label_list_(label_list), vrf_name_(vrf_name), vxlan_id_(0) {
426  agent_ = peer->agent();
427 }
428 
430  const BgpPeer *bgp_peer,
431  const string &default_vrf,
432  const Ip4Address &router_id,
433  const string &vrf_name,
434  const Ip4Address &tunnel_dest,
436  uint32_t label,
437  const MacAddress rewrite_dmac,
438  const VnListType &dest_vn_list,
439  const SecurityGroupList &sg_list,
440  const TagList &tag_list,
441  const PathPreference &path_preference,
442  bool ecmp_suppressed,
443  const EcmpLoadBalance &ecmp_load_balance,
444  bool etree_leaf) {
445 
447  // Make Tunnel-NH request
448  nh_req.key.reset(new TunnelNHKey(default_vrf, router_id, tunnel_dest, false,
450  rewrite_dmac));
451  nh_req.data.reset(new TunnelNHData());
452 
453  // Make route request pointing to Tunnel-NH created above
454  ControllerVmRoute *data =
455  new ControllerVmRoute(bgp_peer, default_vrf, tunnel_dest, label,
456  dest_vn_list, bmap, sg_list, tag_list, path_preference,
457  nh_req, ecmp_suppressed,
458  ecmp_load_balance, etree_leaf, rewrite_dmac);
459  return data;
460 }
461 
463  const BgpPeer *bgp_peer,
464  const string &default_vrf,
465  const Ip4Address &router_id,
466  const string &vrf_name,
467  const Ip4Address &tunnel_dest,
469  uint32_t label,
470  const MacAddress rewrite_dmac,
471  const VnListType &dest_vn_list,
472  const SecurityGroupList &sg_list,
473  const TagList &tag_list,
474  const PathPreference &path_preference,
475  bool ecmp_suppressed,
476  const EcmpLoadBalance &ecmp_load_balance,
477  bool etree_leaf) {
478 
480  // Make Labelled Tunnel-NH request
481  nh_req.key.reset(new LabelledTunnelNHKey(default_vrf, router_id, tunnel_dest, false,
483  rewrite_dmac, label));
484  nh_req.data.reset(new LabelledTunnelNHData());
485 
486  // Make route request pointing to Labelled Tunnel-NH created above
487  ControllerMplsRoute *data =
488  new ControllerMplsRoute(bgp_peer, default_vrf, tunnel_dest, label,
489  dest_vn_list, bmap, sg_list, tag_list, path_preference,
490  nh_req, ecmp_suppressed,
491  ecmp_load_balance, etree_leaf, rewrite_dmac);
492  return data;
493 }
495  bool ret = false;
496  // For IP subnet routes with Tunnel NH, update arp_flood_ and
497  // local_host_flag_ flags
498  if ((rt->GetTableType() == Agent::INET4_UNICAST) ||
499  (rt->GetTableType() == Agent::INET6_UNICAST)) {
500  InetUnicastRouteEntry *inet_rt =
501  static_cast<InetUnicastRouteEntry *>(rt);
502  //If its the IPAM route then no change required neither
503  //super net needs to be searched.
504  if (inet_rt->ipam_subnet_route())
505  return ret;
506 
507  bool ipam_subnet_route = inet_rt->IpamSubnetRouteAvailable();
508  ret = inet_rt->UpdateIpamHostFlags(ipam_subnet_route);
509  }
510  return ret;
511 }
512 
514  const AgentRoute *rt) {
515  bool ret = false;
516  NextHop *nh = NULL;
517  SecurityGroupList path_sg_list;
518 
520  if (path->tunnel_bmap() != tunnel_bmap_) {
522  ret = true;
523  }
524 
526  if (new_tunnel_type == TunnelType::MPLS_OVER_MPLS) {
527  // this path depends on inet.3 route table,
528  // update dependent_table if it is not set already.
529  if (!path->GetDependentTable()) {
530  InetUnicastAgentRouteTable *table = NULL;
531  table = static_cast<InetUnicastAgentRouteTable *>
532  (agent->fabric_inet4_mpls_table());
533  assert(table != NULL);
534  path->SetDependentTable(table);
535  }
538 
542  path->GetParentRoute()));
544  const NextHop *anh;
545  if (uc_rt == NULL || uc_rt->prefix_length() == 0 || (anh = uc_rt->GetActiveNextHop()) == NULL) {
546  path->set_unresolved(true);
547  member->SetUnresolved(false);
548  } else {
549  path->set_unresolved(false);
551  const NextHopKey *nh_key =
552  static_cast<const NextHopKey*>(key.get());
553  nh = static_cast<NextHop *>(agent->nexthop_table()->
554  FindActiveEntry(nh_key));
555  assert(nh !=NULL);
556  //Reset to new gateway route, no nexthop for indirect route
557  member->UpdateDependentRoute(uc_rt);
558  member->SetUnresolved(false);
559  path->set_gw_ip(tunnel_dest_);
560  path->set_nexthop(NULL);
561  }
562  new_list.push_back(member);
563  path->ResetEcmpMemberList(new_list);
564 
565  } else {
566 
567  if ((tunnel_bmap_ == (1 << TunnelType::VXLAN) &&
568  (new_tunnel_type != TunnelType::VXLAN)) ||
569  (tunnel_bmap_ != (1 << TunnelType::VXLAN) &&
570  (new_tunnel_type == TunnelType::VXLAN))) {
571  new_tunnel_type = TunnelType::INVALID;
572  nh_req_.key.reset(new TunnelNHKey(agent->fabric_vrf_name(),
573  agent->router_id(), tunnel_dest_,
574  false, new_tunnel_type,
575  rewrite_dmac_));
576  }
577  agent->nexthop_table()->Process(nh_req_);
578  TunnelNHKey key(agent->fabric_vrf_name(), agent->router_id(), tunnel_dest_,
579  false, new_tunnel_type, rewrite_dmac_);
580  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
581 
582  path->set_unresolved(false);
583  }
585 
586  if (path->tunnel_type() != new_tunnel_type) {
587  path->set_tunnel_type(new_tunnel_type);
588  ret = true;
589  }
590 
591  //Interpret label sent by control node
593  // Only VXLAN encap is sent, so label is VXLAN
594  // For vxlan routing vn external route label can change , add path change
595  if (rt->vrf() && rt->vrf()->vn() &&
596  rt->vrf()->vn()->vxlan_routing_vn() && path->vxlan_id() != label_) {
597  ret = true;
598  }
599  path->set_vxlan_id(label_);
600  if (path->label() != MplsTable::kInvalidLabel) {
602  ret = true;
603  }
604  } else if ((tunnel_bmap_ == TunnelType::MplsType())||
606  //MPLS (GRE/UDP) is the only encap sent,
607  //so label is MPLS.
608  if (path->label() != label_) {
609  path->set_label(label_);
610  ret = true;
611  }
613  } else {
614  //Got a mix of Vxlan and Mpls, so interpret label
615  //as per the computed tunnel type.
616  if (new_tunnel_type == TunnelType::VXLAN) {
617  if (path->vxlan_id() != label_) {
618  path->set_vxlan_id(label_);
620  ret = true;
621  }
622  } else {
623  if (path->label() != label_) {
624  path->set_label(label_);
626  ret = true;
627  }
628  }
629  }
630 
631  if (path->dest_vn_list() != dest_vn_list_) {
633  ret = true;
634  }
635 
636  if (nh != NULL) {
637  if (path->ChangeNH(agent, nh) == true)
638  ret = true;
639  }
640 
641  path_sg_list = path->sg_list();
642  if (path_sg_list != sg_list_) {
643  path->set_sg_list(sg_list_);
644  ret = true;
645  }
646 
647  if (tag_list_ != path->tag_list()) {
648  path->set_tag_list(tag_list_);
649  ret = true;
650  }
651 
652  if (path->path_preference() != path_preference_) {
654  ret = true;
655  }
656 
657  //If a transition of path happens from ECMP to non ECMP
658  //reset local mpls label reference and composite nh key
659  if (path->composite_nh_key()) {
660  path->set_composite_nh_key(NULL);
661  path->set_local_ecmp_mpls_label(NULL);
662  }
663 
664  if (path->ecmp_suppressed() != ecmp_suppressed_) {
666  ret = true;
667  }
668 
669  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
671  ret = true;
672  }
673 
674  if (path->etree_leaf() != etree_leaf_) {
676  ret = true;
677  }
678 
679  return ret;
680 }
682  const AgentRoute *rt) {
683  bool ret = false;
684  NextHop *nh = NULL;
685  SecurityGroupList path_sg_list;
686 
688  if (path->tunnel_bmap() != tunnel_bmap_) {
690  ret = true;
691  }
692 
693  agent->nexthop_table()->Process(nh_req_);
696  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
698 
699  if (path->label() != label_) {
700  path->set_label(label_);
701  ret = true;
702  }
703 
704  if (path->dest_vn_list() != dest_vn_list_) {
706  ret = true;
707  }
708 
709  path->set_unresolved(false);
710  if (path->ChangeNH(agent, nh) == true)
711  ret = true;
712 
713  path_sg_list = path->sg_list();
714  if (path_sg_list != sg_list_) {
715  path->set_sg_list(sg_list_);
716  ret = true;
717  }
718 
719  if (tag_list_ != path->tag_list()) {
720  path->set_tag_list(tag_list_);
721  ret = true;
722  }
723 
724  if (path->path_preference() != path_preference_) {
726  ret = true;
727  }
728 
729  //If a transition of path happens from ECMP to non ECMP
730  //reset local mpls label reference and composite nh key
731  if (path->composite_nh_key()) {
732  path->set_composite_nh_key(NULL);
733  path->set_local_ecmp_mpls_label(NULL);
734  }
735 
736  if (path->ecmp_suppressed() != ecmp_suppressed_) {
738  ret = true;
739  }
740 
741  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
743  ret = true;
744  }
745 
746  if (path->etree_leaf() != etree_leaf_) {
748  ret = true;
749  }
750 
751  return ret;
752 }
753 
755  const AgentRoute *rt) {
756  bool ret = false;
757 
758  AgentPath *local_path = NULL;
760  local_path = rt->FindPath(agent->fabric_rt_export_peer());
761  if (local_path == NULL) {
762  local_path = rt->FindLocalVmPortPath();
763  }
764  path->set_copy_local_path(true);
765  } else {
766  MplsLabel *mpls = agent->mpls_table()->FindMplsLabel(mpls_label_);
767  if (!mpls) {
768  return ret;
769  }
770 
771  assert(mpls->nexthop()->GetType() == NextHop::VRF);
772  const VrfNH *vrf_nh = static_cast<const VrfNH *>(mpls->nexthop());
773  const InetUnicastRouteEntry *uc_rt =
774  static_cast<const InetUnicastRouteEntry *>(rt);
775  const AgentRoute *mpls_vrf_uc_rt =
776  vrf_nh->GetVrf()->GetUcRoute(uc_rt->prefix_address());
777  if (mpls_vrf_uc_rt == NULL) {
778  return ret;
779  }
780  local_path = mpls_vrf_uc_rt->FindLocalVmPortPath();
781  }
782 
784 
785  if (!local_path) {
786  return ret;
787  }
788 
789  if (path->dest_vn_list() != vn_list_) {
790  path->set_dest_vn_list(vn_list_);
791  ret = true;
792  }
793  path->set_unresolved(false);
794 
795  if (path->sg_list() != sg_list_) {
796  path->set_sg_list(sg_list_);
797  ret = true;
798  }
799 
800  path->set_tunnel_bmap(local_path->tunnel_bmap());
801  TunnelType::Type new_tunnel_type =
803  if (new_tunnel_type == TunnelType::VXLAN &&
804  local_path->vxlan_id() == VxLanTable::kInvalidvxlan_id) {
805  new_tunnel_type = TunnelType::ComputeType(TunnelType::MplsType());
806  }
807 
808  if (path->tunnel_type() != new_tunnel_type) {
809  path->set_tunnel_type(new_tunnel_type);
810  ret = true;
811  }
812 
813  // If policy force-enabled in request, enable policy
814  path->set_force_policy(local_path->force_policy());
815 
816  if (path->label() != local_path->label()) {
817  path->set_label(local_path->label());
818  ret = true;
819  }
820 
821  if (path->vxlan_id() != local_path->vxlan_id()) {
822  path->set_vxlan_id(local_path->vxlan_id());
823  ret = true;
824  }
825 
826  if (path->path_preference() != local_path->path_preference()) {
827  path->set_path_preference(local_path->path_preference());
828  ret = true;
829  }
830 
831  NextHop *nh = const_cast<NextHop *>(local_path->ComputeNextHop(agent));
832  if (path->ChangeNH(agent, nh) == true) {
833  ret = true;
834  }
836  CompositeNHKey *nh_key = dynamic_cast<CompositeNHKey *>(key.release());
837  path->set_composite_nh_key(nh_key);
838 
839  return ret;
840 }
841 
843  const AgentRoute *route) {
844  if (path->peer_sequence_number() >= sequence_number_)
845  return false;
846 
847  if (route->IsDeleted())
848  return false;
849 
850  //Delete old stale path
852  AgentRouteKey *key = (static_cast<AgentRouteKey *>(route->
853  GetDBRequestKey().get()))->Clone();
854  key->set_peer(path->peer());
855  req.key.reset(key);
856  req.data.reset();
857  AgentRouteTable *table = static_cast<AgentRouteTable *>(route->get_table());
858  table->Process(req);
859  return true;
860 }
861 
863  const AgentRoute *route) const {
864  if (path->peer_sequence_number() >= sequence_number_)
865  return false;
866  return true;
867 }
868 
869 //Force instantiation
871  const VnListType &vn_list,
872  const EcmpLoadBalance &ecmp_load_balance,
873  const TagList &tag_list, const autogen::ItemType *item,
874  const AgentRouteTable *rt_table, const std::string &prefix_str);
876  const VnListType &vn_list,
877  const EcmpLoadBalance &ecmp_load_balance,
878  const TagList &tag_list, const autogen::EnetItemType *item,
879  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:743
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 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:882
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:256
void set_copy_local_path(bool copy_local_path)
Definition: agent_path.h:307
Definition: trace.h:220
static void AddInterfaceComponentToList(const std::string &prefix_str, const std::string &vrf_name, const NhType &nh_item, ComponentNHKeyList &comp_nh_list, std::vector< std::string > &peer_sources)
Adds an interface or a composite of interfaces nexthops to the list of components NH keys needed for ...
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:389
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:865
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