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  composite_nh_type = Composite::LOCAL_ECMP;
359  }
360 
361  tunnel_bmap_ = encap;
362  if ((encap != TunnelType::MplsoMplsType()) ||
363  ((encap == TunnelType::MplsoMplsType()) &&
364  (vrf_name_ == agent_->fabric_vrf_name()))) {
365  // Build the NH request and then create route data to be passed
367  nh_req.key.reset(new CompositeNHKey(composite_nh_type, comp_nh_policy,
368  comp_nh_list, vrf_name));
369  nh_req.data.reset(new CompositeNHData());
370  nh_req_.Swap(&nh_req);
371  }
372  }
373 
375  const VnListType &vn_list,
376  const EcmpLoadBalance &ecmp_load_balance,
377  const TagList &tag_list,
378  const SecurityGroupList &sg_list,
379  const PathPreference &path_pref,
380  TunnelType::TypeBmap tunnel_bmap,
381  DBRequest &nh_req,
382  const std::string &prefix_str,
383  const std::string vrf_name) :
384  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
385  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
386  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
387  copy_local_path_(false), vxlan_id_(0) {
388  nh_req_.Swap(&nh_req);
389  agent_ = peer->agent();
390  if (vrf_name.size() == 0) {
392  } else {
393  vrf_name_ = vrf_name;
394  }
395  const bool is_routing_vrf = VxlanRoutingManager::IsVxlanAvailable(agent_) && VxlanRoutingManager::IsRoutingVrf(vrf_name,
396  agent_);
397  if (is_routing_vrf || tunnel_bmap == TunnelType::VxlanType()) {
399  vxlan_id_ = agent_->vrf_table()->
400  FindVrfFromName(vrf_name)->vxlan_id();
401  }
402 }
403 
405  const VnListType &vn_list,
406  const EcmpLoadBalance &ecmp_load_balance,
407  const TagList &tag_list,
408  const SecurityGroupList &sg_list,
409  const PathPreference &path_pref,
410  TunnelType::TypeBmap tunnel_bmap,
411  std::vector<IpAddress> &tunnel_dest_list,
412  std::vector<uint32_t> &label_list,
413  const std::string &prefix_str,
414  const std::string &vrf_name):
415  ControllerPeerPath(peer), vn_list_(vn_list), sg_list_(sg_list),
416  ecmp_load_balance_(ecmp_load_balance), tag_list_(tag_list),
417  path_preference_(path_pref), tunnel_bmap_(tunnel_bmap),
418  copy_local_path_(false), tunnel_dest_list_(tunnel_dest_list),
419  label_list_(label_list), vrf_name_(vrf_name), vxlan_id_(0) {
420  agent_ = peer->agent();
421 }
422 
424  const BgpPeer *bgp_peer,
425  const string &default_vrf,
426  const Ip4Address &router_id,
427  const string &vrf_name,
428  const Ip4Address &tunnel_dest,
430  uint32_t label,
431  const MacAddress rewrite_dmac,
432  const VnListType &dest_vn_list,
433  const SecurityGroupList &sg_list,
434  const TagList &tag_list,
435  const PathPreference &path_preference,
436  bool ecmp_suppressed,
437  const EcmpLoadBalance &ecmp_load_balance,
438  bool etree_leaf) {
439 
441  // Make Tunnel-NH request
442  nh_req.key.reset(new TunnelNHKey(default_vrf, router_id, tunnel_dest, false,
444  rewrite_dmac));
445  nh_req.data.reset(new TunnelNHData());
446 
447  // Make route request pointing to Tunnel-NH created above
448  ControllerVmRoute *data =
449  new ControllerVmRoute(bgp_peer, default_vrf, tunnel_dest, label,
450  dest_vn_list, bmap, sg_list, tag_list, path_preference,
451  nh_req, ecmp_suppressed,
452  ecmp_load_balance, etree_leaf, rewrite_dmac);
453  return data;
454 }
455 
457  const BgpPeer *bgp_peer,
458  const string &default_vrf,
459  const Ip4Address &router_id,
460  const string &vrf_name,
461  const Ip4Address &tunnel_dest,
463  uint32_t label,
464  const MacAddress rewrite_dmac,
465  const VnListType &dest_vn_list,
466  const SecurityGroupList &sg_list,
467  const TagList &tag_list,
468  const PathPreference &path_preference,
469  bool ecmp_suppressed,
470  const EcmpLoadBalance &ecmp_load_balance,
471  bool etree_leaf) {
472 
474  // Make Labelled Tunnel-NH request
475  nh_req.key.reset(new LabelledTunnelNHKey(default_vrf, router_id, tunnel_dest, false,
477  rewrite_dmac, label));
478  nh_req.data.reset(new LabelledTunnelNHData());
479 
480  // Make route request pointing to Labelled Tunnel-NH created above
481  ControllerMplsRoute *data =
482  new ControllerMplsRoute(bgp_peer, default_vrf, tunnel_dest, label,
483  dest_vn_list, bmap, sg_list, tag_list, path_preference,
484  nh_req, ecmp_suppressed,
485  ecmp_load_balance, etree_leaf, rewrite_dmac);
486  return data;
487 }
489  bool ret = false;
490  // For IP subnet routes with Tunnel NH, update arp_flood_ and
491  // local_host_flag_ flags
492  if ((rt->GetTableType() == Agent::INET4_UNICAST) ||
493  (rt->GetTableType() == Agent::INET6_UNICAST)) {
494  InetUnicastRouteEntry *inet_rt =
495  static_cast<InetUnicastRouteEntry *>(rt);
496  //If its the IPAM route then no change required neither
497  //super net needs to be searched.
498  if (inet_rt->ipam_subnet_route())
499  return ret;
500 
501  bool ipam_subnet_route = inet_rt->IpamSubnetRouteAvailable();
502  ret = inet_rt->UpdateIpamHostFlags(ipam_subnet_route);
503  }
504  return ret;
505 }
506 
508  const AgentRoute *rt) {
509  bool ret = false;
510  NextHop *nh = NULL;
511  SecurityGroupList path_sg_list;
512 
514  if (path->tunnel_bmap() != tunnel_bmap_) {
516  ret = true;
517  }
518 
520  if (new_tunnel_type == TunnelType::MPLS_OVER_MPLS) {
521  // this path depends on inet.3 route table,
522  // update dependent_table if it is not set already.
523  if (!path->GetDependentTable()) {
524  InetUnicastAgentRouteTable *table = NULL;
525  table = static_cast<InetUnicastAgentRouteTable *>
526  (agent->fabric_inet4_mpls_table());
527  assert(table != NULL);
528  path->SetDependentTable(table);
529  }
532 
536  path->GetParentRoute()));
538  const NextHop *anh;
539  if (uc_rt == NULL || uc_rt->prefix_length() == 0 || (anh = uc_rt->GetActiveNextHop()) == NULL) {
540  path->set_unresolved(true);
541  member->SetUnresolved(false);
542  } else {
543  path->set_unresolved(false);
545  const NextHopKey *nh_key =
546  static_cast<const NextHopKey*>(key.get());
547  nh = static_cast<NextHop *>(agent->nexthop_table()->
548  FindActiveEntry(nh_key));
549  assert(nh !=NULL);
550  //Reset to new gateway route, no nexthop for indirect route
551  member->UpdateDependentRoute(uc_rt);
552  member->SetUnresolved(false);
553  path->set_gw_ip(tunnel_dest_);
554  path->set_nexthop(NULL);
555  }
556  new_list.push_back(member);
557  path->ResetEcmpMemberList(new_list);
558 
559  } else {
560 
561  if ((tunnel_bmap_ == (1 << TunnelType::VXLAN) &&
562  (new_tunnel_type != TunnelType::VXLAN)) ||
563  (tunnel_bmap_ != (1 << TunnelType::VXLAN) &&
564  (new_tunnel_type == TunnelType::VXLAN))) {
565  new_tunnel_type = TunnelType::INVALID;
566  nh_req_.key.reset(new TunnelNHKey(agent->fabric_vrf_name(),
567  agent->router_id(), tunnel_dest_,
568  false, new_tunnel_type,
569  rewrite_dmac_));
570  }
571  agent->nexthop_table()->Process(nh_req_);
572  TunnelNHKey key(agent->fabric_vrf_name(), agent->router_id(), tunnel_dest_,
573  false, new_tunnel_type, rewrite_dmac_);
574  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
575 
576  path->set_unresolved(false);
577  }
579 
580  if (path->tunnel_type() != new_tunnel_type) {
581  path->set_tunnel_type(new_tunnel_type);
582  ret = true;
583  }
584 
585  //Interpret label sent by control node
587  // Only VXLAN encap is sent, so label is VXLAN
588  // For vxlan routing vn external route label can change , add path change
589  if (rt->vrf() && rt->vrf()->vn() &&
590  rt->vrf()->vn()->vxlan_routing_vn() && path->vxlan_id() != label_) {
591  ret = true;
592  }
593  path->set_vxlan_id(label_);
594  if (path->label() != MplsTable::kInvalidLabel) {
596  ret = true;
597  }
598  } else if ((tunnel_bmap_ == TunnelType::MplsType())||
600  //MPLS (GRE/UDP) is the only encap sent,
601  //so label is MPLS.
602  if (path->label() != label_) {
603  path->set_label(label_);
604  ret = true;
605  }
607  } else {
608  //Got a mix of Vxlan and Mpls, so interpret label
609  //as per the computed tunnel type.
610  if (new_tunnel_type == TunnelType::VXLAN) {
611  if (path->vxlan_id() != label_) {
612  path->set_vxlan_id(label_);
614  ret = true;
615  }
616  } else {
617  if (path->label() != label_) {
618  path->set_label(label_);
620  ret = true;
621  }
622  }
623  }
624 
625  if (path->dest_vn_list() != dest_vn_list_) {
627  ret = true;
628  }
629 
630  if (nh != NULL) {
631  if (path->ChangeNH(agent, nh) == true)
632  ret = true;
633  }
634 
635  path_sg_list = path->sg_list();
636  if (path_sg_list != sg_list_) {
637  path->set_sg_list(sg_list_);
638  ret = true;
639  }
640 
641  if (tag_list_ != path->tag_list()) {
642  path->set_tag_list(tag_list_);
643  ret = true;
644  }
645 
646  if (path->path_preference() != path_preference_) {
648  ret = true;
649  }
650 
651  //If a transition of path happens from ECMP to non ECMP
652  //reset local mpls label reference and composite nh key
653  if (path->composite_nh_key()) {
654  path->set_composite_nh_key(NULL);
655  path->set_local_ecmp_mpls_label(NULL);
656  }
657 
658  if (path->ecmp_suppressed() != ecmp_suppressed_) {
660  ret = true;
661  }
662 
663  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
665  ret = true;
666  }
667 
668  if (path->etree_leaf() != etree_leaf_) {
670  ret = true;
671  }
672 
673  return ret;
674 }
676  const AgentRoute *rt) {
677  bool ret = false;
678  NextHop *nh = NULL;
679  SecurityGroupList path_sg_list;
680 
682  if (path->tunnel_bmap() != tunnel_bmap_) {
684  ret = true;
685  }
686 
687  agent->nexthop_table()->Process(nh_req_);
690  nh = static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
692 
693  if (path->label() != label_) {
694  path->set_label(label_);
695  ret = true;
696  }
697 
698  if (path->dest_vn_list() != dest_vn_list_) {
700  ret = true;
701  }
702 
703  path->set_unresolved(false);
704  if (path->ChangeNH(agent, nh) == true)
705  ret = true;
706 
707  path_sg_list = path->sg_list();
708  if (path_sg_list != sg_list_) {
709  path->set_sg_list(sg_list_);
710  ret = true;
711  }
712 
713  if (tag_list_ != path->tag_list()) {
714  path->set_tag_list(tag_list_);
715  ret = true;
716  }
717 
718  if (path->path_preference() != path_preference_) {
720  ret = true;
721  }
722 
723  //If a transition of path happens from ECMP to non ECMP
724  //reset local mpls label reference and composite nh key
725  if (path->composite_nh_key()) {
726  path->set_composite_nh_key(NULL);
727  path->set_local_ecmp_mpls_label(NULL);
728  }
729 
730  if (path->ecmp_suppressed() != ecmp_suppressed_) {
732  ret = true;
733  }
734 
735  if (ecmp_load_balance_ != path->ecmp_load_balance()) {
737  ret = true;
738  }
739 
740  if (path->etree_leaf() != etree_leaf_) {
742  ret = true;
743  }
744 
745  return ret;
746 }
747 
749  const AgentRoute *rt) {
750  bool ret = false;
751 
752  AgentPath *local_path = NULL;
754  local_path = rt->FindPath(agent->fabric_rt_export_peer());
755  if (local_path == NULL) {
756  local_path = rt->FindLocalVmPortPath();
757  }
758  path->set_copy_local_path(true);
759  } else {
760  MplsLabel *mpls = agent->mpls_table()->FindMplsLabel(mpls_label_);
761  if (!mpls) {
762  return ret;
763  }
764 
765  assert(mpls->nexthop()->GetType() == NextHop::VRF);
766  const VrfNH *vrf_nh = static_cast<const VrfNH *>(mpls->nexthop());
767  const InetUnicastRouteEntry *uc_rt =
768  static_cast<const InetUnicastRouteEntry *>(rt);
769  const AgentRoute *mpls_vrf_uc_rt =
770  vrf_nh->GetVrf()->GetUcRoute(uc_rt->prefix_address());
771  if (mpls_vrf_uc_rt == NULL) {
772  return ret;
773  }
774  local_path = mpls_vrf_uc_rt->FindLocalVmPortPath();
775  }
776 
778 
779  if (!local_path) {
780  return ret;
781  }
782 
783  if (path->dest_vn_list() != vn_list_) {
784  path->set_dest_vn_list(vn_list_);
785  ret = true;
786  }
787  path->set_unresolved(false);
788 
789  if (path->sg_list() != sg_list_) {
790  path->set_sg_list(sg_list_);
791  ret = true;
792  }
793 
794  path->set_tunnel_bmap(local_path->tunnel_bmap());
795  TunnelType::Type new_tunnel_type =
797  if (new_tunnel_type == TunnelType::VXLAN &&
798  local_path->vxlan_id() == VxLanTable::kInvalidvxlan_id) {
799  new_tunnel_type = TunnelType::ComputeType(TunnelType::MplsType());
800  }
801 
802  if (path->tunnel_type() != new_tunnel_type) {
803  path->set_tunnel_type(new_tunnel_type);
804  ret = true;
805  }
806 
807  // If policy force-enabled in request, enable policy
808  path->set_force_policy(local_path->force_policy());
809 
810  if (path->label() != local_path->label()) {
811  path->set_label(local_path->label());
812  ret = true;
813  }
814 
815  if (path->vxlan_id() != local_path->vxlan_id()) {
816  path->set_vxlan_id(local_path->vxlan_id());
817  ret = true;
818  }
819 
820  if (path->path_preference() != local_path->path_preference()) {
821  path->set_path_preference(local_path->path_preference());
822  ret = true;
823  }
824 
825  NextHop *nh = const_cast<NextHop *>(local_path->ComputeNextHop(agent));
826  if (path->ChangeNH(agent, nh) == true) {
827  ret = true;
828  }
830  CompositeNHKey *nh_key = dynamic_cast<CompositeNHKey *>(key.release());
831  path->set_composite_nh_key(nh_key);
832 
833  return ret;
834 }
835 
837  const AgentRoute *route) {
838  if (path->peer_sequence_number() >= sequence_number_)
839  return false;
840 
841  if (route->IsDeleted())
842  return false;
843 
844  //Delete old stale path
846  AgentRouteKey *key = (static_cast<AgentRouteKey *>(route->
847  GetDBRequestKey().get()))->Clone();
848  key->set_peer(path->peer());
849  req.key.reset(key);
850  req.data.reset();
851  AgentRouteTable *table = static_cast<AgentRouteTable *>(route->get_table());
852  table->Process(req);
853  return true;
854 }
855 
857  const AgentRoute *route) const {
858  if (path->peer_sequence_number() >= sequence_number_)
859  return false;
860  return true;
861 }
862 
863 //Force instantiation
865  const VnListType &vn_list,
866  const EcmpLoadBalance &ecmp_load_balance,
867  const TagList &tag_list, const autogen::ItemType *item,
868  const AgentRouteTable *rt_table, const std::string &prefix_str);
870  const VnListType &vn_list,
871  const EcmpLoadBalance &ecmp_load_balance,
872  const TagList &tag_list, const autogen::EnetItemType *item,
873  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:744
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:883
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:378
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:866
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