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: 89 94 94.7 %
Date: 2026-11-09 02:10:49 Functions: 8 10 80.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14