diff --git a/src/vnsw/agent/oper/mirror_table.h b/src/vnsw/agent/oper/mirror_table.h index 7254d0435ea..3860e788041 100644 --- a/src/vnsw/agent/oper/mirror_table.h +++ b/src/vnsw/agent/oper/mirror_table.h @@ -73,6 +73,7 @@ class MirrorEntry : AgentRefCount, public AgentDBEntry { class MirrorTable : public AgentDBTable { public: const static unsigned bufLen = 512; + const static uint8_t kInvalidIndex = 0xFF; typedef std::vector MirrorEntryList; typedef std::map VrfMirrorEntryList; typedef std::pair VrfMirrorEntry; diff --git a/src/vnsw/agent/pkt/flow_entry.cc b/src/vnsw/agent/pkt/flow_entry.cc index d5636e28b81..48918774cb2 100644 --- a/src/vnsw/agent/pkt/flow_entry.cc +++ b/src/vnsw/agent/pkt/flow_entry.cc @@ -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; @@ -1436,6 +1449,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); @@ -1595,10 +1609,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); diff --git a/src/vnsw/agent/pkt/pkt_flow_info.cc b/src/vnsw/agent/pkt/pkt_flow_info.cc index 9add478ba8a..3809c610ffa 100644 --- a/src/vnsw/agent/pkt/pkt_flow_info.cc +++ b/src/vnsw/agent/pkt/pkt_flow_info.cc @@ -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) diff --git a/src/vnsw/agent/pkt/test/SConscript b/src/vnsw/agent/pkt/test/SConscript index 9dc9b071c3b..84a1a1977f4 100644 --- a/src/vnsw/agent/pkt/test/SConscript +++ b/src/vnsw/agent/pkt/test/SConscript @@ -42,7 +42,9 @@ test_sg_flow = AgentEnv.MakeTestCmd(env, 'test_sg_flow', pkt_flaky_test_suite) 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) + pkt_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) diff --git a/src/vnsw/agent/pkt/test/test_ecmp_mx.cc b/src/vnsw/agent/pkt/test/test_ecmp_mx.cc index 6d877b4abcc..e84896e3c34 100644 --- a/src/vnsw/agent/pkt/test/test_ecmp_mx.cc +++ b/src/vnsw/agent/pkt/test/test_ecmp_mx.cc @@ -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(); @@ -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(); diff --git a/src/vnsw/agent/pkt/test/test_flow_util.h b/src/vnsw/agent/pkt/test/test_flow_util.h index 91cd7d87c6d..236f8729706 100644 --- a/src/vnsw/agent/pkt/test/test_flow_util.h +++ b/src/vnsw/agent/pkt/test/test_flow_util.h @@ -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): diff --git a/src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc b/src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc index 15838d13824..72e645cd3cf 100644 --- a/src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc +++ b/src/vnsw/agent/pkt/test/test_vrf_assign_acl.cc @@ -25,67 +25,6 @@ struct PortInfo input2[] = { }; class TestVrfAssignAclFlow : public ::testing::Test { -public: - void AddAddressVrfAssignAcl(const char *intf_name, int intf_id, - const char *sip, const char *dip, int proto, int sport_start, - int sport_end, int dport_start, int dport_end, const char *vrf, - const char *ignore_acl) { - char buf[3000]; - sprintf(buf, - " \n" - " \n" - " \n" - " \n" - " %d\n" - " \n" - " \n" - " \n" - " \n" - " %s\n" - " \n" - " \n" - " 24\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " %d\n" - " \n" - " \n" - " %d\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " %s\n" - " \n" - " \n" - " 24\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " %d\n" - " \n" - " \n" - " %d\n" - " \n" - " \n" - " \n" - " 0\n" - " %s\n" - " %s\n" - " \n" - " \n", - proto, sip, sport_start, sport_end, dip, dport_start, dport_end, vrf, - ignore_acl); - AddNode("virtual-machine-interface", intf_name, intf_id, buf); - client->WaitForIdle(); - } - protected: virtual void SetUp() { agent_ = Agent::GetInstance(); @@ -105,19 +44,23 @@ class TestVrfAssignAclFlow : public ::testing::Test { //Leak route for 1.1.1.0 to default-project:vn2:vn2 and //default-project:vn3:vn3 + VnListType vn_list; + vn_list.insert(std::string("default-project:vn1")); Ip4Address ip2 = Ip4Address::from_string("1.1.1.0"); agent_->fabric_inet4_unicast_table()-> AddLocalVmRouteReq(agent_->local_peer(), "default-project:vn2:vn2", ip2, 24, MakeUuid(1), - "default-project:vn1", 16, SecurityGroupList(), + vn_list, + 16, SecurityGroupList(), CommunityList(), false, - PathPreference(), Ip4Address(0)); + PathPreference(), Ip4Address(0), EcmpLoadBalance()); agent_->fabric_inet4_unicast_table()-> AddLocalVmRouteReq(agent_->local_peer(), "default-project:vn3:vn3", ip2, 24, MakeUuid(1), - "default-project:vn1", 16, SecurityGroupList(), + vn_list, + 16, SecurityGroupList(), CommunityList(), false, - PathPreference(), Ip4Address(0)); + PathPreference(), Ip4Address(0), EcmpLoadBalance()); client->WaitForIdle(); } @@ -189,14 +132,17 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl2) { //Add an VRF translate ACL to send all ssh traffic to "2.1.1.1" via VN4 //which is not present, make sure flow is marked as short flow TEST_F(TestVrfAssignAclFlow, VrfAssignAcl3) { + client->agent()->flow_stats_manager()->set_delete_short_flow(false); //Leak route for 2.1.1.0 to default-project:vn1:vn1 Ip4Address ip1 = Ip4Address::from_string("2.1.1.0"); + VnListType vn_list; + vn_list.insert(std::string("default-project:vn2")); agent_->fabric_inet4_unicast_table()-> AddLocalVmRouteReq(agent_->local_peer(), "default-project:vn1:vn1", ip1, 24, MakeUuid(3), - "default-project:vn2", 16, SecurityGroupList(), + vn_list, 16, SecurityGroupList(), CommunityList(), false, - PathPreference(), Ip4Address(0)); + PathPreference(), Ip4Address(0), EcmpLoadBalance()); AddAddressVrfAssignAcl("intf1", 1, "1.1.1.0", "2.1.1.0", 6, 1, 65535, 1, 65535, "vrf4", "true"); TestFlow flow[] = { @@ -213,13 +159,14 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl3) { 10, 20, nh_id); EXPECT_TRUE(fe != NULL && fe->is_flags_set(FlowEntry::ShortFlow) == true && fe->short_flow_reason() == FlowEntry::SHORT_NO_SRC_ROUTE); + client->agent()->flow_stats_manager()->set_delete_short_flow(true); } //Add a VRF translate ACL to send all ssh traffic to "2.1.1.1" //via default-project:vn2 with ignore acl option set, add an ACL //to deny all traffic from default-project:vn1 to default-project:vn2 TEST_F(TestVrfAssignAclFlow, VrfAssignAcl4) { - AddAcl("Acl", 10, "default-project:vn1", "default-project:vn2", "drop"); + AddAcl("Acl", 10, "default-project:vn1", "default-project:vn2", "deny"); AddLink("virtual-network", "default-project:vn1", "access-control-list", "Acl"); AddAddressVrfAssignAcl("intf1", 1, "1.1.1.0", "2.1.1.0", 6, 1, 65535, 1, 65535, "default-project:vn2:vn2", "false"); @@ -231,8 +178,7 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl4) { new VerifyVn("default-project:vn1", "default-project:vn2"), new VerifyAction((1 << TrafficAction::DENY) | (1 << TrafficAction::VRF_TRANSLATE), - (1 << TrafficAction::DENY) | - (1 << TrafficAction::IMPLICIT_DENY)) + (1 << TrafficAction::DENY)) } } }; @@ -245,7 +191,7 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl4) { //and ensure it get applied TEST_F(TestVrfAssignAclFlow, VrfAssignAcl5) { AddAcl("egress-access-control-list-Acl", 10, "default-project:vn1", - "default-project:vn2", "drop"); + "default-project:vn2", "deny"); AddSg("sg1", 1); AddLink("security-group", "sg1", "access-control-list", "egress-access-control-list-Acl"); @@ -330,6 +276,7 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl6) { //Where 3.1.1.1 is a ecmp source and verify //that flow becomes short flow since destination VRF is not present TEST_F(TestVrfAssignAclFlow, VrfAssignAcl7) { + client->agent()->flow_stats_manager()->set_delete_short_flow(false); AddAddressVrfAssignAcl("intf1", 1, "3.1.1.0", "1.1.1.0", 6, 1, 65535, 1, 65535, "xyz", "no"); //Remote VM IP @@ -379,12 +326,16 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl7) { agent_->fabric_inet4_unicast_table()->DeleteReq(agent_->local_peer(), "default-project:vn1:vn1", ip, 32, NULL); client->WaitForIdle(); + client->agent()->flow_stats_manager()->set_delete_short_flow(true); } TEST_F(TestVrfAssignAclFlow, VrfAssignAcl8) { - - TunnelRouteAdd("10.1.1.2", "2.1.1.1", "default-project:vn1:vn1", - 16, "default-project:vn2"); + Ip4Address server_ip = Ip4Address::from_string("10.1.1.2"); + Ip4Address vm_ip = Ip4Address::from_string("2.1.1.1"); + Inet4TunnelRouteAdd(bgp_peer_, "default-project:vn1:vn1", vm_ip, 32, + server_ip, TunnelType::AllType(), 16, + "default-project:vn2", + SecurityGroupList(), PathPreference()); client->WaitForIdle(); TestFlow flow[] = { @@ -405,203 +356,10 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAcl8) { 10, 20, nh_id); EXPECT_TRUE(fe != NULL); EXPECT_TRUE(fe->acl_assigned_vrf() == "default-project:vn3:vn3"); - DeleteRoute("default-project:vn1:vn1", "2.1.1.1", 32); - client->WaitForIdle(); -} - - -TEST_F(TestVrfAssignAclFlow, FloatingIp) { - struct PortInfo input[] = { - {"intf7", 7, "4.1.1.1", "00:00:00:01:01:01", 4, 7}, - }; - CreateVmportEnv(input, 1); - client->WaitForIdle(); - - //Leak route for 2.1.1.0 to default-project:vn1:vn1 - Ip4Address ip1 = Ip4Address::from_string("2.1.1.0"); - Ip4Address ip2 = Ip4Address::from_string("1.1.1.100"); - agent_->fabric_inet4_unicast_table()-> - AddLocalVmRouteReq(agent_->local_peer(), - "default-project:vn1:vn1", ip1, 24, MakeUuid(3), - "default-project:vn2", 16, SecurityGroupList(), - CommunityList(), false, - PathPreference(), Ip4Address(0)); - client->WaitForIdle(); - - //Add an ACL, such that for traffic from vn4:vn4 to default-project:vn2, - //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:vn3"); - AddLink("virtual-network", "default-project:vn1", "access-control-list", "Acl"); - 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(); - - agent_->fabric_inet4_unicast_table()-> - AddLocalVmRouteReq(agent_->local_peer(), - "default-project:vn3:vn3", ip2, 32, MakeUuid(7), - "default-project:vn1", 16, SecurityGroupList(), - CommunityList(), false, PathPreference(), Ip4Address(0)); - 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:vn3"), - 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-project:vn1"); - DelLink("virtual-machine-interface", "intf7", "floating-ip", "fip1"); - DelLink("virtual-network", "default-project:vn1", - "access-control-list", "Acl"); - DelFloatingIp("fip1"); - 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(); -} - -//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}, - }; - CreateVmportEnv(input, 1); - client->WaitForIdle(); - - //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:vn2", 16, SecurityGroupList(), - CommunityList(), 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 - //(assume default-project:vn3 in test case) - AddVrfAssignNetworkAcl("Acl", 10, "default-project:vn1", - "default-project:vn2", "pass", - "vrf9"); - AddLink("virtual-network", "default-project:vn1", "access-control-list", "Acl"); - 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: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"); + DeleteRoute("default-project:vn1:vn1", "2.1.1.1", 32, bgp_peer_); 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(), - CommunityList(), 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(); -} - - //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 @@ -609,14 +367,16 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAclWithMirror1) { AddAddressVrfAssignAcl("intf1", 1, "1.1.1.0", "2.1.1.0", 6, 1, 65535, 1, 65535, "default-project:vn2:vn2", "true"); + VnListType vn_list; + vn_list.insert(std::string("default-project:vn2")); //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:vn2", 16, SecurityGroupList(), + vn_list, 16, SecurityGroupList(), CommunityList(), false, - PathPreference(), Ip4Address(0)); + PathPreference(), Ip4Address(0), EcmpLoadBalance()); client->WaitForIdle(); AddMirrorAcl("Acl", 10, "default-project:vn1", "default-project:vn2", "pass", @@ -632,7 +392,8 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAclWithMirror1) { new VerifyAction((1 << TrafficAction::PASS) | (1 << TrafficAction::VRF_TRANSLATE) | (1 << TrafficAction::MIRROR), - (1 << TrafficAction::DENY) | (1 << TrafficAction::IMPLICIT_DENY)) + (1 << TrafficAction::PASS | + 1 << TrafficAction::MIRROR)) } } }; @@ -643,70 +404,17 @@ TEST_F(TestVrfAssignAclFlow, VrfAssignAclWithMirror1) { client->WaitForIdle(); } -TEST_F(TestVrfAssignAclFlow, FloatingIp_1) { - struct PortInfo input[] = { - {"intf7", 7, "4.1.1.1", "00:00:00:01:01:01", 4, 7}, - }; - CreateVmportEnv(input, 1); - client->WaitForIdle(); - - //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:vn2", 16, SecurityGroupList(), - CommunityList(), false, - PathPreference(), Ip4Address(0)); - 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 - AddVrfAssignNetworkAcl("Acl", 10, "default-project:vn1", - "default-project:vn2", "pass", - "default-project:vn3:xyz"); - AddLink("virtual-network", "default-project:vn1", "access-control-list", "Acl"); - 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 ShortFlow() - } - } - }; - 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"); - DelLink("virtual-network", "default-project:vn1", - "access-control-list", "Acl"); - DelFloatingIp("fip1"); - DelFloatingIpPool("fip-pool1"); - DeleteVmportEnv(input, 1, true); - client->WaitForIdle(); -} - - int main(int argc, char *argv[]) { GETUSERARGS(); client = TestInit(init_file, ksync_init); + + boost::system::error_code ec; + bgp_peer_ = CreateBgpPeer(Ip4Address::from_string("0.0.0.1", ec), + "xmpp channel"); + int ret = RUN_ALL_TESTS(); client->WaitForIdle(); + DeleteBgpPeer(bgp_peer_); TestShutdown(); delete client; return ret; diff --git a/src/vnsw/agent/pkt/test/test_vrf_assign_acl_fip.cc b/src/vnsw/agent/pkt/test/test_vrf_assign_acl_fip.cc new file mode 100644 index 00000000000..f3e3296b70f --- /dev/null +++ b/src/vnsw/agent/pkt/test/test_vrf_assign_acl_fip.cc @@ -0,0 +1,195 @@ + /* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +#include "base/os.h" +#include "test/test_cmn_util.h" +#include "test_flow_util.h" + +void RouterIdDepInit(Agent *agent) { +} + +struct PortInfo input[] = { + {"intf1", 1, "1.1.1.1", "00:00:00:01:01:01", 1, 1}, +}; + +struct PortInfo input1[] = { + {"intf2", 2, "2.1.1.1", "00:00:00:01:01:01", 2, 2}, +}; + +class TestVrfAssignAclFlowFip : public ::testing::Test { +public: +protected: + virtual void SetUp() { + agent_ = Agent::GetInstance(); + flow_proto_ = agent_->pkt()->get_flow_proto(); + fip_dest_ip = Ip4Address::from_string("2.1.1.1"); + remote_server = Ip4Address::from_string("10.10.10.10"); + Ip4Address fip_src_ip = Ip4Address::from_string("2.1.1.100"); + + EXPECT_EQ(0U, flow_proto_->FlowCount()); + + CreateVmportFIpEnv(input, 1); + CreateVmportFIpEnv(input1, 1); + client->WaitForIdle(); + + EXPECT_TRUE(VmPortActive(1)); + EXPECT_TRUE(VmPortActive(2)); + client->WaitForIdle(); + + AddVrf("__internal__"); + client->WaitForIdle(); + + //Add src FIP and destination IP route in __internal__ vrf + vm_intf = static_cast(VmPortGet(1)); + VnListType vn_list; + vn_list.insert("default-project:vn2"); + agent_->fabric_inet4_unicast_table()->AddLocalVmRouteReq(vm_intf->peer(), + std::string("__internal__"), fip_src_ip, 32, vm_intf->GetUuid(), + vn_list, vm_intf->label(), SecurityGroupList(), CommunityList(), + false, PathPreference(), Ip4Address(0), EcmpLoadBalance()); + client->WaitForIdle(); + + Inet4TunnelRouteAdd(bgp_peer_, "__internal__", + fip_dest_ip, 32, remote_server, + TunnelType::AllType(), 20, + "default-project:vn2", SecurityGroupList(), + PathPreference()); + client->WaitForIdle(); + + AddFloatingIpPool("fip-pool1", 1); + AddFloatingIp("fip1", 1, "2.1.1.100"); + AddLink("floating-ip", "fip1", "floating-ip-pool", "fip-pool1"); + AddLink("floating-ip-pool", "fip-pool1", "virtual-network", + "default-project:vn2"); + AddLink("virtual-machine-interface", "intf1", "floating-ip", "fip1"); + client->WaitForIdle(); + + AddVrfAssignNetworkAcl("Acl", 10, "default-project:vn2", + "default-project:vn2", "pass", "__internal__"); + AddLink("virtual-network", "default-project:vn2", "access-control-list", + "Acl"); + client->WaitForIdle(); + } + + virtual void TearDown() { + DelLink("virtual-network", "default-project:vn2", "access-control-list", + "Acl"); + DelNode("access-control-list", "Acl"); + client->WaitForIdle(); + + DelLink("floating-ip", "fip1", "floating-ip-pool", "fip-pool1"); + DelLink("floating-ip-pool", "fip-pool1", + "virtual-network", "default-project:vn2"); + DelLink("virtual-machine-interface", "intf1", "floating-ip", "fip1"); + DelFloatingIp("fip1"); + DelFloatingIpPool("fip-pool1"); + client->WaitForIdle(); + + DeleteRoute("__internal__", "2.1.1.100", 32, vm_intf->peer()); + DeleteRoute("__internal__", "2.1.1.1", 32, bgp_peer_); + client->WaitForIdle(); + + DelVrf("__internal__"); + DeleteVmportFIpEnv(input, 1, true); + DeleteVmportFIpEnv(input1, 1, true); + client->WaitForIdle(); + EXPECT_EQ(0U, flow_proto_->FlowCount()); + } + + Agent *agent_; + FlowProto *flow_proto_; + Ip4Address fip_dest_ip; + Ip4Address remote_server; + const VmInterface *vm_intf; +}; + +//Ingress flow +//Fwd flow from VM via floating-ip to external compute node destination +TEST_F(TestVrfAssignAclFlowFip, VrfAssignAcl1) { + TestFlow flow[] = { + { TestFlowPkt(Address::INET, "1.1.1.1", "2.1.1.1", IPPROTO_TCP, + 10, 20, "default-project:vn1:vn1", VmPortGet(1)->id()), + { + new VerifyVn("default-project:vn2", "default-project:vn2"), + new VerifyAction((1 << TrafficAction::PASS) | + (1 << TrafficAction::VRF_TRANSLATE), + (1 << TrafficAction::PASS) | + (1 << TrafficAction::VRF_TRANSLATE)), + new VerifyNat("2.1.1.1", "2.1.1.100", IPPROTO_TCP, 20, 10), + new VerifySrcDstVrf("default-project:vn1:vn1", "__internal__", + "__internal__", "default-project:vn1:vn1") + } + } + }; + CreateFlow(flow, 1); +} + +//Egress flow +//Fwd flow from remote compute node to local FIP +TEST_F(TestVrfAssignAclFlowFip, VrfAssignAcl2) { + const VmInterface *vm_intf = static_cast(VmPortGet(1)); + TestFlow flow[] = { + { TestFlowPkt(Address::INET, "2.1.1.1", "2.1.1.100", + IPPROTO_TCP, 10, 20, "default-project:vn1:vn1", + remote_server.to_string(), vm_intf->label()), + { + new VerifyVn("default-project:vn2", "default-project:vn2"), + new VerifyAction((1 << TrafficAction::PASS) | + (1 << TrafficAction::VRF_TRANSLATE), + (1 << TrafficAction::PASS | + (1 << TrafficAction::VRF_TRANSLATE))), + new VerifyNat("1.1.1.1", "2.1.1.1", IPPROTO_TCP, 20, 10), + new VerifySrcDstVrf("default-project:vn1:vn1", "default-project:vn1:vn1", + "default-project:vn1:vn1", "__internal__") + } + } + }; + + CreateFlow(flow, 1); +} + +//Verify that interface VRF assign rule doesnt get +//applied on floating-ip packets +TEST_F(TestVrfAssignAclFlowFip, VrfAssignAcl3) { + AddVrf("__invalid__"); + client->WaitForIdle(); + AddAddressVrfAssignAcl("intf1", 1, "2.1.1.0", "2.1.1.0", 6, 1, 65535, + 1, 65535, "__invalid__", "true"); + + const VmInterface *vm_intf = static_cast(VmPortGet(1)); + TestFlow flow[] = { + { TestFlowPkt(Address::INET, "2.1.1.1", "2.1.1.100", + IPPROTO_TCP, 10, 20, "default-project:vn1:vn1", + remote_server.to_string(), vm_intf->label()), + { + new VerifyVn("default-project:vn2", "default-project:vn2"), + new VerifyAction((1 << TrafficAction::PASS) | + (1 << TrafficAction::VRF_TRANSLATE), + (1 << TrafficAction::PASS | + (1 << TrafficAction::VRF_TRANSLATE))), + new VerifyNat("1.1.1.1", "2.1.1.1", IPPROTO_TCP, 20, 10), + new VerifySrcDstVrf("default-project:vn1:vn1", "default-project:vn1:vn1", + "default-project:vn1:vn1", "__internal__") + } + } + }; + + CreateFlow(flow, 1); +} + +int main(int argc, char *argv[]) { + GETUSERARGS(); + client = TestInit(init_file, ksync_init); + + boost::system::error_code ec; + bgp_peer_ = CreateBgpPeer(Ip4Address::from_string("0.0.0.1", ec), + "xmpp channel"); + + int ret = RUN_ALL_TESTS(); + client->WaitForIdle(); + DeleteBgpPeer(bgp_peer_); + TestShutdown(); + delete client; + return ret; +} diff --git a/src/vnsw/agent/test/test_cmn_util.h b/src/vnsw/agent/test/test_cmn_util.h index cce321a2c0c..ae4207e5e80 100644 --- a/src/vnsw/agent/test/test_cmn_util.h +++ b/src/vnsw/agent/test/test_cmn_util.h @@ -495,4 +495,8 @@ void AddPhysicalDeviceVn(Agent *agent, int dev_id, int vn_id, bool validate); void DelPhysicalDeviceVn(Agent *agent, int dev_id, int vn_id, bool validate); void AddStaticPreference(std::string intf_name, int intf_id, uint32_t value); bool VnMatch(VnListType &vn_list, std::string &vn); +void AddAddressVrfAssignAcl(const char *intf_name, int intf_id, + const char *sip, const char *dip, int proto, + int sport_start, int sport_end, int dport_start, + int dport_end, const char *vrf, const char *ignore_acl); #endif // vnsw_agent_test_cmn_util_h diff --git a/src/vnsw/agent/test/test_util.cc b/src/vnsw/agent/test/test_util.cc index 13f9e3ff898..9cfd68155c8 100644 --- a/src/vnsw/agent/test/test_util.cc +++ b/src/vnsw/agent/test/test_util.cc @@ -1950,12 +1950,54 @@ static string AddAclXmlString(const char *node_name, const char *name, int id, " " " \n" " \n" + " \n" + " \n" + " \n" + " any\n" + " \n" + " \n" + " \n" + " %s\n" + " \n" + " \n" + " \n" + " \n" + " 10\n" + " \n" + " \n" + " 20\n" + " \n" + " \n" + " \n" + " \n" + " %s\n" + " \n" + " \n" + " \n" + " \n" + " 10\n" + " \n" + " \n" + " 20\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " %s\n" + " \n" + " %s\n" + " " + " %s\n" + " " + " \n" + " \n" " \n" " \n" " \n" "\n", node_name, name, id, src_vn, dest_vn, action, - mirror.str().c_str(), - vrf_assign.c_str()); + mirror.str().c_str(), vrf_assign.c_str(), dest_vn, src_vn, action, + mirror.str().c_str(), vrf_assign.c_str()); string s(buff); return s; } @@ -3872,3 +3914,63 @@ bool VnMatch(VnListType &vn_list, std::string &vn) { } return false; } + +void AddAddressVrfAssignAcl(const char *intf_name, int intf_id, + const char *sip, const char *dip, int proto, + int sport_start, int sport_end, int dport_start, + int dport_end, const char *vrf, const char *ignore_acl) { + char buf[3000]; + sprintf(buf, + " \n" + " \n" + " \n" + " \n" + " %d\n" + " \n" + " \n" + " \n" + " \n" + " %s\n" + " \n" + " \n" + " 24\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " %d\n" + " \n" + " \n" + " %d\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " %s\n" + " \n" + " \n" + " 24\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " %d\n" + " \n" + " \n" + " %d\n" + " \n" + " \n" + " \n" + " 0\n" + " %s\n" + " %s\n" + " \n" + " \n", + proto, sip, sport_start, sport_end, dip, dport_start, dport_end, vrf, + ignore_acl); + AddNode("virtual-machine-interface", intf_name, intf_id, buf); + client->WaitForIdle(); +} diff --git a/src/vnsw/agent/vrouter/ksync/flowtable_ksync.cc b/src/vnsw/agent/vrouter/ksync/flowtable_ksync.cc index a46e5030e81..5a789c85168 100644 --- a/src/vnsw/agent/vrouter/ksync/flowtable_ksync.cc +++ b/src/vnsw/agent/vrouter/ksync/flowtable_ksync.cc @@ -311,7 +311,7 @@ int FlowTableKSyncEntry::Encode(sandesh_op::type op, char *buf, int buf_len) { if (fe_action & (1 << TrafficAction::VRF_TRANSLATE)) { flags |= VR_FLOW_FLAG_VRFT; - req.set_fr_flow_dvrf(flow_entry_->acl_assigned_vrf_index()); + req.set_fr_flow_dvrf(flow_entry_->data().dest_vrf); } if (flow_entry_->is_flags_set(FlowEntry::Trap)) { diff --git a/src/vnsw/agent/vrouter/ksync/mirror_ksync.cc b/src/vnsw/agent/vrouter/ksync/mirror_ksync.cc index e30d898ec10..d1ad4f5a096 100644 --- a/src/vnsw/agent/vrouter/ksync/mirror_ksync.cc +++ b/src/vnsw/agent/vrouter/ksync/mirror_ksync.cc @@ -147,7 +147,11 @@ KSyncEntry *MirrorKSyncObject::DBToKSyncEntry(const DBEntry *e) { uint32_t MirrorKSyncObject::GetIdx(std::string analyzer_name) { MirrorKSyncEntry key(this, analyzer_name); - return Find(&key)->GetIndex(); + KSyncEntry *entry = Find(&key); + if (entry) { + entry->GetIndex(); + } + return MirrorTable::kInvalidIndex; } void vr_mirror_req::Process(SandeshContext *context) {