From fb7c84b3d67ac01f284b52124942bcdaa55c5d02 Mon Sep 17 00:00:00 2001 From: ashoksingh Date: Mon, 25 May 2015 09:50:27 +0530 Subject: [PATCH] Send underlay udp source port from agent flow log message in all cases. Currently underlay source port is exported only once when the flow is being exported for the first time. At this point it is possible that agent does not have this underlay source port yet to be exported. As a fix ensure that underlay source port is sent when the flow is being exported again if it is not already sent. Change-Id: Ieabd1058dbe24d8ec2027c7aed18e74b19daa4a1 Closes-Bug: #1458337 --- src/vnsw/agent/pkt/flow_table.cc | 50 +++++++++++++++++++++++++++++++- src/vnsw/agent/pkt/flow_table.h | 7 +++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/vnsw/agent/pkt/flow_table.cc b/src/vnsw/agent/pkt/flow_table.cc index 4a91f831dbb..d5bc9685334 100644 --- a/src/vnsw/agent/pkt/flow_table.cc +++ b/src/vnsw/agent/pkt/flow_table.cc @@ -98,7 +98,7 @@ FlowEntry::FlowEntry(const FlowKey &k) : linklocal_src_port_(), linklocal_src_port_fd_(PktFlowInfo::kLinkLocalInvalidFd), peer_vrouter_(), tunnel_type_(TunnelType::INVALID), - underlay_source_port_(0) { + underlay_source_port_(0), underlay_sport_exported_(false) { flow_uuid_ = FlowTable::rand_gen_(); egress_uuid_ = FlowTable::rand_gen_(); refcount_ = 0; @@ -3450,6 +3450,31 @@ FlowTable::~FlowTable() { delete nh_listener_; } +bool FlowTable::SetUnderlayPort(FlowEntry *flow, FlowDataIpv4 &s_flow) { + uint16_t underlay_src_port = 0; + bool exported = false; + if (flow->is_flags_set(FlowEntry::LocalFlow)) { + /* Set source_port as 0 for local flows. Source port is calculated by + * vrouter irrespective of whether flow is local or not. So for local + * flows we need to ignore port given by vrouter + */ + s_flow.set_underlay_source_port(0); + exported = true; + } else { + if (flow->tunnel_type().GetType() != TunnelType::MPLS_GRE) { + underlay_src_port = flow->underlay_source_port(); + if (underlay_src_port) { + exported = true; + } + } else { + exported = true; + } + s_flow.set_underlay_source_port(underlay_src_port); + } + flow->set_underlay_sport_exported(exported); + return exported; +} + void FlowTable::SetUnderlayInfo(FlowEntry *flow, FlowDataIpv4 &s_flow) { string rid = agent_->router_id().to_string(); uint16_t underlay_src_port = 0; @@ -3461,11 +3486,17 @@ void FlowTable::SetUnderlayInfo(FlowEntry *flow, FlowDataIpv4 &s_flow) { * flows we need to ignore port given by vrouter */ s_flow.set_underlay_source_port(0); + flow->set_underlay_sport_exported(true); } else { s_flow.set_vrouter_ip(rid); s_flow.set_other_vrouter_ip(flow->peer_vrouter()); if (flow->tunnel_type().GetType() != TunnelType::MPLS_GRE) { underlay_src_port = flow->underlay_source_port(); + if (underlay_src_port) { + flow->set_underlay_sport_exported(true); + } + } else { + flow->set_underlay_sport_exported(true); } s_flow.set_underlay_source_port(underlay_src_port); } @@ -3545,7 +3576,23 @@ void FlowTable::FlowExport(FlowEntry *flow, uint64_t diff_bytes, stats.exported = true; level = SandeshLevel::SYS_ERR; SetUnderlayInfo(flow, s_flow); + } else { + /* When the flow is being exported for first time, underlay port + * info is set as part of SetUnderlayInfo. At this point it is possible + * that port is not yet populated to flow-entry because of either + * (i) flow-entry has not got chance to be evaluated by + * flow-stats-collector + * (ii) there is no flow entry in vrouter yet + * (iii) the flow entry in vrouter does not have underlay source port + * populated yet + */ + if (!flow->underlay_sport_exported()) { + if (SetUnderlayPort(flow, s_flow)) { + level = SandeshLevel::SYS_ERR; + } + } } + if (stats.teardown_time) { s_flow.set_teardown_time(stats.teardown_time); //Teardown time will be set in flow only when flow is deleted. @@ -3553,6 +3600,7 @@ void FlowTable::FlowExport(FlowEntry *flow, uint64_t diff_bytes, //handle flow entry reuse case (Flow add request coming for flows //marked as deleted) stats.exported = false; + flow->set_underlay_sport_exported(false); level = SandeshLevel::SYS_ERR; } diff --git a/src/vnsw/agent/pkt/flow_table.h b/src/vnsw/agent/pkt/flow_table.h index 29fc295d631..4c394a2249e 100644 --- a/src/vnsw/agent/pkt/flow_table.h +++ b/src/vnsw/agent/pkt/flow_table.h @@ -422,6 +422,11 @@ class FlowEntry { void set_underlay_source_port(uint16_t port) { underlay_source_port_ = port; } + bool underlay_sport_exported() const { return underlay_sport_exported_; } + void set_underlay_sport_exported(bool value) { + underlay_sport_exported_ = value; + } + uint16_t short_flow_reason() const { return short_flow_reason_; } bool set_pending_recompute(bool value); const MacAddress &smac() const { return data_.smac; } @@ -465,6 +470,7 @@ class FlowEntry { TunnelType tunnel_type_; //Underlay source port. 0 for local flows. Used during flow-export uint16_t underlay_source_port_; + bool underlay_sport_exported_; // atomic refcount tbb::atomic refcount_; }; @@ -771,6 +777,7 @@ class FlowTable { void UpdateReverseFlow(FlowEntry *flow, FlowEntry *rflow); void SourceIpOverride(FlowEntry *flow, FlowDataIpv4 &s_flow); void SetUnderlayInfo(FlowEntry *flow, FlowDataIpv4 &s_flow); + bool SetUnderlayPort(FlowEntry *flow, FlowDataIpv4 &s_flow); DISALLOW_COPY_AND_ASSIGN(FlowTable); };