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_diag_diag_hpp
7 : #define vnsw_agent_diag_diag_hpp
8 :
9 : #include <base/logging.h>
10 : #include <base/address.h>
11 : #include <base/timer.h>
12 : #include <base/queue_task.h>
13 : #include "boost/date_time/posix_time/posix_time.hpp"
14 :
15 : class Agent;
16 : struct AgentDiagPktData;
17 : struct OverlayOamPktData;
18 : class DiagProto;
19 : class DiagTable;
20 : class DiagPktHandler;
21 :
22 : class DiagEntry {
23 : public:
24 : typedef uint16_t DiagKey;
25 : typedef Timer DiagTimer;
26 :
27 : DiagEntry(const std::string &sip, const std::string &dip, uint8_t proto,
28 : uint16_t sport, uint16_t dport, const std::string &vrf_name,
29 : int timeout, int count, DiagTable *diag_table);
30 : virtual ~DiagEntry();
31 : void Init();
32 : void EnqueueForceDelete();
33 : virtual void SendRequest() = 0;
34 : virtual void HandleReply(DiagPktHandler *handler) = 0;
35 : virtual void RequestTimedOut(uint32_t seq_no) = 0;
36 0 : virtual void SendSummary() { };
37 : bool TimerExpiry(uint32_t seqno);
38 : void RestartTimer();
39 : virtual bool IsDone();
40 0 : virtual bool ResendOnTimerExpiry() { return true; }
41 0 : DiagKey GetKey() { return key_;};
42 0 : uint32_t GetSeqNo() {return seq_no_;};
43 0 : uint32_t GetMaxAttempts() {return max_attempts_;};
44 0 : void SetKey(DiagKey key) {key_ = key;};
45 : virtual void Retry();
46 0 : bool TimerCancel() {
47 0 : return timer_->Cancel();
48 : }
49 0 : DiagTable* diag_table() const {
50 0 : return diag_table_;
51 : }
52 : uint32_t HashValUdpSourcePort();
53 : void FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id,
54 : const boost::posix_time::ptime &time);
55 :
56 : protected:
57 : IpAddress sip_;
58 : IpAddress dip_;
59 : uint8_t proto_;
60 : uint16_t sport_;
61 : uint16_t dport_;
62 : std::string vrf_name_;
63 : boost::system::error_code ec_;
64 :
65 : DiagTable *diag_table_;
66 : DiagKey key_;
67 :
68 : int timeout_;
69 : DiagTimer *timer_;
70 : uint32_t max_attempts_;
71 : uint32_t seq_no_;
72 : };
73 :
74 : struct AgentDiagPktData {
75 : enum Op {
76 : DIAG_REQUEST = 1,
77 : DIAG_REPLY
78 : };
79 :
80 0 : AgentDiagPktData() {
81 0 : memset(data_, 0, sizeof(data_));
82 0 : }
83 : uint32_t op_;
84 : DiagEntry::DiagKey key_;
85 : uint32_t seq_no_;
86 : char data_[8];
87 : boost::posix_time::ptime rtt_;
88 : };
89 :
90 : struct DiagEntryOp {
91 : enum Op {
92 : ADD = 1,
93 : DEL,
94 : RETRY,
95 : FORCE_DELETE
96 : };
97 :
98 0 : DiagEntryOp(DiagEntryOp::Op op, DiagEntry *de): op_(op), de_(de) {
99 0 : }
100 :
101 : Op op_;
102 : DiagEntry *de_;
103 : };
104 :
105 : class DiagTable {
106 : public:
107 : typedef std::map<DiagEntry::DiagKey, DiagEntry *> DiagEntryTree;
108 : static const std::string kDiagData;
109 : DiagTable(Agent *agent);
110 : ~DiagTable();
111 : void Add(DiagEntry *);
112 : void Delete(DiagEntry *);
113 : DiagEntry* Find(DiagEntry::DiagKey &key);
114 :
115 : void Shutdown();
116 : void Enqueue(DiagEntryOp *op);
117 : bool Process(DiagEntryOp *op);
118 0 : Agent* agent() const { return agent_; }
119 0 : DiagProto *diag_proto() const { return diag_proto_.get(); }
120 :
121 : private:
122 : uint16_t index_;
123 : DiagEntryTree tree_;
124 : boost::scoped_ptr<DiagProto> diag_proto_;
125 : WorkQueue<DiagEntryOp *> *entry_op_queue_;
126 : Agent *agent_;
127 : };
128 :
129 : struct OamTlv {
130 : enum Type {
131 : VXLAN_PING_IPv4 = 1,
132 : VXLAN_PING_IPv6 = 2,
133 : NVGRE_PING_IPv4 = 3,
134 : NVGRE_PING_IPv6 = 4,
135 : MPLSoGRE_PING_IPv4 = 5,
136 : MPLSoGRE_PING_IPv6 = 6,
137 : MPLSoUDP_PING_IPv4 = 7,
138 : MPLSoUDP_PING_IPv6 = 8,
139 : };
140 :
141 : struct VxlanOamV4Tlv {
142 : uint32_t vxlan_id_;
143 : uint32_t sip_;
144 : };
145 :
146 : struct VxlanOamV6Tlv {
147 : uint32_t vxlan_id_;
148 : uint8_t sip_[16];
149 : };
150 :
151 : uint16_t type_;
152 : uint16_t length_;
153 : char data_[1];
154 : };
155 :
156 : struct SubTlv {
157 : enum Type {
158 : END_SYSTEM_MAC = 1,
159 : END_SYSTEM_IPv4 = 2,
160 : END_SYSTEM_IPv6 = 3,
161 : END_SYSTEM_MAC_IPv4 = 4,
162 : END_SYSTEM_MAC_IPv6 = 5,
163 : };
164 :
165 : enum ReturnCode {
166 : END_SYSTEM_PRESENT = 1,
167 : END_SYSTEM_NOT_PRESENT = 2,
168 : };
169 :
170 : uint16_t type_;
171 : uint16_t length_;
172 :
173 : struct EndSystemMac {
174 : uint8_t mac[6];
175 : uint16_t return_code;
176 : };
177 : };
178 :
179 : struct OverlayOamPktData {
180 : enum MsgType {
181 : OVERLAY_ECHO_REQUEST = 1,
182 : OVERLAY_ECHO_REPLY = 2
183 : };
184 :
185 : enum Returncode {
186 : NO_RETURN_CODE = 0,
187 : MALFORMED_ECHO_REQUEST = 1,
188 : OVERLAY_SEGMENT_NOT_PRESENT = 2,
189 : OVERLAY_SEGMENT_NOT_OPERATIONAL = 3,
190 : RETURN_CODE_OK = 4,
191 : };
192 :
193 : enum Replymode {
194 : DONT_REPLY = 1,
195 : REPLY_IPV4ORV6_UDP = 2,
196 : REPLY_OVERLAY_SEGMENT = 3,
197 : };
198 :
199 : uint8_t msg_type_;
200 : uint8_t reply_mode_;
201 : uint8_t return_code_;
202 : uint8_t return_subcode_;
203 : uint32_t org_handle_;
204 : uint32_t seq_no_;
205 : uint32_t timesent_sec_;
206 : uint32_t timesent_misec_;
207 : uint32_t timerecv_sec_;
208 : uint32_t timerecv_misec_;
209 : OamTlv oamtlv_;
210 : };
211 : #endif
|