From 6635abfd2956a863f907d2b98c94a37ff3e65277 Mon Sep 17 00:00:00 2001 From: Nischal Sheth Date: Tue, 26 Jan 2016 14:03:55 -0800 Subject: [PATCH] Display list of secondary tables for a primary path Change-Id: I88f099d0eb2491879d24b88feee98159e9d18091 Closes-Bug: 1496698 --- src/bgp/bgp_peer.sandesh | 1 + src/bgp/bgp_route.cc | 9 ++++ src/bgp/bgp_server.h | 13 +++++- .../routing-instance/routepath_replicator.cc | 41 ++++++++++++++++++- .../routing-instance/routepath_replicator.h | 6 ++- src/bgp/routing-instance/static_route.cc | 13 +++++- src/bgp/routing-instance/static_route.sandesh | 3 +- src/net/address.cc | 18 ++++++++ src/net/address.h | 1 + 9 files changed, 97 insertions(+), 8 deletions(-) diff --git a/src/bgp/bgp_peer.sandesh b/src/bgp/bgp_peer.sandesh index fd393108f24..8282d672f5c 100644 --- a/src/bgp/bgp_peer.sandesh +++ b/src/bgp/bgp_peer.sandesh @@ -145,6 +145,7 @@ struct ShowRoutePath { 12: u32 label; 13: bool replicated; 14: string primary_table (link="ShowRouteReq"); + 24: list secondary_tables; 15: list communities; 16: string origin_vn; 17: u32 flags; diff --git a/src/bgp/bgp_route.cc b/src/bgp/bgp_route.cc index 5aafcf9c94f..be46b9448fa 100644 --- a/src/bgp/bgp_route.cc +++ b/src/bgp/bgp_route.cc @@ -14,6 +14,7 @@ #include "bgp/extended-community/mac_mobility.h" #include "bgp/extended-community/site_of_origin.h" #include "bgp/origin-vn/origin_vn.h" +#include "bgp/routing-instance/routepath_replicator.h" #include "bgp/routing-instance/routing_instance.h" #include "bgp/security_group/security_group.h" #include "bgp/tunnel_encap/tunnel_encap.h" @@ -462,6 +463,14 @@ void BgpRoute::FillRouteInfo(const BgpTable *table, srp.set_primary_table(replicated->src_table()->name()); } else { srp.set_replicated(false); + Address::Family vpn_family = + Address::VpnFamilyFromFamily(table->family()); + const RoutePathReplicator *replicator = + table->server()->replicator(vpn_family); + if (replicator) { + srp.set_secondary_tables( + replicator->GetReplicatedTableNameList(table, this, path)); + } } if (attr->cluster_list()) { FillRoutePathClusterListInfo(attr->cluster_list(), &srp); diff --git a/src/bgp/bgp_server.h b/src/bgp/bgp_server.h index 0b4d03d378f..f76609e3a3a 100644 --- a/src/bgp/bgp_server.h +++ b/src/bgp/bgp_server.h @@ -119,8 +119,17 @@ class BgpServer { return ermvpn_replicator_.get(); if (family == Address::INET6VPN) return inet6vpn_replicator_.get(); - - assert(false); + return NULL; + } + const RoutePathReplicator *replicator(Address::Family family) const { + if (family == Address::INETVPN) + return inetvpn_replicator_.get(); + if (family == Address::EVPN) + return evpn_replicator_.get(); + if (family == Address::ERMVPN) + return ermvpn_replicator_.get(); + if (family == Address::INET6VPN) + return inet6vpn_replicator_.get(); return NULL; } diff --git a/src/bgp/routing-instance/routepath_replicator.cc b/src/bgp/routing-instance/routepath_replicator.cc index bf0a2d510d0..e07a0d4a3d4 100644 --- a/src/bgp/routing-instance/routepath_replicator.cc +++ b/src/bgp/routing-instance/routepath_replicator.cc @@ -20,6 +20,7 @@ using std::ostringstream; using std::make_pair; using std::pair; using std::string; +using std::vector; // // RoutePathReplication trace macro. Optionally logs the server name as well for @@ -134,6 +135,25 @@ void RtReplicated::DeleteRouteInfo(BgpTable *table, BgpRoute *rt, replicate_list_.erase(it); } +// +// Return the list of secondary table names for the given primary path. +// We go through all SecondaryRouteInfos and skip the ones that don't +// match the primary path. +// +vector RtReplicated::GetTableNameList(const BgpPath *path) const { + vector table_list; + BOOST_FOREACH(const SecondaryRouteInfo &rinfo, replicate_list_) { + if (rinfo.peer_ != path->GetPeer()) + continue; + if (rinfo.path_id_ != path->GetPathId()) + continue; + if (rinfo.src_ != path->GetSource()) + continue; + table_list.push_back(rinfo.table_->name()); + } + return table_list; +} + RoutePathReplicator::RoutePathReplicator(BgpServer *server, Address::Family family) : server_(server), @@ -206,8 +226,10 @@ TableState *RoutePathReplicator::FindTableState(BgpTable *table) { return (loc != table_state_list_.end() ? loc->second : NULL); } -const TableState *RoutePathReplicator::FindTableState(BgpTable *table) const { - TableStateList::const_iterator loc = table_state_list_.find(table); +const TableState *RoutePathReplicator::FindTableState( + const BgpTable *table) const { + TableStateList::const_iterator loc = + table_state_list_.find(const_cast(table)); return (loc != table_state_list_.end() ? loc->second : NULL); } @@ -628,6 +650,21 @@ const RtReplicated *RoutePathReplicator::GetReplicationState( return dbstate; } +// +// Return the list of secondary table names for the given primary path. +// +vector RoutePathReplicator::GetReplicatedTableNameList( + const BgpTable *table, const BgpRoute *rt, const BgpPath *path) const { + const TableState *ts = FindTableState(table); + if (!ts) + return vector(); + const RtReplicated *dbstate = static_cast( + rt->GetState(table, ts->listener_id())); + if (!dbstate) + return vector(); + return dbstate->GetTableNameList(path); +} + void RoutePathReplicator::DeleteSecondaryPath(BgpTable *table, BgpRoute *rt, const RtReplicated::SecondaryRouteInfo &rtinfo) { BgpRoute *rt_secondary = rtinfo.rt_; diff --git a/src/bgp/routing-instance/routepath_replicator.h b/src/bgp/routing-instance/routepath_replicator.h index 29ea2b9da19..fc00a4ffd6e 100644 --- a/src/bgp/routing-instance/routepath_replicator.h +++ b/src/bgp/routing-instance/routepath_replicator.h @@ -194,6 +194,7 @@ class RtReplicated : public DBState { const ReplicatedRtPathList &GetList() const { return replicate_list_; } ReplicatedRtPathList *GetMutableList() { return &replicate_list_; } + std::vector GetTableNameList(const BgpPath *path) const; private: RoutePathReplicator *replicator_; @@ -269,6 +270,9 @@ class RoutePathReplicator { const RtReplicated *GetReplicationState(BgpTable *table, BgpRoute *rt) const; + std::vector GetReplicatedTableNameList(const BgpTable *table, + const BgpRoute *route, const BgpPath *path) const; + SandeshTraceBufferPtr trace_buffer() const { return trace_buf_; } private: @@ -290,7 +294,7 @@ class RoutePathReplicator { void DeleteTableState(BgpTable *table); void UnregisterTableState(BgpTable *table); TableState *FindTableState(BgpTable *table); - const TableState *FindTableState(BgpTable *table) const; + const TableState *FindTableState(const BgpTable *table) const; void JoinVpnTable(RtGroup *group); void LeaveVpnTable(RtGroup *group); diff --git a/src/bgp/routing-instance/static_route.cc b/src/bgp/routing-instance/static_route.cc index dfe3034d886..f6a636da090 100644 --- a/src/bgp/routing-instance/static_route.cc +++ b/src/bgp/routing-instance/static_route.cc @@ -14,6 +14,7 @@ #include "bgp/bgp_log.h" #include "bgp/inet6vpn/inet6vpn_route.h" #include "bgp/l3vpn/inetvpn_route.h" +#include "bgp/routing-instance/routepath_replicator.h" #include "bgp/routing-instance/routing_instance.h" #include "bgp/routing-instance/static_route_types.h" #include "net/community_type.h" @@ -245,10 +246,11 @@ template void StaticRoute::FillShowInfo(StaticRouteInfo *info) const { BgpTable *table = bgp_table(); RouteT rt_key(static_route_prefix_); - BgpRoute *route = static_cast(table->Find(&rt_key)); + const BgpRoute *route = static_cast(table->Find(&rt_key)); + const BgpPath *path = route ? route->FindPath(BgpPath::StaticRoute) : NULL; info->set_prefix(static_route_prefix_.ToString()); - info->set_static_rt(route ? true : false); + info->set_static_rt(path ? true : false); info->set_nexthop(nexthop_.to_string()); if (nexthop_route_) { ShowRouteBrief show_route; @@ -262,6 +264,13 @@ void StaticRoute::FillShowInfo(StaticRouteInfo *info) const { route_target_list.push_back(it->ToString()); } info->set_route_target_list(route_target_list); + + if (path) { + const RoutePathReplicator *replicator = table->server()->replicator( + Address::VpnFamilyFromFamily(GetFamily())); + info->set_secondary_tables( + replicator->GetReplicatedTableNameList(table, route, path)); + } } // Match function called from BgpConditionListener diff --git a/src/bgp/routing-instance/static_route.sandesh b/src/bgp/routing-instance/static_route.sandesh index 34c0224fb5c..7e499e63927 100644 --- a/src/bgp/routing-instance/static_route.sandesh +++ b/src/bgp/routing-instance/static_route.sandesh @@ -9,8 +9,9 @@ struct StaticRouteInfo { 1: string prefix; 2: bool static_rt; 3: string nexthop; - 4: bgp_peer.ShowRouteBrief nexthop_rt; 5: list route_target_list; + 6: list secondary_tables; + 4: bgp_peer.ShowRouteBrief nexthop_rt; } struct StaticRouteEntriesInfo { diff --git a/src/net/address.cc b/src/net/address.cc index 0c0a727df8a..520543389bc 100644 --- a/src/net/address.cc +++ b/src/net/address.cc @@ -106,6 +106,24 @@ std::string Address::FamilyToTableString(Address::Family family) { return toTableName.find(family)->second; } +Address::Family Address::VpnFamilyFromFamily(Address::Family family) { + switch (family) { + case Address::INET: + case Address::INETVPN: + return Address::INETVPN; + case Address::INET6: + case Address::INET6VPN: + return Address::INET6VPN; + case Address::EVPN: + return Address::EVPN; + case Address::ERMVPN: + return Address::ERMVPN; + default: + return Address::UNSPEC; + } + return Address::UNSPEC; +} + static int CountDots(const string &str) { int count = 0; size_t pos = 0; diff --git a/src/net/address.h b/src/net/address.h index 328ddc5ebd9..4ae4f30a5e5 100644 --- a/src/net/address.h +++ b/src/net/address.h @@ -44,6 +44,7 @@ class Address { static std::string FamilyToString(Family fmly); static Family FamilyFromRoutingTableName(const std::string &name); static std::string FamilyToTableString(Family family); + static Family VpnFamilyFromFamily(Family family); static Ip4Address V4FromV4MappedV6(const Ip6Address &v6_address); static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen);