Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef vnsw_agent_flow_proto_hpp
6 : #define vnsw_agent_flow_proto_hpp
7 :
8 : #include <atomic>
9 :
10 : #include <net/if.h>
11 : #include "cmn/agent_cmn.h"
12 : #include "base/queue_task.h"
13 : #include "proto.h"
14 : #include "proto_handler.h"
15 : #include "flow_table.h"
16 : #include "flow_handler.h"
17 : #include "flow_event.h"
18 : #include "flow_token.h"
19 : #include "flow_trace_filter.h"
20 : #include "flow_entry.h"
21 :
22 : class ProfileData;
23 :
24 : struct FlowStats {
25 : uint64_t add_count_;
26 : uint64_t delete_count_;
27 : uint64_t flow_messages_;
28 : uint64_t revaluate_count_;
29 : uint64_t recompute_count_;
30 : uint64_t audit_count_;
31 : uint64_t vrouter_responses_;
32 : uint64_t vrouter_error_;
33 : uint64_t evict_count_;
34 :
35 : // Number of events actually processed
36 : uint64_t delete_process_;
37 : uint64_t revaluate_process_;
38 : uint64_t recompute_process_;
39 :
40 2 : FlowStats() :
41 2 : add_count_(0), delete_count_(0), flow_messages_(0),
42 2 : revaluate_count_(0), recompute_count_(0), audit_count_(0),
43 2 : vrouter_responses_(0), vrouter_error_(0), evict_count_(0),
44 2 : delete_process_(0), revaluate_process_(0), recompute_process_(0) {
45 2 : }
46 : };
47 :
48 : class FlowProto : public Proto {
49 : public:
50 : static const int kMinTableCount = 1;
51 : static const int kMaxTableCount = 16;
52 :
53 : FlowProto(Agent *agent, boost::asio::io_context &io);
54 : virtual ~FlowProto();
55 :
56 : void Init();
57 : void InitDone();
58 : void Shutdown();
59 : void FlushFlows();
60 :
61 : bool Validate(PktInfo *msg);
62 : FlowHandler *AllocProtoHandler(PktInfoPtr info,
63 : boost::asio::io_context &io);
64 : bool Enqueue(PktInfoPtr msg);
65 :
66 : FlowEntry *Find(const FlowKey &key, uint32_t table_index) const;
67 : uint16_t FlowTableIndex(const IpAddress &sip, const IpAddress &dip,
68 : uint8_t proto, uint16_t sport,
69 : uint16_t dport, uint32_t flow_handle) const;
70 0 : uint32_t flow_table_count() const { return flow_table_list_.size(); }
71 : FlowTable *GetTable(uint16_t index) const;
72 : FlowTable *GetFlowTable(const FlowKey &key, uint32_t flow_handle) const;
73 : uint32_t FlowCount() const;
74 : void VnFlowCounters(const VnEntry *vn, uint32_t *in_count,
75 : uint32_t *out_count);
76 : void InterfaceFlowCount(const Interface *intf, uint64_t *created,
77 : uint64_t *aged, uint32_t *active_flows) const;
78 :
79 : bool AddFlow(FlowEntry *flow);
80 : bool UpdateFlow(FlowEntry *flow);
81 :
82 : void EnqueueFlowEvent(FlowEvent *event);
83 : void ForceEnqueueFreeFlowReference(FlowEntryPtr &flow);
84 : void DeleteFlowRequest(FlowEntry *flow);
85 : void DeleteFlowRequest(const FlowKey &key);
86 : void EvictFlowRequest(FlowEntry *flow, uint32_t flow_handle,
87 : uint8_t gen_id, uint8_t evict_gen_id);
88 : void CreateAuditEntry(const FlowKey &key, uint32_t flow_handle,
89 : uint8_t gen_id);
90 : bool FlowEventHandler(FlowEvent *req, FlowTable *table);
91 : bool FlowUpdateHandler(FlowEvent *req);
92 : bool FlowDeleteHandler(FlowEvent *req, FlowTable *table);
93 : bool FlowKSyncMsgHandler(FlowEvent *req, FlowTable *table);
94 : void GrowFreeListRequest(FlowTable *table);
95 : void KSyncEventRequest(KSyncEntry *ksync_entry,
96 : KSyncEntry::KSyncEvent event, uint32_t flow_handle,
97 : uint8_t gen_id, int ksync_error,
98 : uint64_t evict_flow_bytes,
99 : uint64_t evict_flow_packets,
100 : int32_t evict_flow_oflow,
101 : uint32_t transcation_id);
102 : void MessageRequest(FlowEntry *flow);
103 :
104 : void DisableFlowEventQueue(uint32_t index, bool disabled);
105 : void DisableFlowUpdateQueue(bool disabled);
106 : void DisableFlowKSyncQueue(uint32_t index, bool disabled);
107 : void DisableFlowDeleteQueue(uint32_t index, bool disabled);
108 : size_t FlowUpdateQueueLength();
109 :
110 11 : const FlowStats *flow_stats() const { return &stats_; }
111 :
112 : void SetProfileData(ProfileData *data);
113 0 : uint32_t linklocal_flow_count() const { return linklocal_flow_count_; }
114 0 : void update_linklocal_flow_count(int val) {
115 0 : int tmp = linklocal_flow_count_.fetch_add(val);
116 0 : if (val < 0)
117 0 : assert(tmp >= val);
118 0 : }
119 : bool EnqueueReentrant(boost::shared_ptr<PktInfo> msg,
120 : uint8_t table_index);
121 : bool ShouldTrace(const FlowEntry *flow, const FlowEntry *rflow);
122 : void EnqueueUnResolvedFlowEntry(FlowEntry *flow);
123 :
124 : virtual void TokenAvailable(TokenPool *pool_base);
125 : TokenPtr GetToken(FlowEvent::Event event);
126 : bool TokenCheck(const FlowTokenPool *pool) const;
127 :
128 0 : PortTableManager* port_table_manager() {
129 0 : return &port_table_manager_;
130 : }
131 :
132 : private:
133 : friend class SandeshIPv4FlowFilterRequest;
134 : friend class SandeshIPv6FlowFilterRequest;
135 : friend class SandeshShowFlowFilterRequest;
136 : friend class FlowTraceFilterTest;
137 : friend class FlowUpdateTest;
138 : friend class FlowTest;
139 0 : FlowTraceFilter *ipv4_trace_filter() { return &ipv4_trace_filter_; }
140 0 : FlowTraceFilter *ipv6_trace_filter() { return &ipv6_trace_filter_; }
141 :
142 : bool ProcessFlowEvent(const FlowEvent &req, FlowTable *table);
143 : bool FlowStatsUpdate() const;
144 :
145 : FlowTokenPool add_tokens_;
146 : FlowTokenPool ksync_tokens_;
147 : FlowTokenPool del_tokens_;
148 : FlowTokenPool update_tokens_;
149 : std::vector<FlowEventQueue *> flow_event_queue_;
150 : std::vector<FlowEventQueue *> flow_tokenless_queue_;
151 : std::vector<DeleteFlowEventQueue *> flow_delete_queue_;
152 : std::vector<KSyncFlowEventQueue *> flow_ksync_queue_;
153 : std::vector<FlowTable *> flow_table_list_;
154 : UpdateFlowEventQueue flow_update_queue_;
155 : std::atomic<int> linklocal_flow_count_;
156 : bool use_vrouter_hash_;
157 : FlowTraceFilter ipv4_trace_filter_;
158 : FlowTraceFilter ipv6_trace_filter_;
159 : FlowStats stats_;
160 : PortTableManager port_table_manager_;
161 : Timer *stats_update_timer_;
162 : };
163 :
164 : extern SandeshTraceBufferPtr PktFlowTraceBuf;
165 :
166 : #define PKTFLOW_TRACE(obj, ...)\
167 : do {\
168 : PktFlow##obj::TraceMsg(PktFlowTraceBuf, __FILE__, __LINE__, ##__VA_ARGS__);\
169 : } while (false)
170 :
171 : #endif // vnsw_agent_flow_proto_hpp
|