OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inet_unicast_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 
7 #include <base/address_util.h>
9 #include <boost/foreach.hpp>
10 #include <cmn/agent_cmn.h>
11 #include <route/route.h>
12 #include <oper/ecmp.h>
13 #include <oper/ecmp_load_balance.h>
14 #include <oper/route_common.h>
15 #include <oper/vrf.h>
16 #include <oper/tunnel_nh.h>
17 #include <oper/mpls.h>
18 #include <oper/vxlan.h>
19 #include <oper/mirror_table.h>
20 #include <oper/multicast.h>
24 #include <oper/agent_sandesh.h>
25 
26 using namespace std;
27 using namespace boost::asio;
28 
29 AgentRoute *
30 InetUnicastRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const {
31  InetUnicastRouteEntry * entry =
32  new InetUnicastRouteEntry(vrf, dip_, plen_, is_multicast);
33  return static_cast<AgentRoute *>(entry);
34 }
35 
37  return (new InetUnicastRouteKey(peer(), vrf_name_, dip_, plen_));
38 }
39 
41  return (new InetMplsUnicastRouteKey(peer(), vrf_name_, dip_, plen_));
42 }
44 // InetUnicastAgentRouteTable functions
47  const std::string &name) :
48  AgentRouteTable(db, name), walkid_(DBTableWalker::kInvalidWalkerId) {
49 
50  if (name.find("uc.route.0") != std::string::npos) {
52  } else if (name.find("uc.route.3") != std::string::npos) {
54  } else if (name.find("uc.route6.0") != std::string::npos) {
56  } else if (name.find("evpn.route.0") != std::string::npos) {
58  } else if (name.find("l2.route.0") != std::string::npos) {
60  } else if (name.find("mc.route.0") != std::string::npos) {
62  } else {
64  }
65 }
66 
68 InetUnicastAgentRouteTable::CreateTable(DB *db, const std::string &name) {
69  AgentRouteTable *table = new InetUnicastAgentRouteTable(db, name);
70  table->Init();
71  return table;
72 }
73 
76  uint32_t plen = 128;
77  if (ip.is_v4()) {
78  plen = 32;
79  }
80  InetUnicastRouteEntry key(NULL, ip, plen, false);
81  return tree_.LPMFind(&key);
82 }
83 
86  return tree_.LPMFind(&rt_key);
87 }
88 
91  uint8_t plen = 32;
92  InetUnicastRouteEntry *rt = NULL;
93  do {
94  InetUnicastRouteEntry key(NULL, ip, plen, false);
95  rt = tree_.LPMFind(&key);
96  if (rt) {
97  const NextHop *nh = rt->GetActiveNextHop();
98  if (nh && nh->GetType() == NextHop::RESOLVE)
99  return rt;
100  }
101  } while (rt && --plen);
102 
103  return NULL;
104 }
105 
108  const Ip4Address &ip) {
109  VrfEntry *vrf =
111  InetUnicastAgentRouteTable *rt_table =
112  static_cast<InetUnicastAgentRouteTable *>
113  (vrf->GetInet4UnicastRouteTable());
114  return rt_table->FindResolveRoute(ip);
115 }
116 
117 static void Inet4UnicastTableEnqueue(Agent *agent, DBRequest *req) {
119  if (table) {
120  table->Enqueue(req);
121  }
122 }
123 
124 static void Inet4MplsUnicastTableEnqueue(Agent *agent, DBRequest *req) {
125  AgentRouteTable *table = agent->fabric_inet4_mpls_table();
126  if (table) {
127  table->Enqueue(req);
128  }
129 }
130 
131 static void Inet6UnicastTableEnqueue(Agent *agent, const string &vrf_name,
132  DBRequest *req) {
134  if (table) {
135  table->Enqueue(req);
136  }
137 }
138 
139 static void InetUnicastTableEnqueue(Agent *agent, const string &vrf,
140  DBRequest *req) {
141  InetUnicastRouteKey *key = static_cast<InetUnicastRouteKey *>(req->key.get());
142  if (key->addr().is_v4()) {
143  Inet4UnicastTableEnqueue(agent, req);
144  } else if (key->addr().is_v6()) {
145  Inet6UnicastTableEnqueue(agent, vrf, req);
146  }
147 }
148 
149 static void Inet4UnicastTableProcess(Agent *agent, const string &vrf_name,
150  DBRequest &req) {
151  AgentRouteTable *table =
152  agent->vrf_table()->GetInet4UnicastRouteTable(vrf_name);
153  if (table) {
154  table->Process(req);
155  }
156 }
157 
158 static void Inet6UnicastTableProcess(Agent *agent, const string &vrf_name,
159  DBRequest &req) {
160  AgentRouteTable *table =
161  agent->vrf_table()->GetInet6UnicastRouteTable(vrf_name);
162  if (table) {
163  table->Process(req);
164  }
165 }
166 
167 static void InetUnicastTableProcess(Agent *agent, const string &vrf_name,
168  DBRequest &req) {
169  InetUnicastRouteKey *key = static_cast<InetUnicastRouteKey *>(req.key.get());
170  if (key->addr().is_v4()) {
171  Inet4UnicastTableProcess(agent, vrf_name, req);
172  } else if (key->addr().is_v6()) {
173  Inet6UnicastTableProcess(agent, vrf_name, req);
174  }
175 }
176 
177 /*
178  * Traverse all smaller subnets w.r.t. route sent and mark the arp flood flag
179  * accordingly.
180  */
182 (const InetUnicastRouteEntry *rt, bool val) {
183  const IpAddress addr = rt->prefix_address();
184  uint16_t plen = rt->prefix_length();
185  InetUnicastRouteEntry *lpm_rt = GetNextNonConst(rt);
186 
187  Ip4Address v4_parent_mask;
188  Ip6Address v6_parent_mask;
189 
190  if (GetTableType() == Agent::INET4_UNICAST) {
191  v4_parent_mask = Address::GetIp4SubnetAddress(addr.to_v4(),
192  plen);
193  } else if (GetTableType() == Agent::INET6_UNICAST) {
194  v6_parent_mask = Address::GetIp6SubnetAddress(addr.to_v6(),
195  plen);
196  } else {
197  // skip processing for inet4_mpls table
198  // not expected
199  return false;
200  }
201 
202 
203  // Iterate thru all the routes under this subnet and update route flags
204  while ((lpm_rt != NULL) && (plen < lpm_rt->prefix_length())) {
205  if (GetTableType() == Agent::INET4_UNICAST) {
206  Ip4Address node_mask =
208  plen);
209  if (v4_parent_mask != node_mask)
210  break;
211 
212  } else if (GetTableType() == Agent::INET6_UNICAST) {
213  Ip6Address node_mask =
215  plen);
216  if (v6_parent_mask != node_mask)
217  break;
218  }
219 
220  // Update ipam_host_route_ and proxy_arp_ flags for host-routes
221  bool notify = false;
222  if (lpm_rt->UpdateIpamHostFlags(val)) {
223  notify = true;
224  }
225 
226  if (notify) {
227  NotifyEntry(lpm_rt);
228  }
229 
230  lpm_rt = GetNextNonConst(lpm_rt);
231  }
232  return false;
233 }
234 
235 //Null peer means sync is done on routes.
236 //If peer is specified then path belonging to peer will be resync'd
237 //Functions in TraverseHostRoutesInSubnet:
238 //1) If subnet rt added does not have any supernet then visit all unresolved
239 // routes and resync them.
240 //2) If supernet route is present then traverse lpm routes under this newly
241 // added subnet and resync all host routes pointing to supernet route of this
242 // subnet.
243 //3) Skip all the host routes present under this subnet belonging to a better
244 // subnet(better subnet is the one which comes under subnet being added).
245 // e.g. 1.1.1.10/24 is a better subnet in 1.1.1.10/16 while supernet can be
246 // 1.1.1.0/8
247 void
249  const Peer *peer)
250 {
251  const IpAddress addr = rt->prefix_address();
252  uint16_t plen = rt->prefix_length();
254 
255  //If supernet route is NULL, then this is the default route and visit to
256  //unresolved route for resync should suffice.
257  if (supernet_rt == NULL) {
258  //Resync all unresolved routes.
260  return;
261  }
262  //So suernet route is present and this subnet route is a better route.
263  //Look for all routes which were pointing to supernet route and move them
264  //to this subnet route, if they fall in same subnet.
265  IpAddress parent_mask = GetSubnetAddress(addr, plen);
266  for (InetUnicastRouteEntry *lpm_rt = GetNextNonConst(rt);
267  (lpm_rt != NULL) && (plen < lpm_rt->prefix_length());
268  lpm_rt= GetNextNonConst(lpm_rt)) {
269  IpAddress node_mask = GetSubnetAddress(lpm_rt->prefix_address(), plen);
270  if (parent_mask != node_mask)
271  break;
272 
273  //Non host route, lets continue as this route will have its own NH and it
274  //need not be modified.
275  if (lpm_rt->IsHostRoute() == false) {
276  continue;
277  }
278 
279  //If supernet route of this subnet route is not parent of lpm_rt added,
280  //then skip as its not lpm_rt dependant as well.
281  //There may be some other subnet which is handling it.
282  //e.g. 1.1.0.0/8, 1.1.0.0/16, 1.1.1.0/24, 1.1.1.1, 1.1.0.1
283  //Here parent of 1.1.1.1 will be 1.1.1.0/24 and not 1.1.0.0/16.
284  //So if subnet route getting added is 1.1.0.0/16 in presence of 1.1.1.0/24
285  //then 1.1.1.1 should not be modified.
286  if (lpm_rt->GetActivePath()->dependant_rt() != supernet_rt)
287  continue;
288 
289 
290  //Proceed only for host route
291  //Resync will ensure that subnet route is added to lpm host route
292  //dependant rt(gw_ip).
293  lpm_rt->EnqueueRouteResync();
294  }
295 }
296 
297 IpAddress
299  uint16_t plen) const {
300  if (type_ == Agent::INET4_UNICAST) {
301  return (Address::GetIp4SubnetAddress(addr.to_v4(), plen));
302  } else if (type_ == Agent::INET6_UNICAST) {
303  return (Address::GetIp6SubnetAddress(addr.to_v6(), plen));
304  }
305  return IpAddress(Ip4Address());
306 }
307 
308 //Tries searching for subnet route to which this route belongs.
309 //Route itself can be a subnet/host. To search for supernet plen is reduced by
310 //one and findlpm is issued.
313  InetUnicastRouteEntry key(NULL, addr, (GetHostPlen(addr) - 1),
314  false);
315  InetUnicastRouteEntry *parent_key = FindLPM(key);
316  return parent_key;
317 }
318 
320 // Inet4UnicastAgentRouteEntry functions
323  const IpAddress &addr,
324  uint8_t plen,
325  bool is_multicast) :
326  AgentRoute(vrf, is_multicast), AgentRoutePrefix(addr, plen),
327  ipam_subnet_route_(false),
328  ipam_host_route_(false), proxy_arp_(false) {
329  if (addr.is_v4()) {
330  prefix_address_ = Address::GetIp4SubnetAddress(addr.to_v4(), plen);
331  } else {
332  prefix_address_ = Address::GetIp6SubnetAddress(addr.to_v6(), plen);
333  }
334 }
335 
337  ostringstream str;
338  str << dip_.to_string();
339  str << "/";
340  str << (int)plen_;
341  return str.str();
342 }
343 
345  ostringstream str;
346  str << prefix_address_.to_string();
347  str << "/";
348  str << (int)prefix_length();
349  return str.str();
350 }
351 
352 
354  return ((InetUnicastAgentRouteTable *)get_table())->GetTableType();
355 }
356 
358  const InetUnicastRouteEntry &a =
359  static_cast<const InetUnicastRouteEntry &>(rhs);
360 
362  return -1;
363  }
364 
366  return 1;
367  }
368 
369  if (prefix_length() < a.prefix_length()) {
370  return -1;
371  }
372 
373  if (prefix_length() > a.prefix_length()) {
374  return 1;
375  }
376 
377  return 0;
378 }
379 
382  (static_cast<InetUnicastAgentRouteTable *>(get_table()));
383  Agent *agent = table->agent();
384  InetUnicastRouteKey *key = NULL;
385  if ((table->GetTableType() == Agent::INET4_MPLS)) {
386  key =
387  new InetMplsUnicastRouteKey(agent->local_peer(),
389  } else {
390  key =
391  new InetUnicastRouteKey(agent->local_peer(),
393  }
394 
395  return DBEntryBase::KeyPtr(key);
396 }
397 
399  Agent *agent =
400  (static_cast<InetUnicastAgentRouteTable *>(get_table()))->agent();
401  const InetUnicastRouteKey *k =
402  static_cast<const InetUnicastRouteKey*>(key);
403  SetVrf(agent->vrf_table()->FindVrfFromName(k->vrf_name()));
404  IpAddress tmp(k->addr());
405  set_addr(tmp);
406  set_prefix_length(k->plen());
407 }
408 
411  static_cast<InetUnicastAgentRouteTable *>(get_table());
412  if (table->GetTableType() == Agent::INET4_UNICAST) {
414  return false;
415  } else if (table->GetTableType() == Agent::INET6_UNICAST) {
417  return false;
418  }
419  return true;
420 }
421 
422 /*
423  * This routine finds out if there is supernet for this subnet route and that
424  * is used to inherit flood flag. In case supernet is pointing to resolve i.e.
425  * gateway without having Ipam path, then search continues further
426  */
428  return (GetIpamSuperNetRoute() != NULL);
429 }
430 
433  if (prefix_length() == 0)
434  return NULL;
435 
436  //Local path present means that this route itself was programmed
437  //because of IPAM add as well and hence its eligible for flood in
438  //all paths where NH is tunnel.
440  static_cast<InetUnicastAgentRouteTable *>(get_table());
441 
442  //Search for supernet, if none then dont flood else again search for
443  //local path. If found then mark for flood otherwise check for active path
444  //and retain flood flag from that path.
445  uint16_t plen = prefix_length() - 1;
446  while (plen != 0) {
447  assert(plen < prefix_length());
448  InetUnicastRouteEntry key(vrf(), prefix_address_, plen, false);
449  // Find next highest matching route
450  InetUnicastRouteEntry *supernet_rt = table->FindRouteUsingKey(key);
451 
452  if (supernet_rt == NULL)
453  return NULL;
454 
455  if (supernet_rt->ipam_subnet_route())
456  return supernet_rt;
457 
458  plen--;
459  }
460 
461  return NULL;
462 }
463 
465  bool ret = false;
466  InetUnicastAgentRouteTable *uc_rt_table =
467  static_cast<InetUnicastAgentRouteTable *>(get_table());
468  if (IsHostRoute() == false)
469  uc_rt_table->TraverseHostRoutesInSubnet(this,
470  uc_rt_table->agent()->
471  inet_evpn_peer());
472 
473  if (path->nexthop() && path->nexthop()->IsValid() &&
474  path->nexthop()->GetType() == NextHop::ARP) {
475  //Add bridge route for IP fabric ARP routes, so that
476  //MAC stitching can be done for VM routes based on corresponding
477  //compute node
478  const ArpNH *arp_nh = static_cast<const ArpNH *>(path->nexthop());
479  BridgeAgentRouteTable *table =
480  static_cast<BridgeAgentRouteTable *>(vrf()->GetBridgeRouteTable());
481  table->AddMacVmBindingRoute(path->peer(), vrf()->GetName(), arp_nh->GetMac(),
482  NULL, false);
483  }
484 
485  // ECMP path are managed by route module. Update ECMP path with
486  // addition of new path
487  EcmpData ecmp_data(uc_rt_table->agent(), vrf()->GetName(), ToString(),
488  path, false);
489  ret |= ecmp_data.Update(this);
490  return ret;
491 }
492 
494  if (IsHostRoute() == false) {
495  //TODO merge both evpn inet and subnet routes handling
497  }
498 
499 
500  if (path->nexthop() && path->nexthop()->GetType() == NextHop::ARP) {
501  const ArpNH *arp_nh =
502  static_cast<const ArpNH *>(path->nexthop());
503  BridgeAgentRouteTable *table =
504  static_cast<BridgeAgentRouteTable *>(vrf()->GetBridgeRouteTable());
505  table->DeleteMacVmBindingRoute(path->peer(), vrf()->GetName(),
506  arp_nh->GetMac(), NULL);
507  }
508 
509  InetUnicastAgentRouteTable *uc_rt_table =
510  static_cast<InetUnicastAgentRouteTable *>(get_table());
511  //Subnet discard = Ipam subnet route.
512  //Ipam path is getting deleted so all the smaller subnets should be
513  //resynced to remove the arp flood marking.
514  if (path->is_subnet_discard()) {
515  // Reset flag on route as ipam is going off.
516  UpdateRouteFlags(false, false, false);
517  uc_rt_table->ResyncSubnetRoutes(this, false);
518  return true;
519  }
520  // ECMP path are managed by route module. Update ECMP path with
521  // deletion of new path
522  EcmpData ecmp_data(uc_rt_table->agent(), vrf()->GetName(), ToString(),
523  path, true);
524  return ecmp_data.Update(this);
525 }
526 
527 // ipam_host_route_ flag:
528 // ipam_host_route_ is set if this is host-route and falls in ipam-subnet range
529 //
530 // proxy_arp_ flag:
531 // For hosts within subnet, we assume ARP must not be proxied and should be
532 // flooded instead. If we get EVPN route, in KSYNC the EVPN path processing
533 // will take preference and KSYNC will set Proxy flag
534 bool InetUnicastRouteEntry::UpdateIpamHostFlags(bool ipam_host_route) {
535  // For non-host routes, set proxy always
536  if (IsHostRoute() == false) {
537  return UpdateRouteFlags(false, false, true);
538  }
539 
540  bool proxy_arp = ipam_host_route ? false : true;
541  return UpdateRouteFlags(false, ipam_host_route, proxy_arp);
542 }
543 
544 bool InetUnicastRouteEntry::UpdateRouteFlags(bool ipam_subnet_route,
545  bool ipam_host_route,
546  bool proxy_arp) {
547  bool ret = false;
548  if (ipam_subnet_route_ != ipam_subnet_route) {
550  ret = true;
551  }
552 
553  if (ipam_host_route_ != ipam_host_route) {
555  ret = true;
556  }
557 
558  if (proxy_arp_ != proxy_arp) {
560  ret = true;
561  }
562 
563  return ret;
564 }
566 (const AgentRouteKey *key, const AgentRouteData *data) const {
567  const Peer *peer = key->peer();
568  const InetEvpnPeer *evpn_peer = dynamic_cast<const InetEvpnPeer*>(peer);
569  assert(evpn_peer != NULL);
570 
571  Route::PathList::const_iterator it;
572  for (it = GetPathList().begin(); it != GetPathList().end(); it++) {
573  const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
574  if (path->peer() != key->peer())
575  continue;
576 
577  //Handle mac route added via evpn route.
578  const InetEvpnRoutePath *evpn_path =
579  dynamic_cast<const InetEvpnRoutePath *>(path);
580  const InetEvpnRouteData *evpn_data =
581  dynamic_cast<const InetEvpnRouteData *>(data);
582  assert(evpn_path != NULL);
583  assert(evpn_data != NULL);
584  if (evpn_path->MacAddr() != evpn_data->MacAddr())
585  continue;
586  return const_cast<AgentPath *>(path);
587  }
588  return NULL;
589 }
591 (const AgentRouteKey *key, const AgentRouteData *data) const {
592  const Peer *peer = key->peer();
593  const InetEvpnPeer *inet_evpn_peer =
594  dynamic_cast<const InetEvpnPeer*>(peer);
595  if (inet_evpn_peer != NULL)
596  return FindEvpnPathUsingKeyData(key, data);
597 
598  return FindPath(peer);
599 }
600 
602 // AgentRouteData virtual functions
604 
606  const AgentRoute *rt) {
607  bool ret = true;
608 
610  NextHop *nh =
611  static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
612  path->set_unresolved(false);
613 
614  if (path->dest_vn_list() != vn_list_) {
615  path->set_dest_vn_list(vn_list_);
616  ret = true;
617  }
618 
619  if (path->sg_list() != sg_list_) {
620  path->set_sg_list(sg_list_);
621  ret = true;
622  }
623 
624  if (path->tag_list() != tag_list_) {
625  path->set_tag_list(tag_list_);
626  ret = true;
627  }
628 
629  if (path->ChangeNH(agent, nh) == true)
630  ret = true;
631 
632  if (nh) {
633  if (path->CopyArpData()) {
634  ret = true;
635  }
636  }
637 
639 
640  return ret;
641 }
642 
644  const AgentRoute *rt) {
645  bool ret = true;
646 
648  NextHop *nh =
649  static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
650  path->set_unresolved(false);
651 
652  if (path->dest_vn_list() != vn_list_) {
653  path->set_dest_vn_list(vn_list_);
654  ret = true;
655  }
656 
657  if (path->sg_list() != sg_list_) {
658  path->set_sg_list(sg_list_);
659  ret = true;
660  }
661 
662  if (path->tag_list() != tag_list_) {
663  path->set_tag_list(tag_list_);
664  ret = true;
665  }
666 
667  if (path->ChangeNH(agent, nh) == true)
668  ret = true;
669 
670  if (nh) {
671  if (path->CopyNdpData()) {
672  ret = true;
673  }
674  }
675 
677 
678  return ret;
679 }
680 
682  const AgentRoute *agent_rt) {
683  path->set_vrf_name(vrf_name_);
684  NextHop *nh = NULL;
685  InetUnicastRouteEntry *rt = NULL;
686 
687  if (gw_list_.empty() || gw_list_.size() == 1) { /* SH case */
688  InetUnicastAgentRouteTable *table = NULL;
689  table = static_cast<InetUnicastAgentRouteTable *>
691  IpAddress gw_ip = gw_list_.empty() ? Ip4Address(0) : gw_list_[0];
692  rt = table->FindRoute(gw_ip);
693  const NextHop *anh;
694  if (rt == NULL || rt->prefix_length() == 0 || (anh = rt->GetActiveNextHop()) == NULL) {
695  path->set_unresolved(true);
696  } else if (anh->GetType() == NextHop::RESOLVE) {
697  const ResolveNH *nh =
698  static_cast<const ResolveNH *>(anh);
699  path->set_unresolved(true);
700  std::string nexthop_vrf = nh->get_interface()->vrf()->GetName();
701  if (nh->get_interface()->vrf()->forwarding_vrf()) {
702  nexthop_vrf = nh->get_interface()->vrf()->forwarding_vrf()->GetName();
703  }
705  nexthop_vrf,
706  nh->get_interface(), nh->PolicyEnabled(),
708  } else {
709  path->set_unresolved(false);
710  }
711  } else { /* MH case */
712  CompositeNHKey *comp_key;
713  bool comp_nh_policy = false;
715 
718 
719  ComponentNHKeyList comp_nh_list;
720  AddressList::const_iterator ptr;
721  for (ptr = gw_list_.begin(); ptr < gw_list_.end(); ptr++) {
722  InetUnicastRouteEntry *uc_rt = table->FindRoute(*ptr);
723  rt = uc_rt;
724  if (uc_rt == NULL || uc_rt->prefix_length() == 0) {
725  path->set_unresolved(true);
726  break;
727  } else if (uc_rt->GetActiveNextHop()->GetType() == NextHop::RESOLVE) {
728  path->set_unresolved(true);
729  const ResolveNH *nh =
730  static_cast<const ResolveNH *>(uc_rt->GetActiveNextHop());
731  path->set_unresolved(true);
732  std::string nexthop_vrf = nh->get_interface()->vrf()->GetName();
733  if (nh->get_interface()->vrf()->forwarding_vrf()) {
734  nexthop_vrf = nh->get_interface()->vrf()->forwarding_vrf()->GetName();
735  }
737  nexthop_vrf, nh->get_interface(), nh->PolicyEnabled(),
739  } else {
740  DBEntryBase::KeyPtr key =
741  uc_rt->GetActiveNextHop()->GetDBRequestKey();
742  NextHopKey *nh_key = static_cast<NextHopKey *>(key.release());
743  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
744  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(-1,
745  std::move(nh_key_ptr)));
746  comp_nh_list.push_back(component_nh_key);
747  }
748  }
749 
750  if (comp_nh_list.size() == gw_list_.size()) {
751  path->set_unresolved(false);
752  nh_req.key.reset(new CompositeNHKey(Composite::ECMP, comp_nh_policy,
753  comp_nh_list, vrf_name_));
754  nh_req.data.reset(new CompositeNHData());
755  comp_key =
756  static_cast<CompositeNHKey *>(nh_req.key.get());
757  nh = static_cast<NextHop *>(agent->nexthop_table()->
758  FindActiveEntry(comp_key));
759  if (!nh) {
760  agent->nexthop_table()->Process(nh_req);
761  nh = static_cast<NextHop *>(agent->nexthop_table()->
762  FindActiveEntry(comp_key));
763  }
764  }
765  }
766 
767  if (path->label() != mpls_label_) {
768  path->set_label(mpls_label_);
769  }
770 
771  if (agent->is_l3mh() == false) {
772  path->set_nexthop(nh);
773  }
774 
775  SecurityGroupList path_sg_list;
776  path_sg_list = path->sg_list();
777  if (path_sg_list != sg_list_) {
778  path->set_sg_list(sg_list_);
779  }
780 
781  TagList path_tag_list;
782  path_tag_list = path->tag_list();
783  if (path_tag_list != tag_list_) {
784  path->set_tag_list(tag_list_);
785  }
786 
787  CommunityList path_communities;
788  path_communities = path->communities();
789  if (path_communities != communities_) {
791  }
792 
793  //Reset to new gateway route, no nexthop for indirect route
794  if (agent->is_l3mh() == false) {
795  IpAddress gw_ip = gw_list_.empty() ? Ip4Address(0) : gw_list_[0];
796  path->set_gw_ip(gw_ip);
797  path->ResetDependantRoute(rt);
798  }
799 
800  if (rt) {
801  path->set_tunnel_bmap(rt->GetActivePath()->tunnel_bmap());
802  }
803 
804  if (native_encap_) {
805  path->set_tunnel_bmap(path->tunnel_bmap() | (1 << TunnelType::NATIVE));
806  }
807 
808  if (path->dest_vn_list() != vn_list_) {
809  path->set_dest_vn_list(vn_list_);
810  }
811 
812  if (agent->is_l3mh() && (path->unresolved() == false) &&
813  path->ChangeNH(agent, nh) == true) {
814  return true;
815  }
816 
817  return true;
818 }
819 
821  const MacAddress& mac,
822  const std::string& parent,
823  AgentRoute *rt) :
824  AgentPath(peer, rt), mac_(mac), parent_(parent) {
825 }
826 
828  //In InetEvpnRoutePath nexthop will always be NULL.
829  //Valid NH is dependant on parent route(subnet).
830  if (dependant_rt()) {
831  const AgentPath *path = dependant_rt()->GetActivePath();
832  if (path != NULL)
833  return path;
834  }
835  return this;
836 }
837 
839  const InetUnicastRouteEntry *dependant_route =
840  dynamic_cast<const InetUnicastRouteEntry *>(dependant_rt());
842  static_cast<InetUnicastAgentRouteTable *>(sync_route->get_table());
843  InetUnicastRouteEntry *parent_subnet_route =
844  table->GetSuperNetRoute(dynamic_cast<const InetUnicastRouteEntry *>
845  (sync_route)->prefix_address());
846 
847  if (parent_subnet_route != dependant_route) {
848  set_gw_ip(parent_subnet_route ? parent_subnet_route->prefix_address() :
849  IpAddress());
850  if (parent_subnet_route) {
851  ResetDependantRoute(parent_subnet_route);
852  set_unresolved(false);
853  } else {
854  //Clear old dependant route
856  set_unresolved(true);
857  }
858  return true;
859  }
860  return false;
861 }
862 
864  return SyncDependantRoute(sync_route);
865 }
866 
868  //InetEvpnRoutePath is deleted when parent evpn route is going off.
869  //Now it may happen that supernet route which was used as dependant_rt in
870  //this path has been deleted.
871  if ((dependant_rt() == NULL) ||
872  (dependant_rt()->GetActiveNextHop() == NULL)) {
873  DiscardNH key;
874  return static_cast<NextHop *>
875  (agent->nexthop_table()->FindActiveEntry(&key));
876  }
877 
878  return AgentPath::ComputeNextHop(agent);
879 }
880 
881 bool InetEvpnRoutePath::IsLess(const AgentPath &r_path) const {
882  const InetEvpnRoutePath *r_evpn_path =
883  dynamic_cast<const InetEvpnRoutePath *>(&r_path);
884  if (r_evpn_path != NULL) {
885  if (r_evpn_path->MacAddr() != mac_) {
886  return (mac_ < r_evpn_path->MacAddr());
887  }
888  }
889 
890  return peer()->IsLess(r_path.peer());
891 }
893  AgentRouteData(AgentRouteData::ADD_DEL_CHANGE,
894  evpn_rt->is_multicast(), 0),
895  mac_(evpn_rt->mac()) {
896  std::stringstream s;
897  s << evpn_rt->ToString();
898  s << " ";
899  parent_ = s.str();
900 }
901 
903  AgentRoute *rt) const {
904  return (new InetEvpnRoutePath(peer, mac_, parent_, rt));
905 }
906 
908  AgentPath *path,
909  const AgentRoute *route) {
910  return dynamic_cast<InetEvpnRoutePath *>(path)->SyncDependantRoute(route);
911 }
912 
914  const AgentRoute *rt) const {
915  const InetEvpnRoutePath *evpn_path =
916  dynamic_cast<const InetEvpnRoutePath *>(path);
917  if (evpn_path == NULL) {
918  return true;
919  }
920  return (evpn_path->MacAddr() == MacAddr());
921 }
922 
924 (const PhysicalInterface *intrface, const std::string &vn_name) :
926  interface_key_(new PhysicalInterfaceKey(intrface->name())),
927  vn_name_(vn_name) {
928 }
929 
931  const AgentRoute *rt) {
932  bool ret = false;
933 
934  path->set_unresolved(false);
935  VnListType vn_list;
936  vn_list.insert(agent->fabric_vn_name());
937  if (path->dest_vn_list() != vn_list) {
938  path->set_dest_vn_list(vn_list);
939  ret = true;
940  }
941 
942  Interface *intf = static_cast<Interface *>(
944  assert(intf);
945  InterfaceNHKey key(interface_key_->Clone(), false,
946  InterfaceNHFlags::INET4, intf->mac());
947  NextHop *nh = static_cast<NextHop *>
948  (agent->nexthop_table()->FindActiveEntry(&key));
949  assert(nh);
950  if (path->ChangeNH(agent, nh) == true) {
951  ret = true;
952  }
953 
954  return ret;
955 }
956 
958 // Sandesh functions
960 
961 bool InetUnicastRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
962 
963  RouteUcSandeshData data;
964  data.set_src_ip(prefix_address_.to_string());
965  data.set_src_plen(prefix_length());
966  data.set_ipam_subnet_route(ipam_subnet_route_);
967  data.set_ipam_host_route(ipam_host_route_);
968  data.set_proxy_arp(proxy_arp_);
969  data.set_src_vrf(vrf()->GetName());
970  data.set_multicast(AgentRoute::is_multicast());
971  data.set_intf_route_type(AgentRoute::intf_route_type());
972  for (Route::PathList::const_iterator it = GetPathList().begin();
973  it != GetPathList().end(); it++) {
974  const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
975  if (path) {
976  PathSandeshData pdata;
977  path->SetSandeshData(pdata);
978  if (vrf()->GetName() == Agent::GetInstance()->fabric_vrf_name()
979  && (path->tunnel_bmap() & TunnelType::NativeType())) {
980  pdata.set_active_tunnel_type("Native");
981  }
982  data.path_list.push_back(pdata);
983  }
984  }
985 
986  if (prefix_address_.is_v4()) {
987  Inet4UcRouteResp *v4_resp = static_cast<Inet4UcRouteResp *>(sresp);
988  std::vector<RouteUcSandeshData> &list =
989  const_cast<std::vector<RouteUcSandeshData>&>(v4_resp->get_route_list());
990  list.push_back(data);
991  } else {
992  Inet6UcRouteResp *v6_resp = static_cast<Inet6UcRouteResp *>(sresp);
993  std::vector<RouteUcSandeshData> &list =
994  const_cast<std::vector<RouteUcSandeshData>&>(v6_resp->get_route_list());
995  list.push_back(data);
996  }
997  return true;
998 }
999 
1001  uint8_t plen, bool stale) const {
1002  if (prefix_address_ == addr && prefix_length() == plen) {
1003  return DBEntrySandesh(sresp, stale);
1004  }
1005 
1006  return false;
1007 }
1008 
1009 void UnresolvedRoute::HandleRequest() const {
1011  if (!vrf) {
1012  ErrorResp *resp = new ErrorResp();
1013  resp->set_context(context());
1014  resp->Response();
1015  return;
1016  }
1017 
1018  int count = 0;
1019  Inet4UcRouteResp *resp = new Inet4UcRouteResp();
1020 
1021  //TODO - Convert inet4ucroutetable to agentroutetable
1022  AgentRouteTable *rt_table = static_cast<AgentRouteTable *>
1023  (vrf->GetInet4UnicastRouteTable());
1024  InetUnicastAgentRouteTable::UnresolvedRouteTree::const_iterator it;
1025  it = rt_table->unresolved_route_begin();
1026  for (;it != rt_table->unresolved_route_end(); it++) {
1027  count++;
1028  const AgentRoute *rt = *it;
1029  rt->DBEntrySandesh(resp, false);
1030  if (count == 1) {
1031  resp->set_context(context()+"$");
1032  resp->Response();
1033  count = 0;
1034  resp = new Inet4UcRouteResp();
1035  }
1036  }
1037 
1038  resp->set_context(context());
1039  resp->Response();
1040  return;
1041 }
1042 
1043 void Inet4UcRouteReq::HandleRequest() const {
1044  VrfEntry *vrf =
1045  Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
1046  if (!vrf) {
1047  ErrorResp *resp = new ErrorResp();
1048  resp->set_context(context());
1049  resp->Response();
1050  return;
1051  }
1052 
1053  AgentSandeshPtr sand;
1054  if (get_src_ip().empty()) {
1055  sand.reset(new AgentInet4UcRtSandesh(vrf, context(), get_stale()));
1056  } else {
1057  boost::system::error_code ec;
1058  Ip4Address src_ip = Ip4Address::from_string(get_src_ip(), ec);
1059  sand.reset(new AgentInet4UcRtSandesh(vrf, context(), src_ip,
1060  (uint8_t)get_prefix_len(),
1061  get_stale()));
1062  }
1063  sand->DoSandesh(sand);
1064 }
1065 
1066 void Inet4MplsUcRouteReq::HandleRequest() const {
1067  VrfEntry *vrf =
1068  Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
1069  if (!vrf) {
1070  ErrorResp *resp = new ErrorResp();
1071  resp->set_context(context());
1072  resp->Response();
1073  return;
1074  }
1075 
1076  AgentSandeshPtr sand;
1077  if (get_src_ip().empty()) {
1078  sand.reset(new AgentInet4MplsUcRtSandesh(vrf, context(), get_stale()));
1079  } else {
1080  boost::system::error_code ec;
1081  Ip4Address src_ip = Ip4Address::from_string(get_src_ip(), ec);
1082  sand.reset(new AgentInet4MplsUcRtSandesh(vrf, context(), src_ip,
1083  (uint8_t)get_prefix_len(),
1084  get_stale()));
1085  }
1086  sand->DoSandesh(sand);
1087 }
1088 
1090 (const AgentSandeshArguments *args, const std::string &context) {
1091  if (type_ == Agent::INET4_UNICAST) {
1092  return AgentSandeshPtr(new AgentInet4UcRtSandesh(vrf_entry(), context,
1093  false));
1094  } else if (type_ == Agent::INET4_MPLS) {
1095  return AgentSandeshPtr(new AgentInet4MplsUcRtSandesh(vrf_entry(), context,
1096  false));
1097  } else {
1098  return AgentSandeshPtr(new AgentInet6UcRtSandesh(vrf_entry(), context,
1099  false));
1100  }
1101 }
1102 
1103 void Inet6UcRouteReq::HandleRequest() const {
1104  VrfEntry *vrf =
1105  Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
1106  if (!vrf) {
1107  ErrorResp *resp = new ErrorResp();
1108  resp->set_context(context());
1109  resp->Response();
1110  return;
1111  }
1112 
1113  AgentSandeshPtr sand;
1114  if (get_src_ip().empty()) {
1115  sand.reset(new AgentInet6UcRtSandesh(vrf, context(), get_stale()));
1116  } else {
1117  boost::system::error_code ec;
1118  Ip6Address src_ip = Ip6Address::from_string(get_src_ip(), ec);
1119  sand.reset(new AgentInet6UcRtSandesh(vrf, context(), src_ip,
1120  (uint8_t)get_prefix_len(),
1121  get_stale()));
1122  }
1123  sand->DoSandesh(sand);
1124 }
1125 
1127 // Helper functions to enqueue request or process inline
1129 
1130 // Request to delete an entry
1131 void
1132 InetUnicastAgentRouteTable::DeleteReq(const Peer *peer, const string &vrf_name,
1133  const IpAddress &addr, uint8_t plen,
1134  AgentRouteData *data) {
1136  req.key.reset(new InetUnicastRouteKey(peer, vrf_name, addr, plen));
1137  req.data.reset(data);
1138  InetUnicastTableEnqueue(Agent::GetInstance(), vrf_name, &req);
1139 
1140 }
1141 
1142 // Inline delete request
1143 void
1144 InetUnicastAgentRouteTable::Delete(const Peer *peer, const string &vrf_name,
1145  const IpAddress &addr, uint8_t plen) {
1147  req.key.reset(new InetUnicastRouteKey(peer, vrf_name, addr, plen));
1148  req.data.reset(NULL);
1149  InetUnicastTableProcess(Agent::GetInstance(), vrf_name, req);
1150 }
1151 
1152 void
1153 InetUnicastAgentRouteTable::Delete(const Peer *peer, const string &vrf_name,
1154  const IpAddress &addr, uint8_t plen,
1155  AgentRouteData *data) {
1157  req.key.reset(new InetUnicastRouteKey(peer, vrf_name, addr, plen));
1158  req.data.reset(data);
1159  InetUnicastTableProcess(Agent::GetInstance(), vrf_name, req);
1160 }
1161 
1162 void
1163 InetUnicastAgentRouteTable::DeleteMplsRouteReq(const Peer *peer, const string &vrf_name,
1164  const IpAddress &addr, uint8_t plen,
1165  AgentRouteData *data) {
1167  req.key.reset(new InetMplsUnicastRouteKey(peer, vrf_name, addr, plen));
1168  req.data.reset(data);
1170 }
1171 
1172 // Utility function to create a route to trap packets to agent.
1173 // Assumes that Interface-NH for "HOST Interface" is already present
1174 void
1176  const IpAddress &addr,
1177  uint8_t plen,
1178  const std::string &dest_vn_name,
1179  bool policy) {
1182  req.key.reset(new InetUnicastRouteKey(agent->local_peer(), vrf_name,
1183  addr, plen));
1184 
1185  PacketInterfaceKey intf_key(boost::uuids::nil_uuid(),
1186  agent->GetHostInterfaceName());
1187  HostRoute *data = new HostRoute(intf_key, dest_vn_name);
1188  data->set_policy(policy);
1189  req.data.reset(data);
1190 
1191  InetUnicastTableEnqueue(Agent::GetInstance(), vrf_name, &req);
1192 }
1193 
1194 // Create Route with VLAN NH
1195 void
1197  const string &vm_vrf,
1198  const IpAddress &addr,
1199  uint8_t plen,
1200  VlanNhRoute *data) {
1202  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1203  req.data.reset(data);
1205 }
1206 
1207 void
1209  const string &vm_vrf,
1210  const IpAddress &addr,
1211  uint8_t plen,
1212  const boost::uuids::uuid &intf_uuid,
1213  uint16_t tag,
1214  uint32_t label,
1215  const VnListType &dest_vn_list,
1216  const SecurityGroupList &sg_list,
1217  const TagList &tag_list,
1218  const PathPreference
1219  &path_preference) {
1220  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_uuid, "");
1221  VlanNhRoute *data = new VlanNhRoute(intf_key, tag, label, dest_vn_list,
1222  sg_list, tag_list, path_preference,
1223  peer->sequence_number());
1224  AddVlanNHRouteReq(peer, vm_vrf, addr, plen, data);
1225 }
1226 
1227 // Create Route with VLAN NH
1228 void
1230  const string &vm_vrf,
1231  const IpAddress &addr,
1232  uint8_t plen,
1233  const boost::uuids::uuid &intf_uuid,
1234  uint16_t tag,
1235  uint32_t label,
1236  const VnListType &dest_vn_list,
1237  const SecurityGroupList &sg_list,
1238  const TagList &tag_list,
1239  const PathPreference
1240  &path_preference) {
1242  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1243 
1244  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_uuid, "");
1245  req.data.reset(new VlanNhRoute(intf_key, tag, label, dest_vn_list,
1246  sg_list, tag_list, path_preference,
1247  peer->sequence_number()));
1249 }
1250 
1251 void
1253  const string &vm_vrf,
1254  const IpAddress &addr,
1255  uint8_t plen,
1256  LocalVmRoute *data) {
1258  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1259 
1260  req.data.reset(data);
1261 
1263 }
1264 
1265 void
1267  const string &vm_vrf,
1268  const IpAddress &addr,
1269  uint8_t plen,
1270  const boost::uuids::uuid &intf_uuid,
1271  const VnListType &vn_list,
1272  uint32_t label,
1273  const SecurityGroupList &sg_list,
1274  const TagList &tag_list,
1275  const CommunityList &communities,
1276  bool force_policy,
1277  const PathPreference
1278  &path_preference,
1279  const IpAddress &subnet_service_ip,
1280  const EcmpLoadBalance &ecmp_load_balance,
1281  bool is_local,
1282  bool is_health_check_service,
1283  bool native_encap,
1284  const std::string &intf_name,
1285  bool is_learnt_route)
1286 {
1287  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_uuid, intf_name);
1288  LocalVmRoute *data = new LocalVmRoute(intf_key, label,
1289  VxLanTable::kInvalidvxlan_id, force_policy,
1290  vn_list, InterfaceNHFlags::INET4, sg_list,
1291  tag_list, communities, path_preference,
1292  subnet_service_ip, ecmp_load_balance,
1293  is_local, is_health_check_service,
1294  peer->sequence_number(),
1295  false, native_encap);
1296 
1297  AddLocalVmRouteReq(peer, vm_vrf, addr, plen, data);
1298 }
1299 
1301  const string &vrf,
1302  const IpAddress &addr,
1303  uint8_t plen) {
1305 
1306  InetUnicastRouteKey *key = new InetUnicastRouteKey(peer, vrf, addr, plen);
1307  key->sub_op_ = AgentKey::RESYNC;
1308  req.key.reset(key);
1309  req.data.reset(NULL);
1311 }
1312 
1313 void
1315  const string &vm_vrf,
1316  const IpAddress &addr,
1317  uint8_t plen,
1318  ClonedLocalPath *data) {
1320  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1321  req.data.reset(data);
1323 }
1324 
1325 // Create Route for a local VM
1326 // Assumes that Interface-NH for "VM Port" is already present
1327 void
1329  const string &vm_vrf,
1330  const IpAddress &addr,
1331  uint8_t plen,
1332  const boost::uuids::uuid &intf_uuid,
1333  const VnListType &vn_list,
1334  uint32_t label,
1335  const SecurityGroupList &sg_list,
1336  const TagList &tag_list,
1337  const CommunityList &communities,
1338  bool force_policy,
1339  const PathPreference
1340  &path_preference,
1341  const IpAddress &subnet_service_ip,
1342  const EcmpLoadBalance &ecmp_load_balance,
1343  bool is_local,
1344  bool is_health_check_service,
1345  const std::string &intf_name,
1346  bool native_encap,
1347  const std::string &intf_route_type,
1348  bool is_learnt_route)
1349 {
1351  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1352 
1353  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_uuid, intf_name);
1354  req.data.reset(new LocalVmRoute(intf_key, label, VxLanTable::kInvalidvxlan_id,
1355  force_policy, vn_list,
1356  InterfaceNHFlags::INET4, sg_list, tag_list,
1357  communities, path_preference,
1358  subnet_service_ip,
1359  ecmp_load_balance, is_local,
1360  is_health_check_service,
1361  peer->sequence_number(), false, native_encap,
1362  intf_route_type,
1363  is_learnt_route));
1365 }
1366 
1367 void
1369  const string &vm_vrf,
1370  const IpAddress &vm_addr,
1371  uint8_t plen,
1372  AgentRouteData *data) {
1373  if (Agent::GetInstance()->simulate_evpn_tor())
1374  return;
1376  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, vm_addr, plen));
1377  req.data.reset(data);
1379 }
1380 
1381 void
1382 InetUnicastAgentRouteTable::AddArpReq(const string &route_vrf_name,
1383  const Ip4Address &ip,
1384  const string &nexthop_vrf_name,
1385  const Interface *intf, bool policy,
1386  const VnListType &vn_list,
1387  const SecurityGroupList &sg_list,
1388  const TagList &tag_list) {
1390  ArpNHKey key(route_vrf_name, ip, policy);
1391  NextHop *nh =
1392  static_cast<NextHop *>(agent->nexthop_table()->FindActiveEntry(&key));
1393  if (!nh) {
1395  nh_req.key.reset(new ArpNHKey(route_vrf_name, ip, policy));
1396  nh_req.data.reset(new ArpNHData(
1397  static_cast<InterfaceKey *>(intf->GetDBRequestKey().release())));
1398  agent->nexthop_table()->Enqueue(&nh_req);
1399  }
1401  rt_req.key.reset(new InetUnicastRouteKey(agent->local_peer(),
1402  route_vrf_name, ip, 32));
1403  rt_req.data.reset(new Inet4UnicastArpRoute(nexthop_vrf_name, ip, policy,
1404  vn_list, sg_list, tag_list));
1405  Inet4UnicastTableEnqueue(agent, &rt_req);
1406 }
1407 
1408 void
1410  const string &route_vrf_name,
1411  const Ip4Address &ip,
1412  const MacAddress &mac,
1413  const string &nexthop_vrf_name,
1414  const Interface &intf,
1415  bool resolved,
1416  const uint8_t plen,
1417  bool policy,
1418  const VnListType &vn_list,
1419  const SecurityGroupList &sg,
1420  const TagList &tag) {
1423  ArpNHKey *nh_key = new ArpNHKey(nexthop_vrf_name, ip, policy);
1424  if (op == DBRequest::DB_ENTRY_DELETE) {
1425  //In case of delete we want to set the
1426  //nexthop as invalid, hence use resync operation
1427  //We dont want the nexthop to created again
1428  //in case of duplicate delete
1429  nh_key->sub_op_ = AgentKey::RESYNC;
1430  }
1431  nh_req.key.reset(nh_key);
1432  ArpNHData *arp_data = new ArpNHData(mac,
1433  static_cast<InterfaceKey *>(intf.GetDBRequestKey().release()),
1434  resolved);
1435  nh_req.data.reset(arp_data);
1436 
1437  DBRequest rt_req(op);
1438  InetUnicastRouteKey *rt_key =
1439  new InetUnicastRouteKey(agent->local_peer(), route_vrf_name, ip, plen);
1440  Inet4UnicastArpRoute *data = NULL;
1441 
1442  switch(op) {
1444  agent->nexthop_table()->Enqueue(&nh_req);
1445  data = new Inet4UnicastArpRoute(nexthop_vrf_name, ip, policy,
1446  vn_list, sg, tag);
1447  break;
1448 
1450  VrfEntry *vrf = agent->vrf_table()->FindVrfFromName(route_vrf_name);
1451  InetUnicastRouteEntry *rt =
1452  static_cast<InetUnicastRouteEntry *>(vrf->
1453  GetInet4UnicastRouteTable()->Find(rt_key));
1454  assert(resolved==false);
1455  agent->nexthop_table()->Enqueue(&nh_req);
1456 
1457  // If no other route is dependent on this, remove the route; else ignore
1458  if (rt && rt->IsDependantRouteEmpty() && rt->IsTunnelNHListEmpty()) {
1459  data = new Inet4UnicastArpRoute(nexthop_vrf_name, ip, policy,
1460  vn_list, sg, tag);
1461  } else {
1462  rt_key->sub_op_ = AgentKey::RESYNC;
1464  }
1465  break;
1466  }
1467 
1468  default:
1469  assert(0);
1470  }
1471 
1472  rt_req.key.reset(rt_key);
1473  rt_req.data.reset(data);
1474  Inet4UnicastTableEnqueue(agent, &rt_req);
1475 }
1476 
1477 void
1479  const string &route_vrf_name,
1480  const IpAddress &ip,
1481  const MacAddress &mac,
1482  const string &nexthop_vrf_name,
1483  const Interface &intf,
1484  bool resolved,
1485  const uint8_t plen,
1486  bool policy,
1487  const VnListType &vn_list,
1488  const SecurityGroupList &sg,
1489  const TagList &tag) {
1492  NdpNHKey *nh_key = new NdpNHKey(nexthop_vrf_name, ip, policy);
1493  if (op == DBRequest::DB_ENTRY_DELETE) {
1494  //In case of delete we want to set the
1495  //nexthop as invalid, hence use resync operation
1496  //We dont want the nexthop to created again
1497  //in case of duplicate delete
1498  nh_key->sub_op_ = AgentKey::RESYNC;
1499  }
1500  nh_req.key.reset(nh_key);
1501  NdpNHData *ndp_data = new NdpNHData(mac,
1502  static_cast<InterfaceKey *>(intf.GetDBRequestKey().release()),
1503  resolved);
1504  nh_req.data.reset(ndp_data);
1505 
1506  DBRequest rt_req(op);
1507  InetUnicastRouteKey *rt_key =
1508  new InetUnicastRouteKey(agent->local_peer(), route_vrf_name, ip, plen);
1509  InetUnicastNdpRoute *data = NULL;
1510 
1511  switch(op) {
1513  agent->nexthop_table()->Enqueue(&nh_req);
1514  data = new InetUnicastNdpRoute(nexthop_vrf_name, ip, policy,
1515  vn_list, sg, tag);
1516  break;
1517 
1519  VrfEntry *vrf = agent->vrf_table()->FindVrfFromName(route_vrf_name);
1520  InetUnicastRouteEntry *rt =
1521  static_cast<InetUnicastRouteEntry *>(vrf->
1522  GetInet6UnicastRouteTable()->Find(rt_key));
1523  assert(resolved==false);
1524  agent->nexthop_table()->Enqueue(&nh_req);
1525 
1526  // If no other route is dependent on this, remove the route; else ignore
1527  if (rt && rt->IsDependantRouteEmpty() && rt->IsTunnelNHListEmpty()) {
1528  data = new InetUnicastNdpRoute(nexthop_vrf_name, ip, policy,
1529  vn_list, sg, tag);
1530  } else {
1531  rt_key->sub_op_ = AgentKey::RESYNC;
1533  }
1534  break;
1535  }
1536 
1537  default:
1538  assert(0);
1539  }
1540 
1541  rt_req.key.reset(rt_key);
1542  rt_req.data.reset(data);
1543  Inet6UnicastTableEnqueue(agent, route_vrf_name, &rt_req);
1544 }
1545 
1547  if (ip == Agent::GetInstance()->router_id() ||
1548  !IsIp4SubnetMember(ip, Agent::GetInstance()->router_id(),
1549  Agent::GetInstance()->vhost_prefix_len())) {
1550  // TODO: add Arp request for GW
1551  // Currently, default GW Arp is added during init
1552  return false;
1553  }
1554 
1555  return true;
1556 }
1557 
1558 void
1560  const Ip4Address &ip,
1561  const MacAddress &mac,
1562  const Interface *intf,
1563  bool resolved,
1564  const VnListType &vn_list,
1565  const SecurityGroupList &sg,
1566  const TagList &tag) {
1567  if (!ShouldAddArp(ip)) {
1568  return;
1569  }
1570  std::string nexthop_vrf = intf->vrf()->GetName();
1571  if (intf->vrf()->forwarding_vrf()) {
1572  nexthop_vrf = intf->vrf()->forwarding_vrf()->GetName();
1573  }
1574  ArpRoute(DBRequest::DB_ENTRY_ADD_CHANGE, route_vrf_name, ip, mac,
1575  nexthop_vrf, *intf, resolved, 32, false, vn_list, sg, tag);
1576 }
1577 
1578 void
1580  const Ip4Address &ip,
1581  const Interface *intf,
1582  const VnListType &vn_list,
1583  const SecurityGroupList &sg,
1584  const TagList &tag) {
1585 
1586  if (!ShouldAddArp(ip)) {
1587  return;
1588  }
1589  std::string nexthop_vrf = intf->vrf()->GetName();
1590  if (intf->vrf()->forwarding_vrf()) {
1591  nexthop_vrf = intf->vrf()->forwarding_vrf()->GetName();
1592  }
1593  AddArpReq(vrf_name, ip, nexthop_vrf, intf, false, vn_list, sg, tag);
1594 }
1595 
1597  const string &vrf_name,
1598  const Ip4Address &ip,
1599  const uint8_t plen,
1600  const InterfaceKey &intf,
1601  const uint32_t label,
1602  bool policy,
1603  const std::string &vn_name,
1604  const SecurityGroupList
1605  &sg_list,
1606  const TagList
1607  &tag_list) {
1609  ResolveNH::CreateReq(&intf, policy);
1611  req.key.reset(new InetUnicastRouteKey(peer, vrf_name, ip,
1612  plen));
1613  req.data.reset(new ResolveRoute(&intf, policy, label, vn_name, sg_list, tag_list));
1614  Inet4UnicastTableEnqueue(agent, &req);
1615 }
1616 
1617 // Create Route for a interface NH.
1618 // Used to create interface-nh pointing routes to vhost interfaces
1620  const string &vm_vrf,
1621  const Ip4Address &addr,
1622  uint8_t plen,
1623  const string &interface,
1624  uint32_t label,
1625  const VnListType &vn_list) {
1626  InetInterfaceKey intf_key(interface);
1628  (intf_key, label, TunnelType::MplsType(), vn_list,
1629  peer->sequence_number());
1630 
1631  AddInetInterfaceRouteReq(peer, vm_vrf, addr, plen, data);
1632 }
1633 
1635  const string &vm_vrf,
1636  const Ip4Address &addr,
1637  uint8_t plen,
1638  InetInterfaceRoute *data) {
1640  req.key.reset(new InetUnicastRouteKey(peer, vm_vrf, addr, plen));
1641  req.data.reset(data);
1642 
1644 }
1645 
1646 static void AddVHostRecvRouteInternal(DBRequest *req, const Peer *peer,
1647  const string &vrf,
1648  const InterfaceKey &intf_key,
1649  const IpAddress &addr, uint8_t plen,
1650  const string &vn_name, bool policy,
1651  bool native_encap) {
1653  req->key.reset(new InetUnicastRouteKey(peer, vrf, addr, plen));
1654 
1655  int tunnel_bmap = TunnelType::AllType();
1656  if (native_encap) {
1657  tunnel_bmap |= TunnelType::NativeType();
1658  }
1659 
1660  req->data.reset(new ReceiveRoute(intf_key, MplsTable::kInvalidExportLabel,
1661  tunnel_bmap, policy, vn_name));
1662 }
1663 
1664 static void AddVHostMplsRecvRouteInternal(DBRequest *req, const Peer *peer,
1665  const string &vrf,
1666  const InterfaceKey &intf_key,
1667  const IpAddress &addr, uint8_t plen,
1668  const string &vn_name, bool policy,
1669  bool native_encap) {
1671  req->key.reset(new InetMplsUnicastRouteKey(peer, vrf, addr, plen));
1672 
1673  int tunnel_bmap = TunnelType::AllType();
1674  if (native_encap) {
1675  tunnel_bmap |= TunnelType::NativeType();
1676  }
1677 
1678  req->data.reset(new ReceiveRoute(intf_key, MplsTable::kImplicitNullLabel,
1679  tunnel_bmap, policy, vn_name));
1680 }
1682  (const Peer *peer, const string &vrf, const InterfaceKey &intf_key,
1683  const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy,
1684  bool native_encap) {
1685  DBRequest req;
1686  AddVHostMplsRecvRouteInternal(&req, peer, vrf, intf_key, addr, plen,
1687  vn_name, policy, native_encap);
1689 }
1691  const string &vrf,
1692  const InterfaceKey &intf_key,
1693  const IpAddress &addr,
1694  uint8_t plen,
1695  const string &vn_name,
1696  bool policy, bool native_encap, bool ipam_host_route) {
1697  DBRequest req;
1698  AddVHostRecvRouteInternal(&req, peer, vrf, intf_key, addr, plen,
1699  vn_name, policy, native_encap);
1700  static_cast<ReceiveRoute *>(req.data.get())->SetProxyArp(true);
1701  static_cast<ReceiveRoute *>(req.data.get())->SetIpamHostRoute(ipam_host_route);
1702  if (addr.is_v4()) {
1704  } else if (addr.is_v6()) {
1706  }
1707 }
1708 
1710  (const Peer *peer, const string &vrf, const InterfaceKey &intf_key,
1711  const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy,
1712  bool native_encap) {
1713  DBRequest req;
1714  AddVHostRecvRouteInternal(&req, peer, vrf, intf_key, addr, plen,
1715  vn_name, policy, native_encap);
1716  static_cast<ReceiveRoute *>(req.data.get())->SetProxyArp(true);
1717  static_cast<ReceiveRoute *>(req.data.get())->SetIpamHostRoute(true);
1718  if (addr.is_v4()) {
1720  } else if (addr.is_v6()) {
1722  }
1723 }
1724 
1725 void
1727  const string &vrf,
1728  const InterfaceKey &intf_key,
1729  const Ip4Address &addr,
1730  uint8_t plen,
1731  const string &vn_name,
1732  bool policy) {
1733  DBRequest req;
1734  AddVHostRecvRouteInternal(&req, peer, vrf, intf_key, addr, plen,
1735  vn_name, policy, true);
1737 }
1738 
1740  const Ip4Address &addr,
1741  uint8_t plen,
1742  const string &vn_name) {
1745  req.key.reset(new InetUnicastRouteKey(agent->local_peer(), vm_vrf,
1746  Address::GetIp4SubnetAddress(addr, plen),
1747  plen));
1748  req.data.reset(new DropRoute(vn_name));
1749  Inet4UnicastTableEnqueue(agent, &req);
1750 }
1751 
1753  const Ip4Address &addr,
1754  uint8_t plen) {
1755  DeleteReq(Agent::GetInstance()->local_peer(), vm_vrf,
1756  Address::GetIp4SubnetAddress(addr, plen), 32, NULL);
1757 }
1758 
1759 static void AddGatewayRouteInternal(const Peer *peer,
1760  DBRequest *req, const string &vrf_name,
1761  const Ip4Address &dst_addr, uint8_t plen,
1762  const AddressList &gw_list,
1763  const VnListType &vn_name, uint32_t label,
1764  const SecurityGroupList &sg_list,
1765  const TagList &tag_list,
1766  const CommunityList &communities,
1767  bool native_encap) {
1769  req->key.reset(new InetUnicastRouteKey(peer,
1770  vrf_name, dst_addr, plen));
1771  req->data.reset(new Inet4UnicastGatewayRoute(gw_list, vrf_name,
1772  vn_name, label, sg_list,
1773  tag_list, communities,
1774  native_encap));
1775 }
1776 
1778  const string &vrf_name,
1779  const Ip4Address &dst_addr,
1780  uint8_t plen,
1781  const AddressList &gw_list,
1782  const VnListType &vn_name,
1783  uint32_t label,
1784  const SecurityGroupList
1785  &sg_list,
1786  const TagList
1787  &tag_list,
1788  const CommunityList
1789  &communities,
1790  bool native_encap) {
1791  DBRequest req;
1792  AddGatewayRouteInternal(peer, &req, vrf_name, dst_addr, plen, gw_list, vn_name,
1793  label, sg_list, tag_list, communities, native_encap);
1794  Inet4UnicastTableProcess(Agent::GetInstance(), vrf_name, req);
1795 }
1796 
1797 void
1799  const string &vrf_name,
1800  const Ip4Address &dst_addr,
1801  uint8_t plen,
1802  const AddressList &gw_list,
1803  const VnListType &vn_list,
1804  uint32_t label,
1805  const SecurityGroupList
1806  &sg_list,
1807  const TagList
1808  &tag_list,
1809  const CommunityList
1810  &communities,
1811  bool native_encap) {
1812  DBRequest req;
1813  AddGatewayRouteInternal(peer, &req, vrf_name, dst_addr, plen, gw_list,
1814  vn_list, label, sg_list, tag_list, communities,
1815  native_encap);
1817 }
1818 
1819 void
1821  const string &vrf_name,
1822  const IpAddress &dst_addr,
1823  uint8_t plen,
1824  AgentRouteData *data ) {
1826  req.key.reset(new InetMplsUnicastRouteKey(peer, vrf_name, dst_addr, plen));
1827  req.data.reset(data);
1829 }
1830 void
1832  const IpAddress &dst_addr,
1833  uint8_t plen,
1834  const string &vn_name) {
1835  Agent *agent_ptr = agent();
1836  AgentRouteTable *table = NULL;
1837  if (dst_addr.is_v4()) {
1838  table = agent_ptr->vrf_table()->GetInet4UnicastRouteTable(vrf_name);
1839  } else if (dst_addr.is_v6()) {
1840  table = agent_ptr->vrf_table()->GetInet6UnicastRouteTable(vrf_name);
1841  }
1842 
1843  //Add local peer path with discard NH
1845  dscd_nh_req.key.reset(new DiscardNHKey());
1846  dscd_nh_req.data.reset(NULL);
1847 
1848  DBRequest req;
1850  req.key.reset(new InetUnicastRouteKey(agent_ptr->local_peer(),
1851  vrf_name, dst_addr, plen));
1852  req.data.reset(new IpamSubnetRoute(dscd_nh_req, vn_name));
1853  if (table) {
1854  table->Process(req);
1855  }
1856 }
1857 
1858 void
1860  uint8_t plen) {
1861  /* Only IPv4 is supported */
1862  if (!dst_addr.is_v4()) {
1863  return;
1864  }
1865  const string &vrf_name = agent()->fabric_vrf_name();
1866  InetUnicastAgentRouteTable *table = NULL;
1867  table = agent()->vrf_table()->GetInet4UnicastRouteTable(vrf_name);
1868  const Peer *peer = agent()->fabric_rt_export_peer();
1869 
1870  VnListType vn_list;
1871  vn_list.insert(agent()->fabric_vn_name());
1872  const Ip4Address &gw = agent()->router_id();
1873  table->AddGatewayRoute(peer, vrf_name, dst_addr.to_v4(), plen, AddressList(1, gw), vn_list, /* PKC: Make it as a list */
1875  TagList(), CommunityList(), true);
1876 }
1877 
1878 void
1880  const Peer *peer) {
1881  /* Only IPv4 is supported */
1882  if (!vhost_addr.is_v4()) {
1883  return;
1884  }
1885  const string &vrf_name = agent()->fabric_vrf_name();
1886  InetUnicastAgentRouteTable *table = NULL;
1887  table = agent()->vrf_table()->GetInet4MplsUnicastRouteTable(vrf_name);
1888 
1889  VmInterfaceKey vmi_key(AgentKey::ADD_DEL_CHANGE, boost::uuids::nil_uuid(),
1890  agent()->vhost_interface_name());
1891  table->AddVHostMplsRecvRouteReq(peer, vrf_name, vmi_key, vhost_addr,
1892  32, agent()->fabric_vn_name(), false, false);
1893 }
1895  if (ip_addr.is_v4()) {
1896  return Address::kMaxV4PrefixLen;
1897  } else {
1898  return Address::kMaxV6PrefixLen;
1899  }
1900 }
1901 
1902 void
1904  const string &vrf_name,
1905  const Ip4Address &ip,
1906  uint8_t plen,
1907  const Interface *intrface,
1908  const string &vn_name) {
1909 
1910  assert(intrface->type() == Interface::PHYSICAL);
1912  rt_req.key.reset(new InetUnicastRouteKey(agent->local_peer(),
1913  vrf_name, ip, plen));
1914  const PhysicalInterface *phy_intf = static_cast<const PhysicalInterface *>
1915  (intrface);
1916  rt_req.data.reset(new Inet4UnicastInterfaceRoute(phy_intf, vn_name));
1917  Inet4UnicastTableEnqueue(agent, &rt_req);
1918 }
1919 
1921  const EvpnRouteEntry *evpn_route =
1922  dynamic_cast<const EvpnRouteEntry *>(route);
1923  const IpAddress &ip_addr = evpn_route->prefix_address();
1924  //No installation for evpn route with zero Ip prefix.
1925  if (ip_addr.is_unspecified())
1926  return;
1927 
1928  //label and parent-ip for NH need to be picket from parent route
1929  DBRequest req;
1931  const uint32_t plen = evpn_route->IsType5() ?
1932  evpn_route->prefix_length() : GetHostPlen(ip_addr);
1933  //Set key and data
1934  req.key.reset(new InetUnicastRouteKey(agent()->inet_evpn_peer(),
1935  evpn_route->vrf()->GetName(),
1936  ip_addr,
1937  plen));
1938  req.data.reset(new InetEvpnRouteData(evpn_route));
1939  Process(req);
1940 }
1941 
1943  const EvpnRouteEntry *evpn_route =
1944  static_cast<const EvpnRouteEntry *>(rt);
1945  const IpAddress &ip_addr = evpn_route->prefix_address();
1947  const Peer *peer = agent()->inet_evpn_peer();
1948  if (evpn_route->IsType5()) {
1949  peer = agent()->evpn_routing_peer();
1950  }
1951  const uint32_t plen = evpn_route->IsType5() ?
1952  evpn_route->prefix_length() : GetHostPlen(ip_addr);
1953  req.key.reset(new InetUnicastRouteKey(peer,
1954  evpn_route->vrf()->GetName(),
1955  ip_addr,
1956  plen));
1957  req.data.reset(new InetEvpnRouteData(evpn_route));
1958  Process(req);
1959 }
1960 
1962  uint8_t plen,
1963  const VrfEntry *vrf,
1964  const Peer *peer,
1965  const SecurityGroupList &sg_list,
1966  const CommunityList &communities,
1967  const PathPreference &path_preference,
1968  const EcmpLoadBalance &ecmp_load_balance,
1969  const TagList &tag_list,
1970  DBRequest &nh_req,
1971  uint32_t vxlan_id,
1972  const VnListType& vn_list,
1973  const std::string& origin_vn) {
1974  DBRequest req;
1976  //Set key and data
1977  req.key.reset(new InetUnicastRouteKey(peer,
1978  vrf_entry()->GetName(),
1979  ip_addr,
1980  plen));
1981  req.data.reset(new EvpnRoutingData(nh_req,
1982  sg_list,
1983  communities,
1984  path_preference,
1985  ecmp_load_balance,
1986  tag_list,
1987  vrf,
1988  vxlan_id,
1989  vn_list,
1990  origin_vn));
1991  Process(req);
1992 }
1993 
InetUnicastRouteEntry * GetNextNonConst(const InetUnicastRouteEntry *rt)
SecurityGroupList sg_list_
Definition: agent_path.h:1008
uint8_t prefix_length() const
!
static void DeleteMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
static void Inet6UnicastTableEnqueue(Agent *agent, const string &vrf_name, DBRequest *req)
const VnListType & dest_vn_list() const
Definition: agent_path.h:258
void set_communities(const CommunityList &communities)
Definition: agent_path.h:293
static void InetUnicastTableProcess(Agent *agent, const string &vrf_name, DBRequest &req)
Type type() const
Definition: interface.h:112
bool ChangeNH(Agent *agent, NextHop *nh)
Definition: agent_path.cc:119
virtual Agent::RouteTableType GetTableType() const
void set_gw_ip(const IpAddress &addr)
Definition: agent_path.h:286
bool ResyncSubnetRoutes(const InetUnicastRouteEntry *rt, bool val)
void set_unresolved(bool unresolved)
Definition: agent_path.h:285
const std::string & vrf_name() const
Definition: agent_route.cc:455
static Agent * GetInstance()
Definition: agent.h:436
static const uint8_t kMaxV6PrefixLen
Definition: address.h:22
virtual int CompareTo(const Route &rhs) const
bool IsTunnelNHListEmpty()
Definition: agent_route.h:304
static void CreateReq(const InterfaceKey *intf, bool policy)
Definition: nexthop.cc:1590
static void AddResolveRoute(const Peer *peer, const string &vrf_name, const Ip4Address &ip, const uint8_t plen, const InterfaceKey &intf_key, const uint32_t label, bool policy, const std::string &vn_name, const SecurityGroupList &sg_list, const TagList &tag_list)
static void AddVHostMplsRecvRouteReq(const Peer *peer, const string &vrf, const InterfaceKey &interface, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap)
Definition: vrf.h:86
const TagList & tag_list() const
Definition: agent_path.h:249
static void Inet4UnicastTableEnqueue(Agent *agent, DBRequest *req)
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
bool CopyArpData()
Definition: agent_path.cc:582
void AddLocalVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, LocalVmRoute *data)
InetUnicastAgentRouteTable(DB *db, const std::string &name)
uint8_t plen() const
const MacAddress & MacAddr() const
Definition: agent_path.h:1152
static void DelVHostSubnetRecvRoute(const string &vm_vrf, const Ip4Address &addr, uint8_t plen)
VrfEntry * FindVrfFromName(const string &name)
Definition: vrf.cc:873
InetUnicastAgentRouteTable * fabric_inet4_unicast_table() const
Definition: agent.h:578
NextHopTable * nexthop_table() const
Definition: agent.h:475
DBTableBase * get_table() const
Definition: db_entry.cc:119
bool ipam_subnet_route() const
const MacAddress & GetMac() const
Definition: nexthop.h:836
static void AddArpReq(const string &route_vrf_name, const Ip4Address &ip, const string &nh_vrf_name, const Interface *intf, bool policy, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list)
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
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
bool IsIp4SubnetMember(const Ip4Address &ip, const Ip4Address &prefix_ip, uint16_t plen)
Definition: address_util.cc:19
void ClearDependantRoute()
Definition: agent_path.h:314
void set_sg_list(const SecurityGroupList &sg)
Definition: agent_path.h:291
Agent::RouteTableType type_
AgentRoute * AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
const std::string & intf_route_type() const
Definition: agent_route.h:277
std::string vrf_name_
Definition: agent_path.h:1004
bool is_l3mh() const
Definition: agent.h:725
UnresolvedRouteTree::const_iterator unresolved_route_end() const
Definition: agent_route.h:140
boost::asio::ip::address IpAddress
Definition: address.h:13
uint8_t sub_op_
Definition: agent_db.h:106
virtual bool IsLess(const AgentPath &rhs) const
void EvaluateUnresolvedRoutes(void)
Definition: agent_route.cc:399
std::vector< int > SecurityGroupList
Definition: agent.h:201
static const uint32_t kInvalidExportLabel
Definition: mpls.h:102
InetEvpnRouteData(const EvpnRouteEntry *evpn_rt)
bool is_multicast() const
Definition: agent_route.h:274
Definition: route.h:14
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
InetUnicastAgentRouteTable * fabric_inet4_mpls_table() const
Definition: agent.h:589
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
virtual AgentPath * CreateAgentPath(const Peer *peer, AgentRoute *rt) const
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
InterfaceTable * interface_table() const
Definition: agent.h:465
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
boost::uuids::uuid uuid
static TypeBmap MplsType()
Definition: nexthop.h:312
static const uint8_t kMaxV4PrefixLen
Definition: address.h:20
const AgentRoute * dependant_rt() const
Definition: agent_path.h:316
InetUnicastRouteEntry * FindRoute(const IpAddress &ip)
void set_prefix_length(uint8_t new_plen)
Sets the length of a stored prefix address.
Definition: agent_route.h:378
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
Definition: nexthop.h:1639
const string & GetName() const
Definition: vrf.h:100
const MacAddress & mac() const
Definition: interface.h:131
virtual bool CanDeletePath(Agent *agent, AgentPath *path, const AgentRoute *rt) const
bool CopyNdpData()
Definition: agent_path.cc:604
bool IsLess(const Peer *rhs) const
Definition: peer.h:73
std::string parent_
Definition: agent_path.h:1179
virtual const NextHop * ComputeNextHop(Agent *agent) const
virtual bool ReComputePathDeletion(AgentPath *path)
VrfEntry * vrf() const
Definition: interface.h:115
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
Definition: address.cc:179
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
VnListType vn_list_
Definition: agent_path.h:982
Type GetType() const
Definition: nexthop.h:405
Base class for all Route entries in agent.
Definition: agent_route.h:224
static void AddVHostSubnetRecvRoute(const Peer *peer, const string &vrf, const InterfaceKey &interface, const Ip4Address &addr, uint8_t plen, const std::string &vn_name, bool policy)
static void AddVHostRecvRouteReq(const Peer *peer, const string &vrf, const InterfaceKey &interface, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap)
void DeleteEvpnRoute(const AgentRoute *rt)
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:898
Definition: ecmp.h:15
virtual KeyPtr GetDBRequestKey() const
static Ip6Address GetIp6SubnetAddress(const Ip6Address &prefix, uint16_t plen)
Definition: address.cc:200
void AddEvpnRoute(const AgentRoute *evpn_entry)
const CommunityList communities_
Definition: agent_path.h:1039
static void AddVHostRecvRoute(const Peer *peer, const string &vrf, const InterfaceKey &interface, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap, bool ipam_host_route=true)
virtual bool DBEntrySandesh(Sandesh *sresp, bool stale) const =0
const MacAddress & MacAddr() const
Definition: agent_path.h:1172
const std::string & fabric_vrf_name() const
Definition: agent.h:903
Definition: db.h:24
void AddVrouterSubnetRoute(const IpAddress &dst_addr, uint8_t plen)
virtual bool Sync(AgentRoute *sync_route)
void AddClonedLocalPathReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, ClonedLocalPath *data)
void set_tunnel_bmap(TunnelType::TypeBmap bmap)
Definition: agent_path.h:289
const AgentPath * GetActivePath() const
Definition: agent_route.cc:876
NextHop * nexthop() const
Definition: agent_path.cc:87
void Init()
Definition: db_table.cc:387
VrfEntry * vrf_entry() const
Definition: agent_route.cc:459
IpAddress prefix_address_
The prefix address.
Definition: agent_route.h:385
InetUnicastRouteEntry(VrfEntry *vrf, const IpAddress &addr, uint8_t plen, bool is_multicast)
bool IsValid() const
Definition: nexthop.h:406
void SetVrf(VrfEntry *vrf)
Definition: agent_route.h:325
void AddEvpnRoutingRoute(const IpAddress &ip_addr, uint8_t plen, const VrfEntry *vrf, const Peer *peer, const SecurityGroupList &sg_list, const CommunityList &communities, const PathPreference &path_preference, const EcmpLoadBalance &ecmp_load_balance, const TagList &tag_list, DBRequest &nh_req, uint32_t vxlan_id, const VnListType &vn_list, const std::string &origin_vn="")
static void Delete(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen)
VrfEntry * FindVrfFromId(size_t index)
Definition: vrf.cc:884
static const uint32_t kInvalidvxlan_id
Definition: vxlan.h:141
virtual AgentRouteKey * Clone() const
IpAddress GetSubnetAddress(const IpAddress &addr, uint16_t plen) const
void AddIpamSubnetRoute(const string &vm_vrf, const IpAddress &addr, uint8_t plen, const std::string &vn_name)
void AddVhostMplsRoute(const IpAddress &vhost_addr, const Peer *peer)
Definition: agent.h:358
const SecurityGroupList sg_list_
Definition: agent_path.h:1037
bool UpdateRouteFlags(bool ipam_subnet_route, bool ipam_host_route, bool proxy_arp)
bool IpamSubnetRouteAvailable() const
static void Inet4UnicastTableProcess(Agent *agent, const string &vrf_name, DBRequest &req)
const NextHop * GetActiveNextHop() const
Definition: agent_route.cc:881
bool is_subnet_discard() const
Definition: agent_path.h:273
uint32_t label() const
Definition: agent_path.h:264
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
Ip4Address router_id() const
Definition: agent.h:666
void set_vrf_name(const std::string &vrf_name)
Definition: agent_path.h:288
InetUnicastAgentRouteTable * GetInet4MplsUnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:904
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
static void AddMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &dst_addr, uint8_t plen, AgentRouteData *data)
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
Inet4UnicastInterfaceRoute(const PhysicalInterface *intrface, const std::string &vn_name)
static void NdpRoute(DBRequest::DBOperation op, const string &route_vrf_name, const IpAddress &ip, const MacAddress &mac, const string &nh_vrf_name, const Interface &intf, bool resolved, const uint8_t plen, bool policy, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list)
Definition: nexthop.h:820
DBOperation oper
Definition: db_table.h:42
const MacAddress mac_
Definition: agent_path.h:1178
static void Inet4MplsUnicastTableEnqueue(Agent *agent, DBRequest *req)
static TypeBmap AllType()
Definition: nexthop.h:321
const Peer * peer() const
Definition: agent_path.h:263
uint64_t sequence_number() const
Definition: peer.h:94
static void CheckAndAddArpRoute(const string &route_vrf_name, const Ip4Address &ip, const MacAddress &mac, const Interface *intf, bool resolved, const VnListType &vn_list, const SecurityGroupList &sg, const TagList &tag)
VnListType vn_list_
Definition: agent_path.h:1007
AgentRouteTable * GetBridgeRouteTable() const
Definition: vrf.cc:334
const Peer * local_peer() const
Definition: agent.h:1022
const bool unresolved() const
Definition: agent_path.h:271
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
Definition: agent_db.h:18
void ResetDependantRoute(AgentRoute *rt)
Definition: agent_path.h:315
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
void SetSandeshData(PathSandeshData &data) const
Definition: agent_path.cc:1720
std::vector< Ip4Address > AddressList
Definition: agent.h:217
D * LPMFind(const D *data)
Definition: patricia.h:107
void TraverseHostRoutesInSubnet(InetUnicastRouteEntry *rt, const Peer *peer)
Definition: peer.h:44
AgentPath * FindEvpnPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
void ResyncRoute(const Peer *peer, const string &vrf, const IpAddress &addr, uint8_t plen)
virtual Agent::RouteTableType GetTableType() const
std::set< std::string > VnListType
Definition: agent.h:212
static void DeleteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
static void AddDropRoute(const string &vm_vrf, const Ip4Address &addr, uint8_t plen, const string &vn_name)
static DBTableBase * CreateTable(DB *db, const std::string &name)
InetUnicastRouteEntry * GetSuperNetRoute(const IpAddress &addr)
virtual KeyPtr GetDBRequestKey() const =0
static TypeBmap NativeType()
Definition: nexthop.h:325
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
SecurityGroupList sg_list_
Definition: agent_path.h:983
VrfTable * vrf_table() const
Definition: agent.h:485
virtual KeyPtr GetDBRequestKey() const =0
static const uint32_t kImplicitNullLabel
Definition: mpls.h:105
void AddVlanNHRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, VlanNhRoute *data)
static void ArpRoute(DBRequest::DBOperation op, const string &route_vrf_name, const Ip4Address &ip, const MacAddress &mac, const string &nh_vrf_name, const Interface &intf, bool resolved, const uint8_t plen, bool policy, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list)
static void AddGatewayRouteInternal(const Peer *peer, DBRequest *req, const string &vrf_name, const Ip4Address &dst_addr, uint8_t plen, const AddressList &gw_list, const VnListType &vn_name, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool native_encap)
static void CheckAndAddArpReq(const string &vrf_name, const Ip4Address &ip, const Interface *intf, const VnListType &vn_list, const SecurityGroupList &sg, const TagList &tag)
static void Inet6UnicastTableProcess(Agent *agent, const string &vrf_name, DBRequest &req)
void set_addr(IpAddress addr)
virtual bool ReComputePathAdd(AgentPath *path)
uint8_t prefix_length() const
!
void set_tag_list(const TagList &tag)
Definition: agent_path.h:292
static void InetUnicastTableEnqueue(Agent *agent, const string &vrf, DBRequest *req)
const TagList tag_list_
Definition: agent_path.h:1038
void set_nexthop(NextHop *nh)
Definition: agent_path.cc:578
uint8_t GetHostPlen(const IpAddress &ip_addr) const
bool Update(AgentRoute *rt)
Definition: ecmp.cc:44
InetUnicastRouteEntry * GetIpamSuperNetRoute() const
const std::string & GetHostInterfaceName() const
Definition: agent.cc:93
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
InetEvpnRoutePath(const Peer *peer, const MacAddress &mac, const std::string &parent, AgentRoute *rt)
void Process(DBRequest &req)
Definition: nexthop.cc:367
void DeleteMacVmBindingRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const VmInterface *vm_intf)
static void AddGatewayRoute(const Peer *peer, const string &vrf_name, const Ip4Address &dst_addr, uint8_t plen, const AddressList &gw_list, const VnListType &vn_name, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool native_encap)
void UpdateDependantRoutes()
Definition: agent_route.cc:935
void AddInterfaceRouteReq(Agent *agent, const Peer *peer, const string &vrf_name, const Ip4Address &ip, uint8_t plen, const Interface *intrface, const std::string &vn_name)
virtual AgentPath * FindPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
const Peer * peer() const
Definition: agent_route.h:47
static void AddVHostMplsRecvRouteInternal(DBRequest *req, const Peer *peer, const string &vrf, const InterfaceKey &intf_key, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap)
const std::string & vrf_name() const
Definition: agent_route.h:46
void AddInetInterfaceRouteReq(const Peer *peer, const string &vm_vrf, const Ip4Address &addr, uint8_t plen, InetInterfaceRoute *data)
VrfEntry * forwarding_vrf() const
Definition: vrf.h:217
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
static void AddLocalVmRoute(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, const boost::uuids::uuid &intf_uuid, const VnListType &vn_list, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool force_policy, const PathPreference &path_preference, const IpAddress &subnet_service_ip, const EcmpLoadBalance &ecmp_load_balance, bool is_local, bool is_health_check_service, const std::string &intf_name, bool native_encap, const std::string &intf_route_type=VmInterface::kInterface, bool is_learnt_route=false)
VrfEntry * vrf() const
Definition: agent_route.h:275
static void AddVlanNHRoute(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, const boost::uuids::uuid &intf_uuid, uint16_t tag, uint32_t label, const VnListType &dest_vn_list, const SecurityGroupList &sg_list_, const TagList &tag_list, const PathPreference &path_preference)
void set_label(uint32_t label)
Definition: agent_path.h:282
Agent * agent() const
Definition: agent_route.h:159
bool SyncDependantRoute(const AgentRoute *sync_route)
void Process(DBRequest &req)
Definition: agent_route.cc:186
MacAddress mac_
Definition: agent_path.h:1159
const std::string & name() const
Definition: interface.h:114
const Interface * get_interface() const
Definition: nexthop.h:754
std::string vrf_name_
Definition: agent_path.h:979
virtual std::string ToString() const
static bool ShouldAddArp(const Ip4Address &ip)
const Peer * inet_evpn_peer() const
Definition: agent.h:1035
bool PolicyEnabled() const
Definition: nexthop.h:407
void set_dest_vn_list(const VnListType &dest_vn_list)
Definition: agent_path.h:283
virtual const NextHop * ComputeNextHop(Agent *agent) const
Definition: agent_path.cc:91
UnresolvedRouteTree::const_iterator unresolved_route_begin() const
Definition: agent_route.h:137
virtual AgentRouteKey * Clone() const
virtual string ToString() const
const Peer * fabric_rt_export_peer() const
Definition: agent.h:1037
bool UpdateIpamHostFlags(bool ipam_host_route)
virtual std::string ToString() const
const IpAddress & addr() const
RouteTableType
Definition: agent.h:415
uint32_t tunnel_bmap() const
Definition: agent_path.h:267
const std::string & fabric_vn_name() const
Definition: agent.h:901
void AddMacVmBindingRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const VmInterface *vm_intf, bool flood_dhcp)
bool IsDependantRouteEmpty()
Definition: agent_route.h:303
const CommunityList & communities() const
Definition: agent_path.h:250
static void AddRemoteVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &vm_addr, uint8_t plen, AgentRouteData *data)
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:922
virtual void SetKey(const DBRequestKey *key)
static void AddHostRoute(const string &vrf_name, const IpAddress &addr, uint8_t plen, const std::string &dest_vn_name, bool policy)
InetUnicastRouteEntry * FindResolveRoute(const Ip4Address &ip)
InetUnicastRouteEntry * FindRouteUsingKey(InetUnicastRouteEntry &key)
static void AddVHostRecvRouteInternal(DBRequest *req, const Peer *peer, const string &vrf, const InterfaceKey &intf_key, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap)
const SecurityGroupList & sg_list() const
Definition: agent_path.h:248
virtual const AgentPath * UsablePath() const
virtual bool DBEntrySandesh(Sandesh *sresp, bool stale) const
virtual bool AddChangePathExtended(Agent *agent, AgentPath *path, const AgentRoute *rt)
const Peer * evpn_routing_peer() const
Definition: agent.h:1027
This class defines interfaces for manipulating the prefix of a route stored in an Agent VRF table...
Definition: agent_route.h:363
const PathList & GetPathList() const
Definition: route.h:46
static void AddGatewayRouteReq(const Peer *peer, const string &vrf_name, const Ip4Address &dst_addr, uint8_t plen, const AddressList &gw_list, const VnListType &vn_name, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool native_encap)
std::vector< int > TagList
Definition: agent.h:202
std::unique_ptr< InterfaceKey > interface_key_
Definition: agent_path.h:1069