FD.io VPP  v21.01.1
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 {
27  cnat_src_policy_main.vip_policy = fp;
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  {
45  ip4 = vlib_buffer_get_current (b);
46  iproto = ip4->protocol;
47  udp0 = (udp_header_t *) (ip4 + 1);
48  }
49  else
50  {
51  ip6 = vlib_buffer_get_current (b);
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);
104  clib_bitmap_set_no_check (ca->bmap, port, 0);
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  return -1;
126  }
127  clib_bitmap_set_no_check (ca->bmap, *port, 1);
128  *port = clib_host_to_net_u16 (*port);
129  clib_spinlock_unlock (&ca->lock);
130  return 0;
131 }
132 
133 static clib_error_t *
135 {
139 
141  for (int i = 0; i < CNAT_N_SPORT_PROTO; i++)
142  {
144  clib_bitmap_validate (cspm->src_ports[i].bmap, UINT16_MAX);
145  }
146  /* Inject cleanup callback */
148  return (NULL);
149 }
150 
152 
153 /*
154  * fd.io coding-style-patch-verification: ON
155  *
156  * Local Variables:
157  * eval: (c-set-style "gnu")
158  * End:
159  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
int cnat_allocate_port(u16 *port, ip_protocol_t iproto)
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
Definition: lock.h:121
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
Definition: lock.h:82
This session source port was allocated, free it on cleanup.
Definition: cnat_session.h:120
void(* cnat_free_port_cb)(u16 port, ip_protocol_t iproto)
Port cleanup callback.
Definition: cnat_session.c:25
cnat_src_policy_main_t cnat_src_policy_main
static cnat_src_port_allocator_t * cnat_get_src_port_allocator(ip_protocol_t iproto)
u16 cs_port[VLIB_N_DIR]
ports in rx/tx
Definition: cnat_session.h:53
A Translation represents the translation of a VEP to one of a set of real server addresses.
void cnat_free_port(u16 port, ip_protocol_t iproto)
vlib_main_t * vm
Definition: in2out_ed.c:1580
enum cnat_source_policy_errors_ cnat_source_policy_errors_t
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
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
#define clib_bitmap_validate(v, n_bits)
Definition: bitmap.h:115
A session represents the memory of a translation.
Definition: cnat_session.h:38
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vl_api_ip6_address_t ip6
Definition: one.api:424
const cJSON *const b
Definition: cJSON.h:255
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)
unsigned int u32
Definition: types.h:88
cnat_src_port_allocator_t * src_ports
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
Indicates a return path session that was source NATed on the way in.
Definition: cnat_session.h:116
enum ip_protocol ip_protocol_t
long ctx[MAX_CONNS]
Definition: main.c:144
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:233
#define PREDICT_FALSE(x)
Definition: clib.h:121
#define always_inline
Definition: ipsec.h:28
vl_api_ip4_address_t ip4
Definition: one.api:376
#define MIN_SRC_PORT
Definition: cnat_types.h:52
cnat_vip_source_policy_t default_policy
ip_address_family_t af
Definition: cnat_types.h:164
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
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)
u32 flags
session flags if cs_lbi == INDEX_INVALID
Definition: cnat_session.h:100
void cnat_register_vip_src_policy(cnat_vip_source_policy_t fp)
VLIB buffer representation.
Definition: buffer.h:102
u16 port
Definition: lb_types.api:73
u8 flags
Translation flags.
Definition: defs.h:46
cnat_vip_source_policy_t vip_policy
struct cnat_session_t_::@633 value
this value sits in the same memory location a &#39;value&#39; in the bihash kvp
static clib_error_t * cnat_src_policy_init(vlib_main_t *vm)