Skip to content

Commit

Permalink
Use label as 24-bit field when encoding/decoding VNI
Browse files Browse the repository at this point in the history
Change-Id: I60cdae79cf4a8b60ebb9ed271ccafca4193d4a91
Closes-Bug: 1464781
  • Loading branch information
Nischal Sheth committed Jun 12, 2015
1 parent 97e195a commit b9d636a
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 14 deletions.
20 changes: 18 additions & 2 deletions src/bgp/bgp_attr_base.cc
Expand Up @@ -12,16 +12,32 @@ const size_t BgpProtoPrefix::kLabelSize = 3;
BgpProtoPrefix::BgpProtoPrefix() : prefixlen(0), type(0) {
}

uint32_t BgpProtoPrefix::ReadLabel(size_t label_offset) const {
//
// Extract the label from the BgpProtorefix.
// EVPN extensions for VXLAN use the label to convey a 24-bit VNI.
//
uint32_t BgpProtoPrefix::ReadLabel(size_t label_offset, bool is_vni) const {
assert((label_offset + kLabelSize) <= prefix.size());
if (is_vni)
return get_value(&prefix[label_offset], kLabelSize);
uint32_t label = (prefix[label_offset] << 16 |
prefix[label_offset + 1] << 8 |
prefix[label_offset + 2]) >> 4;
return label;
}

void BgpProtoPrefix::WriteLabel(size_t label_offset, uint32_t label) {
//
// Write the label to the BgpProtorefix.
// EVPN extensions for VXLAN use the label to convey a 24-bit VNI.
//
void BgpProtoPrefix::WriteLabel(size_t label_offset, uint32_t label,
bool is_vni) {
assert((label_offset + kLabelSize) <= prefix.size());
if (is_vni) {
assert(label <= 0xFFFFFF);
put_value(&prefix[label_offset], kLabelSize, label);
return;
}
assert(label <= 0xFFFFF);
uint32_t tmp = (label << 4 | 0x1);
for (size_t idx = 0; idx < kLabelSize; ++idx) {
Expand Down
4 changes: 2 additions & 2 deletions src/bgp/bgp_attr_base.h
Expand Up @@ -96,8 +96,8 @@ struct BgpProtoPrefix : public ParseObject {

BgpProtoPrefix();

uint32_t ReadLabel(size_t label_offset) const;
void WriteLabel(size_t label_offset, uint32_t label);
uint32_t ReadLabel(size_t label_offset, bool is_vni = false) const;
void WriteLabel(size_t label_offset, uint32_t label, bool is_vni = false);

std::vector<uint8_t> prefix;
int prefixlen;
Expand Down
14 changes: 14 additions & 0 deletions src/bgp/community.cc
Expand Up @@ -212,6 +212,20 @@ vector<string> ExtCommunity::GetTunnelEncap() const {
return encap_list;
}

bool ExtCommunity::ContainsTunnelEncapVxlan() const {
for (ExtCommunityList::const_iterator iter = communities_.begin();
iter != communities_.end(); ++iter) {
if (!ExtCommunity::is_tunnel_encap(*iter))
continue;
TunnelEncap encap(*iter);
if (encap.tunnel_encap() == TunnelEncapType::VXLAN)
return true;
if (encap.tunnel_encap() == TunnelEncapType::VXLAN_CONTRAIL)
return true;
}
return false;
}

ExtCommunity::ExtCommunity(ExtCommunityDB *extcomm_db,
const ExtCommunitySpec spec) : extcomm_db_(extcomm_db) {
refcount_ = 0;
Expand Down
1 change: 1 addition & 0 deletions src/bgp/community.h
Expand Up @@ -163,6 +163,7 @@ class ExtCommunity {
}

std::vector<std::string> GetTunnelEncap() const;
bool ContainsTunnelEncapVxlan() const;

static bool is_origin_vn(const ExtCommunityValue &val) {
//
Expand Down
46 changes: 36 additions & 10 deletions src/bgp/evpn/evpn_route.cc
Expand Up @@ -34,6 +34,36 @@ const size_t EvpnPrefix::kMinInclusiveMulticastRouteSize =
const size_t EvpnPrefix::kMinSegmentRouteSize =
kRdSize + kEsiSize + 1;

//
// Read label from the BgpProtoPrefix.
// If the encapsulation is VXLAN and ethernet tag is non-zero use that as
// the label for backward compatibility with older JUNOS code.
//
static uint32_t ReadLabel(const BgpProtoPrefix &proto_prefix,
const BgpAttr *attr, size_t offset, uint32_t tag) {
if (!attr)
return 0;
const ExtCommunity *extcomm = attr->ext_community();
if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
return (tag ? tag : proto_prefix.ReadLabel(offset, true));
} else {
return proto_prefix.ReadLabel(offset, false);
}
}

//
// Write label to the BgpProtoPrefix.
//
static void WriteLabel(BgpProtoPrefix *proto_prefix,
const BgpAttr *attr, size_t offset, uint32_t label) {
const ExtCommunity *extcomm = attr ? attr->ext_community() : NULL;
if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
proto_prefix->WriteLabel(offset, label, true);
} else {
proto_prefix->WriteLabel(offset, label, false);
}
}

EvpnPrefix::EvpnPrefix()
: type_(Unspecified), tag_(EvpnPrefix::kNullTag), family_(Address::UNSPEC) {
}
Expand Down Expand Up @@ -111,10 +141,8 @@ int EvpnPrefix::FromProtoPrefix(BgpServer *server,
prefix->esi_ = EthernetSegmentId(&proto_prefix.prefix[esi_offset]);
size_t tag_offset = esi_offset + kEsiSize;
prefix->tag_ = get_value(&proto_prefix.prefix[tag_offset], kTagSize);
if (attr) {
size_t label_offset = tag_offset + kTagSize;
*label = proto_prefix.ReadLabel(label_offset);
}
size_t label_offset = tag_offset + kTagSize;
*label = ReadLabel(proto_prefix, attr, label_offset, prefix->tag_);
break;
}
case MacAdvertisementRoute: {
Expand Down Expand Up @@ -146,10 +174,8 @@ int EvpnPrefix::FromProtoPrefix(BgpServer *server,
return -1;
size_t ip_offset = ip_len_offset + 1;
prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size);
if (attr) {
size_t label_offset = ip_offset + ip_size;
*label = proto_prefix.ReadLabel(label_offset);
}
size_t label_offset = ip_offset + ip_size;
*label = ReadLabel(proto_prefix, attr, label_offset, prefix->tag_);
break;
}
case InclusiveMulticastRoute: {
Expand Down Expand Up @@ -231,7 +257,7 @@ void EvpnPrefix::BuildProtoPrefix(const BgpAttr *attr, uint32_t label,
size_t tag_offset = esi_offset + kEsiSize;
put_value(&proto_prefix->prefix[tag_offset], kTagSize, tag_);
size_t label_offset = tag_offset + kTagSize;
proto_prefix->WriteLabel(label_offset, label);
WriteLabel(proto_prefix, attr, label_offset, label);
break;
}
case MacAdvertisementRoute: {
Expand Down Expand Up @@ -260,7 +286,7 @@ void EvpnPrefix::BuildProtoPrefix(const BgpAttr *attr, uint32_t label,
size_t ip_offset = ip_len_offset + 1;
WriteIpAddress(proto_prefix, ip_offset);
size_t label_offset = ip_offset + ip_size;
proto_prefix->WriteLabel(label_offset, label);
WriteLabel(proto_prefix, attr, label_offset, label);
break;
}
case InclusiveMulticastRoute: {
Expand Down

0 comments on commit b9d636a

Please sign in to comment.