FD.io VPP  v21.01.1
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 <vnet/plugin/plugin.h>
16 #include <nat/dslite/dslite.h>
17 #include <nat/dslite/dslite_dpo.h>
18 #include <vnet/fib/fib_table.h>
19 #include <vpp/app/version.h>
20 
23 
25 
26 void
27 add_del_dslite_pool_addr_cb (ip4_address_t addr, u8 is_add, void *opaque);
28 
29 static clib_error_t *
31 {
35  uword *p;
37 
38  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out");
39  dm->dslite_in2out_node_index = node->index;
40 
41  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out-slowpath");
43 
44  node = vlib_get_node_by_name (vm, (u8 *) "dslite-out2in");
45  dm->dslite_out2in_node_index = node->index;
46 
47  dm->first_worker_index = 0;
48  dm->num_workers = 0;
49 
50  // init nat address pool
53 
54  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
55  if (p)
56  {
57  tr = (vlib_thread_registration_t *) p[0];
58  if (tr)
59  {
60  dm->num_workers = tr->count;
62  }
63  }
64 
65  if (dm->num_workers)
66  dm->port_per_thread = (0xffff - 1024) / dm->num_workers;
67  else
68  dm->port_per_thread = 0xffff - 1024;
69 
71 
72  dm->is_ce = 0;
73  dm->is_enabled = 0;
74 
75  /* Init counters */
76  dm->total_b4s.name = "total-b4s";
77  dm->total_b4s.stat_segment_name = "/dslite/total-b4s";
80  dm->total_sessions.name = "total-sessions";
81  dm->total_sessions.stat_segment_name = "/dslite/total-sessions";
84 
86 
87  nat_fib_src_hi = fib_source_allocate ("dslite-hi",
90 
91  return dslite_api_hookup (vm);
92 }
93 
94 static void
96 {
99  u32 translation_buckets = 1024;
100  u32 translation_memory_size = 128 << 20;
101  u32 b4_buckets = 128;
102  u32 b4_memory_size = 64 << 20;
103 
104  /* *INDENT-OFF* */
105  vec_foreach (td, dm->per_thread_data)
106  {
107  clib_bihash_init_24_8 (&td->in2out, "dslite in2out", translation_buckets,
108  translation_memory_size);
109 
110  clib_bihash_init_8_8 (&td->out2in, "dslite out2in", translation_buckets,
111  translation_memory_size);
112 
113  clib_bihash_init_16_8 (&td->b4_hash, "dslite b4s", b4_buckets, b4_memory_size);
114  }
115  /* *INDENT-ON* */
116  dm->is_enabled = 1;
117 }
118 
119 void
121 {
122  dm->is_ce = (set != 0);
123 }
124 
125 static clib_error_t *
127 {
128  dslite_main_t *dm = &dslite_main;
129 
131  {
132  if (unformat (input, "ce"))
133  dslite_set_ce (dm, 1);
134  }
135  return 0;
136 }
137 
139 
140 int
142 {
143  dpo_id_t dpo = DPO_INVALID;
144 
145  if (!dm->is_enabled)
147 
148  if (dm->is_ce)
149  {
151  fib_prefix_t pfx = {
153  .fp_len = 0,
154  .fp_addr.ip4.as_u32 = 0,
155  };
158  }
159  else
160  {
161  dslite_dpo_create (DPO_PROTO_IP6, 0, &dpo);
162  fib_prefix_t pfx = {
164  .fp_len = 128,
165  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
166  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
167  };
170  }
171 
172  dpo_reset (&dpo);
173 
174  dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0];
175  dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1];
176  return 0;
177 }
178 
179 int
181 {
182  dm->aftr_ip4_addr.as_u32 = addr->as_u32;
183  return 0;
184 }
185 
186 int
188 {
189  if (!dm->is_enabled)
191 
192  if (dm->is_ce)
193  {
194  dpo_id_t dpo = DPO_INVALID;
195 
197  fib_prefix_t pfx = {
199  .fp_len = 128,
200  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
201  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
202  };
205 
206  dpo_reset (&dpo);
207 
208  dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0];
209  dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1];
210  }
211  else
212  {
213  return VNET_API_ERROR_FEATURE_DISABLED;
214  }
215 
216  return 0;
217 }
218 
219 int
221 {
222  if (dm->is_ce)
223  {
224  dm->b4_ip4_addr.as_u32 = addr->as_u32;
225  }
226  else
227  {
228  return VNET_API_ERROR_FEATURE_DISABLED;
229  }
230 
231  return 0;
232 }
233 
234 void
236 {
237  dpo_id_t dpo_v4 = DPO_INVALID;
238  fib_prefix_t pfx = {
240  .fp_len = 32,
241  .fp_addr.ip4.as_u32 = addr.as_u32,
242  };
243 
244  if (is_add)
245  {
246  dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
248  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
249  dpo_reset (&dpo_v4);
250  }
251  else
252  {
254  }
255 }
256 
257 u8 *
258 format_dslite_trace (u8 * s, va_list * args)
259 {
260  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
261  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
262  dslite_trace_t *t = va_arg (*args, dslite_trace_t *);
263 
264  s =
265  format (s, "next index %d, session %d", t->next_index, t->session_index);
266 
267  return s;
268 }
269 
270 u8 *
271 format_dslite_ce_trace (u8 * s, va_list * args)
272 {
273  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
274  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
275  dslite_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *);
276 
277  s = format (s, "next index %d", t->next_index);
278 
279  return s;
280 }
281 
283 
284 /* *INDENT-OFF* */
286 {
287  .version = VPP_BUILD_VER,
288  .description = "Dual-Stack Lite",
289 };
290 /* *INDENT-ON* */
291 
292 /*
293  * fd.io coding-style-patch-verification: ON
294  *
295  * Local Variables:
296  * eval: (c-set-style "gnu")
297  * End:
298  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
void dslite_set_ce(dslite_main_t *dm, u8 set)
Definition: dslite.c:120
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
enum fib_source_t_ fib_source_t
The different sources that can create a route.
void dslite_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
Definition: dslite_dpo.c:22
int nat_alloc_ip4_addr_and_port_cb_default(nat_ip4_pool_t *pool, u32 fib_index, u32 thread_index, u32 nat_thread_index, u16 port_per_thread, u16 protocol, nat_ip4_addr_port_t *out)
Definition: alloc.c:112
#define CLIB_UNUSED(x)
Definition: clib.h:87
u16 port_per_thread
Definition: dslite.h:112
u8 * format_dslite_trace(u8 *s, va_list *args)
Definition: dslite.c:258
static void dslite_init_datastructures(void)
Definition: dslite.c:95
clib_error_t * dslite_api_hookup(vlib_main_t *vm)
Definition: dslite_api.c:171
ip4_address_t aftr_ip4_addr
Definition: dslite.h:106
u32 index
Definition: node.h:280
VLIB_PLUGIN_REGISTER()
add paths without path extensions
Definition: fib_source.h:205
vlib_main_t * vm
Definition: in2out_ed.c:1580
u32 session_index
Definition: dslite.h:137
clib_bihash_16_8_t b4_hash
Definition: dslite.h:91
vhost_vring_addr_t addr
Definition: vhost_user.h:111
unsigned char u8
Definition: types.h:56
static clib_error_t * dslite_config(vlib_main_t *vm, unformat_input_t *input)
Definition: dslite.c:126
u32 first_worker_index
Definition: dslite.h:111
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
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:424
nat_alloc_ip4_addr_and_port_cb_t * alloc_addr_and_port_cb
Definition: alloc.h:63
description fragment has unexpected format
Definition: map.api:433
ip6_address_t b4_ip6_addr
Definition: dslite.h:107
Aggregate type for a prefix.
Definition: fib_types.h:202
void add_del_dslite_pool_addr_cb(ip4_address_t addr, u8 is_add, void *opaque)
Definition: dslite.c:235
u32 num_workers
Definition: dslite.h:110
unsigned int u32
Definition: types.h:88
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
Definition: fib_source.c:118
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:116
clib_bihash_8_8_t out2in
Definition: dslite.h:87
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they&#39;ll ...
Definition: fib_source.h:273
u32 dslite_in2out_slowpath_node_index
Definition: dslite.h:123
struct _unformat_input_t unformat_input_t
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:182
int dslite_set_b4_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:220
nat_add_del_ip4_pool_addr_cb_t * add_del_pool_addr_cb
Definition: alloc.h:62
void dslite_dpo_module_init(void)
Definition: dslite_dpo.c:116
ip6_address_t aftr_ip6_addr
Definition: dslite.h:105
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
ip4_address_t b4_ip4_addr
Definition: dslite.h:108
dslite_main_t dslite_main
Definition: dslite.c:21
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
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:324
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
Definition: counter.c:79
fib_source_t nat_fib_src_hi
Definition: dslite.c:22
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:158
uword * thread_registrations_by_name
Definition: threads.h:295
vlib_simple_counter_main_t total_b4s
Definition: dslite.h:118
dslite_per_thread_data_t * per_thread_data
Definition: dslite.h:109
int dslite_set_aftr_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:180
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:65
u32 next_index
Definition: dslite.h:136
int dslite_set_b4_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:187
nat_ip4_pool_t pool
Definition: dslite.h:115
vlib_simple_counter_main_t total_sessions
Definition: dslite.h:119
u64 uword
Definition: types.h:112
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:202
#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:28
u8 is_enabled
Definition: dslite.h:130
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:271
clib_bihash_24_8_t in2out
Definition: dslite.h:88
static clib_error_t * dslite_init(vlib_main_t *vm)
Definition: dslite.c:30
u32 dslite_out2in_node_index
Definition: dslite.h:124
int dslite_set_aftr_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:141
u32 dslite_in2out_node_index
Definition: dslite.h:122
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170