Skip to content

Commit

Permalink
* Dont apply interface VRF assign rule when packet gets NATed
Browse files Browse the repository at this point in the history
Interface VRF assign rules are ysed to steer traffic thru service
instances in service chain. If a packet gets NATed then destination
VRF should be set to native VRF of interface to which the floating
ip belong, and in this case there is no need to apply VRF translation
rule. Test case to verify the same.
Closes-bug:#1465728

Change-Id: I19ae3dda079269f7f7d041ebfd110c37c01f16c1
  • Loading branch information
naveen-n committed Jun 19, 2015
1 parent 5a72c7e commit 111cec1
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 8 deletions.
6 changes: 5 additions & 1 deletion src/vnsw/agent/pkt/flow_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,11 @@ void FlowEntry::GetVrfAssignAcl() {
//If interface has a VRF assign rule, choose the acl and match the
//packet, else get the acl attached to VN and try matching the packet to
//network acl
const AclDBEntry* acl = intf->vrf_assign_acl();
const AclDBEntry* acl = NULL;
if (is_flags_set(FlowEntry::NatFlow) == false) {
acl = intf->vrf_assign_acl();
}

if (acl == NULL) {
acl = data_.vn_entry.get()->GetAcl();
}
Expand Down
16 changes: 11 additions & 5 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ void PktFlowInfo::FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in,
return;
}

if (VrfTranslate(pkt, in, out, fip_it->floating_ip_) == false) {
if (VrfTranslate(pkt, in, out, fip_it->floating_ip_, true) == false) {
return;
}
if (out->rt_ == NULL || in->rt_ == NULL) {
Expand Down Expand Up @@ -896,7 +896,8 @@ void PktFlowInfo::FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in,
}

bool PktFlowInfo::VrfTranslate(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out, const IpAddress &src_ip) {
PktControlInfo *out, const IpAddress &src_ip,
bool nat_flow) {
const Interface *intf = NULL;
if (ingress) {
intf = in->intf_;
Expand All @@ -911,7 +912,12 @@ bool PktFlowInfo::VrfTranslate(const PktInfo *pkt, PktControlInfo *in,
//If interface has a VRF assign rule, choose the acl and match the
//packet, else get the acl attached to VN and try matching the packet to
//network acl
const AclDBEntry *acl = vm_intf->vrf_assign_acl();
const AclDBEntry *acl = NULL;
if (nat_flow == false) {
acl = vm_intf->vrf_assign_acl();
}
//In case of floating IP translation, dont apply
//interface VRF assign rule
if (acl == NULL) {
if (ingress && in->vn_) {
//Check if the network ACL is present
Expand Down Expand Up @@ -999,7 +1005,7 @@ void PktFlowInfo::IngressProcess(const PktInfo *pkt, PktControlInfo *in,
//exact same route with different nexthop, hence if both ingress
//route and egress route are present in native vrf, acl match condition
//can be applied
if (VrfTranslate(pkt, in, out, pkt->ip_saddr) == false) {
if (VrfTranslate(pkt, in, out, pkt->ip_saddr, false) == false) {
return;
}

Expand Down Expand Up @@ -1130,7 +1136,7 @@ void PktFlowInfo::EgressProcess(const PktInfo *pkt, PktControlInfo *in,
}

//Apply vrf translate ACL to get ingress route
if (VrfTranslate(pkt, in, out, pkt->ip_saddr) == false) {
if (VrfTranslate(pkt, in, out, pkt->ip_saddr, false) == false) {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/pkt/pkt_flow_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class PktFlowInfo {
MatchPolicy *m_policy);
void RewritePktInfo(uint32_t index);
bool VrfTranslate(const PktInfo *pkt, PktControlInfo *ctrl,
PktControlInfo *rev_flow, const IpAddress &src_ip);
PktControlInfo *rev_flow, const IpAddress &src_ip,
bool nat_flow);
uint32_t LinkLocalBindPort(const VmEntry *vm, uint8_t proto);
void UpdateFipStatsInfo(FlowEntry *flow, FlowEntry *rflow, const PktInfo *p,
const PktControlInfo *in, const PktControlInfo *o);
Expand Down
61 changes: 60 additions & 1 deletion src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp) {
DelFloatingIpPool("fip-pool1");
agent_->fabric_inet4_unicast_table()->DeleteReq(
agent_->local_peer(), "default-project:vn3:vn3", ip2, 32, NULL);
DelLink("virtual-network", "default-project:vn1", "access-control-list", "Acl");
DeleteVmportEnv(input, 1, true);
client->WaitForIdle();
}
Expand Down Expand Up @@ -511,7 +512,64 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp1) {
{ TestFlowPkt(Address::INET, "4.1.1.1", "2.1.1.1", IPPROTO_TCP, 10, 20,
"vrf4", VmPortGet(7)->id()),
{
new ShortFlow()
new VerifyVn("default-project:vn1", "default-project:vn2"),
new VerifyVrf("vrf4", "default-project:vn3:vn3"),
new VerifyNat("2.1.1.1", "1.1.1.100", IPPROTO_TCP, 20, 10)
}
}
};
CreateFlow(flow, 1);

DelLink("floating-ip", "fip1", "floating-ip-pool", "fip-pool1");
DelLink("floating-ip-pool", "fip-pool1", "virtual-network", "default:vn4");
DelLink("virtual-network", "default-project:vn1", "access-control-list", "Acl");
DelFloatingIp("fip1");
DelFloatingIpPool("fip-pool1");
DeleteVmportEnv(input, 1, true);
DelVrf("vrf9");
client->WaitForIdle();
}

//Verify Interface VRF assign rule doesnt get applied for
//floating IP traslation
TEST_F(TestVrfAssignAclFlow, FloatingIp2) {
struct PortInfo input[] = {
{"intf7", 7, "4.1.1.1", "00:00:00:01:01:01", 4, 7},
};
CreateVmportEnv(input, 1);
client->WaitForIdle();

AddVrf("vrf9");
//Leak route for 2.1.1.0 to default-project:vn1:vn1
Ip4Address ip1 = Ip4Address::from_string("2.1.1.0");
agent_->fabric_inet4_unicast_table()->
AddLocalVmRouteReq(agent_->local_peer(),
"default-project:vn1:vn1", ip1, 24, MakeUuid(3),
"default-project:vn1", 16, SecurityGroupList(),
false, PathPreference(), Ip4Address(0));
client->WaitForIdle();

AddAddressVrfAssignAcl("intf7", 7, "4.1.1.0", "2.1.1.0", 6, 1, 65535,
1, 65535, "vrf9", "true");
client->WaitForIdle();

//Configure Floating-IP for intf7 in default-project:vn1
AddFloatingIpPool("fip-pool1", 1);
AddFloatingIp("fip1", 1, "1.1.1.100");
AddLink("floating-ip", "fip1", "floating-ip-pool", "fip-pool1");
AddLink("floating-ip-pool", "fip-pool1", "virtual-network",
"default-project:vn1");
AddLink("virtual-machine-interface", "intf7", "floating-ip", "fip1");
client->WaitForIdle();

TestFlow flow[] = {
{ TestFlowPkt(Address::INET, "4.1.1.1", "2.1.1.1", IPPROTO_TCP, 10, 20,
"vrf4", VmPortGet(7)->id()),
{
new VerifyVn("default-project:vn1", "default-project:vn1"),
new VerifyAction(1 << TrafficAction::PASS,
1 << TrafficAction::PASS),
new VerifyNat("2.1.1.1", "1.1.1.100", IPPROTO_TCP, 20, 10)
}
}
};
Expand All @@ -526,6 +584,7 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp1) {
client->WaitForIdle();
}


//Add an VRF translate ACL to send all ssh traffic to "2.1.1.1"
//via default-project:vn2 and also add mirror ACL for VN1
//Verify that final action has mirror action also
Expand Down

0 comments on commit 111cec1

Please sign in to comment.