Skip to content

Commit

Permalink
Add end to end support for L3 label in EVPN Type 2 routes
Browse files Browse the repository at this point in the history
This includes the following:

- Add l3-label to xmpp_enet schema
- Encode and decode l3-label in xmpp messages
- Add l3-label to BgpPath and RibOutAttr

Change-Id: I81261683fd7082e9fd041e6fbbbbcb4ceeaf1d58
Partial-Bug: 1636654
  • Loading branch information
Nischal Sheth committed Mar 30, 2017
1 parent 7a9f37a commit 3824962
Show file tree
Hide file tree
Showing 20 changed files with 320 additions and 77 deletions.
2 changes: 1 addition & 1 deletion src/bgp/bgp_message_builder.cc
Expand Up @@ -130,7 +130,7 @@ bool BgpMessage::StartReach(const RibOut *ribout, const RibOutAttr *roattr,
update.path_attributes.push_back(nlri);

BgpProtoPrefix *prefix = new BgpProtoPrefix;
route->BuildProtoPrefix(prefix, attr, roattr->label());
route->BuildProtoPrefix(prefix, attr, roattr->label(), roattr->l3_label());
nlri->nlri.push_back(prefix);

int result =
Expand Down
22 changes: 12 additions & 10 deletions src/bgp/bgp_path.cc
Expand Up @@ -19,27 +19,28 @@ string BgpPath::PathIdString(uint32_t path_id) {
}

BgpPath::BgpPath(const IPeer *peer, uint32_t path_id, PathSource src,
const BgpAttrPtr ptr, uint32_t flags, uint32_t label)
const BgpAttrPtr ptr, uint32_t flags, uint32_t label,
uint32_t l3_label)
: peer_(peer), path_id_(path_id), source_(src), attr_(ptr),
original_attr_(ptr), flags_(flags), label_(label) {
original_attr_(ptr), flags_(flags), label_(label), l3_label_(l3_label) {
}

BgpPath::BgpPath(const IPeer *peer, PathSource src, const BgpAttrPtr ptr,
uint32_t flags, uint32_t label)
uint32_t flags, uint32_t label, uint32_t l3_label)
: peer_(peer), path_id_(0), source_(src), attr_(ptr), original_attr_(ptr),
flags_(flags), label_(label) {
flags_(flags), label_(label), l3_label_(l3_label) {
}

BgpPath::BgpPath(uint32_t path_id, PathSource src, const BgpAttrPtr ptr,
uint32_t flags, uint32_t label)
uint32_t flags, uint32_t label, uint32_t l3_label)
: peer_(NULL), path_id_(path_id), source_(src), attr_(ptr),
original_attr_(ptr), flags_(flags), label_(label) {
original_attr_(ptr), flags_(flags), label_(label), l3_label_(l3_label) {
}

BgpPath::BgpPath(PathSource src, const BgpAttrPtr ptr,
uint32_t flags, uint32_t label)
uint32_t flags, uint32_t label, uint32_t l3_label)
: peer_(NULL), path_id_(0), source_(src), attr_(ptr), original_attr_(ptr),
flags_(flags), label_(label) {
flags_(flags), label_(label), l3_label_(l3_label) {
}

// True is better
Expand Down Expand Up @@ -267,8 +268,9 @@ string BgpPath::GetSourceString(bool combine_bgp_and_xmpp) const {
}

BgpSecondaryPath::BgpSecondaryPath(const IPeer *peer, uint32_t path_id,
PathSource src, const BgpAttrPtr ptr, uint32_t flags, uint32_t label)
: BgpPath(peer, path_id, src, ptr, flags, label) {
PathSource src, const BgpAttrPtr ptr, uint32_t flags, uint32_t label,
uint32_t l3_label)
: BgpPath(peer, path_id, src, ptr, flags, label, l3_label) {
}

RouteDistinguisher BgpSecondaryPath::GetPrimaryRouteDistinguisher() const {
Expand Down
14 changes: 9 additions & 5 deletions src/bgp/bgp_path.h
Expand Up @@ -47,13 +47,14 @@ class BgpPath : public Path {
static std::string PathIdString(uint32_t path_id);

BgpPath(const IPeer *peer, uint32_t path_id, PathSource src,
const BgpAttrPtr ptr, uint32_t flags, uint32_t label);
const BgpAttrPtr ptr, uint32_t flags, uint32_t label,
uint32_t l3_label = 0);
BgpPath(const IPeer *peer, PathSource src, const BgpAttrPtr attr,
uint32_t flags, uint32_t label);
uint32_t flags, uint32_t label, uint32_t l3_label = 0);
BgpPath(uint32_t path_id, PathSource src, const BgpAttrPtr attr,
uint32_t flags = 0, uint32_t label = 0);
uint32_t flags = 0, uint32_t label = 0, uint32_t l3_label = 0);
BgpPath(PathSource src, const BgpAttrPtr attr,
uint32_t flags = 0, uint32_t label = 0);
uint32_t flags = 0, uint32_t label = 0, uint32_t l3_label = 0);
virtual ~BgpPath() {
}

Expand Down Expand Up @@ -81,6 +82,7 @@ class BgpPath : public Path {
const BgpAttr *GetAttr() const { return attr_.get(); }
const BgpAttr *GetOriginalAttr() const { return original_attr_.get(); }
uint32_t GetLabel() const { return label_; }
uint32_t GetL3Label() const { return l3_label_; }
virtual bool IsReplicated() const { return false; }
bool IsFeasible() const { return ((flags_ & INFEASIBLE_MASK) == 0); }

Expand Down Expand Up @@ -139,12 +141,14 @@ class BgpPath : public Path {
BgpAttrPtr original_attr_;
uint32_t flags_;
uint32_t label_;
uint32_t l3_label_;
};

class BgpSecondaryPath : public BgpPath {
public:
BgpSecondaryPath(const IPeer *peer, uint32_t path_id, PathSource src,
const BgpAttrPtr attr, uint32_t flags, uint32_t label);
const BgpAttrPtr attr, uint32_t flags, uint32_t label,
uint32_t l3_label = 0);

virtual bool IsReplicated() const {
return true;
Expand Down
6 changes: 3 additions & 3 deletions src/bgp/bgp_peer.cc
Expand Up @@ -1601,8 +1601,8 @@ void BgpPeer::ProcessNlri(Address::Family family, DBRequest::DBOperation oper,
DBRequest req;
req.oper = oper;
if (oper == DBRequest::DB_ENTRY_ADD_CHANGE) {
req.data.reset(
new typename TableT::RequestData(new_attr, flags, label));
req.data.reset(new typename TableT::RequestData(
new_attr, flags, label, l3_label, 0));
}
req.key.reset(new typename TableT::RequestKey(prefix, this));
table->Enqueue(&req);
Expand Down Expand Up @@ -1686,7 +1686,7 @@ void BgpPeer::ProcessUpdate(const BgpProto::Update *msg, size_t msgsize) {

DBRequest req;
req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
req.data.reset(new InetTable::RequestData(attr, flags, 0));
req.data.reset(new InetTable::RequestData(attr, flags, 0, 0, 0));
req.key.reset(new InetTable::RequestKey(prefix, this));
table->Enqueue(&req);
}
Expand Down
28 changes: 16 additions & 12 deletions src/bgp/bgp_ribout.cc
Expand Up @@ -27,10 +27,11 @@
using std::find;

RibOutAttr::NextHop::NextHop(const BgpTable *table, IpAddress address,
uint32_t label, const ExtCommunity *ext_community,
bool vrf_originated)
uint32_t label, uint32_t l3_label, const ExtCommunity *ext_community,
bool vrf_originated)
: address_(address),
label_(label),
l3_label_(l3_label),
origin_vn_index_(-1) {
if (ext_community) {
encap_ = ext_community->GetTunnelEncap();
Expand All @@ -47,6 +48,8 @@ int RibOutAttr::NextHop::CompareTo(const NextHop &rhs) const {
if (address_ > rhs.address_) return 1;
if (label_ < rhs.label_) return -1;
if (label_ > rhs.label_) return 1;
if (l3_label_ < rhs.l3_label_) return -1;
if (l3_label_ > rhs.l3_label_) return 1;
if (origin_vn_index_ < rhs.origin_vn_index_) return -1;
if (origin_vn_index_ > rhs.origin_vn_index_) return 1;
if (encap_.size() < rhs.encap_.size()) return -1;
Expand Down Expand Up @@ -78,12 +81,12 @@ RibOutAttr::RibOutAttr(const RibOutAttr &rhs) {
}

RibOutAttr::RibOutAttr(const BgpTable *table, const BgpAttr *attr,
uint32_t label)
uint32_t label, uint32_t l3_label)
: attr_out_(attr),
is_xmpp_(false),
vrf_originated_(false) {
if (attr) {
nexthop_list_.push_back(NextHop(table, attr->nexthop(), label,
nexthop_list_.push_back(NextHop(table, attr->nexthop(), label, l3_label,
attr->ext_community(), false));
}
}
Expand All @@ -94,7 +97,7 @@ RibOutAttr::RibOutAttr(const BgpTable *table, const BgpRoute *route,
is_xmpp_(is_xmpp),
vrf_originated_(route->BestPath()->IsVrfOriginated()) {
if (attr && include_nh) {
nexthop_list_.push_back(NextHop(table, attr->nexthop(), label,
nexthop_list_.push_back(NextHop(table, attr->nexthop(), label, 0,
attr->ext_community(), vrf_originated_));
}
}
Expand All @@ -108,14 +111,15 @@ RibOutAttr::RibOutAttr(const BgpRoute *route, const BgpAttr *attr,

// Always encode best path's attributes (including it's nexthop) and label.
if (!is_xmpp) {
set_attr(table, attr, route->BestPath()->GetLabel(), false);
set_attr(table, attr, route->BestPath()->GetLabel(),
route->BestPath()->GetL3Label(), false);
return;
}

// Encode ECMP NextHops only for XMPP peers.
// Vrf Origination matters only for XMPP peers.
set_attr(table, attr, route->BestPath()->GetLabel(),
route->BestPath()->IsVrfOriginated());
route->BestPath()->GetL3Label(), route->BestPath()->IsVrfOriginated());

for (Route::PathList::const_iterator it = route->GetPathList().begin();
it != route->GetPathList().end(); ++it) {
Expand All @@ -135,8 +139,8 @@ RibOutAttr::RibOutAttr(const BgpRoute *route, const BgpAttr *attr,
// determine if VRF's VN name can be used as the origin VN for the
// nexthop.
NextHop nexthop(table, path->GetAttr()->nexthop(), path->GetLabel(),
path->GetAttr()->ext_community(),
path->IsVrfOriginated());
path->GetL3Label(), path->GetAttr()->ext_community(),
path->IsVrfOriginated());

// Skip if we have already encoded this next-hop
if (find(nexthop_list_.begin(), nexthop_list_.end(), nexthop) !=
Expand Down Expand Up @@ -186,12 +190,12 @@ int RibOutAttr::CompareTo(const RibOutAttr &rhs) const {
}

void RibOutAttr::set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
uint32_t label, bool vrf_originated) {
uint32_t label, uint32_t l3_label, bool vrf_originated) {
if (!attr_out_) {
attr_out_ = attrp;
assert(nexthop_list_.empty());
NextHop nexthop(table, attrp->nexthop(), label, attrp->ext_community(),
vrf_originated);
NextHop nexthop(table, attrp->nexthop(), label, l3_label,
attrp->ext_community(), vrf_originated);
nexthop_list_.push_back(nexthop);
return;
}
Expand Down
24 changes: 19 additions & 5 deletions src/bgp/bgp_ribout.h
Expand Up @@ -49,10 +49,12 @@ class RibOutAttr {
class NextHop {
public:
NextHop(const BgpTable *table, IpAddress address, uint32_t label,
const ExtCommunity *ext_community, bool vrf_originated);
uint32_t l3_label, const ExtCommunity *ext_community,
bool vrf_originated);

const IpAddress address() const { return address_; }
uint32_t label() const { return label_; }
uint32_t l3_label() const { return l3_label_; }
int origin_vn_index() const { return origin_vn_index_; }
std::vector<std::string> encap() const { return encap_; }

Expand All @@ -62,7 +64,8 @@ class RibOutAttr {

private:
IpAddress address_;
uint32_t label_;
uint32_t label_;
uint32_t l3_label_;
int origin_vn_index_;
std::vector<std::string> encap_;
};
Expand All @@ -71,11 +74,12 @@ class RibOutAttr {

RibOutAttr(const RibOutAttr &rhs);
RibOutAttr() : attr_out_(NULL), is_xmpp_(false), vrf_originated_(false) { }
RibOutAttr(const BgpTable *table, const BgpAttr *attr, uint32_t label);
RibOutAttr(const BgpRoute *route, const BgpAttr *attr, bool is_xmpp);
RibOutAttr(const BgpTable *table, const BgpAttr *attr, uint32_t label,
uint32_t l3_label = 0);
RibOutAttr(const BgpTable *table, const BgpRoute *route,
const BgpAttr *attr, uint32_t label, bool include_nh = true,
bool is_xmpp = false);
RibOutAttr(const BgpRoute *route, const BgpAttr *attr, bool is_xmpp);

RibOutAttr &operator=(const RibOutAttr &rhs);
bool operator==(const RibOutAttr &rhs) const { return CompareTo(rhs) == 0; }
Expand All @@ -84,8 +88,15 @@ class RibOutAttr {

const NextHopList &nexthop_list() const { return nexthop_list_; }
const BgpAttr *attr() const { return attr_out_.get(); }
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp) {
set_attr(table, attrp, 0, 0, false);
}
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
uint32_t label = 0, bool vrf_originated = false);
uint32_t label) {
set_attr(table, attrp, label, 0, false);
}
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
uint32_t label, uint32_t l3_label, bool vrf_originated);

void clear() {
attr_out_.reset();
Expand All @@ -94,6 +105,9 @@ class RibOutAttr {
uint32_t label() const {
return nexthop_list_.empty() ? 0 : nexthop_list_.at(0).label();
}
uint32_t l3_label() const {
return nexthop_list_.empty() ? 0 : nexthop_list_.at(0).l3_label();
}
bool is_xmpp() const { return is_xmpp_; }
bool vrf_originated() const { return vrf_originated_; }
const std::string &repr() const { return repr_; }
Expand Down
16 changes: 9 additions & 7 deletions src/bgp/bgp_table.cc
Expand Up @@ -398,13 +398,14 @@ bool BgpTable::PathSelection(const Path &path1, const Path &path2) {

bool BgpTable::DeletePath(DBTablePartBase *root, BgpRoute *rt, BgpPath *path) {
return InputCommon(root, rt, path, path->GetPeer(), NULL,
DBRequest::DB_ENTRY_DELETE, NULL, path->GetPathId(), 0, 0);
DBRequest::DB_ENTRY_DELETE, NULL, path->GetPathId(), 0, 0, 0);
}

bool BgpTable::InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
const IPeer *peer, DBRequest *req,
DBRequest::DBOperation oper, BgpAttrPtr attrs,
uint32_t path_id, uint32_t flags, uint32_t label) {
uint32_t path_id, uint32_t flags, uint32_t label,
uint32_t l3_label) {
bool notify_rt = false;

switch (oper) {
Expand All @@ -420,7 +421,8 @@ bool BgpTable::InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
if (path != NULL) {
if ((path->GetAttr() != attrs.get()) ||
(path->GetFlags() != flags) ||
(path->GetLabel() != label)) {
(path->GetLabel() != label) ||
(path->GetL3Label() != l3_label)) {
// Update Attributes and notify (if needed)
if (path->NeedsResolution())
path_resolver_->StopPathResolution(root->index(), path);
Expand All @@ -432,8 +434,8 @@ bool BgpTable::InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
}

BgpPath *new_path;
new_path =
new BgpPath(peer, path_id, BgpPath::BGP_XMPP, attrs, flags, label);
new_path = new BgpPath(
peer, path_id, BgpPath::BGP_XMPP, attrs, flags, label, l3_label);

if (new_path->NeedsResolution()) {
Address::Family family = new_path->GetAttr()->nexthop_family();
Expand Down Expand Up @@ -581,7 +583,7 @@ void BgpTable::Input(DBTablePartition *root, DBClient *client,

notify_rt |= InputCommon(root, rt, path, peer, req, req->oper,
attr, path_id, nexthop.flags_,
nexthop.label_);
nexthop.label_, nexthop.l3_label_);
}
}

Expand All @@ -591,7 +593,7 @@ void BgpTable::Input(DBTablePartition *root, DBClient *client,
BgpPath *path = it->first;
notify_rt |= InputCommon(root, rt, path, peer, req,
DBRequest::DB_ENTRY_DELETE, NULL,
path->GetPathId(), 0, 0);
path->GetPathId(), 0, 0, 0);
}

InputCommonPostProcess(root, rt, notify_rt);
Expand Down
37 changes: 29 additions & 8 deletions src/bgp/bgp_table.h
Expand Up @@ -41,24 +41,44 @@ class BgpTable : public RouteTable {

struct RequestData : DBRequestData {
struct NextHop {
NextHop() : flags_(0), address_(Ip4Address(0)), label_(0) { }
NextHop(uint32_t flags, IpAddress address, uint32_t label) :
flags_(flags), address_(address), label_(label) { }
NextHop()
: flags_(0),
address_(Ip4Address(0)),
label_(0),
l3_label_(0) {
}
NextHop(uint32_t flags, IpAddress address, uint32_t label,
uint32_t l3_label = 0)
: flags_(flags),
address_(address),
label_(label),
l3_label_(l3_label) {
}

uint32_t flags_;
IpAddress address_;
uint32_t label_;
uint32_t l3_label_;
RouteDistinguisher source_rd_;
ExtCommunity::ExtCommunityList tunnel_encapsulations_;
};

typedef std::vector<NextHop> NextHops;

RequestData(const BgpAttrPtr &attrs, uint32_t flags, uint32_t label,
uint64_t subscription_gen_id = 0)
uint32_t l3_label, uint64_t subscription_gen_id)
: attrs_(attrs), subscription_gen_id_(subscription_gen_id) {
nexthops_.push_back(NextHop(flags,
attrs ? attrs->nexthop() : Ip4Address(0),
label));
nexthops_.push_back(
NextHop(flags, attrs ? attrs->nexthop() : Ip4Address(0),
label, l3_label));
}

RequestData(const BgpAttrPtr &attrs, uint32_t flags, uint32_t label,
uint32_t l3_label = 0)
: attrs_(attrs), subscription_gen_id_(0) {
nexthops_.push_back(
NextHop(flags, attrs ? attrs->nexthop() : Ip4Address(0),
label, l3_label));
}

RequestData(const BgpAttrPtr &attrs, NextHops nexthops,
Expand Down Expand Up @@ -155,7 +175,8 @@ class BgpTable : public RouteTable {
bool InputCommon(DBTablePartBase *root, BgpRoute *rt, BgpPath *path,
const IPeer *peer, DBRequest *req,
DBRequest::DBOperation oper, BgpAttrPtr attrs,
uint32_t path_id, uint32_t flags, uint32_t label);
uint32_t path_id, uint32_t flags, uint32_t label,
uint32_t l3_label);
void InputCommonPostProcess(DBTablePartBase *root, BgpRoute *rt,
bool notify_rt);

Expand Down

0 comments on commit 3824962

Please sign in to comment.