/* // Copyright (c) 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. */ #ifndef _CGNAPT_PCP_H_ #define _CGNAPT_PCP_H_ /** * @file * * PCP-related defines */ #include #include #include #include #include #include "pipeline_cgnapt_common.h" void handle_pcp_req(struct rte_mbuf *rx_pkt, uint8_t ver, void *pipeline_cgnapt_ptr); void construct_pcp_resp(struct rte_mbuf *rx_pkt, struct rte_mbuf *tx_pkt, uint8_t ver, struct rte_pipeline *rte_p); void *pipeline_cgnapt_msg_req_pcp_handler( __rte_unused struct pipeline *p, void *msg); #ifdef __cplusplus extern "C" { #endif /************************** Constats used in PCP ****************************/ #define PCP_SERVER_PORT 5351 /* PCP Req or Resp */ enum{ PCP_REQ, PCP_RESP, }; /* PCP life time in seconds */ enum{ PCP_LONG_LTIME = 30 * 60, PCP_SHORT_LTIME = 30, MAX_PCP_LIFE_TIME = 120 * 60, }; /* PCP opcodes */ enum{ PCP_ANNOUNCE, PCP_MAP, PCP_PEER, }; /* PCP result codes */ enum{ PCP_SUCCESS, PCP_UNSUPP_VERSION, PCP_NOT_AUTHORIZED, PCP_MALFORMED_REQUEST, PCP_UNSUPP_OPCODE, PCP_UNSUPP_OPTION, PCP_MALFORMED_OPTION, PCP_NETWORK_FAILURE, PCP_NO_RESOURCES, PCP_UNSUPP_PROTOCOL, PCP_USER_EX_QUOTA, PCP_CANNOT_PROVIDE_EXTERNAL, PCP_ADDRESS_MISMATCH, PCP_EXCESSIVE_REMOTE_PEERS }; /* * @struct * * PCP request header format */ struct pcp_req_hdr { uint8_t ver; uint8_t opcode:7; //First LSB uint8_t req_resp:1;// MSB uint16_t res_unuse; uint32_t life_time; uint32_t cli_ip[4]; } __attribute__((__packed__)); /* * @struct * * PCP response header format */ struct pcp_resp_hdr { uint8_t ver; uint8_t opcode:7; //First LSB uint8_t req_resp:1;// MSB uint8_t res_unuse; uint8_t result_code; uint32_t life_time; uint32_t epoch_time; uint32_t reserve[3]; } __attribute__((__packed__)); /* * @struct * * PCP MAP request header format */ struct pcp_map_req { uint32_t nonce[3]; uint8_t protocol; uint32_t res_unuse1:24; uint16_t int_port; uint16_t ext_port; uint32_t ext_ip[4]; } __attribute__((__packed__)); /* * @struct * * PCP MAP response header format */ struct pcp_map_resp { uint32_t nonce[3]; uint8_t protocol; uint32_t res_unuse1:24; uint16_t int_port; uint16_t ext_port; uint32_t ext_ip[4]; } __attribute__((__packed__)); /* * @struct * * PCP PEER request header format */ struct pcp_peer_req { uint32_t nonce[3]; uint8_t protocol; uint32_t res_unuse1:24; uint16_t int_port; uint16_t ext_port; uint32_t ext_ip[4]; uint16_t rpeer_port; uint16_t res_unuse2; uint32_t rpeer_ip[4]; } __attribute__((__packed__)); /* * @struct * * PCP PEER response header format */ struct pcp_peer_resp { uint32_t nonce[3]; uint8_t protocol; uint32_t res_unuse1:24; uint16_t int_port; uint16_t ext_port; uint32_t ext_ip[4]; uint16_t rpeer_port; uint16_t res_unuse2; uint32_t rpeer_ip[4]; } __attribute__((__packed__)); /* * @struct * * Customized IPv4 header of struct ipv4_hdr */ struct ipv4 { uint8_t version_ihl; /**< version and header length */ uint8_t type_of_service; /**< type of service */ uint16_t total_length; /**< length of packet */ uint16_t packet_id; /**< packet ID */ uint16_t fragment_offset; /**< fragmentation offset */ uint8_t time_to_live; /**< time to live */ uint8_t next_proto_id; /**< protocol ID */ uint16_t hdr_checksum; /**< header checksum */ uint32_t src_addr; /**< source address */ uint32_t dst_addr; /**< destination address */ uint16_t src_port; uint16_t dst_port; } __attribute__((__packed__)); /* * @struct * * Customized IPv6 header of struct ipv6_hdr */ struct ipv6 { uint32_t vtc_flow; /**< IP version, traffic class & flow label. */ uint16_t payload_len; /**< IP packet length - * includes sizeof(ip_header). */ uint8_t proto; /**< Protocol, next header. */ uint8_t hop_limits; /**< Hop limits. */ uint8_t src_addr[16]; /**< IP address of source host. */ uint8_t dst_addr[16]; /**< IP address of destination host(s). */ uint16_t src_port; uint16_t dst_port; } __attribute__((__packed__)); /* * @struct * * To represent the entire pkt data in one structure */ struct pcp_pkt { struct ether_hdr eth; union{ struct ipv4 ipv4; struct ipv6 ipv6; }; } __attribute__((__packed__)); /** * A structure defining the PCP msg request */ struct pipeline_cgnapt_pcp_msg_req { enum pipeline_msg_req_type type; enum pipeline_cgnapt_msg_req_type subtype; /* data */ uint8_t cmd; uint32_t lifetime; }; /** * A structure defining the PCP cmd response message. */ struct pipeline_cgnapt_pcp_msg_rsp { int status; }; /* All required offsets */ enum{ MBUF_HEAD_ROOM = 256, ETH_HDR_SZ = 14, IPV4_HDR_SZ = 20, IPV6_HDR_SZ = 40, IPV4_SZ = 4, IPV6_SZ = 6, TCP_HDR_SZ = 20, UDP_HDR_SZ = 8, PCP_REQ_RESP_HDR_SZ = 24, PCP_MAP_REQ_RESP_SZ = 36, PCP_PEER_REQ_RESP_SZ = 56, }; enum{ ETH_DST_MAC = MBUF_HEAD_ROOM, ETH_SRC_MAC = MBUF_HEAD_ROOM + 6, PKT_TYPE = MBUF_HEAD_ROOM + 12, IP_OFFSET = MBUF_HEAD_ROOM + ETH_HDR_SZ, /* IPV4 Offsets */ IPV4_PROTOCOL = MBUF_HEAD_ROOM + ETH_HDR_SZ + 9, IPV4_SRC_ADD_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + 12, IPV4_DST_ADD_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + 12 + IPV4_SZ, IPV4_TCP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ, IPV4_TCP_SRC_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ, IPV4_TCP_DST_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ + 2, IPV4_UDP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ, IPV4_UDP_SRC_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ, IPV4_UDP_DST_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ + 2, IPV4_PCP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ + UDP_HDR_SZ, IPV4_PCP_MAP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ, IPV4_PCP_PEER_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV4_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ, IPV4_PCP_MAP_PL_LEN = IPV4_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ + PCP_MAP_REQ_RESP_SZ, IPV4_PCP_PEER_PL_LEN = IPV4_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ + PCP_PEER_REQ_RESP_SZ, /* IPV6 Offsets */ IPV6_PROTOCOL = MBUF_HEAD_ROOM + ETH_HDR_SZ + 6, IPV6_SRC_ADD_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + 8, IPV6_DST_ADD_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + 8 + IPV6_SZ, IPV6_TCP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ, IPV6_TCP_SRC_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ, IPV6_TCP_DST_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ + 2, IPV6_UDP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ, IPV6_UCP_SRC_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ, IPV6_UCP_DST_PORT_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ + 2, IPV6_PCP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ + UDP_HDR_SZ, IPV6_PCP_MAP_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ, IPV6_PCP_PEER_OFST = MBUF_HEAD_ROOM + ETH_HDR_SZ + IPV6_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ, IPV6_PCP_MAP_PL_LEN = IPV6_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ + PCP_MAP_REQ_RESP_SZ, IPV6_PCP_PEER_PL_LEN = IPV6_HDR_SZ + UDP_HDR_SZ + PCP_REQ_RESP_HDR_SZ + PCP_PEER_REQ_RESP_SZ, }; enum{ STATIC_CGNAPT_TIMEOUT = -1, DYNAMIC_CGNAPT_TIMEOUT = 0, }; enum PCP_RET { PCP_INIT_SUCCESS, PCP_INIT_UNSUCCESS, PCP_PCP_PKT, //PCP_PCP_PKT_SUCCESS, PCP_NOT_PCP_PKT, PCP_PKT_CORRUPT, }; uint8_t _PCP_DEBUG; uint32_t pcp_success_count; uint32_t pcp_error_count; uint32_t pcp_entry_count; uint32_t pcp_enable; uint8_t pcp_pool_init; struct rte_mempool *pcp_mbuf_pool; enum PCP_RET pcp_init(void); #ifdef __cplusplus } #endif #endif /* CGNAPT_PCP_H_ */