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 2 : VrouterControlInterface() : ControlInterface() { } 22 2 : virtual ~VrouterControlInterface() { 23 2 : vr_cmd_list_.clear(); 24 2 : vr_cmd_params_list_.clear(); 25 2 : agent_cmd_list_.clear(); 26 2 : } 27 : 28 2 : virtual void InitControlInterface() { 29 : // Init and populate vector for translating command types from vrouter 30 : // to agent 31 2 : vr_cmd_list_.insert(vr_cmd_list_.begin(), MAX_AGENT_HDR_COMMANDS, 32 2 : AgentHdr::INVALID); 33 2 : vr_cmd_list_[AGENT_TRAP_ARP] = AgentHdr::TRAP_ARP; 34 2 : vr_cmd_list_[AGENT_TRAP_L2_PROTOCOLS] = AgentHdr::TRAP_L2_PROTOCOL; 35 2 : vr_cmd_list_[AGENT_TRAP_NEXTHOP] = AgentHdr::TRAP_NEXTHOP; 36 2 : vr_cmd_list_[AGENT_TRAP_RESOLVE] = AgentHdr::TRAP_RESOLVE; 37 2 : vr_cmd_list_[AGENT_TRAP_FLOW_MISS] = AgentHdr::TRAP_FLOW_MISS; 38 2 : vr_cmd_list_[AGENT_TRAP_L3_PROTOCOLS] = AgentHdr::TRAP_L3_PROTOCOLS; 39 2 : vr_cmd_list_[AGENT_TRAP_DIAG] = AgentHdr::TRAP_DIAG; 40 2 : vr_cmd_list_[AGENT_TRAP_SOURCE_MISMATCH] = 41 : AgentHdr::TRAP_SOURCE_MISMATCH; 42 2 : vr_cmd_list_[AGENT_TRAP_HANDLE_DF] = AgentHdr::TRAP_HANDLE_DF; 43 2 : vr_cmd_list_[AGENT_TRAP_ZERO_TTL] = AgentHdr::TRAP_ZERO_TTL; 44 2 : vr_cmd_list_[AGENT_TRAP_ICMP_ERROR] = AgentHdr::TRAP_ICMP_ERROR; 45 2 : vr_cmd_list_[AGENT_TRAP_FLOW_ACTION_HOLD] = AgentHdr::TRAP_FLOW_ACTION_HOLD; 46 2 : vr_cmd_list_[AGENT_TRAP_TOR_CONTROL_PKT] = AgentHdr::TRAP_TOR_CONTROL_PKT; 47 2 : vr_cmd_list_[AGENT_TRAP_FLOW_ACTION_HOLD] = AgentHdr::TRAP_FLOW_ACTION_HOLD; 48 2 : vr_cmd_list_[AGENT_TRAP_ROUTER_ALERT] = AgentHdr::TRAP_ROUTER_ALERT; 49 2 : vr_cmd_list_[AGENT_TRAP_MAC_LEARN] = AgentHdr::TRAP_MAC_LEARN; 50 2 : vr_cmd_list_[AGENT_TRAP_MAC_MOVE] = AgentHdr::TRAP_MAC_MOVE; 51 2 : vr_cmd_list_[AGENT_TRAP_MAC_IP_LEARNING] = AgentHdr::TRAP_MAC_IP_LEARNING; 52 2 : vr_cmd_list_[AGENT_TRAP_BFD] = AgentHdr::TRAP_BFD; 53 : // Init and populate vector for translating command params from vrouter 54 : // to agent 55 2 : vr_cmd_params_list_.insert(vr_cmd_params_list_.begin(), MAX_CMD_PARAMS, 56 2 : AgentHdr::MAX_PACKET_CMD_PARAM); 57 2 : vr_cmd_params_list_[CMD_PARAM_PACKET_CTRL] = AgentHdr::PACKET_CMD_PARAM_CTRL; 58 2 : 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 2 : agent_cmd_list_.insert(agent_cmd_list_.begin(), AgentHdr::INVALID, 63 2 : MAX_AGENT_HDR_COMMANDS); 64 2 : agent_cmd_list_[AgentHdr::TX_SWITCH] = AGENT_CMD_SWITCH; 65 2 : agent_cmd_list_[AgentHdr::TX_ROUTE] = AGENT_CMD_ROUTE; 66 2 : } 67 : 68 : // Length of header added by implementation of VrouterControlInterface. 69 : // Buffer passed in Send should reserve atleast EncapsulationLength() bytes 70 0 : virtual uint32_t EncapsulationLength() const { 71 0 : return kAgentHdrLen; 72 : } 73 : 74 18064 : int DecodeAgentHdr(AgentHdr *hdr, uint8_t *buff, uint32_t len) { 75 : // Enusure sanity of the packet 76 18064 : 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 18063 : agent_hdr *vr_agent_hdr = 85 : (agent_hdr *) (buff + sizeof(ether_header)); 86 : 87 18063 : hdr->ifindex = ntohs(vr_agent_hdr->hdr_ifindex); 88 18063 : hdr->vrf = ntohs(vr_agent_hdr->hdr_vrf); 89 18063 : hdr->cmd = VrCmdToAgentCmd(ntohs(vr_agent_hdr->hdr_cmd)); 90 18063 : hdr->cmd_param = ntohl(vr_agent_hdr->hdr_cmd_param); 91 18063 : hdr->nh = ntohl(vr_agent_hdr->hdr_cmd_param_1); 92 18063 : hdr->cmd_param_2 = ntohl(vr_agent_hdr->hdr_cmd_param_2); 93 18063 : hdr->cmd_param_3 = ntohl(vr_agent_hdr->hdr_cmd_param_3); 94 18063 : hdr->cmd_param_4 = ntohl(vr_agent_hdr->hdr_cmd_param_4); 95 18063 : hdr->cmd_param_5 = vr_agent_hdr->hdr_cmd_param_5; 96 18063 : 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 18063 : return kAgentHdrLen; 102 : } 103 : 104 : // Handle packet received by VrouterControlInterface 105 : // Format of packet trapped is OUTER_ETH - AGENT_HDR - PAYLOAD 106 18024 : bool Process(const PacketBufferPtr &pkt) { 107 18024 : AgentHdr hdr; 108 18024 : int agent_hdr_len = 0; 109 : 110 18024 : agent_hdr_len = DecodeAgentHdr(&hdr, pkt->data(), pkt->data_len()); 111 18024 : if (agent_hdr_len <= 0) { 112 1 : return false; 113 : } 114 : 115 18023 : pkt->SetOffset(agent_hdr_len); 116 18023 : return ControlInterface::Process(hdr, pkt); 117 18024 : } 118 : 119 217 : int EncodeAgentHdr(uint8_t *buff, const AgentHdr &hdr) { 120 217 : memset(buff, 0, sizeof(agent_hdr)); 121 : 122 : // Add outer ethernet header 123 217 : struct ether_header *eth = (struct ether_header *)buff; 124 217 : eth->ether_shost[ETHER_ADDR_LEN - 1] = 1; 125 217 : eth->ether_dhost[ETHER_ADDR_LEN - 1] = 2; 126 217 : eth->ether_type = htons(ETHERTYPE_IP); 127 : 128 : // Fill agent_hdr 129 217 : agent_hdr *vr_agent_hdr = (agent_hdr *) (eth + 1); 130 217 : vr_agent_hdr->hdr_ifindex = htons(hdr.ifindex); 131 217 : vr_agent_hdr->hdr_vrf = htons(hdr.vrf); 132 217 : vr_agent_hdr->hdr_cmd = htons(hdr.cmd); 133 217 : vr_agent_hdr->hdr_cmd_param = htonl(hdr.cmd_param); 134 217 : vr_agent_hdr->hdr_cmd_param_1 = htonl(hdr.cmd_param_1); 135 217 : return 0; 136 : } 137 : 138 : // Transmit packet on VrouterControlInterface. 139 : // Format of packet after encapsulation is OUTER_ETH - AGENT_HDR - PAYLOAD 140 217 : virtual int Send(const AgentHdr &hdr, const PacketBufferPtr &pkt) { 141 217 : uint16_t agent_hdr_len = kAgentHdrLen; 142 217 : uint8_t *agent_hdr_buff = new uint8_t [agent_hdr_len]; 143 217 : EncodeAgentHdr(agent_hdr_buff, hdr); 144 : 145 217 : int ret = Send(agent_hdr_buff, agent_hdr_len, pkt); 146 217 : if (ret <= 0) 147 0 : return ret; 148 : 149 217 : 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 18063 : AgentHdr::PktCommand VrCmdToAgentCmd(uint16_t vr_cmd) { 156 18063 : AgentHdr::PktCommand cmd = AgentHdr::INVALID; 157 18063 : if (vr_cmd < vr_cmd_list_.size()) { 158 18057 : cmd = vr_cmd_list_[vr_cmd]; 159 : } 160 : 161 18063 : 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