OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
overlay_traceroute.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <stdint.h>
6 #include <netinet/udp.h>
7 #include "vr_defs.h"
8 #include "cmn/agent_cmn.h"
9 #include "oper/route_common.h"
10 #include "pkt/proto.h"
11 #include "pkt/proto_handler.h"
12 #include "diag/diag_types.h"
13 #include "diag/diag.h"
15 #include "diag/overlay_ping.h"
16 #include "diag/traceroute.h"
17 #include "diag/diag_pkt_handler.h"
18 
19 using namespace boost::posix_time;
20 OverlayTraceRoute::OverlayTraceRoute(const OverlayTraceReq *traceroute_req,
21  DiagTable *diag_table) :
22  DiagEntry(traceroute_req->get_source_ip(), traceroute_req->get_dest_ip(),
23  traceroute_req->get_protocol(), traceroute_req->get_source_port(),
24  traceroute_req->get_dest_port(), Agent::GetInstance()->fabric_vrf_name(),
25  traceroute_req->get_interval() * 100,traceroute_req->get_max_attempts(), diag_table),
26  vn_uuid_(StringToUuid(traceroute_req->get_vn_uuid())),
27  remote_vm_mac_(traceroute_req->get_vm_remote_mac()), ttl_(2),
28  max_ttl_(traceroute_req->get_max_hops()),
29  context_(traceroute_req->context()) {
30 }
31 
33 }
34 
35 
37 {
38  Agent *agent = diag_table_->agent();
39  Ip4Address tunneldst;
40  Ip4Address tunnelsrc;
41  seq_no_++;
42  string vrf_name;
43  boost::system::error_code ec;
44  uint8_t data_len = 50;
45  int vxlan_id = agent->vn_table()->Find(vn_uuid_)->GetVxLanId();
46  VxLanId *vxlan = agent->vxlan_table()->Find(vxlan_id);
47  if (!vxlan)
48  return;
49 
51  remote_vm_mac_.ToString(), agent);
52  if (!rt)
53  return;
54  const AgentPath *path = rt->GetActivePath();
55  const TunnelNH *nh = static_cast<const TunnelNH *>(path->nexthop());
56 
57  tunneldst = *nh->GetDip();
58  tunnelsrc = *nh->GetSip();
60  boost::shared_ptr<PktInfo> pkt_info(new PktInfo(agent, len_,
61  PktHandler::DIAG, 0));
62  uint8_t *buf = pkt_info->packet_buffer()->data();
63  memset(buf, 0, len_);
64  OverlayOamPktData *pktdata = NULL;
66 
67  boost::posix_time::ptime senttime = microsec_clock::universal_time();
68  FillOamPktHeader(pktdata, vxlan_id, senttime);
69  DiagPktHandler *pkt_handler = new DiagPktHandler(diag_table_->agent(), pkt_info,
70  *(diag_table_->agent()->event_manager())->io_service());
71  // FIll outer header
72  pkt_info->eth = (struct ether_header *)(buf);
73  pkt_handler->EthHdr(agent->vhost_interface()->mac(), *nh->GetDmac(),
74  ETHERTYPE_IP);
75  pkt_info->ip = (struct ip *)(pkt_info->eth +1);
76  pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
77  uint8_t len;
78  len = data_len+2 * sizeof(udphdr)+sizeof(VxlanHdr)+
79  sizeof(struct ip) + sizeof(struct ether_header);
80  pkt_handler->UdpHdr(len, ntohl(tunnelsrc.to_ulong()), HashValUdpSourcePort(),
81  ntohl(tunneldst.to_ulong()), VXLAN_UDP_DEST_PORT);
82 
83  pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(tunnelsrc.to_ulong()),
84  ntohl(tunneldst.to_ulong()), IPPROTO_UDP,
86  // Fill VxLan Header
87  VxlanHdr *vxlanhdr = (VxlanHdr *)(buf + sizeof(udphdr)+ sizeof(struct ip)
88  + sizeof(struct ether_header));
89  vxlanhdr->vxlan_id = ntohl(vxlan_id << 8);
91 
92  //Fill inner packet details.
93  pkt_info->eth = (struct ether_header *)(vxlanhdr + 1);
94 
96  ETHERTYPE_IP);
97 
98  pkt_info->ip = (struct ip *)(pkt_info->eth +1);
99  Ip4Address dip = Ip4Address::from_string("127.0.0.1", ec);
100  pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
101  len = data_len+sizeof(struct udphdr);
102  pkt_handler->UdpHdr(len, sip_.to_v4().to_ulong(), sport_,
103  dip.to_ulong(), VXLAN_UDP_DEST_PORT);
104  pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(sip_.to_v4().to_ulong()),
105  ntohl(dip.to_ulong()), proto_,
107  //pkt_handler->SetDiagChkSum();
108  pkt_handler->pkt_info()->set_len(len_);
110  Interface *intf = static_cast<Interface *>
111  (agent->interface_table()->Find(&key1, true));
112  pkt_handler->Send(intf->id(), agent->fabric_vrf()->vrf_id(),
113  AgentHdr::TX_SWITCH, CMD_PARAM_PACKET_CTRL,
114  CMD_PARAM_1_DIAG, PktHandler::DIAG);
115 
116  delete pkt_handler;
117  return;
118 }
119 
120 void OverlayTraceReq::HandleRequest() const {
121  std::string err_str;
122  boost::system::error_code ec;
123  OverlayTraceRoute *overlaytraceroute = NULL;
124 
125  {
126  Agent *agent = Agent::GetInstance();
127  boost::uuids::uuid vn_uuid = StringToUuid(get_vn_uuid());
128  IpAddress sip(IpAddress::from_string(get_source_ip(), ec));
129  if (ec.failed()) {
130  err_str = "Invalid source IP";
131  goto error;
132  }
133 
134  if (!sip.is_v4()) {
135  err_str = "V6 is not supported";
136  goto error;
137  }
138 
139  IpAddress dip(IpAddress::from_string(get_dest_ip(), ec));
140  if (ec.failed()) {
141  err_str = "Invalid destination IP";
142  goto error;
143  }
144 
145  if (!dip.is_v4()) {
146  err_str = "V6 is not supported";
147  goto error;
148  }
149 
150  uint8_t proto = get_protocol();
151  if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
152  err_str = "Invalid protocol - Supported protocols are TCP & UDP";
153  goto error;
154  }
155  VnEntry *vn = agent->vn_table()->Find(vn_uuid);
156 
157  if (!vn) {
158  err_str = "Invalid VN segment";
159  goto error;
160  }
161 
162  int vxlan_id = vn->GetVxLanId();
163  VxLanId* vxlan = agent->vxlan_table()->Find(vxlan_id);
164 
165  if (!vxlan) {
166  err_str = "Invalid vxlan segment";
167  goto error;
168  }
169 
171  get_vm_remote_mac(), agent);
172  if (!rt) {
173  err_str = "Invalid remote mac";
174  goto error;
175  }
176  }
177  overlaytraceroute = new OverlayTraceRoute(this,
178  Agent::GetInstance()->diag_table());
179  overlaytraceroute->Init();
180  overlaytraceroute->ReplyLocalHop();
181  return;
182 
183 error:
184  TraceRouteErrResp *resp = new TraceRouteErrResp;
185  resp->set_error_response(err_str);
186  resp->set_context(context());
187  resp->Response();
188  return;
189 }
190 // if timed out max times for a TTL, reply and increment ttl
192  if (seq_no_ >= GetMaxAttempts()) {
193  std::string address;
194  for (uint32_t i = 0; i < GetMaxAttempts(); i++)
195  address += "* ";
196 
197  done_ = ((ttl_ >= max_ttl_) ? true : false);
199  IncrementTtl();
200  }
201 }
202 
203 // Ready to send a response and increment ttl
205  if (ttl_ >= max_ttl_) {
206  handler->set_done(true);
207  done_ = true;
208  }
209  struct ip *ip = handler->pkt_info()->tunnel.ip;
210  IpAddress saddr = IpAddress(Ip4Address(ntohl(ip->ip_src.s_addr)));
211  TraceRoute::SendSandeshReply(saddr.to_v4().to_string(), context_,
212  !handler->IsDone());
213  IncrementTtl();
214 }
215 
216 // Reply with local node as the first hop
219  context_, true);
220 }
221 
223  ttl_++;
224  seq_no_ = 0;
225 }
int GetVxLanId() const
Definition: vn.cc:727
IpAddress sip_
Definition: diag.h:56
uint32_t GetMaxAttempts()
Definition: diag.h:42
#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
VrfEntry * fabric_vrf() const
Definition: agent.h:915
static const uint32_t kVxlanRABit
Definition: overlay_ping.h:21
void set_done(bool done)
const Interface * vhost_interface() const
Definition: agent.h:935
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)
InterfaceTable * interface_table() const
Definition: agent.h:465
const Ip4Address * GetDip() const
Definition: tunnel_nh.h:37
boost::uuids::uuid uuid
VnTable * vn_table() const
Definition: agent.h:495
const MacAddress & mac() const
Definition: interface.h:131
Definition: vxlan.h:14
std::string ToString() const
Definition: mac_address.cc:53
void RequestTimedOut(uint32_t seqno)
void FillOamPktHeader(OverlayOamPktData *pktdata, uint32_t vxlan_id, const boost::posix_time::ptime &time)
Definition: diag.cc:173
TunnelInfo tunnel
Definition: pkt_handler.h:407
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
OverlayTraceRoute(const OverlayTraceReq *req, DiagTable *diag_table)
#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
Ip4Address router_id() const
Definition: agent.h:666
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
virtual void HandleReply(DiagPktHandler *handler)
static const MacAddress in_dst_mac_
Definition: overlay_ping.h:23
Agent * agent() const
Definition: diag.h:117
const Ip4Address * GetSip() const
Definition: tunnel_nh.h:36
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
PktInfo * pkt_info() const
Definition: proto_handler.h:88
boost::uuids::uuid vn_uuid_
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
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
virtual void SendRequest()
VxLanId * Find(uint32_t vxlan_id)
Definition: vxlan.cc:223
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)
static void SendSandeshReply(const std::string &address, const std::string &context, bool more)
Definition: traceroute.cc:22
bool IsDone() const
Definition: diag.h:21
const MacAddress * GetDmac() const
Definition: tunnel_nh.h:39
static const uint32_t kOverlayUdpHdrLength
Definition: overlay_ping.h:18
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)
struct ip * ip
Definition: pkt_handler.h:218