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