Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Handle RPF check failure for floating-ip ecmp.
Change-Id: Icf21c3a40783c9b4ff22e5340ae6599f2c293551 Closes-bug:#1555000
- Loading branch information
Showing
6 changed files
with
1,044 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. | ||
*/ | ||
#include "base/os.h" | ||
#include "test/test_cmn_util.h" | ||
#include "test_pkt_util.h" | ||
#include "pkt/flow_proto.h" | ||
|
||
#define AGE_TIME 10*1000 | ||
|
||
void RouterIdDepInit(Agent *agent) { | ||
} | ||
|
||
struct PortInfo input1[] = { | ||
{"vnet1", 1, "1.1.1.1", "00:00:00:01:01:01", 1, 1}, | ||
{"vnet2", 2, "1.1.1.1", "00:00:00:01:01:01", 1, 2} | ||
}; | ||
|
||
class EcmpTest : public ::testing::Test { | ||
virtual void SetUp() { | ||
agent_ = Agent::GetInstance(); | ||
|
||
boost::system::error_code ec; | ||
bgp_peer = CreateBgpPeer(Ip4Address::from_string("0.0.0.1", ec), | ||
"xmpp channel"); | ||
client->WaitForIdle(); | ||
|
||
flow_proto_ = agent_->pkt()->get_flow_proto(); | ||
CreateVmportWithEcmp(input1, 2); | ||
AddVn("vn2", 2); | ||
AddVrf("vrf2"); | ||
client->WaitForIdle(); | ||
strcpy(router_id, agent_->router_id().to_string().c_str()); | ||
strcpy(MX_0, "100.1.1.1"); | ||
strcpy(MX_1, "100.1.1.2"); | ||
strcpy(MX_2, "100.1.1.3"); | ||
strcpy(MX_3, "100.1.1.4"); | ||
|
||
const VmInterface *vmi = static_cast<const VmInterface *>(VmPortGet(1)); | ||
vm1_label = vmi->label(); | ||
vmi = static_cast<const VmInterface *>(VmPortGet(2)); | ||
vm2_label = vmi->label(); | ||
eth_intf_id = EthInterfaceGet("vnet0")->id(); | ||
} | ||
|
||
virtual void TearDown() { | ||
DeleteVmportEnv(input1, 2, true); | ||
DelVn("vn2"); | ||
DelVrf("vrf2"); | ||
client->WaitForIdle(); | ||
DeleteBgpPeer(bgp_peer); | ||
client->WaitForIdle(); | ||
EXPECT_FALSE(VrfFind("vrf1", true)); | ||
EXPECT_FALSE(VrfFind("vrf2", true)); | ||
WAIT_FOR(1000, 1000, (flow_proto_->FlowCount() == 0)); | ||
client->WaitForIdle(); | ||
} | ||
public: | ||
void AddRemoteEcmpRoute(const string vrf_name, const string ip, | ||
uint32_t plen, const string vn, int count, bool reverse = false, | ||
bool same_label = false) { | ||
//If there is a local route, include that always | ||
Ip4Address vm_ip = Ip4Address::from_string(ip); | ||
|
||
ComponentNHKeyList comp_nh_list; | ||
int remote_server_ip = 0x64010101; | ||
int label = 16; | ||
SecurityGroupList sg_id_list; | ||
|
||
for(int i = 0; i < count; i++) { | ||
ComponentNHKeyPtr comp_nh(new ComponentNHKey( | ||
label, Agent::GetInstance()->fabric_vrf_name(), | ||
Agent::GetInstance()->router_id(), | ||
Ip4Address(remote_server_ip++), | ||
false, TunnelType::AllType())); | ||
comp_nh_list.push_back(comp_nh); | ||
if (!same_label) { | ||
label++; | ||
} | ||
} | ||
if (reverse) { | ||
std::reverse(comp_nh_list.begin(), comp_nh_list.end()); | ||
} | ||
|
||
EcmpTunnelRouteAdd(bgp_peer, vrf_name, vm_ip, plen, | ||
comp_nh_list, -1, vn, sg_id_list, | ||
PathPreference()); | ||
} | ||
|
||
FlowProto *get_flow_proto() const { return flow_proto_; } | ||
Agent *agent_; | ||
Peer *bgp_peer; | ||
FlowProto *flow_proto_; | ||
AgentXmppChannel *channel; | ||
char router_id[80]; | ||
char MX_0[80]; | ||
char MX_1[80]; | ||
char MX_2[80]; | ||
char MX_3[80]; | ||
int vm1_label; | ||
int vm2_label; | ||
int agg_label; | ||
int eth_intf_id; | ||
}; | ||
|
||
//Send packet from ECMP VM to ECMP MX | ||
//Verify component index is set and correspnding | ||
//rpf nexthop | ||
TEST_F(EcmpTest, EcmpTest_1) { | ||
AddRemoteEcmpRoute("vrf1", "0.0.0.0", 0, "vn1", 4); | ||
AddRemoteEcmpRoute("vrf1", "1.1.1.1", 32, "vn1", 4); | ||
|
||
TxIpPacket(VmPortGetId(1), "1.1.1.1", "2.1.1.1", 1); | ||
client->WaitForIdle(); | ||
|
||
AgentRoute *rt = RouteGet("vrf1", Ip4Address::from_string("0.0.0.0"), 0); | ||
InetUnicastRouteEntry *src_rt = static_cast<InetUnicastRouteEntry *>( | ||
RouteGet("vrf1", Ip4Address::from_string("1.1.1.1"), 32)); | ||
|
||
FlowEntry *entry = FlowGet(VrfGet("vrf1")->vrf_id(), | ||
"1.1.1.1", "2.1.1.1", 1, 0, 0, GetFlowKeyNH(1)); | ||
EXPECT_TRUE(entry != NULL); | ||
EXPECT_TRUE(entry->data().component_nh_idx != | ||
CompositeNH::kInvalidComponentNHIdx); | ||
EXPECT_TRUE(entry->data().nh.get() == src_rt->GetLocalNextHop()); | ||
|
||
//Reverse flow is no ECMP | ||
FlowEntry *rev_entry = entry->reverse_flow_entry(); | ||
EXPECT_TRUE(rev_entry->data().component_nh_idx != | ||
CompositeNH::kInvalidComponentNHIdx); | ||
EXPECT_TRUE(rev_entry->data().nh.get() == rt->GetActiveNextHop()); | ||
|
||
DeleteRoute("vrf1", "0.0.0.0", 0, bgp_peer); | ||
client->WaitForIdle(); | ||
sleep(1); | ||
client->WaitForIdle(); | ||
WAIT_FOR(1000, 1000, (get_flow_proto()->FlowCount() == 0)); | ||
} | ||
|
||
int main(int argc, char *argv[]) { | ||
GETUSERARGS(); | ||
client = TestInit(init_file, ksync_init, true, true, true, 100*1000); | ||
int ret = RUN_ALL_TESTS(); | ||
client->WaitForIdle(); | ||
TestShutdown(); | ||
delete client; | ||
return ret; | ||
} |
Oops, something went wrong.