LCOV - code coverage report
Current view: top level - vnsw/agent/services - bfd_handler.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 6 80 7.5 %
Date: 2026-06-04 02:06:09 Functions: 2 6 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <cmn/agent_cmn.h>
       6             : #include <init/agent_init.h>
       7             : #include <pkt/pkt_init.h>
       8             : #include <pkt/pkt_handler.h>
       9             : #include <services/bfd_proto.h>
      10             : #include "mac_learning/mac_learning_proto.h"
      11             : 
      12           2 : BfdHandler::BfdHandler(Agent *agent, boost::shared_ptr<PktInfo> info,
      13           2 :                        boost::asio::io_context &io)
      14           2 :     : ProtoHandler(agent, info, io) {
      15           2 : }
      16             : 
      17           2 : BfdHandler::~BfdHandler() {
      18           2 : }
      19             : 
      20           0 : bool BfdHandler::HandleReceive() {
      21           0 :     BfdProto *bfd_proto = agent()->GetBfdProto();
      22           0 :     uint8_t len = ntohs(pkt_info_->transp.udp->len) - 8;
      23           0 :     uint8_t *data = new uint8_t[len];
      24           0 :     memcpy(data, pkt_info_->data, len);
      25           0 :     boost::asio::const_buffer buffer(boost::asio::buffer(data, len));
      26             : 
      27           0 :     boost::system::error_code ec;
      28           0 :     boost::asio::ip::udp::endpoint local_endpoint(pkt_info_->ip_daddr,
      29           0 :                                                   pkt_info_->dport);
      30           0 :     boost::asio::ip::udp::endpoint remote_endpoint(pkt_info_->ip_saddr,
      31           0 :                                                    pkt_info_->sport);
      32             :     // thread safe!
      33           0 :     bfd_proto->HandleReceiveSafe(
      34             :                                   buffer, local_endpoint, remote_endpoint,
      35           0 :                                   BFD::SessionIndex(GetInterfaceIndex()),
      36             :                                   len, ec);
      37           0 :     return true;
      38             : }
      39             : 
      40           0 : bool BfdHandler::Run() {
      41             :     Interface *itf =
      42           0 :         agent()->interface_table()->FindInterface(GetInterfaceIndex());
      43           0 :     if (itf == NULL) {
      44           0 :         return true;
      45             :     }
      46             : 
      47           0 :     return HandleReceive();
      48             : }
      49             : 
      50           0 : void BfdHandler::SendPacket(
      51             :          const boost::asio::ip::udp::endpoint &local_endpoint,
      52             :          const boost::asio::ip::udp::endpoint &remote_endpoint,
      53             :          uint32_t interface_id, const boost::asio::mutable_buffer &packet,
      54             :          int packet_length) {
      55             : 
      56             :     Interface *intrface =
      57           0 :         agent()->interface_table()->FindInterface(interface_id);
      58           0 :     if (!intrface || intrface->type() != Interface::VM_INTERFACE)
      59           0 :         return;
      60             : 
      61           0 :     if (pkt_info_->packet_buffer() == NULL) {
      62           0 :         pkt_info_->AllocPacketBuffer(agent(), PktHandler::BFD,
      63             :                                      BFD_TX_BUFF_LEN, 0);
      64             :     }
      65             : 
      66           0 :     uint16_t buf_len = pkt_info_->packet_buffer()->data_len();
      67           0 :     char *ptr = (char *)pkt_info_->packet_buffer()->data();
      68           0 :     memset(ptr, 0, buf_len);
      69           0 :     pkt_info_->eth = (struct ether_header *)ptr;
      70             : 
      71           0 :     VmInterface *vm_interface = static_cast<VmInterface *>(intrface);
      72           0 :     bool is_v4 = local_endpoint.address().is_v4();
      73           0 :     uint16_t len = 0;
      74             : 
      75           0 :     uint8_t *data = boost::asio::buffer_cast<uint8_t *>(packet);
      76           0 :     uint16_t eth_proto = is_v4 ? ETHERTYPE_IP : ETHERTYPE_IPV6;
      77             :     MacAddress mac = agent()->mac_learning_proto()->
      78             :                         GetMacIpLearningTable()->GetPairedMacAddress(
      79           0 :                                 vm_interface->vrf()?
      80           0 :                                 vm_interface->vrf()->vrf_id():
      81             :                                 VrfEntry::kInvalidIndex,
      82           0 :                                 remote_endpoint.address());
      83             : 
      84           0 :     if (mac == MacAddress()) {
      85           0 :         mac = vm_interface->vm_mac();
      86             :     }
      87             : 
      88           0 :     len += EthHdr(ptr + len, buf_len - len,
      89           0 :                   agent()->vrrp_mac(),
      90             :                   mac,
      91           0 :                   eth_proto, vm_interface->tx_vlan_id());
      92             : 
      93           0 :     if (is_v4) {
      94           0 :         uint16_t ip_len = sizeof(struct ip) + sizeof(udphdr) + packet_length;
      95           0 :         len += IpHdr(ptr + len, buf_len - len, ip_len,
      96           0 :                      htonl(local_endpoint.address().to_v4().to_ulong()),
      97           0 :                      htonl(remote_endpoint.address().to_v4().to_ulong()),
      98             :                      IPPROTO_UDP, 0, 255);
      99           0 :         memcpy(ptr + len + sizeof(udphdr), data, packet_length);
     100           0 :         len += UdpHdr((udphdr *)(ptr + len), buf_len - len,
     101           0 :                       sizeof(udphdr) + packet_length,
     102           0 :                       htonl(local_endpoint.address().to_v4().to_ulong()),
     103           0 :                       local_endpoint.port(),
     104           0 :                       htonl(remote_endpoint.address().to_v4().to_ulong()),
     105           0 :                       remote_endpoint.port());
     106             :     } else {
     107           0 :         pkt_info_->ip6 = (struct ip6_hdr *)(ptr + len);
     108           0 :         Ip6Hdr((ip6_hdr *)(ptr + len),
     109           0 :                sizeof(udphdr) + packet_length,
     110             :                IPPROTO_UDP, 64,
     111           0 :                local_endpoint.address().to_v6().to_bytes().data(),
     112           0 :                remote_endpoint.address().to_v6().to_bytes().data());
     113           0 :         len += sizeof(ip6_hdr);
     114           0 :         memcpy(ptr + len + sizeof(udphdr), data, packet_length);
     115           0 :         pkt_info_->transp.udp = (struct udphdr *)(ptr + len);
     116           0 :         UdpHdr((udphdr *)(ptr + len), sizeof(udphdr) + packet_length,
     117           0 :                local_endpoint.address().to_v6().to_bytes().data(),
     118           0 :                local_endpoint.port(),
     119           0 :                remote_endpoint.address().to_v6().to_bytes().data(),
     120           0 :                remote_endpoint.port(), IPPROTO_UDP);
     121           0 :         len += sizeof(udphdr);
     122             :     }
     123             : 
     124           0 :     len += packet_length;
     125             : 
     126           0 :     pkt_info_->set_len(len);
     127           0 :     Send(interface_id, vm_interface->vrf_id(),
     128             :          AgentHdr::TX_SWITCH, PktHandler::BFD);
     129           0 :     pkt_info_->reset_packet_buffer();
     130           0 :     const uint8_t *p = boost::asio::buffer_cast<const uint8_t *>(packet);
     131           0 :     delete[] p;
     132             : }

Generated by: LCOV version 1.14