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