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

Generated by: LCOV version 1.14