6 #include <boost/asio.hpp>
7 #include <boost/bind/bind.hpp>
35 #include "vr_nexthop.h"
36 #include "vr_vrf_table.h"
38 using namespace boost::placeholders;
44 rt_type_(entry->rt_type_), vrf_id_(entry->vrf_id_),
45 addr_(entry->addr_), src_addr_(entry->src_addr_), mac_(entry->mac_),
46 prefix_len_(entry->prefix_len_), nh_(entry->nh_), label_(entry->label_),
47 proxy_arp_(false), flood_dhcp_(entry->flood_dhcp_),
48 address_string_(entry->address_string_),
49 tunnel_type_(entry->tunnel_type_),
50 wait_for_traffic_(entry->wait_for_traffic_),
51 local_vm_peer_route_(entry->local_vm_peer_route_),
52 flood_(entry->flood_), ethernet_tag_(entry->ethernet_tag_),
53 layer2_control_word_(entry->layer2_control_word_),
54 is_learnt_route_(entry->is_learnt_route_) {
59 vrf_id_(rt->vrf_id()), mac_(), nh_(NULL), label_(0), proxy_arp_(false),
60 flood_dhcp_(false), tunnel_type_(
TunnelType::DefaultType()),
61 wait_for_traffic_(false), local_vm_peer_route_(false),
62 flood_(false), ethernet_tag_(0), layer2_control_word_(false),
63 is_learnt_route_(false) {
64 boost::system::error_code ec;
71 src_addr_ = IpAddress::from_string(
"0.0.0.0", ec).to_v4();
174 return "INET4_UNICAST";
177 return "INET6_UNICAST";
180 return "INET_MULTICAST";
202 s <<
"Route Vrf : " << vrf->
GetName() <<
" ";
207 s <<
" Label : " <<
label_;
213 s <<
" NextHop : <NULL>";
229 intf = (
static_cast<const InterfaceNH *
>(nh))->GetInterface();
233 intf = (
static_cast<const VlanNH *
>(nh))->GetInterface();
235 intf = (
static_cast<const ArpNH *
>(nh))->GetInterface();
276 switch (
nh->GetType()) {
330 if (local_vm_path != NULL) {
444 FindActiveEntry(&key));
448 if (old_nh !=
nh()) {
454 uint32_t old_label =
label_;
461 if (
label_ != old_label) {
530 KSyncRouteInfo &info)
const {
531 if (
type == sandesh_op::ADD) {
532 info.set_operation(
"ADD/CHANGE");
534 info.set_operation(
"DELETE");
542 info.set_nh_idx(
nh()->nh_id());
547 info.set_nh_idx(NH_DISCARD_ID);
555 char *buf,
int buf_len) {
556 vr_route_req encoder;
560 encoder.set_h_op(op);
561 encoder.set_rtr_rid(0);
562 encoder.set_rtr_vrf_id(
vrf_id_);
565 encoder.set_rtr_family(AF_INET);
566 Ip4Address::bytes_type bytes =
addr_.to_v4().to_bytes();
567 std::vector<int8_t> rtr_prefix(bytes.begin(), bytes.end());
568 encoder.set_rtr_prefix(rtr_prefix);
569 }
else if (
addr_.is_v6()) {
570 encoder.set_rtr_family(AF_INET6);
571 Ip6Address::bytes_type bytes =
addr_.to_v6().to_bytes();
572 std::vector<int8_t> rtr_prefix(bytes.begin(), bytes.end());
573 encoder.set_rtr_prefix(rtr_prefix);
579 LOG(ERROR,
"Unexpected MAC stitching for route "
583 std::vector<int8_t>
mac((int8_t *)
mac_,
585 encoder.set_rtr_mac(
mac);
588 encoder.set_rtr_family(AF_BRIDGE);
590 std::vector<int8_t>
mac((int8_t *)
mac_,
592 encoder.set_rtr_mac(
mac);
605 flags |= VR_RT_LABEL_VALID_FLAG;
613 flags |= VR_BE_LABEL_VALID_FLAG;
616 flags |= VR_BE_FLOOD_DHCP_FLAG;
619 flags |= VR_BE_EVPN_CONTROL_PROCESSING_FLAG;
624 flags |= VR_RT_ARP_PROXY_FLAG;
628 flags |= VR_RT_ARP_TRAP_FLAG;
632 flags |= VR_RT_ARP_FLOOD_FLAG;
636 flags |= VR_RT_MAC_IP_LEARNT_FLAG;
642 flags |= VR_BE_L2_CONTROL_DATA_FLAG;
645 encoder.set_rtr_label_flags(flags);
646 encoder.set_rtr_label(
label);
647 if (nexthop != NULL) {
648 encoder.set_rtr_nh_id(nexthop->
nh_id());
650 encoder.set_rtr_nh_id(NH_DISCARD_ID);
653 if (op == sandesh_op::DEL) {
654 encoder.set_rtr_replace_plen(replace_plen);
658 encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
660 assert(encode_len <= buf_len);
669 return Encode(sandesh_op::ADD, 0, buf, buf_len);
677 return Encode(sandesh_op::ADD, 0, buf, buf_len);
694 for (
int plen = (
prefix_len() - 1); plen >= 0; plen--) {
699 }
else if (
addr_.is_v6()) {
710 ksync_nh = route->
nh();
725 uint8_t new_plen = 0;
727 if (new_rt == NULL) {
752 char *buf,
int buf_len) {
758 return Encode(sandesh_op::DEL, replace_plen, buf, buf_len);
788 return mac_route_reference;
800 KSyncDBObject(
"KSync Route"), ksync_(ksync), marked_delete_(false),
801 table_delete_ref_(this, rt_table->
deleter()) {
858 vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
859 hbf_lintf_(entry->hbf_lintf()) {
866 vrf_id_(entry->vrf_id()), hbf_rintf_(entry->hbf_rintf()),
867 hbf_lintf_(entry->hbf_lintf()) {
913 char *buf,
int buf_len) {
917 encoder.set_h_op(op);
921 encoder.set_vrf_flags(VRF_FLAG_HBF_L_VALID|VRF_FLAG_HBF_R_VALID);
923 std::stringstream ss;
924 ss <<
"Encoding VrfKSyncEntry, vrf_id_ " <<
vrf_id_ <<
929 encode_len = encoder.WriteBinary((uint8_t *)buf, buf_len, &error);
931 assert(encode_len <= buf_len);
936 KSyncVrfInfo &info)
const {
937 if (
type == sandesh_op::ADD) {
938 info.set_operation(
"ADD/CHANGE");
940 info.set_operation(
"DELETE");
952 return Encode(sandesh_op::ADD, 0, buf, buf_len);
960 return Encode(sandesh_op::ADD, 0, buf, buf_len);
968 return Encode(sandesh_op::DEL, 0, buf, buf_len);
977 evpn_rt_table_listener_id_(
DBTableBase::kInvalidId) {
1018 if (state == NULL) {
1020 state->
seen_ =
true;
1033 GetInet4UnicastRouteTable());
1038 GetInet6UnicastRouteTable());
1043 GetBridgeRouteTable());
1051 GetInet4MulticastRouteTable());
1056 GetEvpnRouteTable());
1058 "Subscribing to route table "\
1069 if (
ksync->Sync(vrf) ||
ksync->IsDeleted()) {
1101 GetEvpnRouteTable());
1162 if (vn == NULL || (vn->
bridging() ==
false))
1200 nh = path ? path->
nexthop() : NULL;
1232 uint32_t ethernet_tag,
1234 bool wait_for_traffic) {
1240 IpToMacBinding::iterator it =
1246 state->
ip_mac_binding_.insert(std::pair<IpToMacBindingKey, MacBinding>
1247 (std::make_pair(ip, ethernet_tag), mac_binding));
1249 it->second.set_mac(path_pref, mac);
1257 uint32_t ethernet_tag) {
1263 IpToMacBinding::iterator it =
1266 it->second.reset_mac(mac);
1267 if (it->second.can_erase()) {
1278 if (state == NULL) {
1282 IpToMacBinding::const_iterator it =
1285 (it->first.first != ip)) {
1289 return it->second.WaitForTraffic();
1303 const ArpNH *arp_nh =
1311 IpToMacBinding::const_iterator it =
1314 (it->first.first != ip)) {
1318 return it->second.get_mac();
1323 marked_for_deletion_(false) {
1332 return (state != NULL);
1350 partition) ==
false) {
1357 partition) ==
false) {
1364 partition) ==
false) {
1371 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)
bool IsResolvedAndInSync()
True only when the entry is resolved AND kernel-acknowledged (IN_SYNC).
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_