Skip to content

Commit

Permalink
Merge "Make nexthops processing for inet6 routes more flexible"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jan 25, 2016
2 parents ecbb459 + b5fd6d2 commit cc92093
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 17 deletions.
29 changes: 24 additions & 5 deletions src/bgp/bgp_peer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1552,11 +1552,30 @@ BgpAttrPtr BgpPeer::GetMpNlriNexthop(BgpMpNlri *nlri, BgpAttrPtr attr) {
}
} else if (nlri->afi == BgpAf::IPv6) {
if (nlri->safi == BgpAf::Unicast) {
Ip6Address::bytes_type bt = { { 0 } };
copy(nlri->nexthop.begin(),
nlri->nexthop.begin() + sizeof(bt), bt.begin());
addr = Ip6Address(bt);
update_nh = true;
// There could be either 1 or 2 v6 addresses in the nexthop field.
// The first one is supposed to be global and the optional second
// one, if present, is link local. We will be liberal and find the
// global address, whether it's first or second. Further, if the
// address is a v4-mapped v6 address, we use the corresponding v4
// address as the nexthop.
for (int idx = 0; idx < 2; ++idx) {
Ip6Address::bytes_type bt = { { 0 } };
if ((idx + 1) * sizeof(bt) > nlri->nexthop.size())
break;
copy(nlri->nexthop.begin() + idx * sizeof(bt),
nlri->nexthop.begin() + (idx + 1) * sizeof(bt), bt.begin());
Ip6Address v6_addr(bt);
if (v6_addr.is_v4_mapped()) {
addr = Address::V4FromV4MappedV6(v6_addr);
update_nh = true;
break;
}
if (!v6_addr.is_link_local()) {
addr = v6_addr;
update_nh = true;
break;
}
}
} else if (nlri->safi == BgpAf::Vpn) {
Ip6Address::bytes_type bt = { { 0 } };
size_t rdsize = RouteDistinguisher::kSize;
Expand Down
12 changes: 11 additions & 1 deletion src/bgp/inet6/inet6_route.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,20 @@ void Inet6Route::BuildProtoPrefix(BgpProtoPrefix *prefix,
back_inserter(prefix->prefix));
}

//
// Fill in the vector based on the supplied nexthop.
//
void Inet6Route::BuildBgpProtoNextHop(vector<uint8_t> &nh,
IpAddress nexthop) const {
nh.resize(Address::kMaxV6Bytes);
const Ip6Address::bytes_type &addr_bytes = nexthop.to_v6().to_bytes();
Ip6Address address;
if (nexthop.is_v4()) {
address = Ip6Address::v4_mapped(nexthop.to_v4());
} else {
address = nexthop.to_v6();
}

const Ip6Address::bytes_type &addr_bytes = address.to_bytes();
copy(addr_bytes.begin(), addr_bytes.end(), nh.begin());
}

Expand Down
11 changes: 10 additions & 1 deletion src/bgp/test/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ bgp_ip_test = env.UnitTest('bgp_ip_test',
['bgp_ip_test.cc'])
env.Alias('src/bgp:bgp_ip_test', bgp_ip_test)

bgp_ip_test1 = env.UnitTest('bgp_ip_test1',
['bgp_ip_test1.cc'])
env.Alias('src/bgp:bgp_ip_test1', bgp_ip_test1)

bgp_ip_test2 = env.UnitTest('bgp_ip_test2',
['bgp_ip_test2.cc'])
env.Alias('src/bgp:bgp_ip_test2', bgp_ip_test2)

bgp_msg_builder_test = env.UnitTest('bgp_msg_builder_test',
['bgp_msg_builder_test.cc'])
env.Alias('src/bgp:bgp_msg_builder_test', bgp_msg_builder_test)
Expand Down Expand Up @@ -528,7 +536,8 @@ test_suite = [
bgp_export_rstate_test,
bgp_export_rtupdate_test,
bgp_export_uplist_test,
bgp_ip_test,
bgp_ip_test1,
bgp_ip_test2,
bgp_msg_builder_test,
bgp_multicast_test,
bgp_peer_close_test,
Expand Down
55 changes: 45 additions & 10 deletions src/bgp/test/bgp_ip_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/

#include <boost/assign/list_of.hpp>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

#include "base/test/task_test_util.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_session_manager.h"
Expand All @@ -12,6 +16,7 @@
#include "control-node/control_node.h"
#include "testing/gunit.h"

using namespace boost::program_options;
using std::string;

class PeerMock : public IPeer {
Expand Down Expand Up @@ -81,20 +86,22 @@ static const char *cfg_template = "\
</config>\
";

// Overlay nexthop address family.
static bool nexthop_family_is_inet;

//
// Template structure to pass to fixture class template. Needed because
// gtest fixture class template can accept only one template parameter.
//
template <typename T1, typename T2, typename T3>
template <typename T1, typename T2>
struct TypeDefinition {
typedef T1 TableT;
typedef T2 PrefixT;
typedef T3 AddressT;
};

// TypeDefinitions that we want to test.
typedef TypeDefinition<InetTable, Ip4Prefix, Ip4Address> InetDefinition;
typedef TypeDefinition<Inet6Table, Inet6Prefix, Ip6Address> Inet6Definition;
typedef TypeDefinition<InetTable, Ip4Prefix> InetDefinition;
typedef TypeDefinition<Inet6Table, Inet6Prefix> Inet6Definition;

//
// Fixture class template - instantiated later for each TypeDefinition.
Expand All @@ -104,7 +111,6 @@ class BgpIpTest : public ::testing::Test {
protected:
typedef typename T::TableT TableT;
typedef typename T::PrefixT PrefixT;
typedef typename T::AddressT AddressT;

BgpIpTest()
: thread_(&evm_),
Expand All @@ -114,7 +120,7 @@ class BgpIpTest : public ::testing::Test {
peer_yx_(NULL),
family_(GetFamily()),
master_(BgpConfigManager::kMasterInstance),
ipv6_prefix_("::ffff:") {
ipv6_prefix_("::") {
bs_x_.reset(new BgpServerTest(&evm_, "X"));
bs_x_->session_manager()->Initialize(0);
bs_y_.reset(new BgpServerTest(&evm_, "Y"));
Expand Down Expand Up @@ -197,7 +203,11 @@ class BgpIpTest : public ::testing::Test {
return ipv4_addr;
}
if (family_ == Address::INET6) {
return ipv6_prefix_ + ipv4_addr;
if (nexthop_family_is_inet) {
return ipv4_addr;
} else {
return ipv6_prefix_ + ipv4_addr;
}
}
assert(false);
return "";
Expand Down Expand Up @@ -252,7 +262,7 @@ class BgpIpTest : public ::testing::Test {
path_spec.path_segments.push_back(path_seg);
attr_spec.push_back(&path_spec);

AddressT nh_addr = AddressT::from_string(nexthop_str, ec);
IpAddress nh_addr = IpAddress::from_string(nexthop_str, ec);
EXPECT_FALSE(ec);
BgpAttrNextHop nh_spec(nh_addr);
attr_spec.push_back(&nh_spec);
Expand Down Expand Up @@ -544,12 +554,37 @@ static void TearDown() {
scheduler->Terminate();
}

int main(int argc, char **argv) {
static void process_command_line_args(int argc, const char **argv) {
options_description desc("BgpIpTest");
desc.add_options()
("help", "produce help message")
("nexthop-address-family", value<string>()->default_value("inet"),
"set nexthop address family (inet/inet6)");
variables_map vm;
store(parse_command_line(argc, argv, desc), vm);
notify(vm);

if (vm.count("nexthop-address-family")) {
nexthop_family_is_inet =
(vm["nexthop-address-family"].as<string>() == "inet");
}
}

int bgp_ip_test_main(int argc, const char **argv) {
bgp_log_test::init();
::testing::InitGoogleTest(&argc, argv);
::testing::InitGoogleTest(&argc, const_cast<char **>(argv));
::testing::AddGlobalTestEnvironment(new TestEnvironment());
process_command_line_args(argc, const_cast<const char **>(argv));
SetUp();
int result = RUN_ALL_TESTS();
TearDown();
return result;
}

#ifndef __BGP_IP_TEST_WRAPPER_TEST_SUITE__

int main(int argc, char **argv) {
return bgp_ip_test_main(argc, const_cast<const char **>(argv));
}

#endif
14 changes: 14 additions & 0 deletions src/bgp/test/bgp_ip_test1.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#define __BGP_IP_TEST_WRAPPER_TEST_SUITE__
#include "bgp_ip_test.cc"

int main(int argc, char **argv) {
const char *largv[] = {
__FILE__,
"--nexthop-address-family=inet",
};
return bgp_ip_test_main(sizeof(largv)/sizeof(largv[0]), largv);
}

14 changes: 14 additions & 0 deletions src/bgp/test/bgp_ip_test2.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#define __BGP_IP_TEST_WRAPPER_TEST_SUITE__
#include "bgp_ip_test.cc"

int main(int argc, char **argv) {
const char *largv[] = {
__FILE__,
"--nexthop-address-family=inet6",
};
return bgp_ip_test_main(sizeof(largv)/sizeof(largv[0]), largv);
}

0 comments on commit cc92093

Please sign in to comment.