From 80d6ea3cc1c53503ca7ef94a0a4d23851e4d4415 Mon Sep 17 00:00:00 2001 From: jayaramsatya Date: Thu, 5 May 2016 15:31:37 +0530 Subject: [PATCH] Issue: ----- This Crash is seen becuase while getting the Policy enabled NH, the interface marked as delete. Fix: ---- Before getting the Policy enabled NH Check for Interface active if it is not active, mark that flow as short flow. closes-bug: #1572418 Change-Id: I493e61e97a1d833af096421ea2c3c3a5a68e66f6 --- src/vnsw/agent/pkt/pkt_flow_info.cc | 10 ++++- src/vnsw/agent/pkt/test/test_flow_error.cc | 48 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/vnsw/agent/pkt/pkt_flow_info.cc b/src/vnsw/agent/pkt/pkt_flow_info.cc index b335f5040da..dad38c307ec 100644 --- a/src/vnsw/agent/pkt/pkt_flow_info.cc +++ b/src/vnsw/agent/pkt/pkt_flow_info.cc @@ -302,7 +302,15 @@ static bool NhDecode(const NextHop *nh, const PktInfo *pkt, PktFlowInfo *info, //use policy disabled interface if (local_intf && local_intf->type() == Interface::VM_INTERFACE) { - out->nh_ = GetPolicyEnabledNH(nh_table, local_nh)->id(); + if (local_nh->IsActive()) { + out->nh_ = + GetPolicyEnabledNH(nh_table, local_nh)->id(); + } else { + LogError(pkt, "Invalid or Inactive ifindex"); + info->short_flow = true; + info->short_flow_reason = + FlowEntry::SHORT_UNAVIALABLE_INTERFACE; + } } } } else { diff --git a/src/vnsw/agent/pkt/test/test_flow_error.cc b/src/vnsw/agent/pkt/test/test_flow_error.cc index dc62ceff7ca..dadca5dfce0 100644 --- a/src/vnsw/agent/pkt/test/test_flow_error.cc +++ b/src/vnsw/agent/pkt/test/test_flow_error.cc @@ -252,6 +252,54 @@ TEST_F(FlowTest, Flow_ksync_nh_state_find_failure) { client->WaitForIdle(); } +TEST_F(FlowTest, Flow_Deleted_Interace_nh) { + EXPECT_EQ(0U, get_flow_proto()->FlowCount()); + //Create PHYSICAL interface to receive GRE packets on it. + FlowSetup(); + PhysicalInterfaceKey key(eth_itf); + Interface *intf = static_cast + (agent()->interface_table()->FindActiveEntry(&key)); + + EXPECT_TRUE(intf != NULL); + CreateRemoteRoute("vrf6", remote_vm1_ip, remote_router_ip, 30, "vn6"); + client->WaitForIdle(); + TestFlow flow[] = { + { + TestFlowPkt(Address::INET, vm_a_ip, remote_vm1_ip, 1, 0, 0, "vrf6", + flow5->id()), + { + } + } + }; + //remove policy enabled Interface + DBRequest req(DBRequest::DB_ENTRY_DELETE); + req.key.reset(new InterfaceNHKey + (new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, flow5->GetUuid(), ""), + true, InterfaceNHFlags::INET4)); + req.data.reset(NULL); + NextHopTable::GetInstance()->Enqueue(&req); + //remove policy disabled Interface + DBRequest req1(DBRequest::DB_ENTRY_DELETE); + client->WaitForIdle(1); + req1.key.reset(new InterfaceNHKey + (new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, flow5->GetUuid(), ""), + false, InterfaceNHFlags::INET4)); + req1.data.reset(NULL); + NextHopTable::GetInstance()->Enqueue(&req1); + + CreateFlow(flow, 1); + client->WaitForIdle(); + + FlowEntry *fe = + FlowGet(VrfGet("vrf6")->vrf_id(), vm_a_ip, remote_vm1_ip, 1, 0, 0, + GetFlowKeyNH(input4[0].intf_id)); + EXPECT_TRUE(fe != NULL && fe->is_flags_set(FlowEntry::ShortFlow) == true); + DeleteFlow(flow, 1); + DeleteRemoteRoute("vrf6", remote_vm1_ip); + FlowTeardown(); + client->WaitForIdle(); +} + int main(int argc, char *argv[]) { GETUSERARGS();