OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
route_ksync.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/asio.hpp>
6 #include <boost/bind.hpp>
7 
8 #include <base/logging.h>
9 #include <db/db_entry.h>
10 #include <db/db_table.h>
11 #include <db/db_table_partition.h>
12 #include <ksync/ksync_index.h>
13 #include <ksync/ksync_entry.h>
14 #include <ksync/ksync_object.h>
15 #include <ksync/ksync_netlink.h>
16 #include <ksync/ksync_sock.h>
17 
18 #include "cmn/agent.h"
19 #include "oper/interface_common.h"
20 #include "oper/tunnel_nh.h"
21 #include "oper/nexthop.h"
22 #include "oper/route_common.h"
23 #include "oper/mirror_table.h"
25 #include "oper/hbf.h"
26 
30 
31 #include "ksync_init.h"
32 #include "vr_types.h"
33 #include "vr_defs.h"
34 #include "vr_nexthop.h"
35 #include "vr_vrf_table.h"
36 
38  const RouteKSyncEntry *entry,
39  uint32_t index) :
40  KSyncNetlinkDBEntry(index), ksync_obj_(obj),
41  rt_type_(entry->rt_type_), vrf_id_(entry->vrf_id_),
42  addr_(entry->addr_), src_addr_(entry->src_addr_), mac_(entry->mac_),
43  prefix_len_(entry->prefix_len_), nh_(entry->nh_), label_(entry->label_),
44  proxy_arp_(false), flood_dhcp_(entry->flood_dhcp_),
45  address_string_(entry->address_string_),
46  tunnel_type_(entry->tunnel_type_),
47  wait_for_traffic_(entry->wait_for_traffic_),
48  local_vm_peer_route_(entry->local_vm_peer_route_),
49  flood_(entry->flood_), ethernet_tag_(entry->ethernet_tag_),
50  layer2_control_word_(entry->layer2_control_word_),
51  is_learnt_route_(entry->is_learnt_route_) {
52 }
53 
55  KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj),
56  vrf_id_(rt->vrf_id()), mac_(), nh_(NULL), label_(0), proxy_arp_(false),
57  flood_dhcp_(false), tunnel_type_(TunnelType::DefaultType()),
58  wait_for_traffic_(false), local_vm_peer_route_(false),
59  flood_(false), ethernet_tag_(0), layer2_control_word_(false),
60  is_learnt_route_(false) {
61  boost::system::error_code ec;
62  rt_type_ = rt->GetTableType();
63  switch (rt_type_) {
64  case Agent::INET4_UNICAST: {
65  const InetUnicastRouteEntry *uc_rt =
66  static_cast<const InetUnicastRouteEntry *>(rt);
67  addr_ = uc_rt->prefix_address();
68  src_addr_ = IpAddress::from_string("0.0.0.0", ec).to_v4();
69  prefix_len_ = uc_rt->prefix_length();
70  AgentPath *local_vm_path = uc_rt->FindLocalVmPortPath();
71  if (local_vm_path && local_vm_path->IsDynamicLearntRoute()) {
72  is_learnt_route_ = true;
73  }
74 
75  break;
76  }
77  case Agent::INET6_UNICAST: {
78  const InetUnicastRouteEntry *uc_rt =
79  static_cast<const InetUnicastRouteEntry *>(rt);
80  addr_ = uc_rt->prefix_address();
82  prefix_len_ = uc_rt->prefix_length();
83  break;
84  }
86  const Inet4MulticastRouteEntry *mc_rt =
87  static_cast<const Inet4MulticastRouteEntry *>(rt);
88  addr_ = mc_rt->dest_ip_addr();
89  src_addr_ = mc_rt->src_ip_addr();
90  prefix_len_ = 32;
91  break;
92  }
93  case Agent::BRIDGE: {
94  const BridgeRouteEntry *l2_rt =
95  static_cast<const BridgeRouteEntry *>(rt);
96  mac_ = l2_rt->prefix_address();
97  prefix_len_ = 0;
98  break;
99  }
100  default: {
101  assert(0);
102  }
103  }
105 }
106 
108 }
109 
111  return ksync_obj_;
112 }
113 
114 bool RouteKSyncEntry::UcIsLess(const KSyncEntry &rhs) const {
115  const RouteKSyncEntry &entry = static_cast<const RouteKSyncEntry &>(rhs);
116  if (vrf_id_ != entry.vrf_id_) {
117  return vrf_id_ < entry.vrf_id_;
118  }
119 
120  if (addr_ != entry.addr_) {
121  return addr_ < entry.addr_;
122  }
123 
124  return (prefix_len_ < entry.prefix_len_);
125 }
126 
127 bool RouteKSyncEntry::McIsLess(const KSyncEntry &rhs) const {
128  const RouteKSyncEntry &entry = static_cast<const RouteKSyncEntry &>(rhs);
129  if (vrf_id_ != entry.vrf_id_) {
130  return vrf_id_ < entry.vrf_id_;
131  }
132 
133  if (src_addr_ != entry.src_addr_) {
134  return src_addr_ < entry.src_addr_;
135  }
136 
137  return (addr_ < entry.addr_);
138 }
139 
140 bool RouteKSyncEntry::L2IsLess(const KSyncEntry &rhs) const {
141  const RouteKSyncEntry &entry = static_cast<const RouteKSyncEntry &>(rhs);
142 
143  if (vrf_id_ != entry.vrf_id_) {
144  return vrf_id_ < entry.vrf_id_;
145  }
146 
147  return mac_ < entry.mac_;
148 }
149 
150 bool RouteKSyncEntry::IsLess(const KSyncEntry &rhs) const {
151  const RouteKSyncEntry &entry = static_cast<const RouteKSyncEntry &>(rhs);
152  if (rt_type_ != entry.rt_type_)
153  return rt_type_ < entry.rt_type_;
154 
155  //First unicast
156  if ((rt_type_ == Agent::INET4_UNICAST) ||
158  return UcIsLess(rhs);
159  }
160 
161  if (rt_type_ == Agent::BRIDGE) {
162  return L2IsLess(rhs);
163  }
164 
165  return McIsLess(rhs);
166 }
167 
169  switch (type) {
171  return "INET4_UNICAST";
172  break;
174  return "INET6_UNICAST";
175  break;
177  return "INET_MULTICAST";
178  break;
179  case Agent::BRIDGE:
180  return "BRIDGE";
181  break;
182  default:
183  break;
184  }
185 
186  assert(0);
187  return "";
188 }
189 
190 std::string RouteKSyncEntry::ToString() const {
191  std::stringstream s;
192  NHKSyncEntry *nexthop;
193  nexthop = nh();
194 
195  s << "Type : " << RouteTypeToString(rt_type_) << " ";
196  const VrfEntry* vrf =
198  if (vrf) {
199  s << "Route Vrf : " << vrf->GetName() << " ";
200  }
201  s << address_string_ << "/" << prefix_len_ << " Type:" << rt_type_;
202 
203 
204  s << " Label : " << label_;
205  s << " Tunnel Type: " << tunnel_type_;
206 
207  if (nexthop) {
208  s << nexthop->ToString();
209  } else {
210  s << " NextHop : <NULL>";
211  }
212 
213  s << " Mac: " << mac_.ToString();
214  s << " Flood DHCP:" << flood_dhcp_;
215  return s.str();
216 }
217 
218 // Check if NH points to a service-chain interface or a Gateway interface
219 static bool IsGatewayOrServiceInterface(const NextHop *nh) {
220  if (nh->GetType() != NextHop::INTERFACE &&
221  nh->GetType() != NextHop::VLAN && nh->GetType() != NextHop::ARP)
222  return false;
223 
224  const Interface *intf = NULL;
225  if (nh->GetType() == NextHop::INTERFACE) {
226  intf = (static_cast<const InterfaceNH *>(nh))->GetInterface();
227  if (intf->type() == Interface::PACKET)
228  return true;
229  } else if (nh->GetType() == NextHop::VLAN) {
230  intf = (static_cast<const VlanNH *>(nh))->GetInterface();
231  } else if (nh->GetType() == NextHop::ARP) {
232  intf = (static_cast<const ArpNH *>(nh))->GetInterface();
233  }
234 
235  const VmInterface *vmi = dynamic_cast<const VmInterface *>(intf);
236  if (vmi == NULL)
237  return false;
238 
239  if (vmi->HasServiceVlan())
240  return true;
242  return true;
243 
244  return false;
245 }
246 
247 // Set the flood_ and proxy_arp_ flag for the route
248 // flood_ flag says that ARP packets hitting route should be flooded
249 // proxy_arp_ flag says VRouter should do proxy ARP
250 //
251 // The flags are set based on NH and Interface-type
253  const MacAddress &mac) {
254  bool ret = false;
255 
256  //Route flags for inet4 and inet6
257  if ((rt_type_ != Agent::INET6_UNICAST) &&
259  return false;
260 
261  Agent *agent = ksync_obj_->ksync()->agent();
262  const InetUnicastRouteEntry *rt =
263  static_cast<const InetUnicastRouteEntry *>(e);
264 
265  // Assume no flood and proxy_arp by default
266  bool flood = false;
267  bool proxy_arp = false;
268  const NextHop *nh = rt->GetActiveNextHop();
269 
270  if (nh == NULL) {
271  return false;
272  }
273  switch (nh->GetType()) {
274  case NextHop::RESOLVE:
275  // RESOLVE NH can be used by Gateway Interface or Fabric VRF
276  // VRouter does not honour flood_ and proxy_arp_ flag for Fabric VRF
277  // We dont want to flood ARP on Gateway Interface
278  if (rt->vrf()->GetName() != agent->fabric_vrf_name()) {
279  proxy_arp = true;
280  }
281  break;
282 
283 
284  case NextHop::COMPOSITE:
285  // ECMP flows have composite NH. We want to do routing for ECMP flows
286  // So, set proxy_arp flag
287  proxy_arp = true;
288  break;
289 
290  case NextHop::TUNNEL:
291  {
292  // set proxy arp flag for MPLS VPN routes
293  // these routes' nexthop is either labelled tunnel or
294  // composite of labelled tunnel nexthops
295  const TunnelNH *tunnel_nh = static_cast<const TunnelNH *>(nh);
296  if (tunnel_nh->GetTunnelType().GetType() ==
298  proxy_arp = true;
299  break;
300  // other tunnel cases should be evaluated under
301  // default case
302  }
303  }
304 
305  default:
306 
307  if (mac != MacAddress::ZeroMac()) {
308  // Proxy-ARP without flood if mac-stitching is present
309  proxy_arp = true;
310  flood = false;
311  break;
312  }
313 
314  // MAC stitching not present.
315  // If interface belongs to service-chain or Gateway, we want packet to
316  // be routed. Following config ensures routing,
317  // - Enable Proxy
318  // - Disable Flood-bit
319  // - Dont do MAC Stitching (in RouteNeedsMacBinding)
320  if (IsGatewayOrServiceInterface(nh) == true) {
321  proxy_arp = true;
322  flood = false;
323  break;
324  }
325 
326  AgentPath *local_vm_path = rt->FindLocalVmPortPath();
327  if (local_vm_path != NULL) {
328  if (local_vm_path->is_health_check_service()) {
329  // for local vm path exported by health check service
330  // set proxy arp to be true to arp with vrouter MAC
331  proxy_arp = true;
332  flood = false;
333  } else {
334  // Local port without MAC stitching should only be a transition
335  // case. In the meanwhile, flood ARP so that VM can respond
336  // Note: In case VN is in L3 forwarding mode flags will be reset
337  // This is done below when VN entry is extracted.
338  proxy_arp_ = false;
339  flood = true;
340  }
341  } else {
342  // Non local-route. Set flags based on the route
343  proxy_arp = rt->proxy_arp();
344  flood = rt->ipam_host_route();
345  }
346  break;
347  }
348 
349  // There is an exception for IPAM subnet routes.
350  // IPAM subnet routes always result in flood of ARP even if the route
351  // is ECMP (resulting from gateway routes)
352  if (rt->ipam_subnet_route()) {
353  proxy_arp = false;
354  flood = true;
355  }
356 
357  // If the route crosses a VN, we want packet to be routed. So, override
358  // the flags set above and set only Proxy flag
359  // When L2 forwarding mode is disabled, reset the proxy arp to true and flood
360  // of arp to false.
361  VnEntry *vn= rt->vrf()->vn();
362  if (vn == NULL || !path->dest_vn_match(vn->GetName()) ||
363  (path->dest_vn_list().size() > 1) ||
364  (vn->bridging() == false)) {
365  proxy_arp = true;
366  flood = false;
367  }
368 
369  //If VN is running in l2 mode, then any l3 route installed should
370  //have flood flag set for ARP.
371  if (vn && (vn->layer3_forwarding() == false)) {
372  proxy_arp = false;
373  flood = true;
374  }
375 
376  // VRouter does not honour flood/proxy_arp flags for fabric-vrf
377  if (rt->vrf()->GetName() == agent->fabric_vrf_name()) {
378  if (mac != MacAddress() || nh->GetType() == NextHop::INTERFACE ||
379  nh->GetType() == NextHop::COMPOSITE) {
380  proxy_arp = true;
381  } else {
382  proxy_arp = false;
383  }
384  flood = false;
385  }
386 
387  if (proxy_arp != proxy_arp_) {
389  ret = true;
390  }
391 
392  if (flood != flood_) {
393  flood_ = flood;
394  ret = true;
395  }
396  return ret;
397 }
398 
399 //Uses internal API to extract path.
401  const AgentPath *path = GetActivePath(route);
402  if (path == NULL)
403  return NULL;
404  return path->ComputeNextHop(ksync_obj_->ksync()->agent());
405 }
406 
407 //Returns the usable path.
408 //In case of bridge tables the path contains reference path which
409 //has all the data. This path known as evpn_path is a level of indirection
410 //to leaked path from MAC+IP route.
412  const AgentPath *path = route->GetActivePath();
413  return path;
414 }
415 
417  bool ret = false;
418  Agent *agent = ksync_obj_->ksync()->agent();
419  const AgentRoute *route = static_cast<AgentRoute *>(e);
420 
421  const AgentPath *path = GetActivePath(route);
422  if (path->peer() == agent->local_vm_peer())
423  local_vm_peer_route_ = true;
424  else
425  local_vm_peer_route_ = false;
426 
427  NHKSyncObject *nh_object = ksync_obj_->ksync()->nh_ksync_obj();
428  NHKSyncEntry *old_nh = nh();
429 
430  const NextHop *tmp = NULL;
431  tmp = GetActiveNextHop(route);
432 
433  // NHs should not be delete marked here. Interface NHs are an exception. If
434  // an NH is found to be delete marked here, dont go ahead and initialize the
435  // ksync entry with a delete marked NH. Make the route ksync entry use the
436  // Discard NH's ksync entry until an update is received for the route.
437  if (tmp == NULL ||
438  ((tmp->GetType() != NextHop::INTERFACE) && tmp->IsDeleted())) {
439  DiscardNHKey key;
440  tmp = static_cast<NextHop *>(agent->nexthop_table()->
441  FindActiveEntry(&key));
442  }
443  NHKSyncEntry nexthop(nh_object, tmp);
444  nh_ = static_cast<NHKSyncEntry *>(nh_object->GetReference(&nexthop));
445  if (old_nh != nh()) {
446  ret = true;
447  }
448 
449  //Bother for label for unicast and bridge routes
451  uint32_t old_label = label_;
452 
453  if (route->is_multicast()) {
454  label_ = path->vxlan_id();
455  } else {
456  label_ = path->GetActiveLabel();
457  }
458  if (label_ != old_label) {
459  ret = true;
460  }
461 
462  if (tunnel_type_ != path->GetTunnelType()) {
463  tunnel_type_ = path->GetTunnelType();
464  ret = true;
465  }
466  }
467 
468  if (wait_for_traffic_ != route->WaitForTraffic()) {
470  ret = true;
471  }
472 
473  if (route->GetActivePath()) {
476  ret = true;
477  }
478  }
479 
482  const InetUnicastRouteEntry *uc_rt =
483  static_cast<const InetUnicastRouteEntry *>(e);
485  bool wait_for_traffic = false;
486 
487  if (obj->RouteNeedsMacBinding(uc_rt)) {
488  mac = obj->GetIpMacBinding(uc_rt->vrf(), addr_, uc_rt);
489  wait_for_traffic = obj->GetIpMacWaitForTraffic(uc_rt->vrf(), addr_);
490  }
491 
492  if (wait_for_traffic_ == false &&
493  wait_for_traffic_ != wait_for_traffic) {
495  ret = true;
496  }
497 
498  if (mac != mac_) {
499  mac_ = mac;
500  ret = true;
501  }
502 
503  if (BuildArpFlags(e, path, mac_))
504  ret = true;
505  }
506 
507  if (rt_type_ == Agent::BRIDGE) {
508  const BridgeRouteEntry *l2_rt =
509  static_cast<const BridgeRouteEntry *>(route);
510 
511  //First search for v4
512  const MacVmBindingPath *dhcp_path = l2_rt->FindMacVmBindingPath();
513  bool flood_dhcp = true; // Flood DHCP if MacVmBindingPath is not present
514  if (dhcp_path)
515  flood_dhcp = dhcp_path->flood_dhcp();
516 
517  if (flood_dhcp_ != flood_dhcp) {
519  ret = true;
520  }
521  }
522 
523  return ret;
524 }
525 
527  KSyncRouteInfo &info) const {
528  if (type == sandesh_op::ADD) {
529  info.set_operation("ADD/CHANGE");
530  } else {
531  info.set_operation("DELETE");
532  }
533 
534  info.set_addr(address_string_);
535  info.set_plen(prefix_len_);
536  info.set_vrf(vrf_id_);
537 
538  if (nh()) {
539  info.set_nh_idx(nh()->nh_id());
540  if (nh()->type() == NextHop::TUNNEL) {
541  info.set_label(label_);
542  }
543  } else {
544  info.set_nh_idx(NH_DISCARD_ID);
545  }
546 
547  info.set_mac(mac_.ToString());
548  info.set_type(RouteTypeToString(rt_type_));
549 }
550 
551 int RouteKSyncEntry::Encode(sandesh_op::type op, uint8_t replace_plen,
552  char *buf, int buf_len) {
553  vr_route_req encoder;
554  int encode_len;
555  NHKSyncEntry *nexthop = nh();
556 
557  encoder.set_h_op(op);
558  encoder.set_rtr_rid(0);
559  encoder.set_rtr_vrf_id(vrf_id_);
560  if (rt_type_ != Agent::BRIDGE) {
561  if (addr_.is_v4()) {
562  encoder.set_rtr_family(AF_INET);
563  Ip4Address::bytes_type bytes = addr_.to_v4().to_bytes();
564  std::vector<int8_t> rtr_prefix(bytes.begin(), bytes.end());
565  encoder.set_rtr_prefix(rtr_prefix);
566  } else if (addr_.is_v6()) {
567  encoder.set_rtr_family(AF_INET6);
568  Ip6Address::bytes_type bytes = addr_.to_v6().to_bytes();
569  std::vector<int8_t> rtr_prefix(bytes.begin(), bytes.end());
570  encoder.set_rtr_prefix(rtr_prefix);
571  }
572  encoder.set_rtr_prefix_len(prefix_len_);
573  if (mac_ != MacAddress::ZeroMac()) {
574  if ((addr_.is_v4() && prefix_len_ != 32) ||
575  (addr_.is_v6() && prefix_len_ != 128)) {
576  LOG(ERROR, "Unexpected MAC stitching for route "
577  << ToString());
579  }
580  std::vector<int8_t> mac((int8_t *)mac_,
581  (int8_t *)mac_ + mac_.size());
582  encoder.set_rtr_mac(mac);
583  }
584  } else {
585  encoder.set_rtr_family(AF_BRIDGE);
586  //TODO add support for mac
587  std::vector<int8_t> mac((int8_t *)mac_,
588  (int8_t *)mac_ + mac_.size());
589  encoder.set_rtr_mac(mac);
590  }
591 
592  int label = 0;
593  int flags = 0;
595  // if next hop is tunnel
596  // or nexthop is composite and composite type is LU_ECMP, then
597  // label is valid
598  if (nexthop != NULL && ((nexthop->type() == NextHop::TUNNEL) ||
599  ((nexthop->type() == NextHop::COMPOSITE) &&
600  (nexthop->CompositeType() == Composite::LU_ECMP)))) {
601  label = label_;
602  flags |= VR_RT_LABEL_VALID_FLAG;
603  }
604  }
605 
606  if (rt_type_ == Agent::BRIDGE) {
607  label = label_;
608  if (nexthop != NULL && ((nexthop->type() == NextHop::COMPOSITE) ||
609  (nexthop->type() == NextHop::TUNNEL))) {
610  flags |= VR_BE_LABEL_VALID_FLAG;
611  }
612  if (flood_dhcp_) {
613  flags |= VR_BE_FLOOD_DHCP_FLAG;
614  }
616  flags |= VR_BE_EVPN_CONTROL_PROCESSING_FLAG;
617  }
618  } else {
619 
620  if (proxy_arp_) {
621  flags |= VR_RT_ARP_PROXY_FLAG;
622  }
623 
624  if (wait_for_traffic_) {
625  flags |= VR_RT_ARP_TRAP_FLAG;
626  }
627 
628  if (flood_) {
629  flags |= VR_RT_ARP_FLOOD_FLAG;
630  }
631 
632  if (is_learnt_route_) {
633  flags |= VR_RT_MAC_IP_LEARNT_FLAG;
634  }
635 
636  }
637 
638  if (layer2_control_word_) {
639  flags |= VR_BE_L2_CONTROL_DATA_FLAG;
640  }
641 
642  encoder.set_rtr_label_flags(flags);
643  encoder.set_rtr_label(label);
644  if (nexthop != NULL) {
645  encoder.set_rtr_nh_id(nexthop->nh_id());
646  } else {
647  encoder.set_rtr_nh_id(NH_DISCARD_ID);
648  }
649 
650  if (op == sandesh_op::DEL) {
651  encoder.set_rtr_replace_plen(replace_plen);
652  }
653 
654  int error = 0;
655  encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
656  assert(error == 0);
657  assert(encode_len <= buf_len);
658  return encode_len;
659 }
660 
661 
662 int RouteKSyncEntry::AddMsg(char *buf, int buf_len) {
663  KSyncRouteInfo info;
664  FillObjectLog(sandesh_op::ADD, info);
665  KSYNC_TRACE(Route, GetObject(), info);
666  return Encode(sandesh_op::ADD, 0, buf, buf_len);
667 }
668 
669 int RouteKSyncEntry::ChangeMsg(char *buf, int buf_len){
670  KSyncRouteInfo info;
671  FillObjectLog(sandesh_op::ADD, info);
672  KSYNC_TRACE(Route, GetObject(), info);
673 
674  return Encode(sandesh_op::ADD, 0, buf, buf_len);
675 }
676 
677 int RouteKSyncEntry::DeleteMsg(char *buf, int buf_len) {
678 
680  KSyncEntry *found = NULL;
681  RouteKSyncEntry *route = NULL;
682  NHKSyncEntry *ksync_nh = NULL;
683 
684  // IF multicast or bridge delete unconditionally
685  if ((rt_type_ == Agent::BRIDGE) ||
687  return DeleteInternal(nh(), NULL, buf, buf_len);
688  }
689 
690  // For INET routes, we need to give replacement NH and prefixlen
691  for (int plen = (prefix_len() - 1); plen >= 0; plen--) {
692 
693  if (addr_.is_v4()) {
694  Ip4Address addr = Address::GetIp4SubnetAddress(addr_.to_v4(), plen);
695  key.set_ip(addr);
696  } else if (addr_.is_v6()) {
697  Ip6Address addr = Address::GetIp6SubnetAddress(addr_.to_v6(), plen);
698  key.set_ip(addr);
699  }
700 
701  key.set_prefix_len(plen);
702  found = GetObject()->Find(&key);
703 
704  if (found) {
705  route = static_cast<RouteKSyncEntry *>(found);
706  if (route->IsResolved()) {
707  ksync_nh = route->nh();
708  if(ksync_nh) {
709  return DeleteInternal(ksync_nh, route, buf, buf_len);
710  }
711  ksync_nh = NULL;
712  }
713  }
714  }
715 
716  /* If better route is not found, send discardNH for route */
717  return DeleteInternal(NULL, NULL, buf, buf_len);
718 }
719 
721  RouteKSyncEntry *new_rt) {
722  uint8_t new_plen = 0;
723  nh_ = nexthop;
724  if (new_rt == NULL) {
725  label_ = 0;
726  proxy_arp_ = false;
727  flood_ = false;
728  wait_for_traffic_ = false;
729  // mac_ is key for bridge entries and modifying it will corrut the
730  // KSync tree. So, reset mac in case of non-bridge entries only
731  if (rt_type_ != Agent::BRIDGE) {
733  }
734  is_learnt_route_ = false;
735  } else {
736  label_ = new_rt->label();
737  new_plen = new_rt->prefix_len();
738  proxy_arp_ = new_rt->proxy_arp();
739  flood_ = new_rt->flood();
741  mac_ = new_rt->mac();
742  is_learnt_route_ = new_rt->IsLearntRoute();
743  }
744  return new_plen;
745 }
746 
748  RouteKSyncEntry *new_rt,
749  char *buf, int buf_len) {
750  uint8_t replace_plen = CopyReplacementData(nexthop, new_rt);
751  KSyncRouteInfo info;
752  FillObjectLog(sandesh_op::DEL, info);
753  KSYNC_TRACE(Route, GetObject(), info);
754 
755  return Encode(sandesh_op::DEL, replace_plen, buf, buf_len);
756 }
757 
759  NHKSyncEntry *nexthop = nh();
760  if (!nexthop->IsResolved()) {
761  return nexthop;
762  }
763 
764  if ((rt_type_ == Agent::INET4_UNICAST) ||
766  if (!mac_.IsZero()) {
767  //Get Vrf and bridge ksync object
768  VrfKSyncObject *vrf_obj = ksync_obj_->ksync()->vrf_ksync_obj();
769  VrfEntry* vrf =
771  if (vrf) {
772  VrfKSyncObject::VrfState *state =
773  static_cast<VrfKSyncObject::VrfState *>
774  (vrf->GetState(vrf->get_table(),
775  vrf_obj->vrf_listener_id()));
776  RouteKSyncObject* bridge_ksync_obj = state->bridge_route_table_;
777  BridgeRouteEntry tmp_l2_rt(vrf, mac_, Peer::EVPN_PEER, false);
778  RouteKSyncEntry key(bridge_ksync_obj, &tmp_l2_rt);
779  RouteKSyncEntry *mac_route_reference =
780  static_cast<RouteKSyncEntry *>(bridge_ksync_obj->
781  GetReference(&key));
782  //Get the ksync entry for stitched mac
783  //else mark dependancy on same.
784  if (!mac_route_reference->IsResolved())
785  return mac_route_reference;
786  } else {
787  // clear the mac_ to avoid failure in programming vrouter
789  }
790  }
791  }
792 
793  return NULL;
794 }
795 
797  KSyncDBObject("KSync Route"), ksync_(ksync), marked_delete_(false),
798  table_delete_ref_(this, rt_table->deleter()) {
799  rt_table_ = rt_table;
800  RegisterDb(rt_table);
801 }
802 
805  table_delete_ref_.Reset(NULL);
806 }
807 
810  const KSyncDBEntry *ksync) {
811  const AgentRoute *route = static_cast<const AgentRoute *>(entry);
812  // Ignore Add/Change notifications when VRF is deleted
813  if (route->vrf()->IsDeleted() == true) {
814  return DBFilterIgnore;
815  }
816 
817  if (route->GetActivePath()->inactive())
818  return DBFilterIgnore;
819  return DBFilterAccept;
820 }
821 
822 KSyncEntry *RouteKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
823  const RouteKSyncEntry *route = static_cast<const RouteKSyncEntry *>(entry);
824  RouteKSyncEntry *ksync = new RouteKSyncEntry(this, route, index);
825  return static_cast<KSyncEntry *>(ksync);
826 }
827 
829  const AgentRoute *route = static_cast<const AgentRoute *>(e);
830  RouteKSyncEntry *key = new RouteKSyncEntry(this, route);
831  return static_cast<KSyncEntry *>(key);
832 }
833 
835  if (IsEmpty() == true && marked_delete_ == true) {
836  KSYNC_TRACE(Trace, this, "Destroying ksync object: "\
837  + rt_table_->name());
839  }
840 }
841 
843  marked_delete_ = true;
844  Unregister();
845 }
846 
848  if (marked_delete_ == true) {
849  Unregister();
850  }
851 }
852 
854  KSyncNetlinkDBEntry(kInvalidIndex), ksync_obj_(obj),
855  vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
856  hbf_lintf_(entry->hbf_lintf()) {
857 }
858 
860  const VrfKSyncEntry *entry,
861  uint32_t index) :
862  KSyncNetlinkDBEntry(index),
863  vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
864  hbf_lintf_(entry->hbf_lintf()) {
865  ksync_obj_ = static_cast<VrfKSyncObject*>(entry->GetObject());
866 }
867 
869 }
870 
872  return ksync_obj_;
873 }
874 
875 bool VrfKSyncEntry::IsLess(const KSyncEntry &rhs) const {
876  const VrfKSyncEntry &entry = static_cast<const VrfKSyncEntry &> (rhs);
877 
878  if (vrf_id_ == entry.vrf_id()) {
879  if (hbf_rintf_ == entry.hbf_rintf()) {
880  return (hbf_lintf_ < entry.hbf_lintf());
881  } else {
882  return (hbf_rintf_ < entry.hbf_rintf());
883  }
884  } else {
885  return (vrf_id_ < entry.vrf_id());
886  }
887 }
888 
889 std::string VrfKSyncEntry::ToString() const {
890  std::stringstream s;
891  s << "Vrf id: " << vrf_id() << " hbf lintf: " << hbf_lintf() <<
892  " hbf rintf: " << hbf_rintf();
893  return s.str();
894 }
895 
897  VrfEntry *vrf = static_cast<VrfEntry *>(e);
898 
899  if ((vrf->hbf_rintf() != hbf_rintf_) ||
900  (vrf->hbf_lintf() != hbf_lintf_)) {
901  hbf_rintf_ = vrf->hbf_rintf();
902  hbf_lintf_ = vrf->hbf_lintf();
903  return true;
904  }
905 
906  return false;
907 }
908 
909 int VrfKSyncEntry::Encode(sandesh_op::type op, uint8_t replace_plen,
910  char *buf, int buf_len) {
911  vr_vrf_req encoder;
912  int encode_len;
913 
914  encoder.set_h_op(op);
915  encoder.set_vrf_idx(vrf_id_);
916  encoder.set_vrf_hbfr_vif_idx(hbf_rintf_);
917  encoder.set_vrf_hbfl_vif_idx(hbf_lintf_);
918  encoder.set_vrf_flags(VRF_FLAG_HBF_L_VALID|VRF_FLAG_HBF_R_VALID);
919 
920  std::stringstream ss;
921  ss << "Encoding VrfKSyncEntry, vrf_id_ " << vrf_id_ <<
922  " hbf_rintf_ " << hbf_rintf_ << " hbf_lintf_ " << hbf_lintf_;
923  HBFTRACE(Trace, ss.str());
924 
925  int error = 0;
926  encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
927  assert(error == 0);
928  assert(encode_len <= buf_len);
929  return encode_len;
930 }
931 
933  KSyncVrfInfo &info) const {
934  if (type == sandesh_op::ADD) {
935  info.set_operation("ADD/CHANGE");
936  } else {
937  info.set_operation("DELETE");
938  }
939 
940  info.set_vrf_id(vrf_id_);
941  info.set_hbf_rintf(hbf_rintf_);
942  info.set_hbf_lintf(hbf_lintf_);
943 }
944 
945 int VrfKSyncEntry::AddMsg(char *buf, int buf_len) {
946  KSyncVrfInfo info;
947  FillObjectLog(sandesh_op::ADD, info);
948  KSYNC_TRACE(Vrf, GetObject(), info);
949  return Encode(sandesh_op::ADD, 0, buf, buf_len);
950 }
951 
952 int VrfKSyncEntry::ChangeMsg(char *buf, int buf_len){
953  KSyncVrfInfo info;
954  FillObjectLog(sandesh_op::ADD, info);
955  KSYNC_TRACE(Vrf, GetObject(), info);
956 
957  return Encode(sandesh_op::ADD, 0, buf, buf_len);
958 }
959 
960 int VrfKSyncEntry::DeleteMsg(char *buf, int buf_len) {
961  KSyncVrfInfo info;
962  FillObjectLog(sandesh_op::DEL, info);
963  KSYNC_TRACE(Vrf, GetObject(), info);
964 
965  return Encode(sandesh_op::DEL, 0, buf, buf_len);
966 }
967 
969  return NULL; // TODO: check this
970 }
971 
973  DBState(), seen_(false),
974  evpn_rt_table_listener_id_(DBTableBase::kInvalidId) {
975  ksync_route_walker_.reset(new KSyncRouteWalker(agent, this));
976  agent->oper_db()->agent_route_walk_manager()->
977  RegisterWalker(static_cast<AgentRouteWalker *>
978  (ksync_route_walker_.get()));
979 }
980 
981 KSyncEntry *VrfKSyncObject::Alloc(const KSyncEntry *entry, uint32_t index) {
982  const VrfKSyncEntry *vrf = static_cast<const VrfKSyncEntry *>(entry);
983  VrfKSyncEntry *ksync = new VrfKSyncEntry(this, vrf, index);
984  return static_cast<KSyncEntry *>(ksync);
985 }
986 
988  const VrfEntry *vrf = static_cast<const VrfEntry *>(e);
989  VrfKSyncEntry *key = new VrfKSyncEntry(this, vrf);
990  return static_cast<KSyncEntry *>(key);
991 }
992 
994  VrfEntry *vrf = static_cast<VrfEntry *>(e);
995  VrfState *state = static_cast<VrfState *>
996  (vrf->GetState(partition->parent(), vrf_listener_id_));
997  if (vrf->IsDeleted()) {
998  if (state) {
1000  vrf->ClearState(partition->parent(), vrf_listener_id_);
1001  (static_cast<KSyncRouteWalker *>(state->ksync_route_walker_.get()))->EnqueueDelete();
1002 
1003  if (state->ksync_->IsDeleted() == false) {
1004  if (state->ksync_->GetDBEntry() != NULL) {
1005  state->ksync_->SetDBEntry(NULL);
1006  }
1008  }
1009 
1010  delete state;
1011  }
1012  return;
1013  }
1014 
1015  if (state == NULL) {
1016  state = new VrfState(ksync_->agent());
1017  state->seen_ = true;
1018 
1019  // Create ksync entry for VRF
1020  KSyncEntry *key;
1021  key = DBToKSyncEntry(vrf);
1022  state->ksync_ = static_cast<VrfKSyncEntry *>(CreateImpl(key));
1023  delete key;
1024  vrf->SetState(partition->parent(), vrf_listener_id_, state);
1025  state->ksync_->SetDBEntry(vrf);
1027 
1028  // Get Inet4 Route table and register with KSync
1029  AgentRouteTable *rt_table = static_cast<AgentRouteTable *>(vrf->
1030  GetInet4UnicastRouteTable());
1031  state->inet4_uc_route_table_ = new RouteKSyncObject(ksync_, rt_table);
1032 
1033  // Get Inet6 Route table and register with KSync
1034  rt_table = static_cast<AgentRouteTable *>(vrf->
1035  GetInet6UnicastRouteTable());
1036  state->inet6_uc_route_table_ = new RouteKSyncObject(ksync_, rt_table);
1037 
1038  // Get Layer 2 Route table and register with KSync
1039  rt_table = static_cast<AgentRouteTable *>(vrf->
1040  GetBridgeRouteTable());
1041  state->bridge_route_table_ = new RouteKSyncObject(ksync_, rt_table);
1042 
1043  //Now for multicast table. Ksync object for multicast table is
1044  //not maintained in vrf list
1045  //TODO Enhance ksyncobject for UC/MC, currently there is only one entry
1046  //in MC so just use the UC object for time being.
1047  rt_table = static_cast<AgentRouteTable *>(vrf->
1048  GetInet4MulticastRouteTable());
1049  state->inet4_mc_route_table_ = new RouteKSyncObject(ksync_, rt_table);
1050 
1051  //Add EVPN route table listener to update IP MAC binding table.
1052  rt_table = static_cast<AgentRouteTable *>(vrf->
1053  GetEvpnRouteTable());
1055  "Subscribing to route table "\
1056  + vrf->GetName());
1059  rt_table->Register(boost::bind(&VrfKSyncObject::EvpnRouteTableNotify,
1060  this, _1, _2));
1061  }
1062  (static_cast<KSyncRouteWalker *>(state->ksync_route_walker_.get()))->
1063  NotifyRoutes(vrf);
1064  } else {
1065  VrfKSyncEntry* ksync = state->ksync_;
1066  if (ksync->Sync(vrf) || ksync->IsDeleted()) {
1068  }
1069  }
1070 }
1071 
1073  DBEntryBase *e) {
1074  const EvpnRouteEntry *evpn_rt = static_cast<const EvpnRouteEntry *>(e);
1075 
1076  if (evpn_rt->IsType5())
1077  return;
1078 
1079  if (evpn_rt->IsDeleted()) {
1080  DelIpMacBinding(evpn_rt->vrf(), evpn_rt->prefix_address(),
1081  evpn_rt->mac(), evpn_rt->ethernet_tag());
1082  } else {
1083  AddIpMacBinding(evpn_rt->vrf(), evpn_rt->prefix_address(),
1084  evpn_rt->mac(),
1085  evpn_rt->ethernet_tag(),
1086  evpn_rt->GetActivePath()->path_preference().preference(),
1087  evpn_rt->WaitForTraffic());
1088  }
1089  return;
1090 }
1091 
1093  VrfState *state) {
1095  return;
1096 
1097  AgentRouteTable *rt_table = static_cast<AgentRouteTable *>(vrf->
1098  GetEvpnRouteTable());
1099  rt_table->Unregister(state->evpn_rt_table_listener_id_);
1101 }
1102 
1104  KSyncDBObject("KSync Vrf"), ksync_(ksync), marked_delete_(false) {
1105  vrf_table_ = ksync_->agent()->vrf_table();
1106 }
1107 
1109 }
1110 
1113  (boost::bind(&VrfKSyncObject::VrfNotify, this, _1, _2));
1114 }
1115 
1118  vrf_listener_id_ = -1;
1119 }
1120 
1121 void vr_route_req::Process(SandeshContext *context) {
1122  AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1123  ioc->RouteMsgHandler(this);
1124 }
1125 
1126 void vr_vrf_req::Process(SandeshContext *context) {
1127  AgentSandeshContext *ioc = static_cast<AgentSandeshContext *>(context);
1128  ioc->VrfMsgHandler(this);
1129 }
1130 
1131 /****************************************************************************
1132  * Methods to stitch IP and MAC addresses. The KSync object maintains mapping
1133  * between IP <-> MAC in ip_mac_binding_ tree. The table is built based on
1134  * Evpn routes.
1135  *
1136  * When an Inet route is notified, if it needs MAC Stitching, the MAC to
1137  * stitch is found from the ip_mac_binding_ tree
1138  *
1139  * Any change to ip_mac_binding_ tree will also result in re-evaluation of
1140  * Inet4/Inet6 route that may potentially have stitching changed
1141  ****************************************************************************/
1142 
1143 // Compute if a route needs IP-MAC binding. A route needs IP-MAC binding if,
1144 // 1. The NH points to interface or Tunnel-NH
1145 // 2. NH does not belong to Service-Chain Interface
1146 // 3. NH does not belong to Gateway Interface
1147 // to interface or tunnel-nh
1149  if (rt->prefix_address().is_v4() && rt->prefix_length() != 32)
1150  return false;
1151 
1152  if (rt->prefix_address().is_v6() && rt->prefix_length() != 128)
1153  return false;
1154 
1155  VnEntry *vn = NULL;
1156  if (rt->vrf() != ksync_->agent()->fabric_vrf()) {
1157  //Check if VN is enabled for bridging, if not then skip mac binding.
1158  VnEntry *vn= rt->vrf()->vn();
1159  if (vn == NULL || (vn->bridging() == false))
1160  return false;
1161  }
1162 
1163  // If the route crosses a VN, we want packet to be routed. So, override
1164  const NextHop *nh = rt->GetActiveNextHop();
1165  if (nh == NULL)
1166  return false;
1167 
1168  if (nh->GetType() != NextHop::INTERFACE &&
1169  nh->GetType() != NextHop::TUNNEL &&
1170  nh->GetType() != NextHop::VLAN &&
1171  nh->GetType() != NextHop::VRF &&
1172  nh->GetType() != NextHop::ARP)
1173  return false;
1174 
1175  if (IsGatewayOrServiceInterface(nh) == true)
1176  return false;
1177 
1178  if (nh->GetType() == NextHop::ARP &&
1179  rt->GetActivePath()->gw_ip() == Ip4Address(0)) {
1180  return false;
1181  }
1182 
1183  if (nh->GetType() == NextHop::ARP && nh->IsValid() == false) {
1184  return false;
1185  }
1186 
1187  //Is this a IPAM gateway? It may happen that better path is present pointing
1188  //to tunnel. In this case IPAM gateway path will not be active path and
1189  //identifying same will be missed. Stitching has to be avoided on non-TSN
1190  //node.
1191  //This has to be done only when layer3 forwarding is enabled on VN,
1192  //else mac binding should be done irrespective of IPAM gateway.
1193  if (vn && vn->layer3_forwarding()) {
1194  const Agent *agent = ksync()->agent();
1195  if (agent->tsn_enabled() == false) {
1196  const AgentPath *path = rt->FindPath(agent->local_peer());
1197  nh = path ? path->nexthop() : NULL;
1198  }
1199  if (nh && (IsGatewayOrServiceInterface(nh) == true))
1200  return false;
1201  }
1202 
1203  return true;
1204 }
1205 
1206 // Notify change to KSync entry of InetUnicast Route
1208  const IpAddress &ip) {
1209  InetUnicastAgentRouteTable *table = NULL;
1210  if (ip.is_v4()) {
1211  table = vrf->GetInet4UnicastRouteTable();
1212  } else {
1213  table = vrf->GetInet6UnicastRouteTable();
1214  }
1215 
1216  InetUnicastRouteEntry *rt = table->FindLPM(ip);
1217  if (rt == NULL || rt->IsDeleted())
1218  return;
1219 
1220  if (rt->GetTableType() == Agent::INET4_UNICAST) {
1222  } else if (rt->GetTableType() == Agent::INET6_UNICAST) {
1224  }
1225 }
1226 
1228  const MacAddress &mac,
1229  uint32_t ethernet_tag,
1230  uint32_t pref,
1231  bool wait_for_traffic) {
1232  VrfState *state = static_cast<VrfState *>
1233  (vrf->GetState(vrf->get_table(), vrf_listener_id_));
1234  if (state == NULL)
1235  return;
1236 
1237  IpToMacBinding::iterator it =
1238  state->ip_mac_binding_.find(std::make_pair(ip, ethernet_tag));
1239 
1240  PathPreference path_pref(0, pref, wait_for_traffic, false);
1241  if (it == state->ip_mac_binding_.end()) {
1242  MacBinding mac_binding(mac, path_pref);
1243  state->ip_mac_binding_.insert(std::pair<IpToMacBindingKey, MacBinding>
1244  (std::make_pair(ip, ethernet_tag), mac_binding));
1245  } else {
1246  it->second.set_mac(path_pref, mac);
1247  }
1248 
1249  NotifyUcRoute(vrf, state, ip);
1250 }
1251 
1253  const MacAddress &mac,
1254  uint32_t ethernet_tag) {
1255  VrfState *state = static_cast<VrfState *>
1256  (vrf->GetState(vrf->get_table(), vrf_listener_id_));
1257  if (state == NULL)
1258  return;
1259 
1260  IpToMacBinding::iterator it =
1261  state->ip_mac_binding_.find(std::make_pair(ip, ethernet_tag));
1262  if (it != state->ip_mac_binding_.end()) {
1263  it->second.reset_mac(mac);
1264  if (it->second.can_erase()) {
1265  state->ip_mac_binding_.erase(std::make_pair(ip, ethernet_tag));
1266  }
1267  }
1268  NotifyUcRoute(vrf, state, ip);
1269 }
1270 
1272  const IpAddress &ip) const {
1273  VrfState *state = static_cast<VrfState *>
1274  (vrf->GetState(vrf->get_table(), vrf_listener_id_));
1275  if (state == NULL) {
1276  return false;
1277  }
1278 
1279  IpToMacBinding::const_iterator it =
1280  state->ip_mac_binding_.lower_bound(std::make_pair(ip, 0));
1281  if (it == state->ip_mac_binding_.end() ||
1282  (it->first.first != ip)) {
1283  return false;
1284  }
1285 
1286  return it->second.WaitForTraffic();
1287 }
1288 
1290  const IpAddress &ip,
1291  const InetUnicastRouteEntry *rt)
1292  const {
1293  VrfState *state = static_cast<VrfState *>
1294  (vrf->GetState(vrf->get_table(), vrf_listener_id_));
1295  if (state == NULL)
1296  return MacAddress::ZeroMac();
1297 
1298  if (vrf->GetName() == ksync_->agent()->fabric_vrf_name()) {
1299  if (rt->GetActivePath()->gw_ip() != Ip4Address(0)) {
1300  const ArpNH *arp_nh =
1301  dynamic_cast<const ArpNH *>(rt->GetActiveNextHop());
1302  if (arp_nh) {
1303  return arp_nh->GetMac();
1304  }
1305  }
1306  }
1307 
1308  IpToMacBinding::const_iterator it =
1309  state->ip_mac_binding_.lower_bound(std::make_pair(ip, 0));
1310  if (it == state->ip_mac_binding_.end() ||
1311  (it->first.first != ip)) {
1312  return MacAddress::ZeroMac();
1313  }
1314 
1315  return it->second.get_mac();
1316 }
1317 
1319  AgentRouteWalker("ksyncroutewalker", agent), state_(state),
1320  marked_for_deletion_(false) {
1321 }
1322 
1324 }
1325 
1327  DBTablePartBase *partition) {
1328  DBState *state = route->GetState(partition->parent(), id);
1329  return (state != NULL);
1330 }
1331 
1333  marked_for_deletion_ = true;
1334  mgr()->ReleaseWalker(static_cast<AgentRouteWalker *>(this));
1335 }
1336 
1338  DBEntryBase *e) {
1340  return true;
1341 
1342  AgentRoute *route = static_cast<AgentRoute *>(e);
1343 
1344  switch (route->GetTableType()) {
1345  case Agent::INET4_UNICAST: {
1347  partition) == false) {
1348  state_->inet4_uc_route_table_->Notify(partition, route);
1349  }
1350  break;
1351  }
1352  case Agent::INET6_UNICAST: {
1354  partition) == false) {
1355  state_->inet6_uc_route_table_->Notify(partition, route);
1356  }
1357  break;
1358  }
1359  case Agent::INET4_MULTICAST: {
1361  partition) == false) {
1362  state_->inet4_mc_route_table_->Notify(partition, route);
1363  }
1364  break;
1365  }
1366  case Agent::BRIDGE: {
1368  partition) == false) {
1369  state_->bridge_route_table_->Notify(partition, route);
1370  }
1371  break;
1372  }
1373  default: {
1374  break;
1375  }
1376  }
1377  return true;
1378 }
1379 
1381  if (marked_for_deletion_ == false)
1382  StartRouteWalk(vrf);
1383 }
void FillObjectLog(sandesh_op::type op, KSyncRouteInfo &info) const
Definition: route_ksync.cc:526
bool local_vm_peer_route_
Definition: route_ksync.h:87
uint8_t prefix_length() const
!
static std::string RouteTypeToString(Agent::RouteTableType type)
Definition: route_ksync.cc:168
static const MacAddress & ZeroMac()
Definition: mac_address.h:158
#define KSYNC_TRACE(obj, parent,...)
Definition: ksync_object.h:304
AgentPath * FindLocalVmPortPath() const
Definition: agent_route.cc:742
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
Definition: route_ksync.cc:551
KSyncDBObject * GetObject() const
Definition: route_ksync.cc:871
bool inactive() const
Definition: agent_path.h:420
virtual std::string ToString() const
Definition: route_ksync.cc:889
const VnListType & dest_vn_list() const
Definition: agent_path.h:258
virtual bool IsLess(const KSyncEntry &rhs) const
Definition: route_ksync.cc:875
DBEntry * GetDBEntry()
Definition: ksync_entry.h:253
#define HBFTRACE(obj,...)
Definition: hbf.h:17
Type type() const
Definition: interface.h:112
virtual bool Sync(DBEntry *e)
Definition: route_ksync.cc:896
uint32_t label_
Definition: route_ksync.h:80
bool tsn_enabled() const
Definition: agent.h:1162
bool HasServiceVlan() const
uint32_t vrf_id_
Definition: route_ksync.h:74
void RegisterDb(DBTableBase *table)
Definition: vrf.h:86
const PathPreference & path_preference() const
Definition: agent_path.h:329
const AgentPath * GetActivePath(const AgentRoute *route) const
Definition: route_ksync.cc:411
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
bool IsResolved()
VrfEntry * fabric_vrf() const
Definition: agent.h:915
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
MacAddress mac_
Definition: route_ksync.h:77
virtual const std::string GetAddressString() const =0
void FillObjectLog(sandesh_op::type op, KSyncVrfInfo &info) const
Definition: route_ksync.cc:932
NextHopTable * nexthop_table() const
Definition: agent.h:475
VrfKSyncObject * ksync_obj_
Definition: route_ksync.h:213
DBTableBase * get_table() const
Definition: db_entry.cc:119
bool ipam_subnet_route() const
const MacAddress & GetMac() const
Definition: nexthop.h:836
Agent * agent() const
Definition: ksync_init.h:39
bool WaitForTraffic() const
Definition: agent_route.cc:971
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
const Ip4Address & dest_ip_addr() const
uint32_t preference() const
Definition: agent_path.h:41
VmInterface::DeviceType device_type() const
bool IsDeleted() const
Definition: db_entry.h:49
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
const uint32_t vrf_id() const
Definition: route_ksync.h:196
boost::asio::ip::address IpAddress
Definition: address.h:13
Type GetType() const
Definition: nexthop.h:303
virtual KSyncEntry * Alloc(const KSyncEntry *entry, uint32_t index)
Definition: route_ksync.cc:981
AgentRouteWalkerPtr ksync_route_walker_
Definition: route_ksync.h:237
VrfKSyncObject(KSync *ksync)
uint32_t nh_id() const
Definition: nexthop_ksync.h:58
RouteKSyncObject * inet4_uc_route_table_
Definition: route_ksync.h:231
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
Definition: route_ksync.cc:909
int ListenerId
Definition: db_table.h:62
bool is_multicast() const
Definition: agent_route.h:274
Definition: route.h:14
void RegisterDBClients()
bool wait_for_traffic_
Definition: route_ksync.h:86
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
DBTableBase * parent()
RouteKSyncObject * bridge_route_table_
Definition: route_ksync.h:234
DBTableBase::ListenerId vrf_listener_id() const
Definition: route_ksync.h:266
void VrfNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: route_ksync.cc:993
KSyncDBObject * GetObject() const
Definition: route_ksync.cc:110
bool IsDynamicLearntRoute()
Definition: agent_path.h:439
DBTableBase::ListenerId evpn_rt_table_listener_id_
Definition: route_ksync.h:236
static size_t size()
Definition: mac_address.h:57
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
Definition: vrf.cc:338
const string & GetName() const
Definition: vrf.h:100
NHKSyncEntry * nh() const
Definition: route_ksync.h:40
virtual KSyncEntry * UnresolvedReference()
Definition: route_ksync.cc:758
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
Definition: address.cc:179
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *e)
Definition: route_ksync.cc:828
static void Unregister(KSyncObject *)
void set_prefix_len(uint32_t len)
Definition: route_ksync.h:43
Type GetType() const
Definition: nexthop.h:405
Base class for all Route entries in agent.
Definition: agent_route.h:224
Agent::RouteTableType rt_type_
Definition: route_ksync.h:73
const uint32_t hbf_lintf() const
Definition: route_ksync.h:195
NextHop::Type type() const
Definition: nexthop_ksync.h:35
bool wait_for_traffic() const
Definition: route_ksync.h:38
virtual int DeleteMsg(char *buf, int buf_len)
Definition: route_ksync.cc:960
uint32_t prefix_len_
Definition: route_ksync.h:78
void Unregister(ListenerId listener)
Definition: db_table.cc:186
bool GetIpMacWaitForTraffic(VrfEntry *vrf, const IpAddress &ip) const
IpToMacBinding ip_mac_binding_
Definition: route_ksync.h:235
OperDB * oper_db() const
Definition: agent.cc:1013
static Ip6Address GetIp6SubnetAddress(const Ip6Address &prefix, uint16_t plen)
Definition: address.cc:200
std::string ToString() const
Definition: mac_address.cc:53
uint32_t ethernet_tag() const
const uint32_t hbf_rintf() const
Definition: vrf.h:143
KSyncEntryPtr nh_
Definition: route_ksync.h:79
virtual std::string ToString() const
void set_ip(IpAddress addr)
Definition: route_ksync.h:44
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
const std::string & fabric_vrf_name() const
Definition: agent.h:903
bool is_learnt_route_
Definition: route_ksync.h:91
bool layer2_control_word() const
Definition: agent_path.h:396
const AgentPath * GetActivePath() const
Definition: agent_route.cc:876
RouteKSyncObject(KSync *ksync, AgentRouteTable *rt_table)
Definition: route_ksync.cc:796
NextHop * nexthop() const
Definition: agent_path.cc:87
TunnelType::Type GetTunnelType() const
Definition: agent_path.h:276
bool RouteNeedsMacBinding(const InetUnicastRouteEntry *rt)
const NextHop * GetActiveNextHop(const AgentRoute *route) const
Definition: route_ksync.cc:400
virtual Agent::RouteTableType GetTableType() const =0
bool tsn_no_forwarding_enabled() const
Definition: agent.h:1158
bool proxy_arp() const
Definition: route_ksync.h:35
KSyncRouteWalker(Agent *agent, VrfKSyncObject::VrfState *state)
VrfTable * vrf_table_
Definition: route_ksync.h:274
bool flood() const
Definition: route_ksync.h:36
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *entry)
Definition: route_ksync.cc:987
KSyncEntry * CreateImpl(const KSyncEntry *key)
bool McIsLess(const KSyncEntry &rhs) const
Definition: route_ksync.cc:127
bool IsValid() const
Definition: nexthop.h:406
VrfKSyncEntry(VrfKSyncObject *obj, const VrfKSyncEntry *entry, uint32_t index)
Definition: route_ksync.cc:859
VrfEntry * FindVrfFromId(size_t index)
Definition: vrf.cc:884
bool BuildArpFlags(const DBEntry *rt, const AgentPath *path, const MacAddress &mac)
Definition: route_ksync.cc:252
bool IsZero() const
Definition: mac_address.cc:29
virtual void VrfMsgHandler(vr_vrf_req *req)=0
uint8_t type
Definition: load_balance.h:109
void NotifyUcRoute(VrfEntry *vrf, VrfState *state, const IpAddress &ip)
Definition: agent.h:358
virtual bool IsLess(const KSyncEntry &rhs) const
Definition: route_ksync.cc:150
NHKSyncObject * nh_ksync_obj() const
Definition: ksync_init.h:43
AgentRouteWalkerManager * agent_route_walk_manager() const
Definition: operdb_init.h:91
const IpAddress & gw_ip() const
Definition: agent_path.h:268
void Reset(LifetimeActor *actor)
Definition: lifetime.h:82
const TunnelType & GetTunnelType() const
Definition: tunnel_nh.h:42
DBTableBase::ListenerId id() const
Definition: ksync_object.h:256
const NextHop * GetActiveNextHop() const
Definition: agent_route.cc:881
RouteKSyncObject * ksync_obj_
Definition: route_ksync.h:72
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
DBTableBase * GetDBTable()
Definition: ksync_object.h:244
DBTableBase::ListenerId vrf_listener_id_
Definition: route_ksync.h:272
VrfKSyncEntry * ksync_
Definition: route_ksync.h:238
Definition: nexthop.h:820
RouteKSyncEntry(RouteKSyncObject *obj, const RouteKSyncEntry *entry, uint32_t index)
Definition: route_ksync.cc:37
bool is_health_check_service() const
Definition: agent_path.h:380
Definition: trace.h:220
void EvpnRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e)
VrfKSyncObject::VrfState * state_
Definition: route_ksync.h:289
DBFilterResp DBEntryFilter(const DBEntry *entry, const KSyncDBEntry *ksync)
Definition: route_ksync.cc:809
const Peer * peer() const
Definition: agent_path.h:263
bool UcIsLess(const KSyncEntry &rhs) const
Definition: route_ksync.cc:114
KSync * ksync() const
Definition: route_ksync.h:112
static const size_t kInvalidIndex
Definition: ksync_entry.h:69
void Notify(DBTablePartBase *partition, DBEntryBase *entry)
void NotifyEvent(KSyncEntry *entry, KSyncEntry::KSyncEvent event)
const Peer * local_peer() const
Definition: agent.h:1022
virtual ~VrfKSyncObject()
MacAddress GetIpMacBinding(VrfEntry *vrf, const IpAddress &ip, const InetUnicastRouteEntry *rt) const
void StartRouteWalk(VrfEntry *vrf)
AgentRouteWalkerManager * mgr()
const std::string & name() const
Definition: db_table.h:110
uint32_t hbf_rintf_
Definition: route_ksync.h:215
KSyncEntry * Find(const KSyncEntry *key)
Definition: ksync_object.cc:99
void DelIpMacBinding(VrfEntry *vrf, const IpAddress &ip, const MacAddress &mac, uint32_t ethernet_tag)
virtual Agent::RouteTableType GetTableType() const
const uint32_t hbf_rintf() const
Definition: route_ksync.h:194
uint32_t vrf_id_
Definition: route_ksync.h:214
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
bool IsEmpty(void)
Definition: ksync_object.h:138
KSyncEntry * GetReference(const KSyncEntry *key)
const MacAddress & mac() const
virtual ~RouteKSyncEntry()
Definition: route_ksync.cc:107
virtual std::string ToString() const
Definition: route_ksync.cc:190
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
void AddIpMacBinding(VrfEntry *vrf, const IpAddress &ip, const MacAddress &mac, uint32_t ethernet_tag, uint32_t pref, bool wait_for_traffic)
Definition: vn.h:151
uint32_t GetActiveLabel() const
Definition: agent_path.cc:79
VrfTable * vrf_table() const
Definition: agent.h:485
IpAddress src_addr_
Definition: route_ksync.h:76
bool IsDeleted()
Definition: ksync_entry.h:163
void ReleaseWalker(AgentRouteWalker *walker)
LifetimeRef< RouteKSyncObject > table_delete_ref_
Definition: route_ksync.h:125
bool IsStatePresent(AgentRoute *route, DBTableBase::ListenerId id, DBTablePartBase *partition)
bool layer2_control_word_
Definition: route_ksync.h:90
virtual void RouteMsgHandler(vr_route_req *req)=0
uint32_t label() const
Definition: route_ksync.h:34
bool layer3_forwarding() const
Definition: vn.h:192
AgentRouteTable * rt_table_
Definition: route_ksync.h:124
virtual int ChangeMsg(char *buf, int buf_len)
Definition: route_ksync.cc:669
VnEntry * vn() const
Definition: vrf.h:101
bool IsLearntRoute()
Definition: route_ksync.h:59
bool dest_vn_match(const std::string &vn) const
Definition: agent_path.cc:1809
static const int kInvalidId
Definition: db_table.h:64
virtual ~KSyncRouteWalker()
virtual int AddMsg(char *buf, int buf_len)
Definition: route_ksync.cc:945
bool flood_dhcp() const
Definition: route_ksync.h:37
virtual bool flood_dhcp() const
Definition: agent_path.h:1094
#define LOG(_Level, _Msg)
Definition: logging.h:33
MacAddress mac() const
Definition: route_ksync.h:39
void UnregisterDb(DBTableBase *table)
VrfEntry * vrf() const
Definition: agent_route.h:275
virtual bool Sync(DBEntry *e)
Definition: route_ksync.cc:416
const MacVmBindingPath * FindMacVmBindingPath() const
IpAddress addr_
Definition: route_ksync.h:75
virtual ~VrfKSyncEntry()
Definition: route_ksync.cc:868
const Peer * local_vm_peer() const
Definition: agent.h:1023
virtual const NextHop * ComputeNextHop(Agent *agent) const
Definition: agent_path.cc:91
KSync * ksync() const
Definition: route_ksync.h:244
VrfKSyncObject * vrf_ksync_obj() const
Definition: ksync_init.h:49
const string & GetName() const
Definition: vn.h:162
uint8_t CopyReplacementData(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt)
Definition: route_ksync.cc:720
virtual void EmptyTable()
Definition: route_ksync.cc:847
DBTablePartBase * get_table_partition() const
Definition: db_entry.cc:115
virtual KSyncEntry * UnresolvedReference()
Definition: route_ksync.cc:968
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
bool L2IsLess(const KSyncEntry &rhs) const
Definition: route_ksync.cc:140
RouteTableType
Definition: agent.h:415
COMPOSITETYPE CompositeType() const
Definition: nexthop_ksync.h:70
bool bridging() const
Definition: vn.h:191
virtual KSyncEntry * Alloc(const KSyncEntry *entry, uint32_t index)
Definition: route_ksync.cc:822
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:864
uint32_t prefix_len() const
Definition: route_ksync.h:33
virtual int DeleteMsg(char *buf, int buf_len)
Definition: route_ksync.cc:677
RouteKSyncObject * inet6_uc_route_table_
Definition: route_ksync.h:233
bool marked_for_deletion_
Definition: route_ksync.h:290
uint32_t hbf_lintf_
Definition: route_ksync.h:216
string address_string_
Definition: route_ksync.h:84
RouteKSyncObject * inet4_mc_route_table_
Definition: route_ksync.h:232
void UnRegisterEvpnRouteTableListener(const VrfEntry *entry, VrfState *state)
static bool IsGatewayOrServiceInterface(const NextHop *nh)
Definition: route_ksync.cc:219
uint32_t vxlan_id() const
Definition: agent_path.h:265
void SetDBEntry(DBEntry *db_entry)
Definition: ksync_entry.h:252
const uint32_t hbf_lintf() const
Definition: vrf.h:144
virtual int AddMsg(char *buf, int buf_len)
Definition: route_ksync.cc:662
void NotifyRoutes(VrfEntry *vrf)
KSync * ksync_
Definition: route_ksync.h:271
TunnelType::Type tunnel_type_
Definition: route_ksync.h:85
virtual ~RouteKSyncObject()
Definition: route_ksync.cc:803
virtual int ChangeMsg(char *buf, int buf_len)
Definition: route_ksync.cc:952
int DeleteInternal(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt, char *buf, int buf_len)
Definition: route_ksync.cc:747
const Ip4Address & src_ip_addr() const