Skip to content

Commit

Permalink
Apply VRF translate rule for DNAT traffic
Browse files Browse the repository at this point in the history
In case of multiple service chain policy RPF
has to be calculated after applying VRF translation rule.
Test case for same.
Add a check to see if mirror index exists before accessing the same.
Closes-bug:#1561775

Change-Id: I6b0f3d9bda8fd39829091c2706fcfe4fe6a56a2f
  • Loading branch information
naveen-n committed Apr 15, 2016
1 parent ecf90a7 commit 032aa59
Show file tree
Hide file tree
Showing 12 changed files with 426 additions and 338 deletions.
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/mirror_table.h
Expand Up @@ -73,6 +73,7 @@ class MirrorEntry : AgentRefCount<MirrorEntry>, public AgentDBEntry {
class MirrorTable : public AgentDBTable {
public:
const static unsigned bufLen = 512;
const static uint8_t kInvalidIndex = 0xFF;
typedef std::vector<MirrorEntry *> MirrorEntryList;
typedef std::map<std::string , MirrorEntryList> VrfMirrorEntryList;
typedef std::pair<std::string , MirrorEntryList> VrfMirrorEntry;
Expand Down
20 changes: 16 additions & 4 deletions src/vnsw/agent/pkt/flow_entry.cc
Expand Up @@ -737,6 +737,19 @@ void FlowEntry::set_acl_assigned_vrf_index() {
flow_table()->agent()->vrf_table()->FindActiveEntry(&vrf_key));
if (vrf) {
data_.acl_assigned_vrf_index_ = vrf->vrf_id();
bool set_dest_vrf = true;
if (is_flags_set(FlowEntry::NatFlow) &&
reverse_flow_entry() &&
key().dst_addr != reverse_flow_entry()->key().src_addr) {
//Packet is getting DNATed, VRF assign ACL action
//is applied on floating-ip VN and the destination VRF should
//be retained as interface VRF
set_dest_vrf = false;
}

if (set_dest_vrf) {
data_.dest_vrf = vrf->vrf_id();
}
return;
}
data_.acl_assigned_vrf_index_ = VrfEntry::kInvalidIndex;
Expand Down Expand Up @@ -1454,6 +1467,7 @@ bool FlowEntry::DoPolicy() {
data_.match_p.mirror_action = 0;
data_.match_p.out_mirror_action = 0;
data_.match_p.sg_action_summary = 0;

const string value = FlowPolicyStateStr.at(NOT_EVALUATED);
FlowPolicyInfo nw_acl_info(value), sg_acl_info(value);
FlowPolicyInfo rev_sg_acl_info(value);
Expand Down Expand Up @@ -1613,10 +1627,8 @@ FlowEntry::GetDestinationVrf() {
const VrfEntry *vrf = NULL;
VrfTable *vrf_table = flow_table()->agent()->vrf_table();

if (match_p().action_info.action &
(1 << TrafficAction::VRF_TRANSLATE)) {
vrf = vrf_table->FindVrfFromId(acl_assigned_vrf_index());
} else if (is_flags_set(FlowEntry::NatFlow)) {
if (is_flags_set(FlowEntry::NatFlow) ||
match_p().action_info.action & (1 << TrafficAction::VRF_TRANSLATE)) {
vrf = vrf_table->FindVrfFromId(data().dest_vrf);
} else {
vrf = vrf_table->FindVrfFromId(data().vrf);
Expand Down
3 changes: 3 additions & 0 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Expand Up @@ -869,6 +869,9 @@ void PktFlowInfo::FloatingIpDNat(const PktInfo *pkt, PktControlInfo *in,
flow_dest_plen_map);
out->vn_ = it->vn_.get();
dest_vrf = out->intf_->vrf()->vrf_id();
if (VrfTranslate(pkt, in, out, pkt->ip_saddr, true) == false) {
return;
}

// Translate the Dest-IP
if (nat_done == false)
Expand Down
2 changes: 2 additions & 0 deletions src/vnsw/agent/pkt/test/SConscript
Expand Up @@ -43,6 +43,8 @@ test_sg_flowv6 = AgentEnv.MakeTestCmd(env, 'test_sg_flowv6', pkt_test_suite)
test_sg_tcp_flow = AgentEnv.MakeTestCmd(env, 'test_sg_tcp_flow', pkt_flaky_test_suite)
test_vrf_assign_acl = AgentEnv.MakeTestCmd(env, 'test_vrf_assign_acl',
pkt_flaky_test_suite)
test_vrf_assign_acl_fip = AgentEnv.MakeTestCmd(env, 'test_vrf_assign_acl_fip',
pkt_test_suite)
test_ecmp_mx = AgentEnv.MakeTestCmd(env, 'test_ecmp_mx', pkt_test_suite)
test_fip_dst_ecmp = AgentEnv.MakeTestCmd(env, 'test_fip_dst_ecmp',
pkt_test_suite)
Expand Down
11 changes: 11 additions & 0 deletions src/vnsw/agent/pkt/test/test_ecmp_mx.cc
Expand Up @@ -224,6 +224,16 @@ TEST_F(EcmpTest, EcmpTest_5) {
//Reverse all the nexthop in vrf2
AddRemoteEcmpRoute("vrf2", "0.0.0.0", 0, "vn2", 4, true);

VnListType vn_list;
vn_list.insert("vn1");
Ip4Address ip = Ip4Address::from_string("1.1.1.1");
agent_->fabric_inet4_unicast_table()->
AddLocalVmRouteReq(agent_->local_peer(),
"vrf2", ip, 32, MakeUuid(1), vn_list,
vm1_label, SecurityGroupList(), CommunityList(),
false, PathPreference(), Ip4Address(0), EcmpLoadBalance());
client->WaitForIdle();

AddVrfAssignNetworkAcl("Acl", 10, "vn1", "vn2", "pass", "vrf2");
AddLink("virtual-network", "vn1", "access-control-list", "Acl");
client->WaitForIdle();
Expand All @@ -248,6 +258,7 @@ TEST_F(EcmpTest, EcmpTest_5) {

DeleteRoute("vrf1", "0.0.0.0", 0, bgp_peer);
DeleteRoute("vrf2", "0.0.0.0", 0, bgp_peer);
DeleteRoute("vrf2", "1.1.1.1", 32, agent_->local_peer());
DelLink("virtual-network", "vn1", "access-control-list", "Acl");
DelAcl("Acl");
client->WaitForIdle();
Expand Down
46 changes: 46 additions & 0 deletions src/vnsw/agent/pkt/test/test_flow_util.h
Expand Up @@ -325,6 +325,52 @@ class VerifyFlowAction : public FlowVerify {
TrafficAction::Action action_;
};

class VerifySrcDstVrf : public FlowVerify {
public:
VerifySrcDstVrf(std::string fwd_flow_src_vrf, std::string fwd_flow_dest_vrf,
std::string rev_flow_src_vrf, std::string rev_flow_dest_vrf):
fwd_flow_src_vrf_(fwd_flow_src_vrf),
fwd_flow_dest_vrf_(fwd_flow_dest_vrf),
rev_flow_src_vrf_(rev_flow_src_vrf),
rev_flow_dest_vrf_(rev_flow_dest_vrf) {};

virtual ~VerifySrcDstVrf() {};

void Verify(FlowEntry *fe) {
Agent *agent = Agent::GetInstance();
const VrfEntry *src_vrf =
agent->vrf_table()->FindVrfFromName(fwd_flow_src_vrf_);
EXPECT_TRUE(src_vrf != NULL);

const VrfEntry *dest_vrf =
agent->vrf_table()->FindVrfFromName(fwd_flow_dest_vrf_);
EXPECT_TRUE(dest_vrf != NULL);

EXPECT_TRUE(fe->data().vrf == src_vrf->vrf_id());
EXPECT_TRUE(fe->data().dest_vrf = dest_vrf->vrf_id());

FlowEntry *rev = fe->reverse_flow_entry();
EXPECT_TRUE(rev != NULL);

src_vrf =
agent->vrf_table()->FindVrfFromName(rev_flow_src_vrf_);
EXPECT_TRUE(src_vrf != NULL);

dest_vrf =
agent->vrf_table()->FindVrfFromName(rev_flow_dest_vrf_);
EXPECT_TRUE(dest_vrf != NULL);

EXPECT_TRUE(rev->data().vrf == src_vrf->vrf_id());
EXPECT_TRUE(rev->data().dest_vrf = dest_vrf->vrf_id());
}

private:
std::string fwd_flow_src_vrf_;
std::string fwd_flow_dest_vrf_;
std::string rev_flow_src_vrf_;
std::string rev_flow_dest_vrf_;
};

class VerifyVrf : public FlowVerify {
public:
VerifyVrf(std::string src_vrf, std::string dest_vrf):
Expand Down

0 comments on commit 032aa59

Please sign in to comment.