Skip to content

Commit

Permalink
Adding route orign override for incoming routes
Browse files Browse the repository at this point in the history
Control node will read this Route Origin override
information associated with a BGP Peer and apply override
to routes received from peer.

Route Origin override will be added as an element under
BgpSessionAttributes.

Implements: blueprint bgpaas-route-origin
Change-Id: I53127d6b74c61589ec8823c88e67efdb591bd04b
Closes-Bug: #1657132
  • Loading branch information
ar631r committed May 11, 2017
1 parent 3f223f7 commit 7bbf59b
Show file tree
Hide file tree
Showing 14 changed files with 274 additions and 3 deletions.
26 changes: 24 additions & 2 deletions src/bgp/bgp_attr.cc
Expand Up @@ -962,8 +962,8 @@ void BgpAttr::set_leaf_olist(const BgpOListSpec *leaf_olist_spec) {
}
}

std::string BgpAttr::origin_string() const {
switch (origin()) {
std::string BgpAttr::OriginToString(BgpAttrOrigin::OriginType origin) {
switch (origin) {
case BgpAttrOrigin::IGP:
return "igp";
break;
Expand All @@ -977,6 +977,20 @@ std::string BgpAttr::origin_string() const {
return "unknown";
}

BgpAttrOrigin::OriginType BgpAttr::OriginFromString(
const std::string &bgp_origin_type) {
if(bgp_origin_type == "IGP"){
return BgpAttrOrigin::IGP;
} else if( bgp_origin_type == "EGP") {
return BgpAttrOrigin::EGP;
}
return BgpAttrOrigin::INCOMPLETE;
}

std::string BgpAttr::origin_string() const {
return OriginToString(origin());
}

Address::Family BgpAttr::nexthop_family() const {
if (nexthop_.is_v6()) {
return Address::INET6;
Expand Down Expand Up @@ -1131,6 +1145,14 @@ BgpAttrPtr BgpAttrDB::ReplaceCommunityAndLocate(const BgpAttr *attr,
return Locate(clone);
}

//Return a clone of attribute with updated origin
BgpAttrPtr BgpAttrDB::ReplaceOriginAndLocate(const BgpAttr *attr,
BgpAttrOrigin::OriginType origin) {
BgpAttr *clone = new BgpAttr(*attr);
clone->set_origin(origin);
return Locate(clone);
}

// Return a clone of attribute with updated extended community.
BgpAttrPtr BgpAttrDB::ReplaceExtCommunityAndLocate(const BgpAttr *attr,
ExtCommunityPtr extcomm) {
Expand Down
5 changes: 5 additions & 0 deletions src/bgp/bgp_attr.h
Expand Up @@ -822,7 +822,10 @@ class BgpAttr {
friend std::size_t hash_value(BgpAttr const &attr);

BgpAttrOrigin::OriginType origin() const { return origin_; }
static std::string OriginToString(BgpAttrOrigin::OriginType origin);
static BgpAttrOrigin::OriginType OriginFromString(const std::string &bgp_origin_type);
std::string origin_string() const;

const IpAddress &nexthop() const { return nexthop_; }
Address::Family nexthop_family() const;
uint32_t med() const { return med_; }
Expand Down Expand Up @@ -927,6 +930,8 @@ class BgpAttrDB : public BgpPathAttributeDB<BgpAttr, BgpAttrPtr, BgpAttrSpec,
AsPathPtr aspath);
BgpAttrPtr ReplaceCommunityAndLocate(const BgpAttr *attr,
CommunityPtr community);
BgpAttrPtr ReplaceOriginAndLocate(const BgpAttr *attr,
BgpAttrOrigin::OriginType origin);
BgpAttrPtr ReplaceExtCommunityAndLocate(const BgpAttr *attr,
ExtCommunityPtr extcomm);
BgpAttrPtr ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
Expand Down
25 changes: 25 additions & 0 deletions src/bgp/bgp_config.cc
Expand Up @@ -146,6 +146,23 @@ vector<string> AuthenticationData::KeysToStringDetail() const {
return auth_keys;
}

BgpNeighborConfig::OriginOverrideConfig::OriginOverrideConfig()
: origin_override(false), origin("IGP") {
}

bool BgpNeighborConfig::OriginOverrideConfig::operator<(
const OriginOverrideConfig &rhs) const {
if (origin_override == rhs.origin_override) {
if (origin_override) {
// chek origin value only if override is set
return origin < rhs.origin;
}
return false;
}

return origin_override < rhs.origin_override;
}

BgpNeighborConfig::BgpNeighborConfig()
: type_(UNSPECIFIED),
admin_down_(false),
Expand Down Expand Up @@ -185,6 +202,7 @@ void BgpNeighborConfig::CopyValues(const BgpNeighborConfig &rhs) {
local_identifier_ = rhs.local_identifier_;
auth_data_ = rhs.auth_data_;
family_attributes_list_ = rhs.family_attributes_list_;
origin_override_ = rhs.origin_override_;
}

int BgpNeighborConfig::CompareTo(const BgpNeighborConfig &rhs) const {
Expand All @@ -195,6 +213,7 @@ int BgpNeighborConfig::CompareTo(const BgpNeighborConfig &rhs) const {
KEY_COMPARE(admin_down_, rhs.admin_down_);
KEY_COMPARE(passive_, rhs.passive_);
KEY_COMPARE(as_override_, rhs.as_override_);
KEY_COMPARE(origin_override_, rhs.origin_override_);
KEY_COMPARE(private_as_action_, rhs.private_as_action_);
KEY_COMPARE(cluster_id_, rhs.cluster_id_);
KEY_COMPARE(peer_as_, rhs.peer_as_);
Expand All @@ -215,6 +234,12 @@ int BgpNeighborConfig::CompareTo(const BgpNeighborConfig &rhs) const {
BgpFamilyAttributesConfigCompare());
}

void BgpNeighborConfig::SetOriginOverride(bool origin_override,
std::string origin) {
origin_override_.origin_override = origin_override;
origin_override_.origin = origin;
}

const IpAddress &BgpNeighborConfig::gateway_address(
Address::Family family) const {
assert(family == Address::INET || family == Address::INET6);
Expand Down
14 changes: 14 additions & 0 deletions src/bgp/bgp_config.h
Expand Up @@ -140,6 +140,14 @@ class BgpNeighborConfig {
EBGP,
};

struct OriginOverrideConfig {
OriginOverrideConfig();
bool operator<(const OriginOverrideConfig &rhs) const;

bool origin_override;
std::string origin;
};

BgpNeighborConfig();

void CopyValues(const BgpNeighborConfig &rhs);
Expand Down Expand Up @@ -255,6 +263,11 @@ class BgpNeighborConfig {
return CompareTo(rhs) != 0;
}

const OriginOverrideConfig &origin_override() const {
return origin_override_;
}
void SetOriginOverride(bool origin_override, std::string origin);

private:
std::string name_;
std::string uuid_;
Expand Down Expand Up @@ -282,6 +295,7 @@ class BgpNeighborConfig {
mutable uint64_t last_change_at_;
AuthenticationData auth_data_;
FamilyAttributesList family_attributes_list_;
OriginOverrideConfig origin_override_;

DISALLOW_COPY_AND_ASSIGN(BgpNeighborConfig);
};
Expand Down
4 changes: 4 additions & 0 deletions src/bgp/bgp_config_ifmap.cc
Expand Up @@ -266,6 +266,10 @@ static void NeighborSetSessionAttributes(
}
BuildFamilyAttributesList(neighbor, attributes);
BuildKeyChain(neighbor, attributes->auth_data);
const autogen::RouteOriginOverride &origin_override =
attributes->route_origin_override;
neighbor->SetOriginOverride(origin_override.origin_override,
origin_override.origin);
}
}

Expand Down
50 changes: 50 additions & 0 deletions src/bgp/bgp_peer.cc
Expand Up @@ -412,6 +412,7 @@ BgpPeer::BgpPeer(BgpServer *server, RoutingInstance *instance,
resolve_paths_(config->router_type() == "bgpaas-client"),
as_override_(config->as_override()),
cluster_id_(config->cluster_id()),
origin_override_(config->origin_override()),
defer_close_(false),
graceful_close_(true),
vpn_tables_registered_(false),
Expand Down Expand Up @@ -498,6 +499,13 @@ BgpPeer::BgpPeer(BgpServer *server, RoutingInstance *instance,
peer_info.set_admin_down(admin_down_);
peer_info.set_passive(passive_);
peer_info.set_as_override(as_override_);
peer_info.set_origin_override(origin_override_.origin_override);
if (origin_override_.origin_override) {
peer_info.set_route_origin(
BgpAttr::OriginToString(origin_override_.origin));
} else {
peer_info.set_route_origin("-");
}
peer_info.set_router_type(router_type_);
peer_info.set_cluster_id(Ip4Address(cluster_id_).to_string());
peer_info.set_peer_type(
Expand Down Expand Up @@ -757,6 +765,18 @@ void BgpPeer::ConfigUpdate(const BgpNeighborConfig *config) {
clear_session = true;
}

OriginOverride origin_override(config->origin_override());
if (origin_override_ != origin_override) {
origin_override_ = origin_override;
peer_info.set_origin_override(origin_override_.origin_override);
if (origin_override_.origin_override) {
peer_info.set_route_origin(config->origin_override().origin);
} else {
peer_info.set_route_origin("-");
}
clear_session = true;
}

if (router_type_ != config->router_type()) {
router_type_ = config->router_type();
peer_info.set_router_type(router_type_);
Expand Down Expand Up @@ -1257,6 +1277,24 @@ static bool SkipUpdateSend() {
return skip_;
}

BgpPeer::OriginOverride::OriginOverride(
const BgpNeighborConfig::OriginOverrideConfig &config)
: origin_override(config.origin_override),
origin(BgpAttr::OriginFromString(config.origin)) {
}

bool BgpPeer::OriginOverride::operator!=(const OriginOverride &rhs) const {
if (origin_override != rhs.origin_override) {
return true;
}

// compare origin only if override is set
if (origin_override && origin != rhs.origin) {
return true;
}
return false;
}

//
// Accumulate the message in the update buffer.
// Flush the existing buffer if the message can't fit.
Expand Down Expand Up @@ -1519,6 +1557,12 @@ void BgpPeer::ProcessUpdate(const BgpProto::Update *msg, size_t msgsize) {
local_pref);
}

// Check if peer is marked to override the route origin attribute
if (origin_override_.origin_override) {
attr = server_->attr_db()->ReplaceOriginAndLocate(attr.get(),
origin_override_.origin);
}

uint32_t reach_count = 0, unreach_count = 0;
RoutingInstance *instance = GetRoutingInstance();
if (msg->nlri.size() || msg->withdrawn_routes.size()) {
Expand Down Expand Up @@ -2046,6 +2090,12 @@ void BgpPeer::FillNeighborInfo(const BgpSandeshContext *bsc,
bnr->set_admin_down(admin_down_);
bnr->set_passive(passive_);
bnr->set_as_override(as_override_);
bnr->set_origin_override(origin_override_.origin_override);
if (origin_override_.origin_override) {
bnr->set_route_origin(BgpAttr::OriginToString(origin_override_.origin));
} else {
bnr->set_route_origin("-");
}
bnr->set_private_as_action(private_as_action_);
bnr->set_peer_address(peer_address_string());
bnr->set_peer_id(bgp_identifier_string());
Expand Down
9 changes: 9 additions & 0 deletions src/bgp/bgp_peer.h
Expand Up @@ -353,6 +353,14 @@ class BgpPeer : public IPeer {
class DeleteActor;
class PeerStats;

struct OriginOverride {
OriginOverride(const BgpNeighborConfig::OriginOverrideConfig &config);
bool operator!=(const OriginOverride &rhs) const;

bool origin_override;
BgpAttrOrigin::OriginType origin;
};

typedef std::map<Address::Family, const uint8_t *> FamilyToCapabilityMap;
typedef std::vector<BgpPeerFamilyAttributes *> FamilyAttributesList;

Expand Down Expand Up @@ -457,6 +465,7 @@ class BgpPeer : public IPeer {
bool as_override_;
string private_as_action_;
uint32_t cluster_id_;
OriginOverride origin_override_;

tbb::atomic<int> membership_req_pending_;
bool defer_close_;
Expand Down
6 changes: 6 additions & 0 deletions src/bgp/bgp_peer.sandesh
Expand Up @@ -86,6 +86,8 @@ struct BgpNeighborResp {
47: bool admin_down;
48: bool passive;
55: bool as_override;
65: bool origin_override;
66: string route_origin;
61: string private_as_action;
62: bool send_ready;
50: u32 peer_port;
Expand Down Expand Up @@ -641,6 +643,8 @@ struct ShowBgpNeighborConfig {
13: bool admin_down;
15: bool passive;
20: bool as_override;
23: bool origin_override;
24: string route_origin;
21: string private_as_action;
18: string router_type;
8: string local_identifier;
Expand Down Expand Up @@ -696,6 +700,8 @@ struct BgpPeerInfoData {
23: optional bool admin_down;
24: optional bool passive;
27: optional bool as_override;
33: optional bool origin_override;
34: optional string route_origin;
25: optional string router_type; // bgp_schema.xsd:BgpRouterType
32: optional string cluster_id;
3: optional string peer_type; // internal/external
Expand Down
8 changes: 8 additions & 0 deletions src/bgp/bgp_show_config.cc
Expand Up @@ -333,6 +333,14 @@ static void FillBgpNeighborConfigInfo(ShowBgpNeighborConfig *sbnc,
sbnc->set_admin_down(neighbor->admin_down());
sbnc->set_passive(neighbor->passive());
sbnc->set_as_override(neighbor->as_override());
const BgpNeighborConfig::OriginOverrideConfig &route_origin =
neighbor->origin_override();
sbnc->set_origin_override(route_origin.origin_override);
if (route_origin.origin_override) {
sbnc->set_route_origin(route_origin.origin);
} else {
sbnc->set_route_origin("-");
}
sbnc->set_private_as_action(neighbor->private_as_action());
sbnc->set_router_type(neighbor->router_type());
sbnc->set_local_identifier(neighbor->local_identifier_string());
Expand Down
14 changes: 14 additions & 0 deletions src/bgp/test/bgp_config_test.cc
Expand Up @@ -108,6 +108,14 @@ class BgpConfigTest : public ::testing::Test {
bool GetPeerResolvePaths(BgpPeer *peer) { return peer->resolve_paths_; }
bool GetPeerAsOverride(BgpPeer *peer) { return peer->as_override_; }

BgpAttrOrigin::OriginType GetPeerRouteOrigin(BgpPeer *peer) {
return peer->origin_override_.origin;
}

bool GetPeerRouteOriginOverride(BgpPeer *peer) {
return peer->origin_override_.origin_override;
}

EventManager evm_;
DB config_db_;
DBGraph db_graph_;
Expand Down Expand Up @@ -915,12 +923,15 @@ TEST_F(BgpConfigTest, BGPaaSNeighbors8) {
BgpPeer *peer1 = rti->peer_manager()->PeerLookup("test:vm1:0");
TASK_UTIL_EXPECT_TRUE(GetPeerResolvePaths(peer1));
TASK_UTIL_EXPECT_TRUE(GetPeerAsOverride(peer1));
TASK_UTIL_EXPECT_TRUE(GetPeerRouteOriginOverride(peer1));
TASK_UTIL_EXPECT_EQ(BgpAttrOrigin::EGP, GetPeerRouteOrigin(peer1));

TASK_UTIL_EXPECT_TRUE(
rti->peer_manager()->PeerLookup("test:vm2:0") != NULL);
BgpPeer *peer2 = rti->peer_manager()->PeerLookup("test:vm2:0");
TASK_UTIL_EXPECT_TRUE(GetPeerResolvePaths(peer2));
TASK_UTIL_EXPECT_FALSE(GetPeerAsOverride(peer2));
TASK_UTIL_EXPECT_FALSE(GetPeerRouteOriginOverride(peer2));

// Update as-override.
content = FileRead("controller/src/bgp/testdata/config_test_41b.xml");
Expand All @@ -930,10 +941,13 @@ TEST_F(BgpConfigTest, BGPaaSNeighbors8) {
TASK_UTIL_EXPECT_EQ(peer1, server_.FindPeer(peer1->endpoint()));
TASK_UTIL_EXPECT_TRUE(GetPeerResolvePaths(peer1));
TASK_UTIL_EXPECT_FALSE(GetPeerAsOverride(peer1));
TASK_UTIL_EXPECT_FALSE(GetPeerRouteOriginOverride(peer1));

TASK_UTIL_EXPECT_EQ(peer2, server_.FindPeer(peer2->endpoint()));
TASK_UTIL_EXPECT_TRUE(GetPeerResolvePaths(peer2));
TASK_UTIL_EXPECT_TRUE(GetPeerAsOverride(peer2));
TASK_UTIL_EXPECT_TRUE(GetPeerRouteOriginOverride(peer2));
TASK_UTIL_EXPECT_EQ(BgpAttrOrigin::INCOMPLETE, GetPeerRouteOrigin(peer2));

// Cleanup.
boost::replace_all(content, "<config>", "<delete>");
Expand Down

0 comments on commit 7bbf59b

Please sign in to comment.