2 *------------------------------------------------------------------
5 * Copyright (c) 2009-2012 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
20 #ifndef __CNAT_PCP_SERVER_H__
21 #define __CNAT_PCP_SERVER_H__
23 #include "dslite_defs.h"
25 /* Debug utils of PCP */
26 #define PCP_DBG(debug, ...) \
27 if(PREDICT_FALSE(cnat_pcp_debug_flag >= debug)) { \
28 printf("%s:%s:%d - ", \
29 __FILE__, __FUNCTION__, __LINE__);\
34 #define PCP_DUMP_PDATA \
35 if(PREDICT_FALSE(cnat_pcp_debug_flag >= 100)) { \
36 printf("%s:%s:%d - \n", \
37 __FILE__, __FUNCTION__, __LINE__);\
38 printf("src - ip = %X, proto = %d, port = %d i_vrf = %d, o_vrf = %d\n", \
39 pcp_data.src_ip[3], pcp_data.proto, pcp_data.src_port, pcp_data.i_vrf, pcp_data.o_vrf); \
40 printf(" third party ip = %X\n", pcp_data.third_party_ip[3]); \
41 printf("map - ip = %X, port = %d \n", \
42 pcp_data.ext_ip[3], pcp_data.ext_port);\
43 printf("remote - ip = %X, port = %d \n", \
44 pcp_data.peer_ip[3], pcp_data.peer_port); \
45 printf("req life time = %d \n", pcp_data.req_lifetime); \
46 printf("drop = %d \n", pcp_data.drop);\
47 printf("udp_len = %d \n", pcp_data.udp_len); \
48 printf("pm = %p \n", pcp_data.pm); \
49 printf("cnat_proto = %X \n", pcp_data.cnat_proto); \
50 printf("inst_id = %X \n", pcp_data.inst_id); \
51 printf("======================================================\n"); \
54 #define PCP_DUMP_PACKET(ip, len) pcp_hex_dump(ip, len)
57 #define PCP_INCR(counter) pcp_counters.pcp_##counter++ ;
59 #define PCP_INCR(counter)
62 typedef struct pcp_debug_counters {
65 u64 pcp_service_nat44;
66 u64 pcp_service_dslite;
67 /* below all are drops */
69 u64 pcp_i2o_key_inuse;
70 u64 pcp_throttle_drops;
76 u64 pcp_invalid_3rd_len;
77 u64 pcp_invalid_option;
79 u64 pcp_invalid_opcode;
80 u64 pcp_invalid_client_ip;
81 u64 pcp_invalid_proto;
83 u64 pcp_invalid_vrfmap;
84 u64 pcp_invalid_ext_addr;
85 u64 pcp_out_addr_inuse;
87 u64 pcp_exact_entry_created;
88 u64 pcp_exact_db_alloc_failed;
90 u64 pcp_noexact_db_allocated;
91 u64 pcp_static_entry_present;
92 u64 pcp_entry_deleted;
93 u64 pcp_3rd_party_option;
99 u64 pcp_map_invalid_option;
100 u64 pcp_map_invalid_option_len;
101 u64 pcp_map_pref_fail_option;
102 u64 pcp_map_invalid_delete_req;
103 u64 pcp_map_delete_req;
104 u64 pcp_map_create_req;
109 u64 pcp_peer_invalid_len;
110 u64 pcp_peer_delete_req;
111 u64 pcp_peer_create_req;
112 u64 pcp_peer_addr_mistmatch;
113 u64 pcp_peer_refresh;
115 } pcp_debug_counters_t;
122 /* better to have a group structures rather than individual
123 variables, any change in counters is will automatically
125 pcp_debug_counters_t counters;
126 } pcp_show_counters_resp_t ;
131 typedef enum pcp_opcode {
138 typedef enum pcp_options {
139 PCP_OPTION_3RD_PARTY = 1,
140 PCP_OPTION_PREF_FAIL = 2,
141 PCP_OPTION_FILTER = 3
144 /* PCP Result codes */
145 typedef enum pcp_result_codes {
147 PCP_ERR_UNSUPP_VERSION = 1,
148 PCP_ERR_NOT_AUTHORIZED = 2,
149 PCP_ERR_MALFORMED_REQUEST = 3,
150 PCP_ERR_UNSUPP_OPCODE = 4,
151 PCP_ERR_UNSUPP_OPTION = 5,
152 PCP_ERR_MALFORMED_OPTION = 6,
153 PCP_ERR_NETWORK_FAILURE = 7,
154 PCP_ERR_NO_RESOURCES = 8,
155 PCP_ERR_UNSUPP_PROTOCOL = 9,
156 PCP_ERR_USER_EX_QUOTA = 10,
157 PCP_ERR_CANNOT_PROVIDE_EXTERNAL = 11,
158 PCP_ERR_ADDRESS_MISMATCH = 12,
159 PCP_ERR_EXCESSIVE_REMOTE_PEERS = 13
160 } pcp_result_codes_t;
162 #define PCP_DISABLED 0
163 #define PCP_ENABLED 1
167 #define PCP_STATIC_LIFETIME 0xFFFFFFFF
168 #define PCP_MAX_LIFETIME 0x00015180 /* 24 hours = 86400 seconds*/
170 #define PCP_VERSION_SUPPORTED 1
172 #define PCP_NO_PREF_FAIL_OPTION 0
173 #define PCP_PREF_FAIL_OPTION 1
175 #define CNAT_DEF_PCP_PORT 5351
177 #define PCP_REQ_RESP_BIT 0x80
178 #define PCP_RESPONSE(r_opcode) (r_opcode & PCP_REQ_RESP_BIT)
179 #define PCP_REQUEST(r_opcode) !(PCP_RESPONSE(r_opcode))
181 #define PCP_REQ_OPCODE(r_opcode) (r_opcode & 0x7F)
184 #define PCP_COMMON_HDR_LEN sizeof(pcp_request_t)
187 #define UDP_HDR_LEN sizeof(udp_hdr_type_t)
189 #define PCP_PREF_FAIL_OPTION_SIZE \
190 sizeof(pcp_prefer_fail_option_t)
192 #define PCP_3RD_PARTY_OPTION_SIZE \
193 sizeof(pcp_3rd_party_option_t)
195 #define PCP_MIN_LEN PCP_COMMON_HDR_LEN
198 #define PCP_MIN_UDP_LEN (PCP_MIN_LEN + UDP_HDR_LEN)
200 #define PCP_MAX_LEN 1024
202 /* 1024+8 = 1032 bytes */
203 #define PCP_MAX_UDP_LEN (PCP_MAX_LEN + UDP_HDR_LEN)
205 /* 24+ 24 = 48 bytes */
206 #define PCP_MAP_OPCODE_MIN_LEN (PCP_COMMON_HDR_LEN + \
207 sizeof( pcp_map_option_specific_data_t))
209 /* 24 + 44 = 68 bytes */
210 #define PCP_PEER_OPCODE_MIN_LEN (PCP_COMMON_HDR_LEN + \
211 sizeof( pcp_peer_option_specific_data_t))
213 /* 48 + 8 = 56 bytes */
214 #define PCP_MAP_OPCODE_MIN_UDP_LEN (PCP_MAP_OPCODE_MIN_LEN + \
217 #define PCP_GET_MAP_OPTION_OFFSET(req) \
218 ((u8*)req + PCP_MAP_OPCODE_MIN_LEN)
220 #define PCP_GET_PEER_OPTION_OFFSET(req) \
221 ((u8*)req + PCP_PEER_OPCODE_MIN_LEN)
224 #define PCP_REQ_TOTAL_LEN(udp) (udp->udp_length - \
226 /* 56 + 4 = 60 bytes */
227 #define PCP_MAP_OPCODE_PREF_FAIL_OPTION_LEN \
228 (PCP_MAP_OPCODE_MIN_UDP_LEN + \
229 sizeof(pcp_prefer_fail_option_t))
232 /* 68 + 8 = 76 bytes */
233 #define PCP_PEER_OPCODE_MIN_UDP_LEN (PCP_PEER_OPCODE_MIN_LEN + \
236 #define PCP_MUST_OPTION(option_code) (option_code & 0x80)
241 #define PCP_DSLITE_MAP_OPCODE_MIN_UDP_LEN \
242 ( PCP_MAP_OPCODE_MIN_UDP_LEN + \
243 PCP_3RD_PARTY_OPTION_SIZE)
246 #define PCP_DSLITE_MAP_OPCODE_MAX_UDP_LEN \
247 ( PCP_MAP_OPCODE_PREF_FAIL_OPTION_LEN + \
248 PCP_3RD_PARTY_OPTION_SIZE)
251 #define PCP_DSLITE_PEER_OPCODE_MIN_UDP_LEN \
252 ( PCP_PEER_OPCODE_MIN_UDP_LEN + \
253 PCP_3RD_PARTY_OPTION_SIZE)
256 #define PCP_SET_CNAT_PROTO(proto) \
257 pcp_data.cnat_proto = (proto == TCP_PROT) ? CNAT_TCP: \
258 (proto == UDP_PROT)? CNAT_UDP : CNAT_ICMP;
260 #define PCP_SET_REQ_LIFETIME() \
261 if(pcp_data.db->flags & CNAT_DB_FLAG_STATIC_PORT) { \
262 pcp_data.db->proto_data.seq_pcp.pcp_lifetime = \
263 PCP_STATIC_LIFETIME; \
264 pcp_data.req_lifetime = PCP_STATIC_LIFETIME; \
266 pcp_data.db->proto_data.seq_pcp.pcp_lifetime = \
267 pcp_data.req_lifetime + cnat_current_time ; \
271 /* per second not more than PCP_THROTTLE_LIMIT
272 * delete requests will be handled.
273 * this excludes , specific entries, in which
274 * only one entry needs to be deleted
276 #define PCP_THROTTLE_LIMIT 2
278 typedef struct pcp_request {
283 u32 ip[4]; /* ipv4 will be represented
284 by the ipv4 mapped ipv6 */
287 typedef struct pcp_response {
298 typedef struct pcp_options_hdr {
306 /* same for both request and response */
307 typedef struct pcp_map_option_specific_data {
312 u32 ext_ip[4]; /* ipv4 will be represnted
313 by the ipv4 mapped ipv6 */
314 } pcp_map_option_specific_data_t;
316 /* same for both request and response */
317 typedef struct pcp_peer_option_specific_data {
322 u32 ext_ip[4]; /* ipv4 will be represented
323 by the ipv4 mapped ipv6 */
327 } pcp_peer_option_specific_data_t;
329 typedef struct pcp_prefer_fail_option {
333 } pcp_prefer_fail_option_t;
336 typedef struct pcp_3rd_party_option{
341 } pcp_3rd_party_option_t;
343 /* structure used as pipeline data */
345 typedef struct pcp_pipeline_data {
351 ipv6_header_t *ipv6 ;
357 pcp_response_t *resp;
366 u32 third_party_ip[4];
368 /* valid for peer opcode */
373 pcp_options_t pref_fail;
374 pcp_options_t third_party;
376 pcp_result_codes_t ret_code;
377 cnat_portmap_v2_t *pm;
378 cnat_main_db_entry_t *db;
379 cnat_vrfmap_t *vrfmap;
380 dslite_table_entry_t *inst_ptr;
385 /* is packet needs to be dropped ? */
387 /* nat44, dslite, nat64 */
388 #define PCP_SERVICE_NAT44 1
389 #define PCP_SERVICE_DSLITE 2
390 #define PCP_SERVICE_NAT64 3
393 #define PCP_REQ_ENTRY_PRESENT 1
394 #define PCP_REQ_EXT_MAP_PRESENT 1
396 } pcp_pipeline_data_t;
398 #endif /* __CNAT_PCP_sERVER_H__ */