FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
dslite.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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 #include <nat/dslite.h>
16 #include <nat/dslite_dpo.h>
17 #include <vnet/fib/fib_table.h>
18 
20 
21 void
23 {
27  uword *p;
28  vlib_node_t *node;
30  u32 translation_buckets = 1024;
31  u32 translation_memory_size = 128 << 20;
32  u32 b4_buckets = 128;
33  u32 b4_memory_size = 64 << 20;
34 
35  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out");
36  dm->dslite_in2out_node_index = node->index;
37 
38  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out-slowpath");
40 
41  node = vlib_get_node_by_name (vm, (u8 *) "dslite-out2in");
42  dm->dslite_out2in_node_index = node->index;
43 
44  dm->first_worker_index = 0;
45  dm->num_workers = 0;
46 
47  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
48  if (p)
49  {
50  tr = (vlib_thread_registration_t *) p[0];
51  if (tr)
52  {
53  dm->num_workers = tr->count;
55  }
56  }
57 
58  if (dm->num_workers)
59  dm->port_per_thread = (0xffff - 1024) / dm->num_workers;
60  else
61  dm->port_per_thread = 0xffff - 1024;
62 
64 
65  /* *INDENT-OFF* */
67  {
68  clib_bihash_init_24_8 (&td->in2out, "in2out", translation_buckets,
69  translation_memory_size);
70 
71  clib_bihash_init_8_8 (&td->out2in, "out2in", translation_buckets,
72  translation_memory_size);
73 
74  clib_bihash_init_16_8 (&td->b4_hash, "b4s", b4_buckets, b4_memory_size);
75  }
76  /* *INDENT-ON* */
77 
78  dm->is_ce = 0;
79 
80  /* Init counters */
81  dm->total_b4s.name = "total-b4s";
82  dm->total_b4s.stat_segment_name = "/dslite/total-b4s";
85  dm->total_sessions.name = "total-sessions";
86  dm->total_sessions.stat_segment_name = "/dslite/total-sessions";
89 
91 }
92 
93 void
95 {
96  dm->is_ce = (set != 0);
97 }
98 
99 int
101 {
102  dpo_id_t dpo = DPO_INVALID;
103 
104  if (dm->is_ce)
105  {
107  fib_prefix_t pfx = {
109  .fp_len = 0,
110  .fp_addr.ip4.as_u32 = 0,
111  };
114  }
115  else
116  {
117  dslite_dpo_create (DPO_PROTO_IP6, 0, &dpo);
118  fib_prefix_t pfx = {
120  .fp_len = 128,
121  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
122  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
123  };
126  }
127 
128  dpo_reset (&dpo);
129 
130  dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0];
131  dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1];
132  return 0;
133 }
134 
135 int
137 {
138  dm->aftr_ip4_addr.as_u32 = addr->as_u32;
139  return 0;
140 }
141 
142 int
144 {
145  if (dm->is_ce)
146  {
147  dpo_id_t dpo = DPO_INVALID;
148 
150  fib_prefix_t pfx = {
152  .fp_len = 128,
153  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
154  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
155  };
158 
159  dpo_reset (&dpo);
160 
161  dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0];
162  dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1];
163  }
164  else
165  {
166  return VNET_API_ERROR_FEATURE_DISABLED;
167  }
168 
169  return 0;
170 }
171 
172 int
174 {
175  if (dm->is_ce)
176  {
177  dm->b4_ip4_addr.as_u32 = addr->as_u32;
178  }
179  else
180  {
181  return VNET_API_ERROR_FEATURE_DISABLED;
182  }
183 
184  return 0;
185 }
186 
187 int
189 {
191  snat_address_t *a = 0;
192  int i = 0;
193  dpo_id_t dpo_v4 = DPO_INVALID;
194  fib_prefix_t pfx = {
196  .fp_len = 32,
197  .fp_addr.ip4.as_u32 = addr->as_u32,
198  };
199 
200  for (i = 0; i < vec_len (dm->addr_pool); i++)
201  {
202  if (dm->addr_pool[i].addr.as_u32 == addr->as_u32)
203  {
204  a = dm->addr_pool + i;
205  break;
206  }
207  }
208  if (is_add)
209  {
210  if (a)
211  return VNET_API_ERROR_VALUE_EXIST;
212  vec_add2 (dm->addr_pool, a, 1);
213  a->addr = *addr;
214 #define _(N, i, n, s) \
215  clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); \
216  a->busy_##n##_ports = 0; \
217  vec_validate_init_empty (a->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0);
219 #undef _
220  dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
222  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
223  dpo_reset (&dpo_v4);
224  }
225  else
226  {
227  if (!a)
228  return VNET_API_ERROR_NO_SUCH_ENTRY;
229 #define _(N, id, n, s) \
230  clib_bitmap_free (a->busy_##n##_port_bitmap); \
231  vec_free (a->busy_##n##_ports_per_thread);
233 #undef _
235  vec_del1 (dm->addr_pool, i);
236  }
237  return 0;
238 }
239 
240 u8 *
241 format_dslite_trace (u8 * s, va_list * args)
242 {
243  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
244  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
245  dslite_trace_t *t = va_arg (*args, dslite_trace_t *);
246 
247  s =
248  format (s, "next index %d, session %d", t->next_index, t->session_index);
249 
250  return s;
251 }
252 
253 u8 *
254 format_dslite_ce_trace (u8 * s, va_list * args)
255 {
256  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
257  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
258  dslite_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *);
259 
260  s = format (s, "next index %d", t->next_index);
261 
262  return s;
263 }
264 
265 /*
266  * fd.io coding-style-patch-verification: ON
267  *
268  * Local Variables:
269  * eval: (c-set-style "gnu")
270  * End:
271  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
void dslite_set_ce(dslite_main_t *dm, u8 set)
Definition: dslite.c:94
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
void dslite_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
Definition: dslite_dpo.c:23
#define CLIB_UNUSED(x)
Definition: clib.h:82
void dslite_init(vlib_main_t *vm)
Definition: dslite.c:22
a
Definition: bitmap.h:538
u16 port_per_thread
Definition: dslite.h:88
u8 * format_dslite_trace(u8 *s, va_list *args)
Definition: dslite.c:241
u64 as_u64[2]
Definition: ip6_packet.h:51
ip4_address_t aftr_ip4_addr
Definition: dslite.h:81
u32 index
Definition: node.h:279
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:560
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u32 session_index
Definition: dslite.h:107
clib_bihash_16_8_t b4_hash
Definition: dslite.h:66
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
u32 first_worker_index
Definition: dslite.h:87
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:407
ip6_address_t b4_ip6_addr
Definition: dslite.h:82
A high priority source a plugin can use.
Definition: fib_entry.h:67
Aggregrate type for a prefix.
Definition: fib_types.h:203
u32 num_workers
Definition: dslite.h:86
unsigned int u32
Definition: types.h:88
char * name
The counter collection&#39;s name.
Definition: counter.h:64
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
Definition: fib_entry.h:285
clib_bihash_8_8_t out2in
Definition: dslite.h:62
u32 dslite_in2out_slowpath_node_index
Definition: dslite.h:96
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:804
snat_address_t * addr_pool
Definition: dslite.h:85
int dslite_add_del_pool_addr(dslite_main_t *dm, ip4_address_t *addr, u8 is_add)
Definition: dslite.c:188
int dslite_set_b4_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:173
void dslite_dpo_module_init(void)
Definition: dslite_dpo.c:117
ip6_address_t aftr_ip6_addr
Definition: dslite.h:80
vlib_main_t * vm
Definition: buffer.c:312
ip4_address_t b4_ip4_addr
Definition: dslite.h:83
dslite_main_t dslite_main
Definition: dslite.c:19
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:307
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
Definition: counter.c:79
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
Definition: counter.h:139
uword * thread_registrations_by_name
Definition: threads.h:289
vlib_simple_counter_main_t total_b4s
Definition: dslite.h:91
ip4_address_t addr
Definition: nat.h:319
dslite_per_thread_data_t * per_thread_data
Definition: dslite.h:84
int dslite_set_aftr_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:136
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:65
u32 next_index
Definition: dslite.h:106
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int dslite_set_b4_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:143
vlib_simple_counter_main_t total_sessions
Definition: dslite.h:92
u64 uword
Definition: types.h:112
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
#define hash_get_mem(h, key)
Definition: hash.h:269
void dslite_ce_dpo_create(dpo_proto_t dproto, u32 b4_index, dpo_id_t *dpo)
Definition: dslite_dpo.c:29
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
#define vec_foreach(var, vec)
Vector iterator.
u8 * format_dslite_ce_trace(u8 *s, va_list *args)
Definition: dslite.c:254
clib_bihash_24_8_t in2out
Definition: dslite.h:63
u32 dslite_out2in_node_index
Definition: dslite.h:97
int dslite_set_aftr_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:100
u32 dslite_in2out_node_index
Definition: dslite.h:95