5 #include <boost/asio.hpp> 
    6 #include <boost/bind.hpp> 
   34 #include "vr_nexthop.h" 
   35 #include "vr_vrf_table.h" 
   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_) {
 
   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;
 
   68           src_addr_ = IpAddress::from_string(
"0.0.0.0", ec).to_v4();
 
  171         return "INET4_UNICAST";
 
  174         return "INET6_UNICAST";
 
  177         return "INET_MULTICAST";
 
  199         s << 
"Route Vrf : " << vrf->
GetName() << 
" ";
 
  204     s << 
" Label : " << 
label_;
 
  210         s << 
" NextHop : <NULL>";
 
  226         intf = (
static_cast<const InterfaceNH *
>(nh))->GetInterface();
 
  230         intf = (
static_cast<const VlanNH *
>(nh))->GetInterface();
 
  232         intf = (
static_cast<const ArpNH *
>(nh))->GetInterface();
 
  273     switch (
nh->GetType()) {
 
  327         if (local_vm_path != NULL) {
 
  441              FindActiveEntry(&key));
 
  445     if (old_nh != 
nh()) {
 
  451         uint32_t old_label = 
label_;
 
  458         if (
label_ != old_label) {
 
  527                                     KSyncRouteInfo &info)
 const {
 
  528     if (
type == sandesh_op::ADD) {
 
  529         info.set_operation(
"ADD/CHANGE");
 
  531         info.set_operation(
"DELETE");
 
  539         info.set_nh_idx(
nh()->nh_id());
 
  544         info.set_nh_idx(NH_DISCARD_ID);
 
  552                             char *buf, 
int buf_len) {
 
  553     vr_route_req encoder;
 
  557     encoder.set_h_op(op);
 
  558     encoder.set_rtr_rid(0);
 
  559     encoder.set_rtr_vrf_id(
vrf_id_);
 
  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);
 
  576                 LOG(ERROR, 
"Unexpected MAC stitching for route " 
  580             std::vector<int8_t> 
mac((int8_t *)
mac_,
 
  582             encoder.set_rtr_mac(
mac);
 
  585         encoder.set_rtr_family(AF_BRIDGE);
 
  587         std::vector<int8_t> 
mac((int8_t *)
mac_,
 
  589         encoder.set_rtr_mac(
mac);
 
  602             flags |= VR_RT_LABEL_VALID_FLAG;
 
  610             flags |= VR_BE_LABEL_VALID_FLAG;
 
  613             flags |= VR_BE_FLOOD_DHCP_FLAG;
 
  616             flags |= VR_BE_EVPN_CONTROL_PROCESSING_FLAG;
 
  621             flags |= VR_RT_ARP_PROXY_FLAG;
 
  625             flags |= VR_RT_ARP_TRAP_FLAG;
 
  629             flags |= VR_RT_ARP_FLOOD_FLAG;
 
  633             flags |= VR_RT_MAC_IP_LEARNT_FLAG;
 
  639         flags |= VR_BE_L2_CONTROL_DATA_FLAG;
 
  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());
 
  647         encoder.set_rtr_nh_id(NH_DISCARD_ID);
 
  650     if (op == sandesh_op::DEL) {
 
  651         encoder.set_rtr_replace_plen(replace_plen);
 
  655     encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
 
  657     assert(encode_len <= buf_len);
 
  666     return Encode(sandesh_op::ADD, 0, buf, buf_len);
 
  674     return Encode(sandesh_op::ADD, 0, buf, buf_len);
 
  691     for (
int plen = (
prefix_len() - 1); plen >= 0; plen--) {
 
  696         } 
else if (
addr_.is_v6()) {
 
  707                 ksync_nh = route->
nh();
 
  722     uint8_t new_plen = 0;
 
  724     if (new_rt == NULL) {
 
  749                                     char *buf, 
int buf_len) {
 
  755     return Encode(sandesh_op::DEL, replace_plen, buf, buf_len);
 
  785                     return mac_route_reference;
 
  797     KSyncDBObject(
"KSync Route"), ksync_(ksync), marked_delete_(false),
 
  798     table_delete_ref_(this, rt_table->
deleter()) {
 
  855     vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
 
  856     hbf_lintf_(entry->hbf_lintf()) {
 
  863     vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
 
  864     hbf_lintf_(entry->hbf_lintf()) {
 
  910                             char *buf, 
int buf_len) {
 
  914     encoder.set_h_op(op);
 
  918     encoder.set_vrf_flags(VRF_FLAG_HBF_L_VALID|VRF_FLAG_HBF_R_VALID);
 
  920     std::stringstream ss;
 
  921     ss << 
"Encoding VrfKSyncEntry, vrf_id_ " << 
vrf_id_ <<
 
  926     encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
 
  928     assert(encode_len <= buf_len);
 
  933                                     KSyncVrfInfo &info)
 const {
 
  934     if (
type == sandesh_op::ADD) {
 
  935         info.set_operation(
"ADD/CHANGE");
 
  937         info.set_operation(
"DELETE");
 
  949     return Encode(sandesh_op::ADD, 0, buf, buf_len);
 
  957     return Encode(sandesh_op::ADD, 0, buf, buf_len);
 
  965     return Encode(sandesh_op::DEL, 0, buf, buf_len);
 
  974     evpn_rt_table_listener_id_(
DBTableBase::kInvalidId) {
 
 1015     if (state == NULL) {
 
 1017         state->
seen_ = 
true;
 
 1030                           GetInet4UnicastRouteTable());
 
 1035                           GetInet6UnicastRouteTable());
 
 1040                           GetBridgeRouteTable());
 
 1048                           GetInet4MulticastRouteTable());
 
 1053                                                   GetEvpnRouteTable());
 
 1055                     "Subscribing to route table "\
 
 1066         if (
ksync->Sync(vrf) || 
ksync->IsDeleted()) {
 
 1098                                             GetEvpnRouteTable());
 
 1159         if (vn == NULL || (vn->
bridging() == 
false))
 
 1197             nh = path ? path->
nexthop() : NULL;
 
 1229                                      uint32_t ethernet_tag,
 
 1231                                      bool wait_for_traffic) {
 
 1237     IpToMacBinding::iterator it =
 
 1243         state->
ip_mac_binding_.insert(std::pair<IpToMacBindingKey, MacBinding>
 
 1244                 (std::make_pair(ip, ethernet_tag), mac_binding));
 
 1246         it->second.set_mac(path_pref, mac);
 
 1254                                      uint32_t ethernet_tag) {
 
 1260     IpToMacBinding::iterator it =
 
 1263         it->second.reset_mac(mac);
 
 1264         if (it->second.can_erase()) {
 
 1275     if (state == NULL) {
 
 1279     IpToMacBinding::const_iterator it =
 
 1282         (it->first.first != ip)) {
 
 1286     return  it->second.WaitForTraffic();
 
 1300             const ArpNH *arp_nh =
 
 1308     IpToMacBinding::const_iterator it =
 
 1311         (it->first.first != ip)) {
 
 1315     return it->second.get_mac();
 
 1320     marked_for_deletion_(false) {
 
 1329     return (state != NULL);
 
 1347                            partition) == 
false) {
 
 1354                            partition) == 
false) {
 
 1361                            partition) == 
false) {
 
 1368                            partition) == 
false) {
 
boost::asio::ip::address_v6 Ip6Address
 
boost::asio::ip::address IpAddress
 
boost::asio::ip::address_v4 Ip4Address
 
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
 
static Ip6Address GetIp6SubnetAddress(const Ip6Address &prefix, uint16_t plen)
 
bool is_health_check_service() const
 
const VnListType & dest_vn_list() const
 
NextHop * nexthop() const
 
bool IsDynamicLearntRoute()
 
uint32_t GetActiveLabel() const
 
const PathPreference & path_preference() const
 
const IpAddress & gw_ip() const
 
uint32_t vxlan_id() const
 
const Peer * peer() const
 
bool dest_vn_match(const std::string &vn) const
 
TunnelType::Type GetTunnelType() const
 
bool layer2_control_word() const
 
virtual const NextHop * ComputeNextHop(Agent *agent) const
 
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
 
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge,...
 
void ReleaseWalker(AgentRouteWalker *walker)
 
void StartRouteWalk(VrfEntry *vrf)
 
AgentRouteWalkerManager * mgr()
 
Base class for all Route entries in agent.
 
const AgentPath * GetActivePath() const
 
const NextHop * GetActiveNextHop() const
 
virtual const std::string GetAddressString() const =0
 
bool WaitForTraffic() const
 
bool is_multicast() const
 
virtual AgentPath * FindPath(const Peer *peer) const
 
virtual Agent::RouteTableType GetTableType() const =0
 
AgentPath * FindLocalVmPortPath() const
 
virtual void VrfMsgHandler(vr_vrf_req *req)=0
 
virtual void RouteMsgHandler(vr_route_req *req)=0
 
bool tsn_no_forwarding_enabled() const
 
VrfTable * vrf_table() const
 
const Peer * local_peer() const
 
const Peer * local_vm_peer() const
 
VrfEntry * fabric_vrf() const
 
NextHopTable * nexthop_table() const
 
const std::string & fabric_vrf_name() const
 
const MacAddress & GetMac() const
 
const MacVmBindingPath * FindMacVmBindingPath() const
 
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
 
DBTableBase * get_table() const
 
void ClearState(DBTableBase *tbl_base, ListenerId listener)
 
DBTablePartBase * get_table_partition() const
 
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
 
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
 
static const int kInvalidId
 
void Unregister(ListenerId listener)
 
const std::string & name() const
 
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
!
 
bool ipam_host_route() const
 
bool ipam_subnet_route() const
 
void SetDBEntry(DBEntry *db_entry)
 
void UnregisterDb(DBTableBase *table)
 
DBTableBase * GetDBTable()
 
void Notify(DBTablePartBase *partition, DBEntryBase *entry)
 
DBTableBase::ListenerId id() const
 
void RegisterDb(DBTableBase *table)
 
static const size_t kInvalidIndex
 
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)
 
VrfKSyncObject::VrfState * state_
 
KSyncRouteWalker(Agent *agent, VrfKSyncObject::VrfState *state)
 
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
 
virtual ~KSyncRouteWalker()
 
void NotifyRoutes(VrfEntry *vrf)
 
bool marked_for_deletion_
 
VrfKSyncObject * vrf_ksync_obj() const
 
NHKSyncObject * nh_ksync_obj() const
 
void Reset(LifetimeActor *actor)
 
std::string ToString() const
 
static const MacAddress & ZeroMac()
 
virtual bool flood_dhcp() const
 
NextHop::Type type() const
 
virtual std::string ToString() const
 
COMPOSITETYPE CompositeType() const
 
AgentRouteWalkerManager * agent_route_walk_manager() const
 
uint32_t preference() const
 
virtual std::string ToString() const
 
virtual int ChangeMsg(char *buf, int buf_len)
 
int DeleteInternal(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt, char *buf, int buf_len)
 
virtual ~RouteKSyncEntry()
 
const AgentPath * GetActivePath(const AgentRoute *route) const
 
const NextHop * GetActiveNextHop(const AgentRoute *route) const
 
RouteKSyncEntry(RouteKSyncObject *obj, const RouteKSyncEntry *entry, uint32_t index)
 
bool L2IsLess(const KSyncEntry &rhs) const
 
bool layer2_control_word_
 
NHKSyncEntry * nh() const
 
KSyncDBObject * GetObject() const
 
uint8_t CopyReplacementData(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt)
 
bool wait_for_traffic() const
 
uint32_t prefix_len() const
 
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
 
void set_prefix_len(uint32_t len)
 
RouteKSyncObject * ksync_obj_
 
virtual int DeleteMsg(char *buf, int buf_len)
 
virtual KSyncEntry * UnresolvedReference()
 
void FillObjectLog(sandesh_op::type op, KSyncRouteInfo &info) const
 
void set_ip(IpAddress addr)
 
bool BuildArpFlags(const DBEntry *rt, const AgentPath *path, const MacAddress &mac)
 
TunnelType::Type tunnel_type_
 
virtual bool IsLess(const KSyncEntry &rhs) const
 
virtual int AddMsg(char *buf, int buf_len)
 
bool UcIsLess(const KSyncEntry &rhs) const
 
virtual bool Sync(DBEntry *e)
 
bool McIsLess(const KSyncEntry &rhs) const
 
bool local_vm_peer_route_
 
Agent::RouteTableType rt_type_
 
virtual void EmptyTable()
 
virtual ~RouteKSyncObject()
 
RouteKSyncObject(KSync *ksync, AgentRouteTable *rt_table)
 
AgentRouteTable * rt_table_
 
virtual KSyncEntry * Alloc(const KSyncEntry *entry, uint32_t index)
 
LifetimeRef< RouteKSyncObject > table_delete_ref_
 
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *e)
 
DBFilterResp DBEntryFilter(const DBEntry *entry, const KSyncDBEntry *ksync)
 
const TunnelType & GetTunnelType() const
 
VmInterface::DeviceType device_type() const
 
bool HasServiceVlan() const
 
const string & GetName() const
 
bool layer3_forwarding() const
 
const string & GetName() const
 
const uint32_t hbf_lintf() const
 
const uint32_t hbf_rintf() const
 
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
 
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
 
const uint32_t hbf_lintf() const
 
VrfKSyncObject * ksync_obj_
 
virtual std::string ToString() const
 
virtual int ChangeMsg(char *buf, int buf_len)
 
virtual bool Sync(DBEntry *e)
 
const uint32_t vrf_id() const
 
void FillObjectLog(sandesh_op::type op, KSyncVrfInfo &info) const
 
virtual int AddMsg(char *buf, int buf_len)
 
VrfKSyncEntry(VrfKSyncObject *obj, const VrfKSyncEntry *entry, uint32_t index)
 
const uint32_t hbf_rintf() const
 
KSyncDBObject * GetObject() const
 
virtual bool IsLess(const KSyncEntry &rhs) const
 
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
 
virtual KSyncEntry * UnresolvedReference()
 
virtual int DeleteMsg(char *buf, int buf_len)
 
void VrfNotify(DBTablePartBase *partition, DBEntryBase *e)
 
virtual ~VrfKSyncObject()
 
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *entry)
 
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)
 
bool RouteNeedsMacBinding(const InetUnicastRouteEntry *rt)
 
bool GetIpMacWaitForTraffic(VrfEntry *vrf, const IpAddress &ip) const
 
void EvpnRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e)
 
DBTableBase::ListenerId vrf_listener_id_
 
VrfKSyncObject(KSync *ksync)
 
DBTableBase::ListenerId vrf_listener_id() const
 
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)
 
#define HBFTRACE(obj,...)
 
#define KSYNC_TRACE(obj, parent,...)
 
#define LOG(_Level, _Msg)
 
static std::string RouteTypeToString(Agent::RouteTableType type)
 
static bool IsGatewayOrServiceInterface(const NextHop *nh)
 
bool IsStatePresent(AgentRoute *route, DBTableBase::ListenerId id, DBTablePartBase *partition)
 
AgentRouteWalkerPtr ksync_route_walker_
 
RouteKSyncObject * inet6_uc_route_table_
 
IpToMacBinding ip_mac_binding_
 
DBTableBase::ListenerId evpn_rt_table_listener_id_
 
RouteKSyncObject * inet4_mc_route_table_
 
RouteKSyncObject * inet4_uc_route_table_
 
RouteKSyncObject * bridge_route_table_