LCOV - code coverage report
Current view: top level - vnsw/agent/diag - overlay_traceroute.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 151 0.0 %
Date: 2026-06-08 02:02:55 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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"
      14             : #include "diag/overlay_traceroute.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           0 : OverlayTraceRoute::OverlayTraceRoute(const OverlayTraceReq *traceroute_req,
      21           0 :                        DiagTable *diag_table) :
      22             :     DiagEntry(traceroute_req->get_source_ip(), traceroute_req->get_dest_ip(),
      23           0 :               traceroute_req->get_protocol(), traceroute_req->get_source_port(),
      24           0 :               traceroute_req->get_dest_port(), Agent::GetInstance()->fabric_vrf_name(),
      25           0 :               traceroute_req->get_interval() * 100,traceroute_req->get_max_attempts(), diag_table),
      26           0 :               vn_uuid_(StringToUuid(traceroute_req->get_vn_uuid())),
      27           0 :               remote_vm_mac_(traceroute_req->get_vm_remote_mac()), ttl_(2),
      28           0 :               max_ttl_(traceroute_req->get_max_hops()),
      29           0 :               context_(traceroute_req->context()) {
      30           0 : }
      31             : 
      32           0 : OverlayTraceRoute::~OverlayTraceRoute() {
      33           0 : }
      34             : 
      35             : 
      36           0 : void OverlayTraceRoute::SendRequest()
      37             : {
      38           0 :     Agent *agent = diag_table_->agent();
      39           0 :     Ip4Address tunneldst;
      40           0 :     Ip4Address tunnelsrc;
      41           0 :     seq_no_++;
      42           0 :     string vrf_name;
      43           0 :     boost::system::error_code ec;
      44           0 :     uint8_t data_len = 50;
      45           0 :     int vxlan_id = agent->vn_table()->Find(vn_uuid_)->GetVxLanId();
      46           0 :     VxLanId *vxlan = agent->vxlan_table()->Find(vxlan_id);
      47           0 :     if (!vxlan)
      48           0 :         return;
      49             : 
      50           0 :     BridgeRouteEntry *rt = OverlayPing::L2RouteGet(vxlan,
      51           0 :                                                    remote_vm_mac_.ToString(), agent);
      52           0 :     if (!rt)
      53           0 :         return;
      54           0 :     const AgentPath *path = rt->GetActivePath();
      55           0 :     const TunnelNH *nh = static_cast<const TunnelNH *>(path->nexthop());
      56             : 
      57           0 :     tunneldst = *nh->GetDip();
      58           0 :     tunnelsrc = *nh->GetSip();
      59           0 :     len_ = OverlayPing::kOverlayUdpHdrLength + data_len;
      60             :     boost::shared_ptr<PktInfo> pkt_info(new PktInfo(agent, len_,
      61           0 :                                                         PktHandler::DIAG, 0));
      62           0 :     uint8_t *buf = pkt_info->packet_buffer()->data();
      63           0 :     memset(buf, 0, len_);
      64           0 :     OverlayOamPktData *pktdata = NULL;
      65           0 :     pktdata = (OverlayOamPktData *)(buf + OverlayPing::kOverlayUdpHdrLength);
      66             : 
      67           0 :     boost::posix_time::ptime senttime = microsec_clock::universal_time();
      68           0 :     FillOamPktHeader(pktdata, vxlan_id, senttime);
      69           0 :     DiagPktHandler *pkt_handler = new DiagPktHandler(diag_table_->agent(), pkt_info,
      70           0 :                                    *(diag_table_->agent()->event_manager())->io_service());
      71             :     // FIll outer header
      72           0 :     pkt_info->eth = (struct ether_header *)(buf);
      73           0 :     pkt_handler->EthHdr(agent->vhost_interface()->mac(), *nh->GetDmac(),
      74             :                         ETHERTYPE_IP);
      75           0 :     pkt_info->ip = (struct ip *)(pkt_info->eth +1);
      76           0 :     pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
      77             :     uint8_t  len;
      78           0 :     len = data_len+2 * sizeof(udphdr)+sizeof(VxlanHdr)+
      79             :                             sizeof(struct ip) + sizeof(struct ether_header);
      80           0 :     pkt_handler->UdpHdr(len, ntohl(tunnelsrc.to_ulong()), HashValUdpSourcePort(),
      81           0 :                      ntohl(tunneldst.to_ulong()), VXLAN_UDP_DEST_PORT);
      82             : 
      83           0 :     pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(tunnelsrc.to_ulong()),
      84           0 :                        ntohl(tunneldst.to_ulong()), IPPROTO_UDP,
      85           0 :                        DEFAULT_IP_ID, ttl_);
      86             :    // Fill VxLan Header
      87           0 :     VxlanHdr *vxlanhdr = (VxlanHdr *)(buf + sizeof(udphdr)+ sizeof(struct ip)
      88             :                                    + sizeof(struct ether_header));
      89           0 :     vxlanhdr->vxlan_id =  ntohl(vxlan_id << 8);
      90           0 :     vxlanhdr->reserved = ntohl(OverlayPing::kVxlanRABit | OverlayPing::kVxlanIBit);
      91             : 
      92             :     //Fill  inner packet details.
      93           0 :     pkt_info->eth = (struct ether_header *)(vxlanhdr + 1);
      94             : 
      95           0 :     pkt_handler->EthHdr(OverlayPing::in_source_mac_, OverlayPing::in_dst_mac_,
      96             :                         ETHERTYPE_IP);
      97             : 
      98           0 :     pkt_info->ip = (struct ip *)(pkt_info->eth +1);
      99           0 :     Ip4Address dip = Ip4Address::from_string("127.0.0.1", ec);
     100           0 :     pkt_info->transp.udp = (struct udphdr *)(pkt_info->ip + 1);
     101           0 :     len = data_len+sizeof(struct udphdr);
     102           0 :     pkt_handler->UdpHdr(len, sip_.to_v4().to_ulong(), sport_,
     103           0 :                         dip.to_ulong(), VXLAN_UDP_DEST_PORT);
     104           0 :     pkt_handler->IpHdr(len + sizeof(struct ip), ntohl(sip_.to_v4().to_ulong()),
     105           0 :                        ntohl(dip.to_ulong()), proto_,
     106             :                        DEFAULT_IP_ID, DEFAULT_IP_TTL);
     107             :     //pkt_handler->SetDiagChkSum();
     108           0 :     pkt_handler->pkt_info()->set_len(len_);
     109           0 :     PhysicalInterfaceKey key1(agent->fabric_interface_name());
     110           0 :     Interface *intf = static_cast<Interface *>
     111           0 :                 (agent->interface_table()->Find(&key1, true));
     112           0 :     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           0 :     delete pkt_handler;
     117           0 :     return;
     118           0 : }
     119             : 
     120           0 : void OverlayTraceReq::HandleRequest() const {
     121           0 :     std::string err_str;
     122           0 :     boost::system::error_code ec;
     123           0 :     OverlayTraceRoute *overlaytraceroute = NULL;
     124             : 
     125             :     {
     126           0 :         Agent *agent = Agent::GetInstance();
     127           0 :         boost::uuids::uuid vn_uuid = StringToUuid(get_vn_uuid());
     128           0 :         IpAddress sip(IpAddress::from_string(get_source_ip(), ec));
     129           0 :         if (ec.failed()) {
     130           0 :             err_str = "Invalid source IP";
     131           0 :             goto error;
     132             :         }
     133             : 
     134           0 :         if (!sip.is_v4()) {
     135           0 :             err_str = "V6 is not supported";
     136           0 :             goto error;
     137             :         }
     138             : 
     139           0 :         IpAddress dip(IpAddress::from_string(get_dest_ip(), ec));
     140           0 :         if (ec.failed()) {
     141           0 :             err_str = "Invalid destination IP";
     142           0 :             goto error;
     143             :         }
     144             : 
     145           0 :         if (!dip.is_v4()) {
     146           0 :             err_str = "V6 is not supported";
     147           0 :             goto error;
     148             :         }
     149             : 
     150           0 :         uint8_t proto = get_protocol();
     151           0 :         if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
     152           0 :             err_str = "Invalid protocol - Supported protocols are TCP & UDP";
     153           0 :             goto error;
     154             :         }
     155           0 :         VnEntry *vn  = agent->vn_table()->Find(vn_uuid);
     156             : 
     157           0 :         if (!vn) {
     158           0 :             err_str = "Invalid VN segment";
     159           0 :             goto error;
     160             :         }
     161             : 
     162           0 :         int vxlan_id = vn->GetVxLanId();
     163           0 :         VxLanId* vxlan = agent->vxlan_table()->Find(vxlan_id);
     164             : 
     165           0 :         if (!vxlan) {
     166           0 :             err_str = "Invalid vxlan segment";
     167           0 :             goto error;
     168             :         }
     169             : 
     170           0 :         BridgeRouteEntry *rt = OverlayPing::L2RouteGet(vxlan,
     171           0 :                                                        get_vm_remote_mac(), agent);
     172           0 :         if (!rt) {
     173           0 :             err_str = "Invalid remote mac";
     174           0 :             goto error;
     175             :         }
     176             :     }
     177           0 :     overlaytraceroute = new OverlayTraceRoute(this,
     178           0 :                                               Agent::GetInstance()->diag_table());
     179           0 :     overlaytraceroute->Init();
     180           0 :     overlaytraceroute->ReplyLocalHop();
     181           0 :     return;
     182             : 
     183           0 : error:
     184           0 :     TraceRouteErrResp *resp = new TraceRouteErrResp;
     185           0 :     resp->set_error_response(err_str);
     186           0 :     resp->set_context(context());
     187           0 :     resp->Response();
     188           0 :     return;
     189           0 : }
     190             : // if timed out max times for a TTL, reply and increment ttl
     191           0 : void OverlayTraceRoute::RequestTimedOut(uint32_t seqno) {
     192           0 :     if (seq_no_ >= GetMaxAttempts()) {
     193           0 :         std::string address;
     194           0 :         for (uint32_t i = 0; i < GetMaxAttempts(); i++)
     195           0 :             address += "* ";
     196             : 
     197           0 :         done_ = ((ttl_ >= max_ttl_) ? true : false);
     198           0 :         TraceRoute::SendSandeshReply(address, context_, !done_);
     199           0 :         IncrementTtl();
     200           0 :     }
     201           0 : }
     202             : 
     203             : // Ready to send a response and increment ttl
     204           0 : void OverlayTraceRoute::HandleReply(DiagPktHandler *handler) {
     205           0 :     if (ttl_ >= max_ttl_) {
     206           0 :         handler->set_done(true);
     207           0 :         done_ = true;
     208             :     }
     209           0 :     struct ip *ip = handler->pkt_info()->tunnel.ip;
     210           0 :     IpAddress saddr = IpAddress(Ip4Address(ntohl(ip->ip_src.s_addr)));
     211           0 :     TraceRoute::SendSandeshReply(saddr.to_v4().to_string(), context_,
     212           0 :                                  !handler->IsDone());
     213           0 :     IncrementTtl();
     214           0 : }
     215             : 
     216             : // Reply with local node as the first hop
     217           0 : void OverlayTraceRoute::ReplyLocalHop() {
     218           0 :     TraceRoute::SendSandeshReply(diag_table_->agent()->router_id().to_string(),
     219           0 :                      context_, true);
     220           0 : }
     221             : 
     222           0 : void OverlayTraceRoute::IncrementTtl() {
     223           0 :     ttl_++;
     224           0 :     seq_no_ = 0;
     225           0 : }

Generated by: LCOV version 1.14