Skip to content

Commit

Permalink
Send underlay udp source port from agent flow log message in all cases.
Browse files Browse the repository at this point in the history
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.

Closes-Bug: #1458337
(cherry picked from commit fb7c84b)

Change-Id: I68287c35020ae480c936196f8a12520e0aa2d3d3
  • Loading branch information
ashoksr committed May 25, 2015
1 parent e89699c commit cbf2099
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
50 changes: 49 additions & 1 deletion src/vnsw/agent/pkt/flow_table.cc
Expand Up @@ -97,7 +97,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;
Expand Down Expand Up @@ -3428,6 +3428,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;
Expand All @@ -3439,11 +3464,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);
}
Expand Down Expand Up @@ -3523,14 +3554,31 @@ 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.
//We need to reset the exported flag when flow is getting deleted to
//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;
}

Expand Down
7 changes: 7 additions & 0 deletions src/vnsw/agent/pkt/flow_table.h
Expand Up @@ -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; }
Expand Down Expand Up @@ -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<int> refcount_;
};
Expand Down Expand Up @@ -770,6 +776,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);
};
Expand Down

0 comments on commit cbf2099

Please sign in to comment.