OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
overlay_ping.cc
Go to the documentation of this file.
1 #include <stdint.h>
2 #include "base/os.h"
3 #include "pkt/proto.h"
4 #include "pkt/proto_handler.h"
5 #include "diag/diag_types.h"
7 #include "diag/diag.h"
8 #include "diag/overlay_ping.h"
9 #include <oper/route_common.h>
10 #include <oper/vrf_assign.h>
11 #include <oper/tunnel_nh.h>
12 
13 using namespace boost::posix_time;
14 extern void time_duration_to_string(time_duration &td, std::string &str);
15 const MacAddress OverlayPing::in_dst_mac_(0x00, 0x00, 0x5E, 0x90, 0x00, 0x01);
16 const MacAddress OverlayPing::in_source_mac_(0x00, 0x00, 0x5E, 0x90, 0x00, 0x02);
17 
18 OverlayPing::OverlayPing(const OverlayPingReq *ping_req, DiagTable *diag_table):
19  DiagEntry(ping_req->get_source_ip(), ping_req->get_dest_ip(),
20  ping_req->get_protocol(), ping_req->get_source_port(),
21  ping_req->get_dest_port(), Agent::GetInstance()->fabric_vrf_name(),
22  ping_req->get_interval() * 100, ping_req->get_count(), diag_table),
23  vn_uuid_(StringToUuid(ping_req->get_vn_uuid())),
24  remote_vm_mac_(ping_req->get_vm_remote_mac()),
25  data_len_(ping_req->get_packet_size()),
26  context_(ping_req->context()),
27  pkt_lost_count_(0) {
28 
29 }
30 /*
31  * Get the L2 Route entry to find the Tunnel NH
32  */
34 OverlayPing::L2RouteGet(VxLanId* vxlan, string remotemac, Agent *agent)
35 {
36  string vrf_name;
37  const VrfNH *vrf_nh = dynamic_cast<const VrfNH *>(vxlan->nexthop());
38  VrfEntry *vrf = NULL;
39  if (vrf_nh) {
40  vrf = const_cast<VrfEntry*> (vrf_nh->GetVrf());
41  if (!vrf || vrf->IsDeleted()) {
42  return NULL;
43  } else {
44  vrf_name = vrf->GetName();
45  }
46  } else {
47  return NULL;
48  }
49  MacAddress mac = MacAddress::FromString(remotemac);
50  BridgeRouteKey key(agent->local_vm_peer(), vrf_name, mac);
51  BridgeRouteEntry *rt = static_cast<BridgeRouteEntry *>
52  (static_cast<BridgeAgentRouteTable *>
53  (vrf->GetBridgeRouteTable())->FindActiveEntry(&key));
54  return rt;
55 }
56 
57 void OverlayPingReq::HandleRequest() const {
58  std::string err_str;
59  boost::system::error_code ec;
60  OverlayPing *overlayping = NULL;
61  {
62  Agent *agent = Agent::GetInstance();
63  boost::uuids::uuid vn_uuid = StringToUuid(get_vn_uuid());
64  IpAddress sip(IpAddress::from_string(get_source_ip(), ec));
65  if (ec.failed()) {
66  err_str = "Invalid source IP";
67  goto error;
68  }
69 
70  if (!sip.is_v4()) {
71  err_str = "V6 is not supported";
72  goto error;
73  }
74 
75  IpAddress dip(IpAddress::from_string(get_dest_ip(), ec));
76  if (ec.failed()) {
77  err_str = "Invalid destination IP";
78  goto error;
79  }
80 
81  if (!dip.is_v4()) {
82  err_str = "V6 is not supported";
83  goto error;
84  }
85 
86  uint8_t proto = get_protocol();
87  if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
88  err_str = "Invalid protocol. Valid Protocols are TCP & UDP";
89  goto error;
90  }
91 
92  VnEntry *vn = agent->vn_table()->Find(vn_uuid);
93  if (!vn) {
94  err_str = "Invalid VN segment";
95  goto error;
96  }
97 
98  int vxlan_id = vn->GetVxLanId();
99  VxLanId* vxlan = agent->vxlan_table()->Find(vxlan_id);
100 
101  if (!vxlan) {
102  err_str = "Invalid vxlan segment";
103  goto error;
104  }
105 
106  BridgeRouteEntry *rt = OverlayPing::L2RouteGet(vxlan, get_vm_remote_mac(),
107  agent);
108  if (!rt) {
109  err_str = "Invalid remote mac";
110  goto error;
111  }
112  }
113  overlayping = new OverlayPing(this, Agent::GetInstance()->diag_table());
114  overlayping->Init();
115  return;
116 error:
117  PingErrResp *resp = new PingErrResp;
118  resp->set_error_response(err_str);
119  resp->set_context(context());
120  resp->Response();
121  return;
122 }
123 
125 
126 }
127 
128 /*
129  * Creat Overlay VXlan packet.
130  * Set the Route alert bit to indicate Overlay OAM packet
131  */
133  // Create VxLan packet
134  Agent *agent = diag_table_->agent();
135  Ip4Address tunneldst;
136  Ip4Address tunnelsrc;
137  seq_no_++;
138  string vrf_name;
139  boost::system::error_code ec;
140 
141  int vxlan_id = agent->vn_table()->Find(vn_uuid_)->GetVxLanId();
142  VxLanId *vxlan = agent->vxlan_table()->Find(vxlan_id);
143  if (!vxlan)
144  return;
145 
146  BridgeRouteEntry *rt = L2RouteGet(vxlan, remote_vm_mac_.ToString(), agent);
147  if (!rt)
148  return;
149  const AgentPath *path = rt->GetActivePath();
150  const TunnelNH *nh = static_cast<const TunnelNH *>(path->nexthop());
151 
152  tunneldst = *nh->GetDip();
153  tunnelsrc = *nh->GetSip();
155  boost::shared_ptr<PktInfo> pkt_info(new PktInfo(agent, len_,
156  PktHandler::DIAG, 0));
157  uint8_t *buf = pkt_info->packet_buffer()->data();
158  memset(buf, 0, len_);
159  OverlayOamPktData *pktdata = NULL;
160  pktdata = (OverlayOamPktData *)(buf + kOverlayUdpHdrLength);
161  memset(pktdata, 0, sizeof(OverlayOamPktData));
162 
163  senttime_ = microsec_clock::universal_time();
164  FillOamPktHeader(pktdata, vxlan_id, senttime_);
165  DiagPktHandler *pkt_handler = new DiagPktHandler(diag_table_->agent(), pkt_info,
166  *(diag_table_->agent()->event_manager())->io_service());
167  // Fill outer header
168  pkt_info->eth = (struct ether_header *)(buf);
169  pkt_handler->EthHdr(agent->vhost_interface()->mac(), *nh->GetDmac(),
170  ETHERTYPE_IP);
171  pkt_info->ip = (struct ip *)(pkt_info->eth +1);
172  pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
173  uint8_t len;
174  len = data_len_+2 * sizeof(udphdr)+sizeof(VxlanHdr)+
175  sizeof(struct ip) + sizeof(struct ether_header);
176  pkt_handler->UdpHdr(len, ntohl(tunnelsrc.to_ulong()), HashValUdpSourcePort(),
177  ntohl(tunneldst.to_ulong()), VXLAN_UDP_DEST_PORT);
178 
179  pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(tunnelsrc.to_ulong()),
180  ntohl(tunneldst.to_ulong()), IPPROTO_UDP,
182  // Fill VxLan Header
183  VxlanHdr *vxlanhdr = (VxlanHdr *)(buf + sizeof(udphdr)+ sizeof(struct ip)
184  + sizeof(struct ether_header));
185  vxlanhdr->vxlan_id = ntohl(vxlan_id << 8);
186  vxlanhdr->reserved = ntohl(kVxlanRABit | kVxlanIBit);
187 
188  //Fill inner packet details.
189  pkt_info->eth = (struct ether_header *)(vxlanhdr + 1);
190 
191  pkt_handler->EthHdr(in_source_mac_, in_dst_mac_,
192  ETHERTYPE_IP);
193 
194  pkt_info->ip = (struct ip *)(pkt_info->eth +1);
195  Ip4Address dip = Ip4Address::from_string("127.0.0.1", ec);
196  pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
197  len = data_len_+sizeof(struct udphdr);
198  pkt_handler->UdpHdr(len, sip_.to_v4().to_ulong(), sport_, dip.to_ulong(),
200  pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(sip_.to_v4().to_ulong()),
201  ntohl(dip.to_ulong()), proto_,
203  //pkt_handler->SetDiagChkSum();
204  pkt_handler->pkt_info()->set_len(len_);
206  Interface *intf = static_cast<Interface *>
207  (agent->interface_table()->Find(&key1, true));
208  pkt_handler->Send(intf->id(), agent->fabric_vrf()->vrf_id(),
209  AgentHdr::TX_SWITCH, CMD_PARAM_PACKET_CTRL,
210  CMD_PARAM_1_DIAG, PktHandler::DIAG);
211 
212  delete pkt_handler;
213  return;
214 }
215 
217  PingResp *resp = new PingResp();
218  OverlayOamPktData *pktdata = (OverlayOamPktData*) handler->GetData();
219  resp->set_seq_no(ntohl(pktdata->seq_no_));
220  boost::posix_time::ptime time = microsec_clock::universal_time();
221  boost::posix_time::time_duration rtt = time - senttime_;
222  avg_rtt_ += rtt;
223  std::string rtt_str;
224  time_duration_to_string(rtt, rtt_str);
225  resp->set_rtt(rtt_str);
226  resp->set_resp("Success");
227  resp->set_context(context_);
228  resp->set_more(true);
229  resp->Response();
230 }
231 
232 void OverlayPing::RequestTimedOut(uint32_t seq_no) {
233  PingResp *resp = new PingResp();
234  pkt_lost_count_++;
235  resp->set_resp("Timed Out");
236  resp->set_seq_no(seq_no_);
237  resp->set_context(context_);
238  resp->set_more(true);
239  resp->Response();
240 }
241 
243 PingSummaryResp *resp = new PingSummaryResp();
244 
246  //If we had some succesful replies, send in
247  //average rtt for succesful ping requests
249  std::string avg_rtt_string;
250  time_duration_to_string(avg_rtt_, avg_rtt_string);
251  resp->set_average_rtt(avg_rtt_string);
252  }
253  resp->set_request_sent(seq_no_);
254  resp->set_response_received(seq_no_ - pkt_lost_count_);
255  uint32_t pkt_loss_percent = (pkt_lost_count_ * 100/seq_no_);
256  resp->set_pkt_loss(pkt_loss_percent);
257  resp->set_context(context_);
258  resp->Response();
259 }
int GetVxLanId() const
Definition: vn.cc:727
IpAddress sip_
Definition: diag.h:56
uint32_t GetMaxAttempts()
Definition: diag.h:42
virtual void RequestTimedOut(uint32_t seq_no)
#define DEFAULT_IP_TTL
Definition: pkt_handler.h:44
static Agent * GetInstance()
Definition: agent.h:436
static boost::uuids::uuid StringToUuid(const std::string &str)
Definition: string_util.h:145
Definition: vrf.h:86
VrfEntry * fabric_vrf() const
Definition: agent.h:915
OverlayPing(const OverlayPingReq *req, DiagTable *diag_table)
Definition: overlay_ping.cc:18
static const uint32_t kVxlanRABit
Definition: overlay_ping.h:21
const VrfEntry * GetVrf() const
Definition: nexthop.h:1444
boost::uuids::uuid vn_uuid_
Definition: overlay_ping.h:35
const Interface * vhost_interface() const
Definition: agent.h:935
bool IsDeleted() const
Definition: db_entry.h:49
uint32_t vxlan_id
Definition: pkt_handler.h:92
uint8_t proto_
Definition: diag.h:58
boost::asio::ip::address IpAddress
Definition: address.h:13
#define DEFAULT_IP_ID
Definition: pkt_handler.h:48
void set_len(uint32_t len)
boost::posix_time::time_duration avg_rtt_
Definition: overlay_ping.h:41
InterfaceTable * interface_table() const
Definition: agent.h:465
const Ip4Address * GetDip() const
Definition: tunnel_nh.h:37
boost::uuids::uuid uuid
MacAddress remote_vm_mac_
Definition: overlay_ping.h:36
VnTable * vn_table() const
Definition: agent.h:495
const string & GetName() const
Definition: vrf.h:100
const MacAddress & mac() const
Definition: interface.h:131
Definition: vxlan.h:14
std::string ToString() const
Definition: mac_address.cc:53
void FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id, const boost::posix_time::ptime &time)
Definition: diag.cc:173
virtual void SendSummary()
const AgentPath * GetActivePath() const
Definition: agent_route.cc:876
NextHop * nexthop() const
Definition: agent_path.cc:87
int EthHdr(const MacAddress &src, const MacAddress &dest, const uint16_t proto)
void Init()
Definition: diag.cc:47
virtual ~OverlayPing()
#define VXLAN_UDP_DEST_PORT
Definition: pkt_handler.h:36
Definition: agent.h:358
const std::string & fabric_interface_name() const
Definition: agent.h:1129
EventManager * event_manager() const
Definition: agent.h:1103
void Send(uint32_t itf, uint32_t vrf, uint16_t, PktHandler::PktModuleName)
uint32_t seq_no_
Definition: diag.h:70
uint16_t data_len_
Definition: overlay_ping.h:37
AgentRouteTable * GetBridgeRouteTable() const
Definition: vrf.cc:334
uint8_t * GetData()
static const MacAddress in_dst_mac_
Definition: overlay_ping.h:23
Agent * agent() const
Definition: diag.h:117
std::string context_
Definition: overlay_ping.h:39
const Ip4Address * GetSip() const
Definition: tunnel_nh.h:36
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
uint32_t pkt_lost_count_
Definition: overlay_ping.h:42
PktInfo * pkt_info() const
Definition: proto_handler.h:88
const uint32_t vrf_id() const
Definition: vrf.h:99
VnEntry * Find(const boost::uuids::uuid &vn_uuid)
Definition: vn.cc:759
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
const NextHop * nexthop() const
Definition: vxlan.h:28
Definition: vn.h:151
uint32_t HashValUdpSourcePort()
Definition: diag.cc:163
uint16_t sport_
Definition: diag.h:59
static const uint32_t kVxlanIBit
Definition: overlay_ping.h:22
uint32_t reserved
Definition: pkt_handler.h:91
void time_duration_to_string(time_duration &td, std::string &str)
Definition: ping.cc:212
VxLanId * Find(uint32_t vxlan_id)
Definition: vxlan.cc:223
boost::posix_time::ptime senttime_
Definition: overlay_ping.h:40
VxLanTable * vxlan_table() const
Definition: agent.h:535
void UdpHdr(uint16_t len, in_addr_t src, uint16_t src_port, in_addr_t dest, uint16_t dest_port)
const Peer * local_vm_peer() const
Definition: agent.h:1023
uint32_t seq_no_
Definition: diag.h:203
Definition: diag.h:21
const MacAddress * GetDmac() const
Definition: tunnel_nh.h:39
virtual void SendRequest()
static MacAddress FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: mac_address.cc:71
static const uint32_t kOverlayUdpHdrLength
Definition: overlay_ping.h:18
virtual void HandleReply(DiagPktHandler *handler)
uint16_t len_
Definition: overlay_ping.h:38
static BridgeRouteEntry * L2RouteGet(VxLanId *vxlan, string remotemac, Agent *agent)
Definition: overlay_ping.cc:34
static const MacAddress in_source_mac_
Definition: overlay_ping.h:24
DiagTable * diag_table_
Definition: diag.h:64
void IpHdr(uint16_t len, in_addr_t src, in_addr_t dest, uint8_t protocol, uint16_t id, uint8_t ttl)