Initial commit of vpp code.
[vpp.git] / vnet / vnet / vcgn / cnat_pcp_server.h
1 /*
2  *------------------------------------------------------------------
3  * cnat_pcp_server.h
4  *
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:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
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  *------------------------------------------------------------------
18  */
19
20 #ifndef __CNAT_PCP_SERVER_H__
21 #define __CNAT_PCP_SERVER_H__ 
22
23 #include "dslite_defs.h"
24
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__);\
30                     printf(__VA_ARGS__);\
31                     printf("\n"); \
32             } 
33
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"); \
52   }
53
54 #define PCP_DUMP_PACKET(ip, len) pcp_hex_dump(ip, len)
55
56 #ifdef TOBE_PORTED
57 #define PCP_INCR(counter) pcp_counters.pcp_##counter++  ;
58 #else
59 #define PCP_INCR(counter) 
60 #endif
61
62 typedef struct pcp_debug_counters {
63    u64 pcp_input;
64    u64 pcp_output;
65    u64 pcp_service_nat44;
66    u64 pcp_service_dslite;
67    /* below all are drops */
68    u64 pcp_drops;
69    u64 pcp_i2o_key_inuse;
70    u64 pcp_throttle_drops;
71    u64 pcp_udp_len;
72    u64 pcp_nrequest;
73    u64 pcp_min_udp_len;
74    u64 pcp_max_udp_len;
75    u64 pcp_mod4_len;
76    u64 pcp_invalid_3rd_len;  
77    u64 pcp_invalid_option;  
78    u64 pcp_version;
79    u64 pcp_invalid_opcode;
80    u64 pcp_invalid_client_ip;
81    u64 pcp_invalid_proto;
82    u64 pcp_invalid_port;
83    u64 pcp_invalid_vrfmap;
84    u64 pcp_invalid_ext_addr;
85    u64 pcp_out_addr_inuse;
86    u64 pcp_exact_match;
87    u64 pcp_exact_entry_created;
88    u64 pcp_exact_db_alloc_failed;
89    u64 pcp_udb_mismatch;
90    u64 pcp_noexact_db_allocated;
91    u64 pcp_static_entry_present;
92    u64 pcp_entry_deleted;
93    u64 pcp_3rd_party_option;
94
95    /* map counters */
96    u64 pcp_map_input;
97    u64 pcp_map_min_len;
98    u64 pcp_map_max_len;
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;
105    u64 pcp_map_refresh;
106
107    /* peer counters */
108    u64 pcp_peer_input;
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;
114
115 } pcp_debug_counters_t;
116
117 typedef struct {
118     u16 msg_id;
119     u8 rc;
120     u8 pad[5];
121
122     /* better to have a group structures rather than individual
123        variables, any change in counters is will automatically
124        reflect here */
125     pcp_debug_counters_t counters;
126 } pcp_show_counters_resp_t ;
127
128
129
130 /* PCP opcodes */
131 typedef enum pcp_opcode  {
132   PCP_OPCODE_MAP = 1, 
133   PCP_OPCODE_PEER = 2 
134 }pcp_opcode_t;
135
136
137 /* PCP opcodes */
138 typedef enum pcp_options  {
139   PCP_OPTION_3RD_PARTY = 1,
140   PCP_OPTION_PREF_FAIL = 2, 
141   PCP_OPTION_FILTER = 3
142 } pcp_options_t;
143
144 /* PCP Result codes */
145 typedef enum pcp_result_codes  {
146     PCP_SUCCESS = 0,
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;
161
162 #define PCP_DISABLED  0 
163 #define PCP_ENABLED   1
164
165 #define PCP_DROP  1
166
167 #define PCP_STATIC_LIFETIME  0xFFFFFFFF
168 #define PCP_MAX_LIFETIME 0x00015180       /* 24 hours = 86400 seconds*/
169
170 #define PCP_VERSION_SUPPORTED    1
171
172 #define PCP_NO_PREF_FAIL_OPTION     0 
173 #define PCP_PREF_FAIL_OPTION        1 
174  
175 #define CNAT_DEF_PCP_PORT 5351  
176
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)) 
180
181 #define PCP_REQ_OPCODE(r_opcode)  (r_opcode & 0x7F)
182
183 /* 24 bytes */
184 #define PCP_COMMON_HDR_LEN   sizeof(pcp_request_t)  
185
186 /* 8 bytes */
187 #define UDP_HDR_LEN          sizeof(udp_hdr_type_t)
188
189 #define PCP_PREF_FAIL_OPTION_SIZE    \
190                        sizeof(pcp_prefer_fail_option_t) 
191
192 #define PCP_3RD_PARTY_OPTION_SIZE   \
193                        sizeof(pcp_3rd_party_option_t) 
194
195 #define PCP_MIN_LEN          PCP_COMMON_HDR_LEN 
196
197 /* 24+8=32 bytes */ 
198 #define PCP_MIN_UDP_LEN      (PCP_MIN_LEN + UDP_HDR_LEN)
199
200 #define PCP_MAX_LEN          1024
201
202 /* 1024+8 = 1032 bytes */
203 #define PCP_MAX_UDP_LEN      (PCP_MAX_LEN + UDP_HDR_LEN) 
204
205 /* 24+ 24 = 48 bytes */
206 #define PCP_MAP_OPCODE_MIN_LEN  (PCP_COMMON_HDR_LEN + \
207                sizeof( pcp_map_option_specific_data_t))
208
209 /* 24 + 44 = 68 bytes */
210 #define PCP_PEER_OPCODE_MIN_LEN  (PCP_COMMON_HDR_LEN + \
211                sizeof( pcp_peer_option_specific_data_t))
212
213 /* 48 + 8 = 56 bytes */
214 #define PCP_MAP_OPCODE_MIN_UDP_LEN (PCP_MAP_OPCODE_MIN_LEN + \
215                     UDP_HDR_LEN )
216
217 #define PCP_GET_MAP_OPTION_OFFSET(req)   \
218              ((u8*)req + PCP_MAP_OPCODE_MIN_LEN)
219
220 #define PCP_GET_PEER_OPTION_OFFSET(req)   \
221              ((u8*)req + PCP_PEER_OPCODE_MIN_LEN)
222
223
224 #define PCP_REQ_TOTAL_LEN(udp)  (udp->udp_length - \
225                                  UDP_HDR_LEN) 
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))
230
231
232 /* 68 + 8 = 76 bytes */
233 #define PCP_PEER_OPCODE_MIN_UDP_LEN  (PCP_PEER_OPCODE_MIN_LEN + \
234                                         UDP_HDR_LEN)
235
236 #define PCP_MUST_OPTION(option_code)  (option_code & 0x80)
237
238
239
240 /* 56 + 20 = 76*/
241 #define PCP_DSLITE_MAP_OPCODE_MIN_UDP_LEN \
242             ( PCP_MAP_OPCODE_MIN_UDP_LEN + \
243               PCP_3RD_PARTY_OPTION_SIZE)
244
245 /* 60 + 20 = 80 */
246 #define PCP_DSLITE_MAP_OPCODE_MAX_UDP_LEN \
247         ( PCP_MAP_OPCODE_PREF_FAIL_OPTION_LEN + \
248           PCP_3RD_PARTY_OPTION_SIZE)
249
250 /* 76 + 20 = 96 */ 
251 #define PCP_DSLITE_PEER_OPCODE_MIN_UDP_LEN \
252             ( PCP_PEER_OPCODE_MIN_UDP_LEN + \
253               PCP_3RD_PARTY_OPTION_SIZE)
254
255
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;
259
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; \
265         } else { \
266             pcp_data.db->proto_data.seq_pcp.pcp_lifetime = \
267             pcp_data.req_lifetime + cnat_current_time ; \
268         }
269
270
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
275  */
276 #define PCP_THROTTLE_LIMIT    2
277
278 typedef struct pcp_request {
279   u8     ver;
280   u8     r_opcode;
281   u16    reserved;
282   u32    req_lifetime;
283   u32    ip[4]; /* ipv4 will be represented 
284                  by the ipv4 mapped ipv6 */
285 } pcp_request_t;
286
287 typedef struct pcp_response {
288   u8     ver;
289   u8     r_opcode;
290   u8     reserved;
291   u8     result_code;
292   u32    lifetime;
293   u32    epochtime;
294   u32    reserved1[3];
295 } pcp_response_t;
296
297
298 typedef struct pcp_options_hdr {
299   u8     code;
300   u8     reserved;
301   u16    len;
302   u8     data[0];
303 } pcp_options_hdr_t;
304
305
306 /* same for both request and response */
307 typedef struct pcp_map_option_specific_data {
308   u8     protocol; 
309   u8     reserved[3];
310   u16    int_port;
311   u16    ext_port;
312   u32    ext_ip[4]; /* ipv4 will be represnted
313                  by the ipv4 mapped ipv6 */
314 } pcp_map_option_specific_data_t;
315
316 /* same for both request and response */
317 typedef struct pcp_peer_option_specific_data {
318   u8     protocol;
319   u8     reserved[3];
320   u16    int_port;
321   u16    ext_port;
322   u32    ext_ip[4]; /* ipv4 will be represented
323                  by the ipv4 mapped ipv6 */
324   u16    peer_port;
325   u16    reserved1;
326   u32    peer_ip[4];
327 } pcp_peer_option_specific_data_t;
328
329 typedef struct pcp_prefer_fail_option {
330    u8 option;
331    u8 reserved;
332    u16 len;
333 } pcp_prefer_fail_option_t;
334
335
336 typedef struct pcp_3rd_party_option{
337    u8 option;
338    u8 reserved;
339    u16 len;
340    u32 ip[4];
341 } pcp_3rd_party_option_t;
342
343 /* structure used as pipeline data */
344
345 typedef struct pcp_pipeline_data {
346
347    union {
348
349     u8 *p;
350     ipv4_header *ip ;
351     ipv6_header_t *ipv6 ;
352
353    } l3addr; 
354
355    udp_hdr_type_t *udp;
356    pcp_request_t *req;
357    pcp_response_t *resp;
358    pcp_opcode_t opcode;
359    u32   src_ip[4];
360    u16   src_port;
361    u8    proto;
362    u16   i_vrf;
363    u16   o_vrf;
364    u32   ext_ip[4];
365    u16   ext_port;
366    u32   third_party_ip[4];
367    
368    /* valid for peer opcode */
369    u32   peer_ip[4];
370    u32   peer_port;
371    u32   req_lifetime;
372    u32 udp_len;
373    pcp_options_t  pref_fail;
374    pcp_options_t  third_party;
375    u8             *option_spec;
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;
381    u16 inst_id;
382    u32  flags;
383    u16  cnat_proto;
384
385   /* is packet needs to be dropped ? */
386    u8   drop;
387    /* nat44, dslite, nat64 */
388 #define PCP_SERVICE_NAT44    1
389 #define PCP_SERVICE_DSLITE   2 
390 #define PCP_SERVICE_NAT64    3 
391    u8   service_type;
392
393 #define PCP_REQ_ENTRY_PRESENT  1
394 #define PCP_REQ_EXT_MAP_PRESENT  1
395    u8   state;
396 } pcp_pipeline_data_t; 
397
398 #endif /* __CNAT_PCP_sERVER_H__ */