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