Skip to content

Commit

Permalink
Implement RouterMac extended community
Browse files Browse the repository at this point in the history
Change-Id: I50f29f797842c7554d7f0f0a6b13397e33444a7c
Partial-Bug: 1636654
  • Loading branch information
Nischal Sheth committed Oct 26, 2016
1 parent 1474bf4 commit 71f4086
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/bgp/bgp_attr.cc
Expand Up @@ -9,6 +9,7 @@

#include "bgp/bgp_server.h"
#include "bgp/extended-community/mac_mobility.h"
#include "bgp/extended-community/router_mac.h"
#include "net/bgp_af.h"

using std::sort;
Expand Down Expand Up @@ -966,6 +967,20 @@ uint32_t BgpAttr::sequence_number() const {
return 0;
}

MacAddress BgpAttr::mac_address() const {
if (!ext_community_)
return MacAddress::kZeroMac;
for (ExtCommunity::ExtCommunityList::const_iterator it =
ext_community_->communities().begin();
it != ext_community_->communities().end(); ++it) {
if (ExtCommunity::is_router_mac(*it)) {
RouterMac router_mac(*it);
return router_mac.mac_address();
}
}
return MacAddress::kZeroMac;
}

void BgpAttr::Remove() {
attr_db_->Delete(this);
}
Expand Down
2 changes: 2 additions & 0 deletions src/bgp/bgp_attr.h
Expand Up @@ -21,6 +21,7 @@
#include "bgp/community.h"
#include "net/address.h"
#include "net/esi.h"
#include "net/mac_address.h"
#include "net/rd.h"

class BgpAttr;
Expand Down Expand Up @@ -852,6 +853,7 @@ class BgpAttr {
BgpOListPtr leaf_olist() const { return leaf_olist_; }
BgpAttrDB *attr_db() const { return attr_db_; }
uint32_t sequence_number() const;
MacAddress mac_address() const;

private:
friend class BgpAttrDB;
Expand Down
8 changes: 8 additions & 0 deletions src/bgp/community.h
Expand Up @@ -217,6 +217,14 @@ class ExtCommunity {
(val[1] == BgpExtendedCommunityEvpnSubType::MacMobility);
}

static bool is_router_mac(const ExtCommunityValue &val) {
//
// Router MAC extended community
//
return (val[0] == BgpExtendedCommunityType::Evpn) &&
(val[1] == BgpExtendedCommunityEvpnSubType::RouterMac);
}

static bool is_route_target(const ExtCommunityValue &val) {
//
// Route target extended community
Expand Down
1 change: 1 addition & 0 deletions src/bgp/extended-community/SConscript
Expand Up @@ -18,6 +18,7 @@ libextended_community = env.Library('extended_community',
'esi_label.cc',
'load_balance.cc',
'mac_mobility.cc',
'router_mac.cc',
'site_of_origin.cc'])

extended_community_test_cases = env.SConscript('test/SConscript', exports='BuildEnv',
Expand Down
35 changes: 35 additions & 0 deletions src/bgp/extended-community/router_mac.cc
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
*/

#include "bgp/extended-community/router_mac.h"

#include <algorithm>
#include <string>

using std::copy;
using std::string;

RouterMac::RouterMac(const MacAddress &mac_addr) {
data_[0] = BgpExtendedCommunityType::Evpn;
data_[1] = BgpExtendedCommunityEvpnSubType::RouterMac;
copy(mac_addr.GetData(), mac_addr.GetData() + 6, data_.begin() + 2);
}

RouterMac::RouterMac(const bytes_type &data) {
copy(data.begin(), data.end(), data_.begin());
}

MacAddress RouterMac::mac_address() const {
uint8_t data[RouterMac::kSize];
copy(data_.begin(), data_.end(), &data[0]);
if (data[0] == BgpExtendedCommunityType::Evpn &&
data[1] == BgpExtendedCommunityEvpnSubType::RouterMac) {
return MacAddress(&data[2]);
}
return MacAddress::kZeroMac;
}

string RouterMac::ToString() {
return string("rtrmac:") + mac_address().ToString();
}
38 changes: 38 additions & 0 deletions src/bgp/extended-community/router_mac.h
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
*/

#ifndef SRC_BGP_EXTENDED_COMMUNITY_ROUTER_MAC_H_
#define SRC_BGP_EXTENDED_COMMUNITY_ROUTER_MAC_H_

#include <boost/array.hpp>
#include <boost/system/error_code.hpp>

#include <string>

#include "base/parse_object.h"
#include "bgp/extended-community/types.h"
#include "net/mac_address.h"

class RouterMac {
public:
static const int kSize = 8;
typedef boost::array<uint8_t, kSize> bytes_type;

explicit RouterMac(const MacAddress &mac_addr);
explicit RouterMac(const bytes_type &data);

MacAddress mac_address() const;

const bytes_type &GetExtCommunity() const { return data_; }

const uint64_t GetExtCommunityValue() const {
return get_value(data_.begin(), 8);
}
std::string ToString();

private:
bytes_type data_;
};

#endif // SRC_BGP_EXTENDED_COMMUNITY_ROUTER_MAC_H_
5 changes: 5 additions & 0 deletions src/bgp/extended-community/test/SConscript
Expand Up @@ -35,6 +35,10 @@ mac_mobility_test = env.UnitTest('mac_mobility_test',
['mac_mobility_test.cc'])
env.Alias('src/bgp/extended-community:mac_mobility_test', mac_mobility_test)

router_mac_test = env.UnitTest('router_mac_test',
['router_mac_test.cc'])
env.Alias('src/bgp/extended-community:router_mac_test', router_mac_test)

site_of_origin_test = env.UnitTest('site_of_origin_test',
['site_of_origin_test.cc'])
env.Alias('src/bgp/extended-community:site_of_origin_test', site_of_origin_test)
Expand All @@ -49,6 +53,7 @@ test_suite = [
esi_label_test,
load_balance_test,
mac_mobility_test,
router_mac_test,
site_of_origin_test,
]

Expand Down
67 changes: 67 additions & 0 deletions src/bgp/extended-community/test/router_mac_test.cc
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/

#include "bgp/extended-community/router_mac.h"

#include "bgp/community.h"
#include "testing/gunit.h"

using namespace std;

class RouterMacTest : public ::testing::Test {
};

TEST_F(RouterMacTest, ByteArray_1) {
RouterMac::bytes_type data = { {
BgpExtendedCommunityType::Evpn,
BgpExtendedCommunityEvpnSubType::RouterMac,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06
} };
RouterMac router_mac(data);
EXPECT_TRUE(ExtCommunity::is_router_mac(router_mac.GetExtCommunity()));
EXPECT_EQ("rtrmac:01:02:03:04:05:06", router_mac.ToString());
}

TEST_F(RouterMacTest, ByteArray_2) {
RouterMac::bytes_type data = { {
BgpExtendedCommunityType::Evpn,
BgpExtendedCommunityEvpnSubType::RouterMac,
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
} };
RouterMac router_mac(data);
EXPECT_TRUE(ExtCommunity::is_router_mac(router_mac.GetExtCommunity()));
EXPECT_EQ("rtrmac:0a:0b:0c:0d:0e:0f", router_mac.ToString());
}

TEST_F(RouterMacTest, MacAddress_1) {
boost::system::error_code ec;
MacAddress mac_addr = MacAddress::FromString("01:02:03:04:05:06", &ec);
EXPECT_EQ(0, ec.value());
RouterMac router_mac(mac_addr);
EXPECT_TRUE(ExtCommunity::is_router_mac(router_mac.GetExtCommunity()));
EXPECT_EQ("rtrmac:01:02:03:04:05:06", router_mac.ToString());
EXPECT_EQ(mac_addr, router_mac.mac_address());
RouterMac router_mac2(router_mac.GetExtCommunity());
EXPECT_EQ(router_mac.GetExtCommunityValue(),
router_mac2.GetExtCommunityValue());
}

TEST_F(RouterMacTest, MacAddress_2) {
boost::system::error_code ec;
MacAddress mac_addr = MacAddress::FromString("0a:0b:0c:0d:0e:0f", &ec);
EXPECT_EQ(0, ec.value());
RouterMac router_mac(mac_addr);
EXPECT_TRUE(ExtCommunity::is_router_mac(router_mac.GetExtCommunity()));
EXPECT_EQ("rtrmac:0a:0b:0c:0d:0e:0f", router_mac.ToString());
EXPECT_EQ(mac_addr, router_mac.mac_address());
RouterMac router_mac2(router_mac.GetExtCommunity());
EXPECT_EQ(router_mac.GetExtCommunityValue(),
router_mac2.GetExtCommunityValue());
}

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
int result = RUN_ALL_TESTS();
return result;
}
1 change: 1 addition & 0 deletions src/bgp/extended-community/types.h
Expand Up @@ -36,6 +36,7 @@ struct BgpExtendedCommunityEvpnSubType {
MacMobility = 0x00,
EsiMplsLabel = 0x01,
EsImport = 0x02,
RouterMac = 0x03,
};
};

Expand Down
26 changes: 26 additions & 0 deletions src/bgp/test/bgp_attr_test.cc
Expand Up @@ -14,9 +14,11 @@
#include "bgp/bgp_server.h"
#include "bgp/evpn/evpn_route.h"
#include "bgp/extended-community/mac_mobility.h"
#include "bgp/extended-community/router_mac.h"
#include "bgp/origin-vn/origin_vn.h"
#include "control-node/control_node.h"
#include "net/community_type.h"
#include "net/mac_address.h"

using boost::assign::list_of;
using boost::system::error_code;
Expand Down Expand Up @@ -1140,6 +1142,30 @@ TEST_F(BgpAttrTest, SequenceNumber2) {
EXPECT_EQ(13, attr->sequence_number());
}

TEST_F(BgpAttrTest, RouterMac1) {
BgpAttrSpec attr_spec;
ExtCommunitySpec spec;
for (int idx = 1; idx < 5; idx++)
spec.communities.push_back(100 * idx);
attr_spec.push_back(&spec);
BgpAttrPtr attr = attr_db_->Locate(attr_spec);
EXPECT_TRUE(attr->mac_address().IsZero());
}

TEST_F(BgpAttrTest, RouterMac2) {
BgpAttrSpec attr_spec;
boost::system::error_code ec;
MacAddress mac_addr = MacAddress::FromString("01:02:03:04:05:06", &ec);
EXPECT_EQ(0, ec.value());
RouterMac router_mac(mac_addr);
ExtCommunitySpec spec;
spec.communities.push_back(router_mac.GetExtCommunityValue());
attr_spec.push_back(&spec);
BgpAttrPtr attr = attr_db_->Locate(attr_spec);
EXPECT_FALSE(attr->mac_address().IsZero());
EXPECT_EQ(mac_addr, attr->mac_address());
}

TEST_F(BgpAttrTest, OriginVnPathToString) {
OriginVnPathSpec spec;
for (int idx = 1; idx < 5; idx++)
Expand Down

0 comments on commit 71f4086

Please sign in to comment.