Skip to content

Commit

Permalink
* Calculate fat flow protocol in packet processing context
Browse files Browse the repository at this point in the history
Calculate port in packet processing context such that packet
gets enqueued to right partition
Store flow partition in stats collector context and use that
for enqueueing delete request.
Closes-bug:#1542268

Change-Id: I4cd4a1f250581dcfa09e9b23108e4a9736850488
  • Loading branch information
naveen-n committed Feb 22, 2016
1 parent a9508b1 commit f568ba9
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 72 deletions.
32 changes: 18 additions & 14 deletions src/vnsw/agent/pkt/flow_event.h
Expand Up @@ -62,68 +62,71 @@ class FlowEvent {
event_(INVALID), flow_(NULL), pkt_info_(), db_entry_(NULL),
gen_id_(0), del_rev_flow_(false),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(NULL),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(0) {
}

FlowEvent(Event event) :
event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
gen_id_(0), del_rev_flow_(false), ksync_entry_(NULL), ksync_event_(),
ksync_error_(0) {
ksync_error_(0), table_index_(0) {
}

FlowEvent(Event event, FlowEntry *flow) :
event_(event), flow_(flow), pkt_info_(), db_entry_(NULL),
gen_id_(0), del_rev_flow_(false),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(NULL),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(0){
}

FlowEvent(Event event, FlowEntry *flow, uint32_t flow_handle) :
event_(event), flow_(flow), pkt_info_(), db_entry_(NULL),
gen_id_(0), del_rev_flow_(false), flow_handle_(flow_handle),
ksync_entry_(NULL), ksync_event_(), ksync_error_(0) {
ksync_entry_(NULL), ksync_event_(), ksync_error_(0),
table_index_(0) {
}

FlowEvent(Event event, FlowEntry *flow, const DBEntry *db_entry) :
event_(event), flow_(flow), pkt_info_(), db_entry_(db_entry),
gen_id_(0), del_rev_flow_(false),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(NULL),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(0) {
}

FlowEvent(Event event, const DBEntry *db_entry, uint32_t gen_id) :
event_(event), flow_(NULL), pkt_info_(), db_entry_(db_entry),
gen_id_(gen_id), del_rev_flow_(false),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(NULL),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(0) {
}

FlowEvent(Event event, const FlowKey &key, bool del_rev_flow) :
FlowEvent(Event event, const FlowKey &key, bool del_rev_flow,
uint32_t table_index) :
event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
gen_id_(0), flow_key_(key), del_rev_flow_(del_rev_flow),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(NULL),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(table_index) {
}

FlowEvent(Event event, const FlowKey &key, uint32_t flow_handle) :
event_(event), flow_(NULL), pkt_info_(), db_entry_(NULL),
gen_id_(0), flow_key_(key), del_rev_flow_(false),
flow_handle_(flow_handle), ksync_entry_(NULL), ksync_event_(),
ksync_error_(0) {
ksync_error_(0), table_index_(0) {
}

FlowEvent(Event event, PktInfoPtr pkt_info) :
event_(event), flow_(NULL), pkt_info_(pkt_info), db_entry_(NULL),
gen_id_(0), flow_key_(), del_rev_flow_(),
flow_handle_(FlowEntry::kInvalidFlowHandle),
ksync_entry_(NULL), ksync_event_(), ksync_error_(0) {
ksync_entry_(NULL), ksync_event_(), ksync_error_(0), table_index_(0) {
}

FlowEvent(KSyncEntry *entry, KSyncEntry::KSyncEvent event) :
event_(KSYNC_EVENT), flow_(NULL), pkt_info_(), db_entry_(NULL),
gen_id_(0), flow_key_(), del_rev_flow_(),
flow_handle_(FlowEntry::kInvalidFlowHandle),
ksync_entry_(entry), ksync_event_(event), ksync_error_(0) {
ksync_entry_(entry), ksync_event_(event), ksync_error_(0),
table_index_(0) {
}

FlowEvent(KSyncEntry *entry, uint32_t flow_handle) :
Expand All @@ -137,7 +140,7 @@ class FlowEvent {
event_(KSYNC_VROUTER_ERROR), flow_(NULL), pkt_info_(),
db_entry_(NULL), gen_id_(0), flow_key_(), del_rev_flow_(),
flow_handle_(FlowEntry::kInvalidFlowHandle), ksync_entry_(entry),
ksync_event_(), ksync_error_(0) {
ksync_event_(), ksync_error_(0), table_index_(0) {
}

FlowEvent(const FlowEvent &rhs) :
Expand All @@ -146,7 +149,7 @@ class FlowEvent {
flow_key_(rhs.flow_key_), del_rev_flow_(rhs.del_rev_flow_),
flow_handle_(rhs.flow_handle_),
ksync_entry_(rhs.ksync_entry_), ksync_event_(rhs.ksync_event_),
ksync_error_(0) {
ksync_error_(0), table_index_(rhs.table_index_) {
}

virtual ~FlowEvent() { }
Expand All @@ -167,7 +170,7 @@ class FlowEvent {

void set_ksync_error(int error) { ksync_error_ = error; }
int ksync_error() const { return ksync_error_; }

uint32_t table_index() const { return table_index_;}
private:
Event event_;
FlowEntryPtr flow_;
Expand All @@ -180,6 +183,7 @@ class FlowEvent {
KSyncEntry::KSyncEntryPtr ksync_entry_;
KSyncEntry::KSyncEvent ksync_event_;
int ksync_error_;
uint32_t table_index_;
};

#endif // __AGENT_FLOW_EVENT_H__
9 changes: 5 additions & 4 deletions src/vnsw/agent/pkt/flow_proto.cc
Expand Up @@ -275,7 +275,7 @@ bool FlowProto::FlowEventHandler(FlowEvent *req, FlowTable *table) {
}

case FlowEvent::DELETE_FLOW: {
FlowTable *table = GetFlowTable(req->get_flow_key());
FlowTable *table = GetTable(req->table_index());
table->Delete(req->get_flow_key(), req->get_del_rev_flow());
break;
}
Expand Down Expand Up @@ -378,9 +378,10 @@ bool FlowProto::FlowEventHandler(FlowEvent *req, FlowTable *table) {
return true;
}

void FlowProto::DeleteFlowRequest(const FlowKey &flow_key, bool del_rev_flow) {
EnqueueFlowEvent(new FlowEvent(FlowEvent::DELETE_FLOW, flow_key,
del_rev_flow));
void FlowProto::DeleteFlowRequest(const FlowKey &flow_key, bool del_rev_flow,
uint32_t table_index) {
EnqueueFlowEvent(new FlowEvent(FlowEvent::DELETE_FLOW, flow_key, del_rev_flow,
table_index));
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/pkt/flow_proto.h
Expand Up @@ -64,7 +64,8 @@ class FlowProto : public Proto {

void EnqueueEvent(FlowEvent *event, FlowTable *table);
void EnqueueFlowEvent(FlowEvent *event);
void DeleteFlowRequest(const FlowKey &flow_key, bool del_rev_flow);
void DeleteFlowRequest(const FlowKey &flow_key, bool del_rev_flow,
uint32_t table_index);
void EvictFlowRequest(FlowEntry *flow, uint32_t flow_handle);
void RetryIndexAcquireRequest(FlowEntry *flow, uint32_t flow_handle);
void CreateAuditEntry(const FlowKey &key, uint32_t flow_handle);
Expand Down
47 changes: 0 additions & 47 deletions src/vnsw/agent/pkt/pkt_flow_info.cc
Expand Up @@ -1121,7 +1121,6 @@ void PktFlowInfo::IngressProcess(const PktInfo *pkt, PktControlInfo *in,
return;
}

CalculatePort(pkt, in->intf_);
// We always expect route for source-ip for ingress flows.
// If route not present, return from here so that a short flow is added
UpdateRoute(&in->rt_, in->vrf_, pkt->ip_saddr, pkt->smac,
Expand Down Expand Up @@ -1271,7 +1270,6 @@ void PktFlowInfo::EgressProcess(const PktInfo *pkt, PktControlInfo *in,
}

if (out->intf_ && out->intf_->type() == Interface::VM_INTERFACE) {
CalculatePort(pkt, out->intf_);
const VmInterface *vm_intf = static_cast<const VmInterface *>(out->intf_);
if (vm_intf->IsFloatingIp(pkt->ip_daddr)) {
pkt->l3_forwarding = true;
Expand Down Expand Up @@ -1475,51 +1473,6 @@ bool PktFlowInfo::Process(const PktInfo *pkt, PktControlInfo *in,
return true;
}

//Mask source port or destination port if a port has fat flow
//configuration. If both source port and destination port are
//present in configuration then the lowest of the port takes
//priority
void PktFlowInfo::CalculatePort(const PktInfo *cpkt, const Interface *in) {
const VmInterface *intf = NULL;
PktInfo *pkt = const_cast<PktInfo *>(cpkt);

if (in == NULL || in->type() != Interface::VM_INTERFACE) {
return;
}

intf = static_cast<const VmInterface *>(in);
if (intf->fat_flow_list().list_.size() == 0) {
return;
}

uint16_t sport = pkt->sport;
if (pkt->ip_proto == IPPROTO_ICMP) {
sport = 0;
}
if (pkt->sport < pkt->dport) {
if (intf->IsFatFlow(pkt->ip_proto, sport)) {
pkt->dport = 0;
return;
}

if (intf->IsFatFlow(pkt->ip_proto, pkt->dport)) {
pkt->sport = 0;
return;
}
return;
}

if (intf->IsFatFlow(pkt->ip_proto, pkt->dport)) {
pkt->sport = 0;
return;
}

if (intf->IsFatFlow(pkt->ip_proto, sport)) {
pkt->dport = 0;
return;
}
}

// A flow can mean that traffic is seen on an interface. The path preference
// module can potentially be interested in this event. Check and generate
// traffic seen event
Expand Down
1 change: 0 additions & 1 deletion src/vnsw/agent/pkt/pkt_flow_info.h
Expand Up @@ -115,7 +115,6 @@ class PktFlowInfo {
const IpAddress &addr, const MacAddress &mac,
FlowRouteRefMap &ref_map);
uint8_t RouteToPrefixLen(const AgentRoute *route);
void CalculatePort(const PktInfo *p, const Interface *intf);
bool RouteAllowNatLookupCommon(const AgentRoute *rt,
uint32_t sport,
uint32_t dport,
Expand Down
62 changes: 62 additions & 0 deletions src/vnsw/agent/pkt/pkt_handler.cc
Expand Up @@ -74,6 +74,64 @@ void PktHandler::Send(const AgentHdr &hdr, const PacketBufferPtr &buff) {
return;
}

void PktHandler::CalculatePort(PktInfo *pkt) {
const Interface *in = NULL;
const VmInterface *intf = NULL;

const NextHop *nh =
agent()->nexthop_table()->FindNextHop(pkt->agent_hdr.nh);
if (!nh) {
return;
}

if (nh->GetType() == NextHop::INTERFACE) {
const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
in = intf_nh->GetInterface();
} else if (nh->GetType() == NextHop::VLAN) {
const VlanNH *vlan_nh = static_cast<const VlanNH *>(nh);
in = vlan_nh->GetInterface();
}

if (in) {
intf = dynamic_cast<const VmInterface *>(in);
}

if (!intf) {
return;
}

if (intf->fat_flow_list().list_.size() == 0) {
return;
}

uint16_t sport = pkt->sport;
if (pkt->ip_proto == IPPROTO_ICMP) {
sport = 0;
}
if (pkt->sport < pkt->dport) {
if (intf->IsFatFlow(pkt->ip_proto, sport)) {
pkt->dport = 0;
return;
}

if (intf->IsFatFlow(pkt->ip_proto, pkt->dport)) {
pkt->sport = 0;
return;
}
return;
}

if (intf->IsFatFlow(pkt->ip_proto, pkt->dport)) {
pkt->sport = 0;
return;
}

if (intf->IsFatFlow(pkt->ip_proto, sport)) {
pkt->dport = 0;
return;
}
}

// Process the packet received from tap interface
PktHandler::PktModuleName PktHandler::ParsePacket(const AgentHdr &hdr,
PktInfo *pkt_info,
Expand Down Expand Up @@ -127,6 +185,10 @@ PktHandler::PktModuleName PktHandler::ParsePacket(const AgentHdr &hdr,
return ARP;
}

if (IsFlowPacket(pkt_info)) {
CalculatePort(pkt_info);
}

// Packets needing flow
if (IsFlowPacket(pkt_info)) {
if ((pkt_info->ip && pkt_info->family == Address::INET) ||
Expand Down
1 change: 1 addition & 0 deletions src/vnsw/agent/pkt/pkt_handler.h
Expand Up @@ -266,6 +266,7 @@ class PktHandler {
PktModule *pkt_module() const { return pkt_module_; }
void Enqueue(PktModuleName module, boost::shared_ptr<PktInfo> pkt_info);
bool IsFlowPacket(PktInfo *pkt_info);
void CalculatePort(PktInfo *pkt_info);

private:
int ParseEthernetHeader(PktInfo *pkt_info, uint8_t *pkt);
Expand Down
7 changes: 4 additions & 3 deletions src/vnsw/agent/pkt/test/test_flow_eviction.cc
Expand Up @@ -426,7 +426,7 @@ TEST_F(FlowEvictionTest, Delete_Evicted_Flow_1) {
EXPECT_TRUE(FlowGet(vrf_id, remote_vm1_ip, vm1_ip, 2, 0, 0,
vif0->flow_key_nh()->id()) == false);

flow_proto_->DeleteFlowRequest(key, true);
flow_proto_->DeleteFlowRequest(key, true, flow->flow_table()->table_index());
client->WaitForIdle();

// New flow should be present
Expand All @@ -450,7 +450,8 @@ TEST_F(FlowEvictionTest, Delete_Evicted_Flow_2) {
EXPECT_TRUE(flow != NULL);

// Generate delete request followed by flow-evict
flow_proto_->DeleteFlowRequest(flow->key(), true);
flow_proto_->DeleteFlowRequest(flow->key(), true,
flow->flow_table()->table_index());
// Generate a flow that evicts flow created above
TxIpMplsPacket(eth->id(), remote_compute, router_id_, vif0->label(),
remote_vm1_ip, vm1_ip, 1, 1);
Expand Down Expand Up @@ -483,7 +484,7 @@ TEST_F(FlowEvictionTest, Delete_Index_Unassigned_Flow_1) {
EXPECT_TRUE(flow != NULL);

FlowKey key = flow->key();
flow_proto_->DeleteFlowRequest(key, true);
flow_proto_->DeleteFlowRequest(key, true, flow->flow_table()->table_index());
client->WaitForIdle();

ksync_sock_->DisableReceiveQueue(false);
Expand Down
7 changes: 6 additions & 1 deletion src/vnsw/agent/vrouter/flow_stats/flow_export_info.cc
Expand Up @@ -11,7 +11,7 @@ FlowExportInfo::FlowExportInfo() :
vm_cfg_name_(), peer_vrouter_(), tunnel_type_(TunnelType::INVALID),
underlay_source_port_(0), changed_(false),
fip_(0), fip_vmi_(AgentKey::ADD_DEL_CHANGE, nil_uuid(), ""), tcp_flags_(0),
delete_enqueued_(false) {
delete_enqueued_(false), flow_partition_(0) {
key_.Reset();
drop_reason_ = FlowEntry::DropReasonStr(FlowEntry::DROP_UNKNOWN);
interface_uuid_ = boost::uuids::nil_uuid();
Expand Down Expand Up @@ -41,6 +41,11 @@ FlowExportInfo::FlowExportInfo(FlowEntry *fe, uint64_t setup_time) :
interface_uuid_ = boost::uuids::nil_uuid();
}
drop_reason_ = FlowEntry::DropReasonStr(fe->data().drop_reason);
if (fe->flow_table()) {
flow_partition_ = fe->flow_table()->table_index();
} else {
flow_partition_ = 0;
}
}

/* This API compares only fields which are copied from FlowEntry. Fields which
Expand Down
4 changes: 4 additions & 0 deletions src/vnsw/agent/vrouter/flow_stats/flow_export_info.h
Expand Up @@ -64,6 +64,9 @@ class FlowExportInfo {
void Copy(const FlowExportInfo &rhs);
void set_delete_enqueued(bool value) { delete_enqueued_ = value; }
bool delete_enqueued() const { return delete_enqueued_; }
uint32_t flow_partition() const {
return flow_partition_;
}
private:
boost::uuids::uuid flow_uuid_;
boost::uuids::uuid egress_uuid_; // used/applicable only for local flows
Expand Down Expand Up @@ -96,6 +99,7 @@ class FlowExportInfo {
std::string drop_reason_;
uint16_t tcp_flags_;
bool delete_enqueued_;
uint32_t flow_partition_;
};

#endif // __AGENT_FLOW_EXPORT_INFO_H__
3 changes: 2 additions & 1 deletion src/vnsw/agent/vrouter/flow_stats/flow_stats_collector.cc
Expand Up @@ -288,7 +288,8 @@ void FlowStatsCollector::UpdateStatsAndExportFlow(FlowExportInfo *info,

void FlowStatsCollector::FlowDeleteEnqueue(FlowExportInfo *info) {
agent_uve_->agent()->pkt()->get_flow_proto()->DeleteFlowRequest(info->key(),
true);
true,
info->flow_partition());
info->set_delete_enqueued(true);
FlowExportInfo *rev_info = FindFlowExportInfo(info->rev_flow_uuid());
if (rev_info) {
Expand Down

0 comments on commit f568ba9

Please sign in to comment.