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

Generated by: LCOV version 1.14