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();
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) {
977 RegisterWalker(static_cast<AgentRouteWalker *>
1015 if (state == NULL) {
1017 state->
seen_ =
true;
1030 GetInet4UnicastRouteTable());
1035 GetInet6UnicastRouteTable());
1040 GetBridgeRouteTable());
1048 GetInet4MulticastRouteTable());
1053 GetEvpnRouteTable());
1055 "Subscribing to route table "\
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) {
void FillObjectLog(sandesh_op::type op, KSyncRouteInfo &info) const
bool local_vm_peer_route_
uint8_t prefix_length() const
!
static std::string RouteTypeToString(Agent::RouteTableType type)
static const MacAddress & ZeroMac()
#define KSYNC_TRACE(obj, parent,...)
AgentPath * FindLocalVmPortPath() const
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
KSyncDBObject * GetObject() const
virtual std::string ToString() const
const VnListType & dest_vn_list() const
virtual bool IsLess(const KSyncEntry &rhs) const
#define HBFTRACE(obj,...)
virtual bool Sync(DBEntry *e)
bool HasServiceVlan() const
void RegisterDb(DBTableBase *table)
const PathPreference & path_preference() const
const AgentPath * GetActivePath(const AgentRoute *route) const
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
VrfEntry * fabric_vrf() const
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
virtual const std::string GetAddressString() const =0
void FillObjectLog(sandesh_op::type op, KSyncVrfInfo &info) const
NextHopTable * nexthop_table() const
VrfKSyncObject * ksync_obj_
DBTableBase * get_table() const
bool ipam_subnet_route() const
const MacAddress & GetMac() const
bool WaitForTraffic() const
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.
const Ip4Address & dest_ip_addr() const
uint32_t preference() const
VmInterface::DeviceType device_type() const
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
const uint32_t vrf_id() const
boost::asio::ip::address IpAddress
virtual KSyncEntry * Alloc(const KSyncEntry *entry, uint32_t index)
AgentRouteWalkerPtr ksync_route_walker_
VrfKSyncObject(KSync *ksync)
RouteKSyncObject * inet4_uc_route_table_
int Encode(sandesh_op::type op, uint8_t replace_plen, char *buf, int buf_len)
bool is_multicast() const
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
RouteKSyncObject * bridge_route_table_
DBTableBase::ListenerId vrf_listener_id() const
void VrfNotify(DBTablePartBase *partition, DBEntryBase *e)
KSyncDBObject * GetObject() const
bool IsDynamicLearntRoute()
DBTableBase::ListenerId evpn_rt_table_listener_id_
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
const string & GetName() const
NHKSyncEntry * nh() const
virtual KSyncEntry * UnresolvedReference()
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *e)
static void Unregister(KSyncObject *)
void set_prefix_len(uint32_t len)
Base class for all Route entries in agent.
Agent::RouteTableType rt_type_
const uint32_t hbf_lintf() const
NextHop::Type type() const
bool wait_for_traffic() const
virtual int DeleteMsg(char *buf, int buf_len)
void Unregister(ListenerId listener)
bool GetIpMacWaitForTraffic(VrfEntry *vrf, const IpAddress &ip) const
IpToMacBinding ip_mac_binding_
static Ip6Address GetIp6SubnetAddress(const Ip6Address &prefix, uint16_t plen)
std::string ToString() const
uint32_t ethernet_tag() const
const uint32_t hbf_rintf() const
virtual std::string ToString() const
void set_ip(IpAddress addr)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
const std::string & fabric_vrf_name() const
bool layer2_control_word() const
const AgentPath * GetActivePath() const
RouteKSyncObject(KSync *ksync, AgentRouteTable *rt_table)
NextHop * nexthop() const
TunnelType::Type GetTunnelType() const
bool RouteNeedsMacBinding(const InetUnicastRouteEntry *rt)
const NextHop * GetActiveNextHop(const AgentRoute *route) const
virtual Agent::RouteTableType GetTableType() const =0
bool tsn_no_forwarding_enabled() const
KSyncRouteWalker(Agent *agent, VrfKSyncObject::VrfState *state)
virtual KSyncEntry * DBToKSyncEntry(const DBEntry *entry)
KSyncEntry * CreateImpl(const KSyncEntry *key)
bool McIsLess(const KSyncEntry &rhs) const
VrfKSyncEntry(VrfKSyncObject *obj, const VrfKSyncEntry *entry, uint32_t index)
VrfEntry * FindVrfFromId(size_t index)
bool BuildArpFlags(const DBEntry *rt, const AgentPath *path, const MacAddress &mac)
virtual void VrfMsgHandler(vr_vrf_req *req)=0
void NotifyUcRoute(VrfEntry *vrf, VrfState *state, const IpAddress &ip)
virtual bool IsLess(const KSyncEntry &rhs) const
NHKSyncObject * nh_ksync_obj() const
AgentRouteWalkerManager * agent_route_walk_manager() const
const IpAddress & gw_ip() const
void Reset(LifetimeActor *actor)
const TunnelType & GetTunnelType() const
DBTableBase::ListenerId id() const
const NextHop * GetActiveNextHop() const
RouteKSyncObject * ksync_obj_
boost::asio::ip::address_v6 Ip6Address
DBTableBase * GetDBTable()
DBTableBase::ListenerId vrf_listener_id_
RouteKSyncEntry(RouteKSyncObject *obj, const RouteKSyncEntry *entry, uint32_t index)
bool is_health_check_service() const
void EvpnRouteTableNotify(DBTablePartBase *partition, DBEntryBase *e)
VrfKSyncObject::VrfState * state_
DBFilterResp DBEntryFilter(const DBEntry *entry, const KSyncDBEntry *ksync)
const Peer * peer() const
bool UcIsLess(const KSyncEntry &rhs) const
bool ipam_host_route() const
static const size_t kInvalidIndex
void Notify(DBTablePartBase *partition, DBEntryBase *entry)
void NotifyEvent(KSyncEntry *entry, KSyncEntry::KSyncEvent event)
const Peer * local_peer() const
virtual ~VrfKSyncObject()
MacAddress GetIpMacBinding(VrfEntry *vrf, const IpAddress &ip, const InetUnicastRouteEntry *rt) const
void StartRouteWalk(VrfEntry *vrf)
AgentRouteWalkerManager * mgr()
const std::string & name() const
KSyncEntry * Find(const KSyncEntry *key)
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
void ClearState(DBTableBase *tbl_base, ListenerId listener)
KSyncEntry * GetReference(const KSyncEntry *key)
const MacAddress & mac() const
virtual ~RouteKSyncEntry()
virtual std::string ToString() const
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
boost::asio::ip::address_v4 Ip4Address
void AddIpMacBinding(VrfEntry *vrf, const IpAddress &ip, const MacAddress &mac, uint32_t ethernet_tag, uint32_t pref, bool wait_for_traffic)
uint32_t GetActiveLabel() const
VrfTable * vrf_table() const
void ReleaseWalker(AgentRouteWalker *walker)
LifetimeRef< RouteKSyncObject > table_delete_ref_
bool IsStatePresent(AgentRoute *route, DBTableBase::ListenerId id, DBTablePartBase *partition)
bool layer2_control_word_
virtual void RouteMsgHandler(vr_route_req *req)=0
bool layer3_forwarding() const
AgentRouteTable * rt_table_
virtual int ChangeMsg(char *buf, int buf_len)
bool dest_vn_match(const std::string &vn) const
static const int kInvalidId
virtual ~KSyncRouteWalker()
virtual int AddMsg(char *buf, int buf_len)
virtual bool flood_dhcp() const
#define LOG(_Level, _Msg)
void UnregisterDb(DBTableBase *table)
virtual bool Sync(DBEntry *e)
const MacVmBindingPath * FindMacVmBindingPath() const
const Peer * local_vm_peer() const
virtual const NextHop * ComputeNextHop(Agent *agent) const
VrfKSyncObject * vrf_ksync_obj() const
const string & GetName() const
uint8_t CopyReplacementData(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt)
virtual void EmptyTable()
DBTablePartBase * get_table_partition() const
virtual KSyncEntry * UnresolvedReference()
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
bool L2IsLess(const KSyncEntry &rhs) const
COMPOSITETYPE CompositeType() const
virtual KSyncEntry * Alloc(const KSyncEntry *entry, uint32_t index)
virtual AgentPath * FindPath(const Peer *peer) const
uint32_t prefix_len() const
virtual int DeleteMsg(char *buf, int buf_len)
RouteKSyncObject * inet6_uc_route_table_
bool marked_for_deletion_
RouteKSyncObject * inet4_mc_route_table_
void UnRegisterEvpnRouteTableListener(const VrfEntry *entry, VrfState *state)
static bool IsGatewayOrServiceInterface(const NextHop *nh)
uint32_t vxlan_id() const
void SetDBEntry(DBEntry *db_entry)
const uint32_t hbf_lintf() const
virtual int AddMsg(char *buf, int buf_len)
void NotifyRoutes(VrfEntry *vrf)
TunnelType::Type tunnel_type_
virtual ~RouteKSyncObject()
virtual int ChangeMsg(char *buf, int buf_len)
int DeleteInternal(NHKSyncEntry *nexthop, RouteKSyncEntry *new_rt, char *buf, int buf_len)
const Ip4Address & src_ip_addr() const