5 #include <boost/asio.hpp>
6 #include <boost/bind/bind.hpp>
34 #include "vr_nexthop.h"
35 #include "vr_vrf_table.h"
37 using namespace boost::placeholders;
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_) {
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;
70 src_addr_ = IpAddress::from_string(
"0.0.0.0", ec).to_v4();
173 return "INET4_UNICAST";
176 return "INET6_UNICAST";
179 return "INET_MULTICAST";
201 s <<
"Route Vrf : " << vrf->
GetName() <<
" ";
206 s <<
" Label : " <<
label_;
212 s <<
" NextHop : <NULL>";
228 intf = (
static_cast<const InterfaceNH *
>(nh))->GetInterface();
232 intf = (
static_cast<const VlanNH *
>(nh))->GetInterface();
234 intf = (
static_cast<const ArpNH *
>(nh))->GetInterface();
275 switch (
nh->GetType()) {
329 if (local_vm_path != NULL) {
443 FindActiveEntry(&key));
447 if (old_nh !=
nh()) {
453 uint32_t old_label =
label_;
460 if (
label_ != old_label) {
529 KSyncRouteInfo &info)
const {
530 if (
type == sandesh_op::ADD) {
531 info.set_operation(
"ADD/CHANGE");
533 info.set_operation(
"DELETE");
541 info.set_nh_idx(
nh()->nh_id());
546 info.set_nh_idx(NH_DISCARD_ID);
554 char *buf,
int buf_len) {
555 vr_route_req encoder;
559 encoder.set_h_op(op);
560 encoder.set_rtr_rid(0);
561 encoder.set_rtr_vrf_id(
vrf_id_);
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);
578 LOG(ERROR,
"Unexpected MAC stitching for route "
582 std::vector<int8_t>
mac((int8_t *)
mac_,
584 encoder.set_rtr_mac(
mac);
587 encoder.set_rtr_family(AF_BRIDGE);
589 std::vector<int8_t>
mac((int8_t *)
mac_,
591 encoder.set_rtr_mac(
mac);
604 flags |= VR_RT_LABEL_VALID_FLAG;
612 flags |= VR_BE_LABEL_VALID_FLAG;
615 flags |= VR_BE_FLOOD_DHCP_FLAG;
618 flags |= VR_BE_EVPN_CONTROL_PROCESSING_FLAG;
623 flags |= VR_RT_ARP_PROXY_FLAG;
627 flags |= VR_RT_ARP_TRAP_FLAG;
631 flags |= VR_RT_ARP_FLOOD_FLAG;
635 flags |= VR_RT_MAC_IP_LEARNT_FLAG;
641 flags |= VR_BE_L2_CONTROL_DATA_FLAG;
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());
649 encoder.set_rtr_nh_id(NH_DISCARD_ID);
652 if (op == sandesh_op::DEL) {
653 encoder.set_rtr_replace_plen(replace_plen);
657 encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
659 assert(encode_len <= buf_len);
668 return Encode(sandesh_op::ADD, 0, buf, buf_len);
676 return Encode(sandesh_op::ADD, 0, buf, buf_len);
693 for (
int plen = (
prefix_len() - 1); plen >= 0; plen--) {
698 }
else if (
addr_.is_v6()) {
709 ksync_nh = route->
nh();
724 uint8_t new_plen = 0;
726 if (new_rt == NULL) {
751 char *buf,
int buf_len) {
757 return Encode(sandesh_op::DEL, replace_plen, buf, buf_len);
787 return mac_route_reference;
799 KSyncDBObject(
"KSync Route"), ksync_(ksync), marked_delete_(false),
800 table_delete_ref_(this, rt_table->
deleter()) {
857 vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
858 hbf_lintf_(entry->hbf_lintf()) {
865 vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
866 hbf_lintf_(entry->hbf_lintf()) {
912 char *buf,
int buf_len) {
916 encoder.set_h_op(op);
920 encoder.set_vrf_flags(VRF_FLAG_HBF_L_VALID|VRF_FLAG_HBF_R_VALID);
922 std::stringstream ss;
923 ss <<
"Encoding VrfKSyncEntry, vrf_id_ " <<
vrf_id_ <<
928 encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
930 assert(encode_len <= buf_len);
935 KSyncVrfInfo &info)
const {
936 if (
type == sandesh_op::ADD) {
937 info.set_operation(
"ADD/CHANGE");
939 info.set_operation(
"DELETE");
951 return Encode(sandesh_op::ADD, 0, buf, buf_len);
959 return Encode(sandesh_op::ADD, 0, buf, buf_len);
967 return Encode(sandesh_op::DEL, 0, buf, buf_len);
976 evpn_rt_table_listener_id_(
DBTableBase::kInvalidId) {
1017 if (state == NULL) {
1019 state->
seen_ =
true;
1032 GetInet4UnicastRouteTable());
1037 GetInet6UnicastRouteTable());
1042 GetBridgeRouteTable());
1050 GetInet4MulticastRouteTable());
1055 GetEvpnRouteTable());
1057 "Subscribing to route table "\
1068 if (
ksync->Sync(vrf) ||
ksync->IsDeleted()) {
1100 GetEvpnRouteTable());
1161 if (vn == NULL || (vn->
bridging() ==
false))
1199 nh = path ? path->
nexthop() : NULL;
1231 uint32_t ethernet_tag,
1233 bool wait_for_traffic) {
1239 IpToMacBinding::iterator it =
1245 state->
ip_mac_binding_.insert(std::pair<IpToMacBindingKey, MacBinding>
1246 (std::make_pair(ip, ethernet_tag), mac_binding));
1248 it->second.set_mac(path_pref, mac);
1256 uint32_t ethernet_tag) {
1262 IpToMacBinding::iterator it =
1265 it->second.reset_mac(mac);
1266 if (it->second.can_erase()) {
1277 if (state == NULL) {
1281 IpToMacBinding::const_iterator it =
1284 (it->first.first != ip)) {
1288 return it->second.WaitForTraffic();
1302 const ArpNH *arp_nh =
1310 IpToMacBinding::const_iterator it =
1313 (it->first.first != ip)) {
1317 return it->second.get_mac();
1322 marked_for_deletion_(false) {
1331 return (state != NULL);
1349 partition) ==
false) {
1356 partition) ==
false) {
1363 partition) ==
false) {
1370 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_