LCOV - code coverage report
Current view: top level - vnsw/agent/pkt - vrouter_interface.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 91 94 96.8 %
Date: 2026-06-22 02:21:21 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : #ifndef vnsw_agent_pkt_vrouter_pkt_io_hpp
       5             : #define vnsw_agent_pkt_vrouter_pkt_io_hpp
       6             : 
       7             : #include "control_interface.h"
       8             : #include "cmn/agent_stats.h"
       9             : #include "vr_types.h"
      10             : #include "vr_defs.h"
      11             : #include "vr_mpls.h"
      12             : 
      13             : // VrouterControlInterface is implementation of ControlInterface for platforms
      14             : // using vrouter. This class assumes agent_hdr defined in
      15             : // vrouter/include/vr_defs.h is prepended with control information
      16             : class VrouterControlInterface : public ControlInterface {
      17             : public:
      18             :     static const uint32_t kAgentHdrLen =
      19             :         (sizeof(ether_header) + sizeof(struct agent_hdr));
      20             : 
      21         166 :     VrouterControlInterface() : ControlInterface() { }
      22         151 :     virtual ~VrouterControlInterface() {
      23         151 :         vr_cmd_list_.clear();
      24         151 :         vr_cmd_params_list_.clear();
      25         151 :         agent_cmd_list_.clear();
      26         151 :     }
      27             : 
      28         166 :     virtual void InitControlInterface() {
      29             :         // Init and populate vector for translating command types from vrouter
      30             :         // to agent
      31         166 :         vr_cmd_list_.insert(vr_cmd_list_.begin(), MAX_AGENT_HDR_COMMANDS,
      32         166 :                             AgentHdr::INVALID);
      33         166 :         vr_cmd_list_[AGENT_TRAP_ARP] = AgentHdr::TRAP_ARP;
      34         166 :         vr_cmd_list_[AGENT_TRAP_L2_PROTOCOLS] = AgentHdr::TRAP_L2_PROTOCOL;
      35         166 :         vr_cmd_list_[AGENT_TRAP_NEXTHOP] = AgentHdr::TRAP_NEXTHOP;
      36         166 :         vr_cmd_list_[AGENT_TRAP_RESOLVE] = AgentHdr::TRAP_RESOLVE;
      37         166 :         vr_cmd_list_[AGENT_TRAP_FLOW_MISS] = AgentHdr::TRAP_FLOW_MISS;
      38         166 :         vr_cmd_list_[AGENT_TRAP_L3_PROTOCOLS] = AgentHdr::TRAP_L3_PROTOCOLS;
      39         166 :         vr_cmd_list_[AGENT_TRAP_DIAG] = AgentHdr::TRAP_DIAG;
      40         166 :         vr_cmd_list_[AGENT_TRAP_SOURCE_MISMATCH] =
      41             :             AgentHdr::TRAP_SOURCE_MISMATCH;
      42         166 :         vr_cmd_list_[AGENT_TRAP_HANDLE_DF] = AgentHdr::TRAP_HANDLE_DF;
      43         166 :         vr_cmd_list_[AGENT_TRAP_ZERO_TTL] = AgentHdr::TRAP_ZERO_TTL;
      44         166 :         vr_cmd_list_[AGENT_TRAP_ICMP_ERROR] = AgentHdr::TRAP_ICMP_ERROR;
      45         166 :         vr_cmd_list_[AGENT_TRAP_FLOW_ACTION_HOLD] = AgentHdr::TRAP_FLOW_ACTION_HOLD;
      46         166 :         vr_cmd_list_[AGENT_TRAP_TOR_CONTROL_PKT] = AgentHdr::TRAP_TOR_CONTROL_PKT;
      47         166 :         vr_cmd_list_[AGENT_TRAP_FLOW_ACTION_HOLD] = AgentHdr::TRAP_FLOW_ACTION_HOLD;
      48         166 :         vr_cmd_list_[AGENT_TRAP_ROUTER_ALERT] = AgentHdr::TRAP_ROUTER_ALERT;
      49         166 :         vr_cmd_list_[AGENT_TRAP_MAC_LEARN] = AgentHdr::TRAP_MAC_LEARN;
      50         166 :         vr_cmd_list_[AGENT_TRAP_MAC_MOVE] = AgentHdr::TRAP_MAC_MOVE;
      51         166 :         vr_cmd_list_[AGENT_TRAP_MAC_IP_LEARNING] = AgentHdr::TRAP_MAC_IP_LEARNING;
      52         166 :         vr_cmd_list_[AGENT_TRAP_BFD] = AgentHdr::TRAP_BFD;
      53             :         // Init and populate vector for translating command params from vrouter
      54             :         // to agent
      55         166 :         vr_cmd_params_list_.insert(vr_cmd_params_list_.begin(), MAX_CMD_PARAMS,
      56         166 :                                    AgentHdr::MAX_PACKET_CMD_PARAM);
      57         166 :         vr_cmd_params_list_[CMD_PARAM_PACKET_CTRL] = AgentHdr::PACKET_CMD_PARAM_CTRL;
      58         166 :         vr_cmd_params_list_[CMD_PARAM_1_DIAG] = AgentHdr::PACKET_CMD_PARAM_DIAG;
      59             : 
      60             :         // Init and populate vector for translating command types from agent
      61             :         // to vrouter
      62         166 :         agent_cmd_list_.insert(agent_cmd_list_.begin(), AgentHdr::INVALID,
      63         166 :                                MAX_AGENT_HDR_COMMANDS);
      64         166 :         agent_cmd_list_[AgentHdr::TX_SWITCH] = AGENT_CMD_SWITCH;
      65         166 :         agent_cmd_list_[AgentHdr::TX_ROUTE] = AGENT_CMD_ROUTE;
      66         166 :     }
      67             : 
      68             :     // Length of header added by implementation of VrouterControlInterface.
      69             :     // Buffer passed in Send should reserve atleast EncapsulationLength() bytes
      70         348 :     virtual uint32_t EncapsulationLength() const {
      71         348 :         return kAgentHdrLen;
      72             :     }
      73             : 
      74       19742 :     int DecodeAgentHdr(AgentHdr *hdr, uint8_t *buff, uint32_t len) {
      75             :         // Enusure sanity of the packet
      76       19742 :         if (len <= kAgentHdrLen) {
      77           1 :             pkt_handler()->agent()->stats()->incr_pkt_invalid_agent_hdr();
      78           1 :             pkt_handler()->agent()->stats()->incr_pkt_exceptions();
      79           1 :             pkt_handler()->agent()->stats()->incr_pkt_dropped();
      80           1 :             return 0;
      81             :         }
      82             : 
      83             :         // Decode agent_hdr
      84       19741 :         agent_hdr *vr_agent_hdr =
      85             :             (agent_hdr *) (buff + sizeof(ether_header));
      86             : 
      87       19741 :         hdr->ifindex = ntohs(vr_agent_hdr->hdr_ifindex);
      88       19741 :         hdr->vrf = ntohs(vr_agent_hdr->hdr_vrf);
      89       19741 :         hdr->cmd = VrCmdToAgentCmd(ntohs(vr_agent_hdr->hdr_cmd));
      90       19741 :         hdr->cmd_param = ntohl(vr_agent_hdr->hdr_cmd_param);
      91       19741 :         hdr->nh = ntohl(vr_agent_hdr->hdr_cmd_param_1);
      92       19741 :         hdr->cmd_param_2 = ntohl(vr_agent_hdr->hdr_cmd_param_2);
      93       19741 :         hdr->cmd_param_3 = ntohl(vr_agent_hdr->hdr_cmd_param_3);
      94       19741 :         hdr->cmd_param_4 = ntohl(vr_agent_hdr->hdr_cmd_param_4);
      95       19741 :         hdr->cmd_param_5 = vr_agent_hdr->hdr_cmd_param_5;
      96       19741 :         if (hdr->cmd == AGENT_TRAP_HANDLE_DF) {
      97           0 :             hdr->mtu = ntohl(vr_agent_hdr->hdr_cmd_param);
      98           0 :             hdr->flow_index = ntohl(vr_agent_hdr->hdr_cmd_param_1);
      99             :         }
     100             : 
     101       19741 :         return kAgentHdrLen;
     102             :     }
     103             : 
     104             :     // Handle packet received by VrouterControlInterface
     105             :     // Format of packet trapped is OUTER_ETH - AGENT_HDR - PAYLOAD
     106       19702 :     bool Process(const PacketBufferPtr &pkt) {
     107       19702 :         AgentHdr hdr;
     108       19702 :         int agent_hdr_len = 0;
     109             : 
     110       19702 :         agent_hdr_len = DecodeAgentHdr(&hdr, pkt->data(), pkt->data_len());
     111       19702 :         if (agent_hdr_len <= 0) {
     112           1 :             return false;
     113             :         }
     114             : 
     115       19701 :         pkt->SetOffset(agent_hdr_len);
     116       19701 :         return ControlInterface::Process(hdr, pkt);
     117       19702 :     }
     118             : 
     119       58481 :     int EncodeAgentHdr(uint8_t *buff, const AgentHdr &hdr) {
     120       58481 :         memset(buff, 0, sizeof(agent_hdr));
     121             : 
     122             :         // Add outer ethernet header
     123       58481 :         struct ether_header *eth = (struct ether_header *)buff;
     124       58481 :         eth->ether_shost[ETHER_ADDR_LEN - 1] = 1;
     125       58481 :         eth->ether_dhost[ETHER_ADDR_LEN - 1] = 2;
     126       58481 :         eth->ether_type = htons(ETHERTYPE_IP);
     127             : 
     128             :         // Fill agent_hdr
     129       58481 :         agent_hdr *vr_agent_hdr = (agent_hdr *) (eth + 1);
     130       58481 :         vr_agent_hdr->hdr_ifindex = htons(hdr.ifindex);
     131       58481 :         vr_agent_hdr->hdr_vrf = htons(hdr.vrf);
     132       58481 :         vr_agent_hdr->hdr_cmd = htons(hdr.cmd);
     133       58481 :         vr_agent_hdr->hdr_cmd_param = htonl(hdr.cmd_param);
     134       58481 :         vr_agent_hdr->hdr_cmd_param_1 = htonl(hdr.cmd_param_1);
     135       58481 :         return 0;
     136             :     }
     137             : 
     138             :     // Transmit packet on VrouterControlInterface.
     139             :     // Format of packet after encapsulation is OUTER_ETH - AGENT_HDR - PAYLOAD
     140       58481 :     virtual int Send(const AgentHdr &hdr, const PacketBufferPtr &pkt) {
     141       58481 :         uint16_t agent_hdr_len = kAgentHdrLen;
     142       58481 :         uint8_t *agent_hdr_buff = new uint8_t [agent_hdr_len];
     143       58481 :         EncodeAgentHdr(agent_hdr_buff, hdr);
     144             : 
     145       58481 :         int ret = Send(agent_hdr_buff, agent_hdr_len, pkt);
     146       58481 :         if (ret <= 0)
     147           0 :             return ret;
     148             : 
     149       58481 :         return ret - sizeof(agent_hdr);
     150             :     }
     151             : 
     152             :     virtual int Send(uint8_t *buff, uint16_t buf_len,
     153             :                      const PacketBufferPtr &pkt) = 0;
     154             : private:
     155       19741 :     AgentHdr::PktCommand VrCmdToAgentCmd(uint16_t vr_cmd) {
     156       19741 :         AgentHdr::PktCommand cmd = AgentHdr::INVALID;
     157       19741 :         if (vr_cmd < vr_cmd_list_.size()) {
     158       19735 :             cmd = vr_cmd_list_[vr_cmd];
     159             :         }
     160             : 
     161       19741 :         return cmd;
     162             :     }
     163             : 
     164             :     AgentHdr::PktCommandParams VrCmdParamtoAgentCmdParam(uint16_t param) {
     165             :         AgentHdr::PktCommandParams cmd = AgentHdr::MAX_PACKET_CMD_PARAM;
     166             :         if (param < vr_cmd_params_list_.size()) {
     167             :             cmd = vr_cmd_params_list_[param];
     168             :         }
     169             : 
     170             :         return cmd;
     171             :     }
     172             : 
     173             :     uint16_t AgentCmdToVrCmd(AgentHdr::PktCommand agent_cmd) {
     174             :         assert((uint32_t)agent_cmd < agent_cmd_list_.size());
     175             :         return agent_cmd_list_[agent_cmd];
     176             :     }
     177             : 
     178             :     std::vector<AgentHdr::PktCommand> vr_cmd_list_;
     179             :     std::vector<AgentHdr::PktCommandParams> vr_cmd_params_list_;
     180             :     std::vector<uint16_t> agent_cmd_list_;
     181             : 
     182             :     DISALLOW_COPY_AND_ASSIGN(VrouterControlInterface);
     183             : };
     184             : #endif // vnsw_agent_pkt_vrouter_pkt_io_hpp

Generated by: LCOV version 1.14