diff --git a/src/vnsw/agent/pkt/pkt_flow_info.cc b/src/vnsw/agent/pkt/pkt_flow_info.cc index 94e3da9f17f..d6b185619ac 100644 --- a/src/vnsw/agent/pkt/pkt_flow_info.cc +++ b/src/vnsw/agent/pkt/pkt_flow_info.cc @@ -258,7 +258,20 @@ static bool NhDecode(const NextHop *nh, const PktInfo *pkt, PktFlowInfo *info, const InetUnicastRouteEntry *rt = static_cast(in->rt_); if (rt != NULL && rt->GetLocalNextHop()) { - out->nh_ = GetPolicyEnabledNH(rt->GetLocalNextHop())->id(); + const NextHop *local_nh = rt->GetLocalNextHop(); + out->nh_ = local_nh->id(); + if (local_nh->GetType() == NextHop::INTERFACE) { + const Interface *local_intf = + static_cast(local_nh)->GetInterface(); + //Get policy enabled nexthop only for + //vm interface, in case of vgw or service interface in + //transparent mode we should still + //use policy disabled interface + if (local_intf && + local_intf->type() == Interface::VM_INTERFACE) { + out->nh_ = GetPolicyEnabledNH(local_nh)->id(); + } + } } else { out->nh_ = in->nh_; } diff --git a/src/vnsw/agent/pkt/test/test_ecmp.cc b/src/vnsw/agent/pkt/test/test_ecmp.cc index aa5a084e888..5b9d96febe3 100644 --- a/src/vnsw/agent/pkt/test/test_ecmp.cc +++ b/src/vnsw/agent/pkt/test/test_ecmp.cc @@ -2263,6 +2263,67 @@ TEST_F(EcmpTest, TrapFlag) { client->WaitForIdle(); } +//Send a packet from vgw to ecmp destination +TEST_F(EcmpTest, VgwFlag) { + Agent *agent = Agent::GetInstance(); + InetInterface::CreateReq(agent->interface_table(), "vgw1", + InetInterface::SIMPLE_GATEWAY, "vrf2", + Ip4Address(0), 0, Ip4Address(0), Agent::NullString(), + ""); + client->WaitForIdle(); + + InetInterfaceKey *intf_key = new InetInterfaceKey("vgw1"); + std::auto_ptr nh_key(new InterfaceNHKey(intf_key, false, + InterfaceNHFlags::INET4)); + + Ip4Address remote_server_ip1 = Ip4Address::from_string("10.10.10.100"); + ComponentNHKeyPtr nh_data1(new ComponentNHKey(16, nh_key)); + ComponentNHKeyPtr nh_data2(new ComponentNHKey(20, agent->fabric_vrf_name(), + agent->router_id(), + remote_server_ip1, + false, + TunnelType::DefaultType())); + Ip4Address ip = Ip4Address::from_string("0.0.0.0"); + ComponentNHKeyList comp_nh_list; + comp_nh_list.push_back(nh_data1); + comp_nh_list.push_back(nh_data2); + EcmpTunnelRouteAdd(bgp_peer, "vrf2", ip, 0, + comp_nh_list, false, "vn2", + SecurityGroupList(), PathPreference()); + client->WaitForIdle(); + + InetInterfaceKey tmp_key("vgw1"); + Interface *intf = + static_cast(agent->interface_table()-> + FindActiveEntry(&tmp_key)); + + //Send packet on vgw interface + TxIpPacket(intf->id(), "100.1.1.1", "2.2.2.2", 1); + client->WaitForIdle(); + + FlowEntry *entry; + FlowEntry *rev_entry; + entry = FlowGet(VrfGet("vrf2")->vrf_id(), + "2.2.2.2", "100.1.1.1", 1, 0, 0, intf->flow_key_nh()->id()); + EXPECT_TRUE(entry != NULL); + EXPECT_TRUE(entry->data().component_nh_idx == + CompositeNH::kInvalidComponentNHIdx); + + rev_entry = FlowGet(VrfGet("vrf2")->vrf_id(), + "100.1.1.1", "2.2.2.2", 1, 0, 0, intf->flow_key_nh()->id()); + EXPECT_TRUE(rev_entry != NULL); + EXPECT_TRUE(rev_entry->data().component_nh_idx == + CompositeNH::kInvalidComponentNHIdx); + + client->WaitForIdle(); + agent->fabric_inet4_unicast_table()->DeleteReq(bgp_peer, "vrf2", + ip, 0, NULL); + InetInterface::DeleteReq(agent->interface_table(), "vgw1"); + client->WaitForIdle(); + WAIT_FOR(1000, 1000, (Agent::GetInstance()->pkt()-> + flow_table()->Size() == 0)); +} + int main(int argc, char *argv[]) { GETUSERARGS(); client = TestInit(init_file, ksync_init, true, true, true, 100*1000);