FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
cnat_src_policy.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 #include <cnat/cnat_src_policy.h>
17 #include <cnat/cnat_inline.h>
18 
19 #include <cnat/cnat_session.h>
20 #include <cnat/cnat_translation.h>
21 
23 
24 void
26 {
28 }
29 
32  vlib_buffer_t * b,
33  cnat_session_t * session,
34  u32 * rsession_flags,
35  const cnat_translation_t * ct,
37 {
38  ip_protocol_t iproto;
39  udp_header_t *udp0;
42 
43  if (AF_IP4 == ctx->af)
44  {
46  iproto = ip4->protocol;
47  udp0 = (udp_header_t *) (ip4 + 1);
48  }
49  else
50  {
52  iproto = ip6->protocol;
53  udp0 = (udp_header_t *) (ip6 + 1);
54  }
55 
56  int rv = 0;
57  if (!session->value.cs_port[VLIB_RX])
58  {
59  u16 sport;
60  sport = udp0->src_port;
61  /* Allocate a port only if asked and if we actually sNATed */
63  && (*rsession_flags & CNAT_SESSION_FLAG_HAS_SNAT))
64  {
65  sport = 0; /* force allocation */
67  rv = cnat_allocate_port (&sport, iproto);
68  if (rv)
70  }
71 
72  session->value.cs_port[VLIB_RX] = sport;
73  }
74  return 0;
75 }
76 
79 {
81  switch (iproto)
82  {
83  case IP_PROTOCOL_TCP:
84  return &cspm->src_ports[CNAT_SPORT_PROTO_TCP];
85  case IP_PROTOCOL_UDP:
86  return &cspm->src_ports[CNAT_SPORT_PROTO_UDP];
87  case IP_PROTOCOL_ICMP:
88  return &cspm->src_ports[CNAT_SPORT_PROTO_ICMP];
89  case IP_PROTOCOL_ICMP6:
90  return &cspm->src_ports[CNAT_SPORT_PROTO_ICMP6];
91  default:
92  return 0;
93  }
94 }
95 
96 void
98 {
100  ca = cnat_get_src_port_allocator (iproto);
101  if (!ca)
102  return;
103  clib_spinlock_lock (&ca->lock);
105  clib_spinlock_unlock (&ca->lock);
106 }
107 
108 int
110 {
111  *port = clib_net_to_host_u16 (*port);
112  if (*port == 0)
113  *port = MIN_SRC_PORT;
115  ca = cnat_get_src_port_allocator (iproto);
116  if (!ca)
117  return -1;
118  clib_spinlock_lock (&ca->lock);
119  if (clib_bitmap_get_no_check (ca->bmap, *port))
120  {
121  *port = clib_bitmap_next_clear (ca->bmap, *port);
122  if (PREDICT_FALSE (*port >= UINT16_MAX))
123  *port = clib_bitmap_next_clear (ca->bmap, MIN_SRC_PORT);
124  if (PREDICT_FALSE (*port >= UINT16_MAX))
125  {
126  clib_spinlock_unlock (&ca->lock);
127  return -1;
128  }
129  }
131  *port = clib_host_to_net_u16 (*port);
132  clib_spinlock_unlock (&ca->lock);
133  return 0;
134 }
135 
136 static clib_error_t *
138 {
142 
144  for (int i = 0; i < CNAT_N_SPORT_PROTO; i++)
145  {
147  clib_bitmap_validate (cspm->src_ports[i].bmap, UINT16_MAX);
148  }
149  /* Inject cleanup callback */
151  return (NULL);
152 }
153 
155 
156 /*
157  * fd.io coding-style-patch-verification: ON
158  *
159  * Local Variables:
160  * eval: (c-set-style "gnu")
161  * End:
162  */
clib_spinlock_init
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
cnat_src_policy_main
cnat_src_policy_main_t cnat_src_policy_main
Definition: cnat_src_policy.c:22
udp_header_t::src_port
u16 src_port
Definition: udp_packet.h:48
cnat_translation.h
cnat_vip_default_source_policy
cnat_source_policy_errors_t cnat_vip_default_source_policy(vlib_main_t *vm, vlib_buffer_t *b, cnat_session_t *session, u32 *rsession_flags, const cnat_translation_t *ct, cnat_node_ctx_t *ctx)
Definition: cnat_src_policy.c:31
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
cnat_session.h
cnat_node_ctx_
Definition: cnat_types.h:155
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
port
u16 port
Definition: lb_types.api:73
cnat_session_t_
A session represents the memory of a translation.
Definition: cnat_session.h:37
CNAT_SOURCE_ERROR_EXHAUSTED_PORTS
@ CNAT_SOURCE_ERROR_EXHAUSTED_PORTS
Definition: cnat_src_policy.h:35
CNAT_SPORT_PROTO_UDP
@ CNAT_SPORT_PROTO_UDP
Definition: cnat_src_policy.h:27
udp_header_t
Definition: udp_packet.h:45
ip4_header_t
Definition: ip4_packet.h:87
sport
u16 sport
Definition: pnat.api:43
cnat_register_vip_src_policy
void cnat_register_vip_src_policy(cnat_vip_source_policy_t fp)
Definition: cnat_src_policy.c:25
cnat_vip_source_policy_t
cnat_source_policy_errors_t(* cnat_vip_source_policy_t)(vlib_main_t *vm, vlib_buffer_t *b, cnat_session_t *session, u32 *rsession_flags, const cnat_translation_t *ct, cnat_node_ctx_t *ctx)
Definition: cnat_src_policy.h:50
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
clib_spinlock_lock
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:82
cnat_src_port_allocator_::bmap
clib_bitmap_t * bmap
Definition: cnat_src_policy.h:42
CNAT_SESSION_FLAG_HAS_SNAT
@ CNAT_SESSION_FLAG_HAS_SNAT
Indicates a return path session that was source NATed on the way in.
Definition: cnat_session.h:116
CNAT_N_SPORT_PROTO
@ CNAT_N_SPORT_PROTO
Definition: cnat_src_policy.h:30
cnat_src_policy_main_::src_ports
cnat_src_port_allocator_t * src_ports
Definition: cnat_src_policy.h:60
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
CNAT_SPORT_PROTO_TCP
@ CNAT_SPORT_PROTO_TCP
Definition: cnat_src_policy.h:26
cnat_inline.h
cnat_allocate_port
int cnat_allocate_port(u16 *port, ip_protocol_t iproto)
Definition: cnat_src_policy.c:109
cnat_src_policy_main_::vip_policy
cnat_vip_source_policy_t vip_policy
Definition: cnat_src_policy.h:56
CNAT_TRANSLATION_FLAG_ALLOCATE_PORT
@ CNAT_TRANSLATION_FLAG_ALLOCATE_PORT
Definition: cnat_translation.h:63
clib_bitmap_get_no_check
static uword clib_bitmap_get_no_check(uword *ai, uword i)
Gets the ith bit value from a bitmap Does not sanity-check the bit position.
Definition: bitmap.h:212
clib_bitmap_validate
#define clib_bitmap_validate(v, n_bits)
Definition: bitmap.h:115
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
MIN_SRC_PORT
#define MIN_SRC_PORT
Definition: cnat_types.h:56
cnat_session_t_::flags
u32 flags
session flags
Definition: cnat_session.h:104
cnat_src_port_allocator_::lock
clib_spinlock_t lock
Definition: cnat_src_policy.h:45
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
cnat_src_policy_init
static clib_error_t * cnat_src_policy_init(vlib_main_t *vm)
Definition: cnat_src_policy.c:137
CNAT_SESSION_FLAG_ALLOC_PORT
@ CNAT_SESSION_FLAG_ALLOC_PORT
This session source port was allocated, free it on cleanup.
Definition: cnat_session.h:120
ip6
vl_api_ip6_address_t ip6
Definition: one.api:424
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
cnat_src_port_allocator_
Definition: cnat_src_policy.h:39
cnat_src_policy_main_::default_policy
cnat_vip_source_policy_t default_policy
Definition: cnat_src_policy.h:57
CNAT_SPORT_PROTO_ICMP
@ CNAT_SPORT_PROTO_ICMP
Definition: cnat_src_policy.h:28
clib_spinlock_unlock
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:121
ip6_header_t
Definition: ip6_packet.h:294
ip_protocol_t
enum ip_protocol ip_protocol_t
vlib_main_t
Definition: main.h:102
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
CNAT_SPORT_PROTO_ICMP6
@ CNAT_SPORT_PROTO_ICMP6
Definition: cnat_src_policy.h:29
clib_error_t
Definition: clib_error.h:21
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
cnat_source_policy_errors_t
enum cnat_source_policy_errors_ cnat_source_policy_errors_t
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
i
int i
Definition: flowhash_template.h:376
cnat_src_policy.h
cnat_get_src_port_allocator
static cnat_src_port_allocator_t * cnat_get_src_port_allocator(ip_protocol_t iproto)
Definition: cnat_src_policy.c:78
rv
int __clib_unused rv
Definition: application.c:491
cnat_session_t_::value
struct cnat_session_t_::@646 value
this value sits in the same memory location a 'value' in the bihash kvp
cnat_translation_t_::flags
u8 flags
Translation flags.
Definition: cnat_translation.h:163
clib_bitmap_set_no_check
static uword clib_bitmap_set_no_check(uword *a, uword i, uword new_value)
Sets the ith bit of a bitmap to new_value.
Definition: bitmap.h:141
cnat_free_port
void cnat_free_port(u16 port, ip_protocol_t iproto)
Definition: cnat_src_policy.c:97
cnat_free_port_cb
void(* cnat_free_port_cb)(u16 port, ip_protocol_t iproto)
Port cleanup callback.
Definition: cnat_session.c:24
cnat_translation_t_
A Translation represents the translation of a VEP to one of a set of real server addresses.
Definition: cnat_translation.h:117
cnat_src_policy_main_
Definition: cnat_src_policy.h:54
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
cnat_session_t_::cs_port
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
Definition: cnat_session.h:52