nat: pnat copy and clear byte instructions
[vpp.git] / src / plugins / nat / pnat / pnat.h
1 /*
2  * Copyright (c) 2021 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef included_pnat_h
17 #define included_pnat_h
18
19 #include <stdbool.h>
20 #include <vnet/ip/ip4_packet.h>
21 #include <vppinfra/bihash_16_8.h>
22
23 #define PNAT_FLOW_HASH_BUCKETS 256
24
25 /* Definitions from pnat.api */
26 #include <pnat/pnat.api_types.h>
27 typedef vl_api_pnat_match_tuple_t pnat_match_tuple_t;
28 typedef vl_api_pnat_rewrite_tuple_t pnat_rewrite_tuple_t;
29 typedef vl_api_pnat_mask_t pnat_mask_t;
30 typedef vl_api_pnat_attachment_point_t pnat_attachment_point_t;
31
32 /* Rewrite instructions */
33 typedef enum {
34     PNAT_INSTR_NONE = 1 << 0,
35     PNAT_INSTR_SOURCE_ADDRESS = 1 << 1,
36     PNAT_INSTR_SOURCE_PORT = 1 << 2,
37     PNAT_INSTR_DESTINATION_ADDRESS = 1 << 3,
38     PNAT_INSTR_DESTINATION_PORT = 1 << 4,
39     PNAT_INSTR_COPY_BYTE = 1 << 5,
40     PNAT_INSTR_CLEAR_BYTE = 1 << 6,
41 } pnat_instructions_t;
42
43 typedef struct {
44     u64 as_u64[2];
45 } pnat_mask_fast_t;
46
47 /* Session cache entries */
48 typedef struct {
49     /* What to translate to */
50     pnat_instructions_t instructions;
51
52     /* Stored in network byte order */
53     ip4_address_t post_sa;
54     ip4_address_t post_da;
55     u16 post_sp;
56     u16 post_dp;
57
58     /* Byte copy inside of packet */
59     u8 from_offset;
60     u8 to_offset;
61
62     u8 clear_offset; /* Clear byte */
63
64     /* Used for trace/show commands */
65     pnat_match_tuple_t match;
66     pnat_rewrite_tuple_t rewrite;
67 } pnat_translation_t;
68
69 /* Interface object */
70 typedef struct {
71     u32 sw_if_index;
72     pnat_mask_t lookup_mask[PNAT_ATTACHMENT_POINT_MAX];
73     pnat_mask_fast_t lookup_mask_fast[PNAT_ATTACHMENT_POINT_MAX];
74
75     /* Feature chain enabled on interface */
76     bool enabled[PNAT_ATTACHMENT_POINT_MAX];
77
78     u32 refcount;
79 } pnat_interface_t;
80
81 /* Globals */
82 typedef struct {
83     bool enabled;
84
85     clib_bihash_16_8_t flowhash; /* Bi-directional */
86
87     /* Interface pool */
88     pnat_interface_t *interfaces;
89     u32 *interface_by_sw_if_index;
90
91     /* Translations pool */
92     pnat_translation_t *translations;
93
94     u16 msg_id_base;
95 } pnat_main_t;
96 extern pnat_main_t pnat_main;
97
98 pnat_interface_t *pnat_interface_by_sw_if_index(u32 sw_if_index);
99
100 /* Packet trace information */
101 typedef struct {
102     u32 pool_index;
103     pnat_match_tuple_t match;
104     pnat_rewrite_tuple_t rewrite;
105 } pnat_trace_t;
106
107 int pnat_binding_add(pnat_match_tuple_t *match, pnat_rewrite_tuple_t *rewrite,
108                      u32 *binding_index);
109 int pnat_binding_del(u32 binding_index);
110 int pnat_binding_attach(u32 sw_if_index, pnat_attachment_point_t attachment,
111                         u32 binding_index);
112 int pnat_binding_detach(u32 sw_if_index, pnat_attachment_point_t attachment,
113                         u32 binding_index);
114 u32 pnat_flow_lookup(u32 sw_if_index, pnat_attachment_point_t attachment,
115                      pnat_match_tuple_t *match);
116
117 static inline void
118 pnat_calc_key(u32 sw_if_index, pnat_attachment_point_t attachment,
119               ip4_address_t src, ip4_address_t dst, u8 protocol, u16 sport,
120               u16 dport, pnat_mask_fast_t mask, clib_bihash_kv_16_8_t *kv) {
121     kv->key[0] = (u64)src.as_u32 << 32 | dst.as_u32;
122     kv->key[0] &= mask.as_u64[0];
123     kv->key[1] =
124         (u64)protocol << 56 | (u64)sw_if_index << 36 | (u64)attachment << 32;
125     kv->key[1] |= (u32)sport << 16 | dport;
126     kv->key[1] &= mask.as_u64[1];
127 }
128
129 #endif