FD.io VPP  v21.06-3-gbb25fbf28
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  */
DPO_INVALID
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:204
fib_table_entry_special_dpo_add
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 'special' entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:324
dslite_set_aftr_ip6_addr
int dslite_set_aftr_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:141
dslite.h
dslite_per_thread_data_t::b4_hash
clib_bihash_16_8_t b4_hash
Definition: dslite.h:91
dslite_main_t
Definition: dslite.h:103
dslite_main_t::per_thread_data
dslite_per_thread_data_t * per_thread_data
Definition: dslite.h:109
dslite_main_t::is_ce
u8 is_ce
Definition: dslite.h:128
nat_fib_src_hi
fib_source_t nat_fib_src_hi
Definition: dslite.c:22
VLIB_PLUGIN_REGISTER
VLIB_PLUGIN_REGISTER()
dslite_main_t::pool
nat_ip4_pool_t pool
Definition: dslite.h:115
dslite_per_thread_data_t::out2in
clib_bihash_8_8_t out2in
Definition: dslite.h:87
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
ip4_address_t::as_u32
u32 as_u32
Definition: ip4_packet.h:57
fib_table.h
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
dslite_init_datastructures
static void dslite_init_datastructures(void)
Definition: dslite.c:95
dslite_main_t::is_enabled
u8 is_enabled
Definition: dslite.h:130
dslite_main_t::aftr_ip6_addr
ip6_address_t aftr_ip6_addr
Definition: dslite.h:105
dslite_config
static clib_error_t * dslite_config(vlib_main_t *vm, unformat_input_t *input)
Definition: dslite.c:126
FIB_ENTRY_FLAG_EXCLUSIVE
@ FIB_ENTRY_FLAG_EXCLUSIVE
Definition: fib_entry.h:116
unformat_input_t
struct _unformat_input_t unformat_input_t
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
vlib_thread_registration_::count
u32 count
Definition: threads.h:38
nat_ip4_pool_s::alloc_addr_and_port_cb
nat_alloc_ip4_addr_and_port_cb_t * alloc_addr_and_port_cb
Definition: alloc.h:63
add_del_dslite_pool_addr_cb
void add_del_dslite_pool_addr_cb(ip4_address_t addr, u8 is_add, void *opaque)
Definition: dslite.c:235
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
set
description can t DF set
Definition: map.api:451
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:283
fib_table_entry_special_remove
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
Definition: fib_table.c:424
dslite_main_t::dslite_in2out_node_index
u32 dslite_in2out_node_index
Definition: dslite.h:122
dslite_set_ce
void dslite_set_ce(dslite_main_t *dm, u8 set)
Definition: dslite.c:120
dslite_trace_t::session_index
u32 session_index
Definition: dslite.h:137
dslite_set_b4_ip4_addr
int dslite_set_b4_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:220
dslite_main_t::total_b4s
vlib_simple_counter_main_t total_b4s
Definition: dslite.h:118
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
dslite_main_t::aftr_ip4_addr
ip4_address_t aftr_ip4_addr
Definition: dslite.h:106
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
format_dslite_trace
u8 * format_dslite_trace(u8 *s, va_list *args)
Definition: dslite.c:258
dslite_api_hookup
clib_error_t * dslite_api_hookup(vlib_main_t *vm)
Definition: dslite_api.c:171
uword
u64 uword
Definition: types.h:112
vlib_thread_main_t::thread_registrations_by_name
uword * thread_registrations_by_name
Definition: threads.h:272
vlib_thread_registration_::first_index
u32 first_index
Definition: threads.h:44
vlib_simple_counter_main_t::name
char * name
The counter collection's name.
Definition: counter.h:60
dslite_ce_trace_t::next_index
u32 next_index
Definition: dslite.h:142
dslite_set_aftr_ip4_addr
int dslite_set_aftr_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:180
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
nat_ip4_pool_s::add_del_pool_addr_cb
nat_add_del_ip4_pool_addr_cb_t * add_del_pool_addr_cb
Definition: alloc.h:62
ip4_address_t
Definition: ip4_packet.h:50
FIB_PROTOCOL_IP4
@ FIB_PROTOCOL_IP4
Definition: fib_types.h:36
dslite_dpo.h
fib_source_allocate
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
Definition: fib_source.c:118
dslite_main_t::total_sessions
vlib_simple_counter_main_t total_sessions
Definition: dslite.h:119
plugin.h
FIB_SOURCE_PRIORITY_HI
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they'll ...
Definition: fib_source.h:284
vlib_get_node_by_name
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
format
description fragment has unexpected format
Definition: map.api:433
vlib_zero_simple_counter
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:154
DPO_PROTO_IP6
@ DPO_PROTO_IP6
Definition: dpo.h:65
dslite_main_t::port_per_thread
u16 port_per_thread
Definition: dslite.h:112
u32
unsigned int u32
Definition: types.h:88
vlib_simple_counter_main_t::stat_segment_name
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:61
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
vlib_thread_main_t
Definition: threads.h:264
dslite_dpo_create
void dslite_dpo_create(dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
Definition: dslite_dpo.c:22
vlib_validate_simple_counter
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
Definition: counter.c:79
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
dslite_trace_t
Definition: dslite.h:134
nat_alloc_ip4_addr_and_port_cb_default
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
dslite_main_t::b4_ip6_addr
ip6_address_t b4_ip6_addr
Definition: dslite.h:107
dslite_main_t::dslite_out2in_node_index
u32 dslite_out2in_node_index
Definition: dslite.h:124
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
dslite_main_t::dslite_in2out_slowpath_node_index
u32 dslite_in2out_slowpath_node_index
Definition: dslite.h:123
fib_prefix_t_::fp_proto
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
dslite_per_thread_data_t::in2out
clib_bihash_24_8_t in2out
Definition: dslite.h:88
dslite_set_b4_ip6_addr
int dslite_set_b4_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:187
vlib_main_t
Definition: main.h:102
format_dslite_ce_trace
u8 * format_dslite_ce_trace(u8 *s, va_list *args)
Definition: dslite.c:271
vlib_node_t
Definition: node.h:247
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
dslite_per_thread_data_t
Definition: dslite.h:84
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
FIB_SOURCE_BH_SIMPLE
@ FIB_SOURCE_BH_SIMPLE
add paths without path extensions
Definition: fib_source.h:210
dslite_ce_trace_t
Definition: dslite.h:140
dslite_main_t::b4_ip4_addr
ip4_address_t b4_ip4_addr
Definition: dslite.h:108
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
dslite_trace_t::next_index
u32 next_index
Definition: dslite.h:136
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
fib_source_t
enum fib_source_t_ fib_source_t
The different sources that can create a route.
dslite_dpo_module_init
void dslite_dpo_module_init(void)
Definition: dslite_dpo.c:116
dslite_main
dslite_main_t dslite_main
Definition: dslite.c:21
vlib_thread_registration_
Definition: threads.h:27
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
dslite_init
static clib_error_t * dslite_init(vlib_main_t *vm)
Definition: dslite.c:30
dpo_reset
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:234
dslite_main_t::first_worker_index
u32 first_worker_index
Definition: dslite.h:111
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
dslite_main_t::num_workers
u32 num_workers
Definition: dslite.h:110
dslite_ce_dpo_create
void dslite_ce_dpo_create(dpo_proto_t dproto, u32 b4_index, dpo_id_t *dpo)
Definition: dslite_dpo.c:28