OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
diag.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <stdint.h>
6 #include "base/os.h"
7 #include <map>
8 #include "vr_defs.h"
9 #include "base/timer.h"
10 #include "cmn/agent_cmn.h"
11 #include "pkt/proto.h"
12 #include "pkt/proto_handler.h"
13 #include "diag/diag.h"
14 #include "diag/diag_proto.h"
15 #include "diag/ping.h"
16 #include "oper/mirror_table.h"
17 #include "diag/diag_pkt_handler.h"
18 
19 
20 const std::string KDiagName("DiagTimeoutHandler");
21 const std::string DiagTable::kDiagData = "diagshc";
22 using namespace boost::posix_time;
24 
25 DiagEntry::DiagEntry(const std::string &sip, const std::string &dip,
26  uint8_t proto, uint16_t sport, uint16_t dport,
27  const std::string &vrf_name, int timeout,
28  int attempts, DiagTable *diag_table) :
29  sip_(IpAddress::from_string(sip, ec_)),
30  dip_(IpAddress::from_string(dip, ec_)),
31  proto_(proto), sport_(sport), dport_(dport),
32  vrf_name_(vrf_name), diag_table_(diag_table), timeout_(timeout),
33  timer_(TimerManager::CreateTimer(*(diag_table->agent()->event_manager())->io_service(),
34  "DiagTimeoutHandler",
35  TaskScheduler::GetInstance()->GetTaskId("Agent::Diag"),
36  PktHandler::DIAG)),
37  max_attempts_(attempts), seq_no_(0) {
38 }
39 
41  timer_->Cancel();
43  //Delete entry in DiagTable
44  diag_table_->Delete(this);
45 }
46 
48  DiagEntryOp *entry_op = new DiagEntryOp(DiagEntryOp::ADD, this);
49  diag_table_->Enqueue(entry_op);
50 }
51 
53  DiagEntryOp *entry_op = new DiagEntryOp(DiagEntryOp::FORCE_DELETE, this);
54  diag_table_->Enqueue(entry_op);
55 }
56 
58  //Cancel timer of running
59  timer_->Cancel();
60  timer_->Start(timeout_, boost::bind(&DiagEntry::TimerExpiry, this, seq_no_));
61 }
62 
64  return (GetSeqNo() == GetMaxAttempts()) ? true : false;
65 }
66 
67 bool DiagEntry::TimerExpiry( uint32_t seq_no) {
68  DiagEntryOp *op;
69  RequestTimedOut(seq_no);
70  if (IsDone()) {
71  op = new DiagEntryOp(DiagEntryOp::DEL, this);
72  diag_table_->Enqueue(op);
73  return false;
74  }
75 
76  if (ResendOnTimerExpiry()) {
77  SendRequest();
78  return true;
79  }
80 
81  return false;
82 }
83 
85  SendRequest();
86  RestartTimer();
87 }
88 
90  switch (op->op_) {
91  case DiagEntryOp::ADD:
92  Add(op->de_);
93  break;
94 
95  case DiagEntryOp::DEL:
96  if (op->de_->TimerCancel() == true) {
97  op->de_->SendSummary();
98  delete op->de_;
99  }
100  break;
101 
103  op->de_->TimerCancel();
104  delete op->de_;
105  break;
106 
107  case DiagEntryOp::RETRY:
108  op->de_->Retry();
109  break;
110  }
111 
112  delete op;
113  return true;
114 }
115 
116 DiagTable::DiagTable(Agent *agent):agent_(agent) {
117  diag_proto_.reset(
118  new DiagProto(agent, *(agent->event_manager())->io_service()));
120  (TaskScheduler::GetInstance()->GetTaskId("Agent::Diag"),
122  boost::bind(&DiagTable::Process, this, _1));
123  entry_op_queue_->set_name("Diagnostics Table");
124  index_ = 1;
125 }
126 
129  delete entry_op_queue_;
130  diag_proto_.reset(NULL);
131 }
132 
134  assert(tree_.size() == 0);
135 }
136 
138  de->SetKey(index_++);
139  tree_.insert(std::make_pair(de->GetKey(), de));
140  de->SendRequest();
141  de->RestartTimer();
142 }
143 
145  tree_.erase(de->GetKey());
146 }
147 
149  DiagEntryTree::const_iterator it;
150 
151  it = tree_.find(key);
152  if (it == tree_.end()) {
153  return NULL;
154  }
155 
156  return static_cast<DiagEntry *>(it->second);
157 }
158 
161 }
162 
164  std::size_t seed = 0;
165  boost::hash_combine(seed, sip_.to_v4().to_ulong());
166  boost::hash_combine(seed, dip_.to_v4().to_ulong());
167  boost::hash_combine(seed, proto_);
168  boost::hash_combine(seed, sport_);
169  boost::hash_combine(seed, dport_);
170  return seed;
171 }
172 
173 void DiagEntry::FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id,
174  const boost::posix_time::ptime &time) {
177  pktdata->org_handle_ = htons(key_);
178  pktdata->seq_no_ = htonl(seq_no_);
179 
180  boost::posix_time::ptime
181  epoch(boost::gregorian::date(1970, boost::gregorian::Jan, 1));
182  boost::posix_time::time_duration td = time - epoch;
183  pktdata->timesent_sec_ = htonl(td.total_seconds());
184  pktdata->timesent_misec_ = htonl(td.total_microseconds());
185 
186  if (sip_.is_v4()) {
187  pktdata->oamtlv_.type_ = htons(OamTlv::VXLAN_PING_IPv4);
188  pktdata->oamtlv_.length_ = htons(sizeof(OamTlv::VxlanOamV4Tlv));
189  OamTlv::VxlanOamV4Tlv *vxlan_tlv =
190  (OamTlv::VxlanOamV4Tlv *) pktdata->oamtlv_.data_;
191  vxlan_tlv->vxlan_id_ = htonl(vxlan_id);
192  vxlan_tlv->sip_ = htonl(sip_.to_v4().to_ulong());
193  } else {
194  pktdata->oamtlv_.type_ = htons(OamTlv::VXLAN_PING_IPv6);
195  pktdata->oamtlv_.length_ = htons(sizeof(OamTlv::VxlanOamV6Tlv));
196  OamTlv::VxlanOamV6Tlv *vxlan_tlv =
197  (OamTlv::VxlanOamV6Tlv *) pktdata->oamtlv_.data_;
198  vxlan_tlv->vxlan_id_ = htonl(vxlan_id);
199  memcpy(vxlan_tlv->sip_, sip_.to_v6().to_bytes().data(), 16);
200  }
201 }
IpAddress dip_
Definition: diag.h:57
int timeout_
Definition: diag.h:67
IpAddress sip_
Definition: diag.h:56
uint32_t GetMaxAttempts()
Definition: diag.h:42
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
void Shutdown(bool delete_entries=true)
Definition: queue_task.h:152
void Shutdown()
Definition: diag.cc:127
DiagTable(Agent *agent)
Definition: diag.cc:116
const std::string KDiagName("DiagTimeoutHandler")
uint8_t proto_
Definition: diag.h:58
boost::asio::ip::address IpAddress
Definition: address.h:13
static const std::string kDiagData
Definition: diag.h:107
void Delete(DiagEntry *)
Definition: diag.cc:144
virtual void RequestTimedOut(uint32_t seq_no)=0
DiagEntry(const std::string &sip, const std::string &dip, uint8_t proto, uint16_t sport, uint16_t dport, const std::string &vrf_name, int timeout, int count, DiagTable *diag_table)
Definition: diag.cc:25
DiagEntryTree tree_
Definition: diag.h:122
uint16_t dport_
Definition: diag.h:60
uint16_t index_
Definition: diag.h:121
~DiagTable()
Definition: diag.cc:133
bool TimerCancel()
Definition: diag.h:45
int GetTaskId(const std::string &name)
Definition: task.cc:856
void FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id, const boost::posix_time::ptime &time)
Definition: diag.cc:173
DiagEntry * de_
Definition: diag.h:101
WorkQueue< DiagEntryOp * > * entry_op_queue_
Definition: diag.h:124
uint32_t vxlan_id_
Definition: diag.h:146
void SetKey(DiagKey key)
Definition: diag.h:43
DiagTimer * timer_
Definition: diag.h:68
uint16_t DiagKey
Definition: diag.h:23
void Init()
Definition: diag.cc:47
Definition: agent.h:358
static TaskScheduler * GetInstance()
Definition: task.cc:547
uint32_t GetSeqNo()
Definition: diag.h:41
void RestartTimer()
Definition: diag.cc:57
uint32_t org_handle_
Definition: diag.h:202
void Add(DiagEntry *)
Definition: diag.cc:137
EventManager * event_manager() const
Definition: agent.h:1103
virtual void SendRequest()=0
uint32_t seq_no_
Definition: diag.h:70
virtual bool ResendOnTimerExpiry()
Definition: diag.h:39
virtual bool IsDone()
Definition: diag.cc:63
Op op_
Definition: diag.h:100
bool Cancel()
Definition: timer.cc:150
char data_[1]
Definition: diag.h:152
uint32_t HashValUdpSourcePort()
Definition: diag.cc:163
uint16_t sport_
Definition: diag.h:59
uint8_t msg_type_
Definition: diag.h:198
uint32_t vxlan_id_
Definition: diag.h:141
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
uint32_t sip_
Definition: diag.h:142
DiagKey GetKey()
Definition: diag.h:40
uint32_t timesent_sec_
Definition: diag.h:204
uint16_t length_
Definition: diag.h:151
boost::scoped_ptr< DiagProto > diag_proto_
Definition: diag.h:123
virtual void SendSummary()
Definition: diag.h:35
void Enqueue(DiagEntryOp *op)
Definition: diag.cc:159
uint32_t seq_no_
Definition: diag.h:203
bool TimerExpiry(uint32_t seqno)
Definition: diag.cc:67
Definition: diag.h:21
OamTlv oamtlv_
Definition: diag.h:208
bool Process(DiagEntryOp *op)
Definition: diag.cc:89
DiagEntry * Find(DiagEntry::DiagKey &key)
Definition: diag.cc:148
bool Enqueue(QueueEntryT entry)
Definition: queue_task.h:248
uint8_t reply_mode_
Definition: diag.h:199
DiagKey key_
Definition: diag.h:65
uint32_t timesent_misec_
Definition: diag.h:205
uint8_t sip_[16]
Definition: diag.h:147
void EnqueueForceDelete()
Definition: diag.cc:52
void set_name(const std::string &name)
Definition: queue_task.h:307
DiagTable * diag_table_
Definition: diag.h:64
virtual void Retry()
Definition: diag.cc:84
uint16_t type_
Definition: diag.h:150
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
virtual ~DiagEntry()
Definition: diag.cc:40