8 #include <boost/date_time/posix_time/posix_time.hpp>
9 #include <boost/assign/list_of.hpp>
10 #include <boost/unordered_map.hpp>
11 #include <sandesh/sandesh_trace.h>
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
42 #include <pkt/pkt_types.h>
60 rand_gen_(boost::uuids::random_generator()),
61 table_index_(table_index),
66 flow_update_task_id_(0),
67 flow_delete_task_id_(0),
68 flow_ksync_task_id_(0),
69 flow_logging_task_id_(0) {
99 if (current == NULL) {
105 if (check_task_instance) {
123 tbb::mutex **mutex_ptr_1,
124 tbb::mutex **mutex_ptr_2) {
127 if (&mutex1 < &mutex2) {
128 *mutex_ptr_1 = &mutex1;
129 *mutex_ptr_2 = &mutex2;
131 *mutex_ptr_1 = &mutex2;
132 *mutex_ptr_2 = &mutex1;
138 FlowEntryMap::iterator it;
159 lhs->
Copy(rhs, update);
164 std::pair<FlowEntryMap::iterator, bool> ret;
166 if (ret.second ==
true) {
168 ret.first->second->set_on_tree();
172 return ret.first->second;
181 AddInternal(flow, new_flow, rflow, new_rflow,
false,
false);
185 bool fwd_flow_update =
true;
189 bool rev_flow_update =
true;
190 if (rflow && new_rflow == NULL) {
192 new_rflow =
Locate(rflow, time);
193 rev_flow_update =
false;
197 AddInternal(flow, new_flow, rflow, new_rflow, fwd_flow_update,
203 bool fwd_flow_update,
bool rev_flow_update) {
217 bool force_update_rflow =
false;
218 if (fwd_flow_update) {
227 if (flow_req != flow) {
233 force_update_rflow =
true;
235 Copy(flow, flow_req, fwd_flow_update);
243 if (rflow_req != rflow) {
244 Copy(rflow, rflow_req, (rev_flow_update || force_update_rflow));
254 force_update_rflow =
false;
263 force_update_rflow =
false;
268 if (fwd_flow_update) {
275 if (rev_flow_update) {
315 UpdateKSync(rflow, (rev_flow_update || force_update_rflow));
352 if (rflow && rflow->
deleted() ==
false) {
355 if (flow && flow->
deleted() ==
false) {
362 if (rflow && rflow->
deleted() ==
false) {
386 if (reverse_flow_entry) {
387 *rflow =
Find(reverse_flow_entry->
key());
430 FlowEntryMap::iterator it;
439 reverse_entry = it->second;
548 uint32_t evict_gen_id) {
560 bool active_flow,
bool deleted_flow) {
578 if (flow == NULL || rflow == NULL)
613 if (tunnel_nh != NULL) {
651 int ksync_error, uint32_t flow_handle,
654 if (flow == NULL || flow != ksync_entry->
flow_entry()) {
660 if ((ksync_error == EBADF || ksync_error == ENOENT)) {
698 ksync_error == EEXIST &&
713 if (ksync_error == EEXIST) {
718 if (kflow && intf && (kflow->fe_action != VR_FLOW_ACTION_HOLD) &&
739 assert(update ==
false);
754 const uint64_t timestamp) {
755 tbb::mutex::scoped_lock mutext(
mutex_);
761 it->second.flow_index = index;
762 it->second.flow_key = key;
767 tbb::mutex::scoped_lock mutext(
mutex_);
817 LOG(DEBUG,
"Flow index changed from <"
829 if (evicted_flow.get() && evicted_flow->deleted() ==
false) {
835 evicted_flow->uuid());
851 bool active_flow =
true;
852 bool deleted_flow = flow->
deleted();
857 switch (req->
event()) {
945 std::string &action_str) {
946 std::bitset<32> bs(action_info.
action);
947 for (
unsigned int i = 0; i < bs.size(); i++) {
949 if (!action_str.empty()) {
953 static_cast<TrafficAction::Action>(i));
966 table_(table), max_count_(0), grow_pending_(false), total_alloc_(0),
967 total_free_(0), free_list_() {
995 for (uint32_t i = 0; i <
kGrowSize; i++) {
boost::uuids::uuid rand_gen()
void Delete(FlowEntry *flow)
LinkLocalFlowInfoMap linklocal_flow_info_map_
bool ConcurrencyCheck(int task_id, bool check_task_instance)
void DelLinkLocalFlowInfo(int fd)
FlowEntryMap flow_entry_map_
uint64_t evict_flow_bytes() const
bool DeleteUnLocked(const FlowKey &key, bool del_reverse_flow)
void DeleteFlowInfo(FlowEntry *fe, const RevFlowDepParams ¶ms)
FlowEntryFreeList free_list_
static Task * Running()
Returns a pointer to the current task the code is executing under.
bool Delete(const FlowKey &key, bool del_reverse_flow)
static const uint32_t kMinThreshold
uint32_t GetTransactionId()
static const uint32_t kInitCount
uint64_t evict_flow_oflow() const
boost::uuids::random_generator rand_gen_
uint8_t underlay_gw_index_
FlowEntryInfo * flow_mgmt_info() const
void HandleKSyncError(FlowEntry *flow, FlowTableKSyncEntry *ksync_entry, int ksync_error, uint32_t flow_handle, uint32_t gen_id)
AgentStats * stats() const
FlowEntry * Locate(FlowEntry *flow, uint64_t t)
static void GetMutexSeq(tbb::mutex &mutex1, tbb::mutex &mutex2, tbb::mutex **mutex_ptr_1, tbb::mutex **mutex_ptr_2)
#define FLOW_LOCK(flow, rflow, flow_event)
uint32_t flow_handle() const
static const uint32_t kTestInitCount
void DeleteKSync(FlowEntry *flow)
void HandleRevaluateDBEntry(const DBEntry *entry, FlowEntry *flow, bool active_flow, bool deleted_flow)
FlowEntryPtr FindByIndex(uint32_t idx)
FlowTable(Agent *agent, uint16_t table_index)
PortTableManager * port_table_manager()
void DeleteInternal(FlowEntry *fe, uint64_t t, const RevFlowDepParams &p)
void AddEvent(FlowEntry *low)
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
std::pair< FlowKey, FlowEntry * > FlowEntryMapPair
void GetPolicyInfo(const VnEntry *vn, const FlowEntry *rflow)
uint16_t allocated_port()
static const uint32_t kMaxThreshold
void UpdateKSync(FlowEntry *flow, bool update)
uint64_t evict_flow_packets() const
bool ProcessFlowEvent(const FlowEvent *req, FlowEntry *flow, FlowEntry *rflow)
int GetTaskId(const std::string &name)
bool flood_unknown_unicast() const
const FlowKey & key() const
static const uint32_t kFlowRetryAttempts
int flow_logging_task_id() const
FlowEntry * Find(const FlowKey &key)
KSyncEntry::KSyncEvent ksync_event() const
void AddLinkLocalFlowInfo(int fd, uint32_t index, const FlowKey &key, const uint64_t timestamp)
void AddFlowInfo(FlowEntry *fe)
bool is_flags_set(const FlowEntryFlags &flags) const
TaskScheduler * task_scheduler() const
void RevFlowDepInfo(RevFlowDepParams *params)
void IncrementTransactionId()
void Copy(FlowEntry *rhs, bool update)
const NextHop * GetActiveNextHop() const
void set_deleted(bool deleted)
std::pair< int, LinkLocalFlowInfo > LinkLocalFlowInfoPair
void DisableKSyncSend(FlowEntry *flow, uint32_t evict_gen_id)
AllowedAddressPairSet list_
void MessageRequest(FlowEntry *flow)
int flow_logging_task_id_
uint32_t transaction_id() const
FlowEntryFreeList(FlowTable *table)
FlowEntry * Allocate(const FlowKey &key)
void set_last_event(uint32_t event)
void set_reverse_flow_entry(FlowEntry *reverse_flow_entry)
void Add(FlowEntry *flow, FlowEntry *rflow)
void set_flags(const FlowEntryFlags &flags)
const FlowKSyncResponseInfo * ksync_response_info() const
void ReleasePort(FlowEntry *flow, bool evict)
void MakeShortFlow(FlowShortReason reason)
static AgentRoute * GetUcRoute(const VrfEntry *entry, const IpAddress &addr)
int GetTaskInstance() const
void Reset(const FlowKey &k)
static void GetFlowSandeshActionParams(const FlowAction &action_info, std::string &action_str)
virtual ~FlowEntryFreeList()
void DeleteEvent(FlowEntry *flow, const RevFlowDepParams ¶ms)
const DBEntry * db_entry() const
void FlowStatsUpdateEvent(FlowEntry *flow, uint32_t bytes, uint32_t packets, uint32_t oflow_bytes, const boost::uuids::uuid &u)
static std::string ActionToString(enum Action at)
void Copy(FlowEntry *lhs, FlowEntry *rhs, bool update)
FlowProto * get_flow_proto() const
void RecomputeFlow(FlowEntry *flow)
void Update(FlowEntry *flow)
bool DeleteFlows(FlowEntry *flow, FlowEntry *rflow)
const Interface * intf_entry() const
const vr_flow_entry * GetKernelFlowEntry(uint32_t idx, bool ignore_active_status) const
void PopulateFlowEntriesUsingKey(const FlowKey &key, bool reverse_flow, FlowEntry **flow, FlowEntry **rflow)
const EncapDataList GetEncapDataList() const
uint32_t flow_handle() const
static uint64_t UTCTimestampUsec()
SandeshTraceBufferPtr FlowTraceBuf
const VnEntry * vn_entry() const
void ProcessKSyncFlowEvent(const FlowEventKSync *req, FlowEntry *flow)
static const uint32_t kInvalidFlowHandle
FlowEntry * reverse_flow_entry()
std::vector< EncapDataPtr > EncapDataList
void Free(FlowEntry *flow)
uint8_t GetMaxRetryAttempts()
#define LOG(_Level, _Msg)
FlowTableKSyncObject * ksync_object_
void Free(const FlowKey &key, uint16_t port, bool release)
KSyncEntry * ksync_entry() const
const VrfEntry * GetDestinationVrf() const
void UpdateFlowHandle(FlowTableKSyncEntry *kentry, uint32_t index, uint8_t gen_id)
FlowEntryPtr flow_entry() const
void TriggerKSyncEvent(FlowTableKSyncEntry *kentry, KSyncEntry::KSyncEvent event)
void AddInternal(FlowEntry *flow, FlowEntry *new_flow, FlowEntry *rflow, FlowEntry *new_rflow, bool fwd_flow_update, bool rev_flow_update)
void EvictFlow(FlowEntry *flow, FlowEntry *rflow, uint32_t evict_gen_id)
void IncrementRetrycount()
KSyncFlowMemory * ksync_flow_memory() const
KSyncFlowIndexManager * ksync_flow_index_manager() const
bool ShouldTrace(const FlowEntry *flow, const FlowEntry *rflow)
FlowMgmtManager * flow_mgmt_manager(uint16_t index) const
const NextHop * rpf_nh() const
void DeleteMessage(FlowEntry *flow)
Task is a wrapper over tbb::task to support policies.
InterfaceConstRef intf_entry
const AllowedAddressPairList & allowed_address_pair_list() const
void DisableSend(FlowEntry *flow, uint8_t evict_gen_id)
uint32_t evict_gen_id() const
void DeleteFlowUveInfo(FlowEntry *fe)
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
void EnqueueUveDeleteEvent(const FlowEntry *flow) const
boost::intrusive_ptr< FlowEntry > FlowEntryPtr
void GrowFreeListRequest(FlowTable *table)
void Update(FlowEntry *flow, FlowEntry *rflow)
void UpdateReverseFlow(FlowEntry *flow, FlowEntry *rflow)
static const uint32_t kGrowSize