Skip to content

Commit

Permalink
Merge "* Dont apply interface VRF assign rule when packet gets NATed"…
Browse files Browse the repository at this point in the history
… into R2.0
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jul 28, 2015
2 parents fcd4fc8 + 5ebca65 commit 44cf506
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 15 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 @@ -785,7 +785,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
25 changes: 18 additions & 7 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,12 @@ void PktFlowInfo::FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in,
return;
}

if (VrfTranslate(pkt, in, out) == false) {
if (VrfTranslate(pkt, in, out, fip_it->floating_ip_, true) == false) {
return;
}
if (out->rt_ == NULL || in->rt_ == NULL) {
//If After VRF translation, ingress route or
//egress route is NULL, mark the flow as short flow
return;
}

Expand Down Expand Up @@ -781,7 +786,8 @@ void PktFlowInfo::FloatingIpSNat(const PktInfo *pkt, PktControlInfo *in,
}

bool PktFlowInfo::VrfTranslate(const PktInfo *pkt, PktControlInfo *in,
PktControlInfo *out) {
PktControlInfo *out, const IpAddress &src_ip,
bool nat_flow) {
const Interface *intf = NULL;
if (ingress) {
intf = in->intf_;
Expand All @@ -796,7 +802,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 All @@ -812,7 +823,7 @@ bool PktFlowInfo::VrfTranslate(const PktInfo *pkt, PktControlInfo *in,

PacketHeader hdr;
hdr.vrf = pkt->vrf;
hdr.src_ip = pkt->ip_saddr;
hdr.src_ip = src_ip;
hdr.dst_ip = pkt->ip_daddr;
hdr.protocol = pkt->ip_proto;
if (hdr.protocol == IPPROTO_UDP || hdr.protocol == IPPROTO_TCP) {
Expand Down Expand Up @@ -852,7 +863,7 @@ bool PktFlowInfo::VrfTranslate(const PktInfo *pkt, PktControlInfo *in,
}
out->vrf_ = vrf;
UpdateRoute(&out->rt_, vrf, pkt->ip_daddr, flow_dest_plen_map);
UpdateRoute(&in->rt_, vrf, pkt->ip_saddr, flow_source_plen_map);
UpdateRoute(&in->rt_, vrf, hdr.src_ip, flow_source_plen_map);
}

return true;
Expand All @@ -879,7 +890,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) == false) {
if (VrfTranslate(pkt, in, out, pkt->ip_saddr, false) == false) {
return;
}

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

//Apply vrf translate ACL to get ingress route
if (VrfTranslate(pkt, in, out) == 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 @@ -75,7 +75,8 @@ class PktFlowInfo {
MatchPolicy *m_policy);
void RewritePktInfo(uint32_t index);
bool VrfTranslate(const PktInfo *pkt, PktControlInfo *ctrl,
PktControlInfo *rev_flow);
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
75 changes: 70 additions & 5 deletions src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl8) {

TunnelRouteAdd("10.1.1.2", "2.1.1.1", "default-project:vn1:vn1",
16, "default-project:vn2");
client->WaitForIdle();

TestFlow flow[] = {
{ TestFlowPkt(Address::INET, "1.1.1.1", "2.1.1.1", IPPROTO_TCP, 10, 20,
Expand Down Expand Up @@ -455,11 +456,13 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp) {
DelLink("floating-ip-pool", "fip-pool1", "virtual-network", "default:vn4");
DelFloatingIp("fip1");
DelFloatingIpPool("fip-pool1");
DelLink("virtual-network", "default-project:vn1", "access-control-list", "Acl");
DeleteVmportEnv(input, 1, true);
client->WaitForIdle();
}

TEST_F(TestVrfAssignAclFlow, FloatingIp_1) {
//Verify flow becomes short flow, when
//vrf assigned ACL doesnt have the routes
TEST_F(TestVrfAssignAclFlow, FloatingIp1) {
struct PortInfo input[] = {
{"intf7", 7, "4.1.1.1", "00:00:00:01:01:01", 4, 7},
};
Expand All @@ -475,12 +478,14 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp_1) {
false, PathPreference(), Ip4Address(0));
client->WaitForIdle();

AddVrf("vrf9");
client->WaitForIdle();
//Add an ACL, such that for traffic from vn4:vn4 to default-project:vn2,
//route lookup happens in internal VRF, in this case VRF doesnt exist
//and hence flow should be short flow
//route lookup happens in internal VRF
//(assume default-project:vn3 in test case)
AddVrfAssignNetworkAcl("Acl", 10, "default-project:vn1",
"default-project:vn2", "pass",
"default-project:vn3:xyz");
"vrf9");
AddLink("virtual-network", "default-project:vn1", "access-control-list", "Acl");
client->WaitForIdle();

Expand All @@ -506,9 +511,69 @@ TEST_F(TestVrfAssignAclFlow, FloatingIp_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)
}
}
};
CreateFlow(flow, 1);

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

Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/test/test_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,7 @@ bool TunnelRouteAdd(const char *server, const char *vmip, const char *vm_vrf,
Agent::GetInstance()->fabric_vrf_name(),
Agent::GetInstance()->router_id(),
vm_vrf, Ip4Address::from_string(server, ec),
TunnelType::AllType(), label, "",
TunnelType::AllType(), label, vn,
SecurityGroupList(), PathPreference());
InetUnicastAgentRouteTable::AddRemoteVmRouteReq(bgp_peer_, vm_vrf,
Ip4Address::from_string(vmip, ec),
Expand Down

0 comments on commit 44cf506

Please sign in to comment.