Skip to content

Commit

Permalink
Merge "Handle SIMPLE_GATEWAY interface in NHDecode()" into R2.20
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jul 16, 2015
2 parents 74522a7 + af7e38e commit 642f3f8
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Expand Up @@ -155,6 +155,18 @@ static const NextHop* GetPolicyDisabledNH(const NextHop *nh) {
Agent::GetInstance()->nexthop_table()->FindActiveEntry(key.get()));
}

static bool IsVgwOrVmInterface(const Interface *intf) {
if (intf->type() == Interface::VM_INTERFACE)
return true;

if (intf->type() == Interface::INET) {
const InetInterface *inet = static_cast<const InetInterface *>(intf);
if (inet->sub_type() == InetInterface::SIMPLE_GATEWAY)
return true;
}
return false;
}

// Get interface from a NH. Also, decode ECMP information from NH
// Responsible to set following fields,
// out->nh_ : outgoing Nexthop Index. Will also be used to set reverse flow-key
Expand Down Expand Up @@ -343,8 +355,7 @@ static bool NhDecode(const NextHop *nh, const PktInfo *pkt, PktFlowInfo *info,
if (!out->intf_->IsActive()) {
out->intf_ = NULL;
ret = false;
} else if (force_vmport &&
out->intf_->type() != Interface::VM_INTERFACE) {
} else if (force_vmport && IsVgwOrVmInterface(out->intf_) == false) {
out->intf_ = NULL;
out->vrf_ = NULL;
ret = true;
Expand Down Expand Up @@ -1120,6 +1131,11 @@ void PktFlowInfo::EgressProcess(const PktInfo *pkt, PktControlInfo *in,
l3_flow = true;
}
}

if (out->vrf_ == NULL) {
return;
}

UpdateRoute(&out->rt_, out->vrf_, pkt->ip_daddr, pkt->dmac,
flow_dest_plen_map);
UpdateRoute(&in->rt_, out->vrf_, pkt->ip_saddr, pkt->smac,
Expand Down
6 changes: 6 additions & 0 deletions src/vnsw/agent/test/test_cmn_util.h
Expand Up @@ -243,6 +243,12 @@ void DelLinkLocalConfig();
void DeleteGlobalVrouterConfig();
void send_icmp(int fd, uint8_t smac, uint8_t dmac, uint32_t sip, uint32_t dip);
bool FlowStats(FlowIp *input, int id, uint32_t bytes, uint32_t pkts);
void AddVmPort(const char *vmi, int intf_id, const char *ip, const char *mac,
const char *vrf, const char *vn, int vn_uuid, const char *vm,
int vm_uuid, const char *instance_ip, int instance_uuid);
void DelVmPort(const char *vmi, int intf_id, const char *ip, const char *mac,
const char *vrf, const char *vn, int vn_uuid, const char *vm,
int vm_uuid, const char *instance_ip, int instance_uuid);
void DeleteVmportEnv(struct PortInfo *input, int count, int del_vn, int acl_id = 0,
const char *vn = NULL, const char *vrf = NULL,
bool with_ip = false, bool with_ip6 = false);
Expand Down
67 changes: 67 additions & 0 deletions src/vnsw/agent/test/test_util.cc
Expand Up @@ -2058,6 +2058,73 @@ bool FlowStats(FlowIp *input, int id, uint32_t bytes, uint32_t pkts) {
return false;
}

void AddVmPort(const char *vmi, int intf_id, const char *ip, const char *mac,
const char *vrf, const char *vn, int vn_uuid, const char *vm,
int vm_uuid, const char *instance_ip, int instance_uuid) {
struct PortInfo input[] = {
{"", 0, "", "", 0, 0 }
};

strcpy(input[0].name, vmi);
input[0].intf_id = intf_id;
strcpy(input[0].addr, ip);
strcpy(input[0].mac, mac);
input[0].vn_id = vn_uuid;
input[0].vm_id = vm_uuid;

AddVn(vn, vn_uuid);
AddVrf(vrf);
AddVm(vm, vm_uuid);
AddPort(vmi, intf_id);
AddVmPortVrf(vmi, "", 0);
IntfCfgAdd(input, 0);
AddInstanceIp(instance_ip, instance_uuid, ip);
AddLink("virtual-machine-interface", vmi, "virtual-network", vn);
AddLink("virtual-network", vn, "routing-instance", vrf);
AddLink("virtual-machine", vm, "virtual-machine-interface", vmi);
AddLink("virtual-machine-interface-routing-instance", vmi,
"routing-instance", vrf);
AddLink("virtual-machine-interface-routing-instance", vmi,
"virtual-machine-interface", vmi);
AddLink("virtual-machine-interface", vmi, "instance-ip", instance_ip);
client->WaitForIdle();
}

void DelVmPort(const char *vmi, int intf_id, const char *ip, const char *mac,
const char *vrf, const char *vn, int vn_uuid, const char *vm,
int vm_uuid, const char *instance_ip, int instance_uuid) {
struct PortInfo input[] = {
{"", 0, "", "", 0, 0 }
};

strcpy(input[0].name, vmi);
input[0].intf_id = intf_id;
strcpy(input[0].addr, ip);
strcpy(input[0].mac, mac);
input[0].vn_id = vn_uuid;
input[0].vm_id = vm_uuid;

DelLink("virtual-machine-interface", vmi, "virtual-network", vm);
DelLink("virtual-network", vn, "routing-instance", vrf);
DelLink("virtual-machine", vm, "virtual-machine-interface", vmi);
DelLink("virtual-machine-interface-routing-instance", vmi,
"routing-instance", vrf);
DelLink("virtual-machine-interface-routing-instance", vmi,
"virtual-machine-interface", vmi);
DelLink("virtual-machine-interface", vmi,
"instance-ip", instance_ip);
DelVn(vn);
DelVrf(vrf);
DelVm(vm);
DelPort(vmi);
DelVmPortVrf(vmi);
DelInstanceIp(instance_ip);
IntfCfgDel(input, 0);
DelNode("virtual-machine-interface", vmi);
DelNode("virtual-machine-interface-routing-instance", vmi);
client->WaitForIdle();
}

void DeleteVmportFIpEnv(struct PortInfo *input, int count, int del_vn, int acl_id,
const char *vn, const char *vrf) {
char vn_name[80];
Expand Down
81 changes: 81 additions & 0 deletions src/vnsw/agent/vgw/test/test_vgw.cc
Expand Up @@ -11,6 +11,7 @@
#include "vgw/cfg_vgw.h"
#include "vgw/vgw.h"
#include "oper/mpls.h"
#include "pkt/test/test_flow_util.h"

namespace opt = boost::program_options;

Expand All @@ -20,13 +21,15 @@ void RouterIdDepInit(Agent *agent) {
class VgwTest : public ::testing::Test {
public:
virtual void SetUp() {
agent_ = Agent::GetInstance();
}

virtual void TearDown() {
}

opt::options_description desc;
opt::variables_map var_map;
Agent *agent_;
};

TEST_F(VgwTest, conf_file_1) {
Expand Down Expand Up @@ -248,6 +251,84 @@ TEST_F(VgwTest, RouteResync) {
ValidateVgwInterface(route, "vgw");
}

TEST_F(VgwTest, IngressFlow_1) {
AddVmPort("vnet2", 2, "2.2.2.3", "00:00:02:02:02:03",
"default-domain:admin:public:public",
"default-domain:admin:public", 2, "vm2", 2, "instance-ip-2", 2);
WAIT_FOR(1000, 100, (VmPortFind(2) == true));
VmInterface *vmi = static_cast<VmInterface *>(VmPortGet(2));
EXPECT_TRUE(vmi != NULL);

const InetInterface *gw = InetInterfaceGet("vgw");
EXPECT_TRUE(gw != NULL);
if (gw == NULL)
return;
TestFlow flow[] = {
{
TestFlowPkt(Address::INET, "2.2.2.2", "100.100.100.100", 1, 0, 0,
"default-domain:admin:public:public", vmi->id()),
},
};
CreateFlow(flow, 1);
client->WaitForIdle();

FlowEntry *fe = FlowGet(vmi->vrf_id(), "2.2.2.2", "100.100.100.100",
1, 0, 0, vmi->flow_key_nh()->id());
EXPECT_TRUE(fe != NULL);

DeleteFlow(flow, 1);
client->WaitForIdle();
WAIT_FOR(1000, 100, (agent_->pkt()->flow_table()->Size() == 0));

DelVmPort("vnet2", 2, "2.2.2.3", "00:00:02:02:02:03",
"default-domain:admin:public:public",
"default-domain:admin:public", 2, "vm2", 2, "instance-ip-2", 2);
client->WaitForIdle();

EXPECT_FALSE(VmPortFind(2));
WAIT_FOR(1000, 100, (VmPortFind(2) == false));
}

TEST_F(VgwTest, EgressFlow_1) {
AddVmPort("vnet2", 2, "2.2.2.3", "00:00:02:02:02:03",
"default-domain:admin:public:public",
"default-domain:admin:public", 2, "vm2", 2, "instance-ip-2", 2);
WAIT_FOR(1000, 100, (VmPortFind(2) == true));
VmInterface *vmi = static_cast<VmInterface *>(VmPortGet(2));
EXPECT_TRUE(vmi != NULL);

const InetInterface *gw = InetInterfaceGet("vgw");
EXPECT_TRUE(gw != NULL);
if (gw == NULL)
return;
TestFlow flow[] = {
{
TestFlowPkt(Address::INET, "100.100.100.100", "2.2.2.2", 1, 0, 0,
"default-domain:admin:public:public", "20.20.20.20",
gw->label()),
},
};
CreateFlow(flow, 1);
client->WaitForIdle();

MplsLabel *label = GetActiveLabel(MplsLabel::VPORT_NH, gw->label());
FlowEntry *fe = FlowGet(vmi->vrf_id(), "100.100.100.100", "2.2.2.2",
1, 0, 0, label->nexthop()->id());
EXPECT_TRUE(fe != NULL);

DeleteFlow(flow, 1);
client->WaitForIdle();
WAIT_FOR(1000, 100, (agent_->pkt()->flow_table()->Size() == 0));

DelVmPort("vnet2", 2, "2.2.2.3", "00:00:02:02:02:03",
"default-domain:admin:public:public",
"default-domain:admin:public", 2, "vm2", 2, "instance-ip-2", 2);
client->WaitForIdle();

EXPECT_FALSE(VmPortFind(2));
WAIT_FOR(1000, 100, (VmPortFind(2) == false));
}

int main(int argc, char **argv) {
GETUSERARGS();

Expand Down

0 comments on commit 642f3f8

Please sign in to comment.