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