From 64d107f78d13560e7144542f383850809361dd73 Mon Sep 17 00:00:00 2001 From: Naveen N Date: Mon, 11 Jan 2016 15:13:57 +0530 Subject: [PATCH] * Fix bug in flow dbclient such that all states are cleared If route 0.0.0.0/0 is the last route to be deleted then flow dbclient would unregister from route table even before all states were cleared, replace upperbound by lowerbound such that 0.0.0.0/0 route is also conidered for vrf deleting Test case for same. Add safe to avoid adding route with 0.0.0.0/32. Closes-bug:#1521879,#1531346 Change-Id: Ide7f76823b229dfc139e5277436b4e9917823c08 --- src/vnsw/agent/oper/vm_interface.cc | 7 +++++ src/vnsw/agent/pkt/flow_mgmt.cc | 10 +++---- src/vnsw/agent/pkt/flow_mgmt.h | 2 +- .../agent/pkt/test/test_flow_mgmt_route.cc | 29 +++++++++++++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/vnsw/agent/oper/vm_interface.cc b/src/vnsw/agent/oper/vm_interface.cc index 8685f59704c..1be85af3ede 100644 --- a/src/vnsw/agent/oper/vm_interface.cc +++ b/src/vnsw/agent/oper/vm_interface.cc @@ -460,6 +460,10 @@ static void BuildInstanceIp(Agent *agent, VmInterfaceConfigData *data, if (ip->secondary() != true) { is_primary = true; if (addr.is_v4()) { + if (addr == Ip4Address(0)) { + return; + } + if (data->addr_ == Ip4Address(0) || data->addr_ > addr.to_v4()) { data->addr_ = addr.to_v4(); @@ -470,6 +474,9 @@ static void BuildInstanceIp(Agent *agent, VmInterfaceConfigData *data, } } } else if (addr.is_v6()) { + if (addr == Ip6Address()) { + return; + } if (data->ip6_addr_ == Ip6Address() || data->ip6_addr_ > addr.to_v6()) { data->ip6_addr_ = addr.to_v6(); diff --git a/src/vnsw/agent/pkt/flow_mgmt.cc b/src/vnsw/agent/pkt/flow_mgmt.cc index a63ca0116ac..892084fd89d 100644 --- a/src/vnsw/agent/pkt/flow_mgmt.cc +++ b/src/vnsw/agent/pkt/flow_mgmt.cc @@ -584,8 +584,8 @@ FlowMgmtEntry *FlowMgmtTree::Locate(FlowMgmtKey *key) { return entry; } -FlowMgmtKey *FlowMgmtTree::UpperBound(FlowMgmtKey *key) { - Tree::iterator it = tree_.upper_bound(key); +FlowMgmtKey *FlowMgmtTree::LowerBound(FlowMgmtKey *key) { + Tree::iterator it = tree_.lower_bound(key); if (it == tree_.end()) return NULL; @@ -1179,10 +1179,10 @@ bool InetRouteFlowMgmtTree::HasVrfFlows(uint32_t vrf, if (type == Agent::INET4_UNICAST) { InetRouteFlowMgmtKey key(vrf, Ip4Address(0), 0); - next_key = static_cast(UpperBound(&key)); + next_key = static_cast(LowerBound(&key)); } else { InetRouteFlowMgmtKey key(vrf, Ip6Address(), 0); - next_key = static_cast(UpperBound(&key)); + next_key = static_cast(LowerBound(&key)); } if (next_key == NULL) @@ -1257,7 +1257,7 @@ bool BridgeRouteFlowMgmtTree::HasVrfFlows(uint32_t vrf, Agent::RouteTableType type) { BridgeRouteFlowMgmtKey key(vrf, MacAddress::ZeroMac()); BridgeRouteFlowMgmtKey *next_key = static_cast - (UpperBound(&key)); + (LowerBound(&key)); if (next_key == false) return false; diff --git a/src/vnsw/agent/pkt/flow_mgmt.h b/src/vnsw/agent/pkt/flow_mgmt.h index 544b74f4a3c..b15532dcce1 100644 --- a/src/vnsw/agent/pkt/flow_mgmt.h +++ b/src/vnsw/agent/pkt/flow_mgmt.h @@ -389,7 +389,7 @@ class FlowMgmtTree { FlowMgmtEntry *Locate(FlowMgmtKey *key); FlowMgmtEntry *Find(FlowMgmtKey *key); - FlowMgmtKey *UpperBound(FlowMgmtKey *key); + FlowMgmtKey *LowerBound(FlowMgmtKey *key); Tree &tree() { return tree_; } FlowMgmtManager *mgr() const { return mgr_; } static bool AddFlowMgmtKey(FlowMgmtKeyTree *tree, FlowMgmtKey *key); diff --git a/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc b/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc index 501334ef1fb..486a9bb566f 100644 --- a/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc +++ b/src/vnsw/agent/pkt/test/test_flow_mgmt_route.cc @@ -246,6 +246,35 @@ TEST_F(FlowMgmtRouteTest, RouteDelete_4) { client->WaitForIdle(10); } +TEST_F(FlowMgmtRouteTest, RouteDelete_5) { + VrfAddReq("vrf10"); + client->WaitForIdle(); + + boost::system::error_code ec; + Ip4Address remote_ip1 = Ip4Address::from_string("0.0.0.0", ec); + Ip4Address remote_compute = Ip4Address::from_string("1.1.1.1", ec); + char router_id[80]; + strcpy(router_id, Agent::GetInstance()->router_id().to_string().c_str()); + + string vn_name = "vn10"; + Inet4TunnelRouteAdd(agent_->local_peer(), "vrf10", remote_ip1, 0, + remote_compute, TunnelType::AllType(), 10, + vn_name, SecurityGroupList(), + PathPreference()); + Inet4TunnelRouteAdd(agent_->local_peer(), "vrf10", remote_compute, 24, + remote_compute, TunnelType::AllType(), 10, + vn_name, SecurityGroupList(), PathPreference()); + client->WaitForIdle(); + + VrfDelReq("vrf10"); + client->WaitForIdle(); + DeleteRoute("vrf10", "1.1.1.1", 24, agent_->local_peer()); + client->WaitForIdle(); + DeleteRoute("vrf10", "0.0.0.0", 0, agent_->local_peer()); + client->WaitForIdle(); +} + + int main(int argc, char *argv[]) { int ret = 0;