Skip to content

Commit

Permalink
BGPaaSv2: Use gateway address in RibExportPolicy
Browse files Browse the repository at this point in the history
Change-Id: Idd14d97d088b51206646e9a9d8578df14ac5497e
Partial-Bug: 1552952
  • Loading branch information
Nischal Sheth committed Mar 10, 2016
1 parent 5fb639f commit b6cb6c0
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 67 deletions.
38 changes: 21 additions & 17 deletions src/bgp/bgp_config_ifmap.cc
Expand Up @@ -305,24 +305,28 @@ static BgpNeighborConfig *MakeBgpNeighborConfig(
}
neighbor->set_peer_identifier(IpAddressToBgpIdentifier(identifier));

IpAddress inet_gw_address =
Ip4Address::from_string(params.gateway_address, err);
if (!params.gateway_address.empty() && err) {
BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_WARN, BGP_LOG_FLAG_ALL,
"Invalid gateway address " << params.gateway_address <<
" for neighbor " << neighbor->name());
} else {
neighbor->set_gateway_address(Address::INET, inet_gw_address);
}
if (params.router_type == "bgpaas-client") {
IpAddress inet_gw_address =
Ip4Address::from_string(params.gateway_address, err);
if (!params.gateway_address.empty() && err) {
BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_WARN, BGP_LOG_FLAG_ALL,
"Invalid gateway address " <<
params.gateway_address <<
" for neighbor " << neighbor->name());
} else {
neighbor->set_gateway_address(Address::INET, inet_gw_address);
}

IpAddress inet6_gw_address =
Ip6Address::from_string(params.ipv6_gateway_address, err);
if (!params.ipv6_gateway_address.empty() && err) {
BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_WARN, BGP_LOG_FLAG_ALL,
"Invalid ipv6 gateway address " << params.ipv6_gateway_address <<
" for neighbor " << neighbor->name());
} else {
neighbor->set_gateway_address(Address::INET6, inet6_gw_address);
IpAddress inet6_gw_address =
Ip6Address::from_string(params.ipv6_gateway_address, err);
if (!params.ipv6_gateway_address.empty() && err) {
BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_WARN, BGP_LOG_FLAG_ALL,
"Invalid ipv6 gateway address " <<
params.ipv6_gateway_address <<
" for neighbor " << neighbor->name());
} else {
neighbor->set_gateway_address(Address::INET6, inet6_gw_address);
}
}

neighbor->set_port(params.port);
Expand Down
57 changes: 35 additions & 22 deletions src/bgp/bgp_peer.cc
Expand Up @@ -248,10 +248,27 @@ BgpPeerFamilyAttributes::BgpPeerFamilyAttributes(
loop_count = config->loop_count();
}
prefix_limit = family_config.prefix_limit;
if (family_config.family == "inet") {
gateway_address = config->gateway_address(Address::INET);
} else if (family_config.family == "inet6") {
gateway_address = config->gateway_address(Address::INET6);

if (config->router_type() == "bgpaas-client") {
if (family_config.family == "inet") {
gateway_address = config->gateway_address(Address::INET);
} else if (family_config.family == "inet6") {
gateway_address = config->gateway_address(Address::INET6);
}
}
}

RibExportPolicy BgpPeer::BuildRibExportPolicy(Address::Family family) const {
BgpPeerFamilyAttributes *family_attributes =
family_attributes_list_[family];
if (!family_attributes ||
family_attributes->gateway_address.is_unspecified()) {
return RibExportPolicy(
peer_type_, RibExportPolicy::BGP, peer_as_, -1, 0);
} else {
IpAddress nexthop = family_attributes->gateway_address;
return RibExportPolicy(
peer_type_, RibExportPolicy::BGP, peer_as_, nexthop, -1, 0);
}
}

Expand Down Expand Up @@ -363,9 +380,6 @@ BgpPeer::BgpPeer(BgpServer *server, RoutingInstance *instance,
peer_bgp_id_(0),
peer_type_((config->peer_as() == config->local_as()) ?
BgpProto::IBGP : BgpProto::EBGP),
policy_((config->peer_as() == config->local_as()) ?
BgpProto::IBGP : BgpProto::EBGP,
RibExportPolicy::BGP, config->peer_as(), -1, 0),
state_machine_(BgpObjectFactory::Create<StateMachine>(this)),
peer_close_(new PeerClose(this)),
peer_stats_(new PeerStats(this)),
Expand Down Expand Up @@ -619,12 +633,6 @@ void BgpPeer::ConfigUpdate(const BgpNeighborConfig *config) {
}
ProcessEndpointConfig(config);

// Check if there is any change in the configured address families.
if (ProcessFamilyAttributesConfig(config)) {
peer_info.set_configured_families(configured_families_);
clear_session = true;
}

BgpProto::BgpPeerType old_type = PeerType();
if (local_as_ != config->local_as()) {
local_as_ = config->local_as();
Expand Down Expand Up @@ -657,8 +665,12 @@ void BgpPeer::ConfigUpdate(const BgpNeighborConfig *config) {
if (old_type != PeerType()) {
peer_info.set_peer_type(
PeerType() == BgpProto::IBGP ? "internal" : "external");
policy_.type = peer_type_;
policy_.as_number = peer_as_;
clear_session = true;
}

// Check if there is any change in the configured address families.
if (ProcessFamilyAttributesConfig(config)) {
peer_info.set_configured_families(configured_families_);
clear_session = true;
}

Expand Down Expand Up @@ -888,8 +900,8 @@ void BgpPeer::RegisterAllTables() {
BgpTable *table = instance->GetTable(family);
BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
table, "Register peer with the table");
membership_mgr->Register(this, table, policy_, -1,
boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_mgr->Register(this, table, BuildRibExportPolicy(family),
-1, boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_req_pending_++;
}

Expand All @@ -899,11 +911,12 @@ void BgpPeer::RegisterAllTables() {
return;
}

BgpTable *table = instance->GetTable(Address::RTARGET);
Address::Family family = Address::RTARGET;
BgpTable *table = instance->GetTable(family);
BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_TRACE,
table, "Register peer with the table");
membership_mgr->Register(this, table, policy_, -1,
boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_mgr->Register(this, table, BuildRibExportPolicy(family),
-1, boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_req_pending_++;
StartEndOfRibTimer();

Expand Down Expand Up @@ -1354,8 +1367,8 @@ void BgpPeer::RegisterToVpnTables() {
BgpTable *table = instance->GetTable(vpn_family);
BGP_LOG_PEER_TABLE(this, SandeshLevel::SYS_INFO, BGP_LOG_FLAG_TRACE,
table, "Register peer with the table");
membership_mgr->Register(this, table, policy_, -1,
boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_mgr->Register(this, table, BuildRibExportPolicy(vpn_family),
-1, boost::bind(&BgpPeer::MembershipRequestCallback, this, _1, _2));
membership_req_pending_++;
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/bgp/bgp_peer.h
Expand Up @@ -309,6 +309,7 @@ class BgpPeer : public IPeer {
void StopKeepaliveTimerUnlocked();
bool KeepaliveTimerExpired();

RibExportPolicy BuildRibExportPolicy(Address::Family family) const;
void ReceiveEndOfRIB(Address::Family family, size_t msgsize);
void SendEndOfRIB(Address::Family family);
void StartEndOfRibTimer();
Expand All @@ -318,8 +319,6 @@ class BgpPeer : public IPeer {

virtual void BindLocalEndpoint(BgpSession *session);

void UnregisterAllTables();

uint32_t GetPathFlags(Address::Family family, const BgpAttr *attr) const;
virtual bool MpNlriAllowed(uint16_t afi, uint8_t safi);
BgpAttrPtr GetMpNlriNexthop(BgpMpNlri *nlri, BgpAttrPtr attr);
Expand Down Expand Up @@ -401,7 +400,6 @@ class BgpPeer : public IPeer {
std::vector<std::string> configured_families_;
std::vector<std::string> negotiated_families_;
BgpProto::BgpPeerType peer_type_;
RibExportPolicy policy_;
boost::scoped_ptr<StateMachine> state_machine_;
boost::scoped_ptr<PeerClose> peer_close_;
boost::scoped_ptr<PeerStats> peer_stats_;
Expand Down
13 changes: 7 additions & 6 deletions src/bgp/bgp_ribout.cc
Expand Up @@ -41,6 +41,12 @@ bool RibExportPolicy::operator<(const RibExportPolicy &rhs) const {
if (as_number > rhs.as_number) {
return false;
}
if (nexthop < rhs.nexthop) {
return true;
}
if (nexthop > rhs.nexthop) {
return false;
}
if (affinity < rhs.affinity) {
return true;
}
Expand Down Expand Up @@ -206,13 +212,8 @@ void RibOutAttr::set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
return;
}

bool nexthop_changed = attr_out_->nexthop() != attrp->nexthop();
assert(attr_out_->nexthop() == attrp->nexthop());
attr_out_ = attrp;

// Update the next-hop list ? We would need label too then.
if (nexthop_changed) {
assert(false);
}
}

RouteState::RouteState() {
Expand Down
18 changes: 16 additions & 2 deletions src/bgp/bgp_ribout.h
Expand Up @@ -218,6 +218,10 @@ class RouteState : public DBState {
// practical deployment scenarios all eBGP peers will belong to the same
// neighbor AS anyway.
//
// Including the nexthop as part of the policy results in creation of a
// different RibOut for each set of BGPaaS clients that belong to the same
// subnet. This allows us to rewrite the nexthop to the specified value.
//
// Including the CPU affinity as part of the RibExportPolicy allows us to
// artificially create more RibOuts than otherwise necessary. This is used
// to achieve higher concurrency at the expense of creating more state.
Expand All @@ -234,7 +238,7 @@ struct RibExportPolicy {
}

RibExportPolicy(BgpProto::BgpPeerType type, Encoding encoding,
int affinity, u_int32_t cluster_id)
int affinity, u_int32_t cluster_id)
: type(type), encoding(encoding), as_number(0),
affinity(affinity), cluster_id(cluster_id) {
if (encoding == XMPP)
Expand All @@ -244,7 +248,7 @@ struct RibExportPolicy {
}

RibExportPolicy(BgpProto::BgpPeerType type, Encoding encoding,
as_t as_number, int affinity, u_int32_t cluster_id)
as_t as_number, int affinity, u_int32_t cluster_id)
: type(type), encoding(encoding), as_number(as_number),
affinity(affinity), cluster_id(cluster_id) {
if (encoding == XMPP)
Expand All @@ -253,11 +257,20 @@ struct RibExportPolicy {
assert(type == BgpProto::IBGP || type == BgpProto::EBGP);
}

RibExportPolicy(BgpProto::BgpPeerType type, Encoding encoding,
as_t as_number, IpAddress nexthop, int affinity, u_int32_t cluster_id)
: type(type), encoding(BGP), as_number(as_number),
nexthop(nexthop), affinity(affinity), cluster_id(cluster_id) {
assert(type == BgpProto::IBGP || type == BgpProto::EBGP);
assert(encoding == BGP);
}

bool operator<(const RibExportPolicy &rhs) const;

BgpProto::BgpPeerType type;
Encoding encoding;
as_t as_number;
IpAddress nexthop;
int affinity;
uint32_t cluster_id;
};
Expand Down Expand Up @@ -329,6 +342,7 @@ class RibOut {

BgpProto::BgpPeerType peer_type() const { return policy_.type; }
as_t peer_as() const { return policy_.as_number; }
const IpAddress &nexthop() const { return policy_.nexthop; }
bool IsEncodingXmpp() const {
return (policy_.encoding == RibExportPolicy::XMPP);
}
Expand Down
15 changes: 10 additions & 5 deletions src/bgp/bgp_table.cc
Expand Up @@ -196,11 +196,13 @@ UpdateInfo *BgpTable::GetUpdateInfo(RibOut *ribout, BgpRoute *route,
attr_ptr = attr->attr_db()->Locate(clone);
attr = attr_ptr.get();
} else if (ribout->peer_type() == BgpProto::EBGP) {
// Don't advertise any routes from non-master instances.
// The ribout can only be for bgpaas-clients since that's
// the only case with bgp peers in non-master instance.
if (!rtinstance_->IsMasterRoutingInstance())
// Don't advertise routes from non-master instances if there's
// no nexthop. The ribout has to be for bgpaas-clients because
// that's the only case with bgp peers in non-master instance.
if (!rtinstance_->IsMasterRoutingInstance() &&
ribout->nexthop().is_unspecified()) {
return NULL;
}

// Sender side AS path loop check.
if (attr->as_path() &&
Expand All @@ -218,6 +220,10 @@ UpdateInfo *BgpTable::GetUpdateInfo(RibOut *ribout, BgpRoute *route,

BgpAttr *clone = new BgpAttr(*attr);

// Update nexthop.
if (!ribout->nexthop().is_unspecified())
clone->set_nexthop(ribout->nexthop());

// Reset LocalPref.
if (attr->local_pref())
clone->set_local_pref(0);
Expand Down Expand Up @@ -285,7 +291,6 @@ bool BgpTable::InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
if ((path->GetAttr() != attrs.get()) ||
(path->GetFlags() != flags) ||
(path->GetLabel() != label)) {

// Update Attributes and notify (if needed)
if (path->NeedsResolution())
path_resolver_->StopPathResolution(root->index(), path);
Expand Down
18 changes: 12 additions & 6 deletions src/bgp/inet/inet_table.cc
Expand Up @@ -127,13 +127,19 @@ bool InetTable::Export(RibOut *ribout, Route *route, const RibPeerSet &peerset,
if (!uinfo)
return false;

// Strip BGP extended communities out by default.
if (ribout->ExportPolicy().encoding == RibExportPolicy::BGP) {
if (uinfo->roattr.attr()->ext_community() != NULL) {
BgpAttrDB *attr_db = routing_instance()->server()->attr_db();
BgpAttrPtr new_attr =
attr_db->ReplaceExtCommunityAndLocate(
uinfo->roattr.attr(), NULL);
BgpAttrDB *attr_db = routing_instance()->server()->attr_db();
// Strip ExtCommunity.
if (uinfo->roattr.attr()->ext_community()) {
BgpAttrPtr new_attr = attr_db->ReplaceExtCommunityAndLocate(
uinfo->roattr.attr(), NULL);
uinfo->roattr.set_attr(this, new_attr);
}

// Strip OriginVnPath.
if (uinfo->roattr.attr()->origin_vn_path()) {
BgpAttrPtr new_attr = attr_db->ReplaceOriginVnPathAndLocate(
uinfo->roattr.attr(), NULL);
uinfo->roattr.set_attr(this, new_attr);
}
}
Expand Down
18 changes: 12 additions & 6 deletions src/bgp/inet6/inet6_table.cc
Expand Up @@ -128,13 +128,19 @@ bool Inet6Table::Export(RibOut *ribout, Route *route, const RibPeerSet &peerset,
return false;
}

// Strip BGP extended communities out by default.
if (ribout->ExportPolicy().encoding == RibExportPolicy::BGP) {
if (uinfo->roattr.attr()->ext_community() != NULL) {
BgpAttrDB *attr_db = routing_instance()->server()->attr_db();
BgpAttrPtr new_attr =
attr_db->ReplaceExtCommunityAndLocate(
uinfo->roattr.attr(), NULL);
BgpAttrDB *attr_db = routing_instance()->server()->attr_db();
// Strip ExtCommunity.
if (uinfo->roattr.attr()->ext_community()) {
BgpAttrPtr new_attr = attr_db->ReplaceExtCommunityAndLocate(
uinfo->roattr.attr(), NULL);
uinfo->roattr.set_attr(this, new_attr);
}

// Strip OriginVnPath.
if (uinfo->roattr.attr()->origin_vn_path()) {
BgpAttrPtr new_attr = attr_db->ReplaceOriginVnPathAndLocate(
uinfo->roattr.attr(), NULL);
uinfo->roattr.set_attr(this, new_attr);
}
}
Expand Down

0 comments on commit b6cb6c0

Please sign in to comment.