FD.io VPP  v20.09-64-g4f7b92f0a
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;
38  u32 translation_buckets = 1024;
39  u32 translation_memory_size = 128 << 20;
40  u32 b4_buckets = 128;
41  u32 b4_memory_size = 64 << 20;
42 
43  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out");
44  dm->dslite_in2out_node_index = node->index;
45 
46  node = vlib_get_node_by_name (vm, (u8 *) "dslite-in2out-slowpath");
48 
49  node = vlib_get_node_by_name (vm, (u8 *) "dslite-out2in");
50  dm->dslite_out2in_node_index = node->index;
51 
52  dm->first_worker_index = 0;
53  dm->num_workers = 0;
54 
55  // init nat address pool
58 
59  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
60  if (p)
61  {
62  tr = (vlib_thread_registration_t *) p[0];
63  if (tr)
64  {
65  dm->num_workers = tr->count;
67  }
68  }
69 
70  if (dm->num_workers)
71  dm->port_per_thread = (0xffff - 1024) / dm->num_workers;
72  else
73  dm->port_per_thread = 0xffff - 1024;
74 
76 
77  /* *INDENT-OFF* */
79  {
80  clib_bihash_init_24_8 (&td->in2out, "in2out", translation_buckets,
81  translation_memory_size);
82 
83  clib_bihash_init_8_8 (&td->out2in, "out2in", translation_buckets,
84  translation_memory_size);
85 
86  clib_bihash_init_16_8 (&td->b4_hash, "b4s", b4_buckets, b4_memory_size);
87  }
88  /* *INDENT-ON* */
89 
90  dm->is_ce = 0;
91 
92  /* Init counters */
93  dm->total_b4s.name = "total-b4s";
94  dm->total_b4s.stat_segment_name = "/dslite/total-b4s";
97  dm->total_sessions.name = "total-sessions";
98  dm->total_sessions.stat_segment_name = "/dslite/total-sessions";
101 
103 
104  nat_fib_src_hi = fib_source_allocate ("dslite-hi",
107 
108  return dslite_api_hookup (vm);
109 }
110 
111 void
113 {
114  dm->is_ce = (set != 0);
115 }
116 
117 static clib_error_t *
119 {
120  dslite_main_t *dm = &dslite_main;
121 
123  {
124  if (unformat (input, "ce"))
125  dslite_set_ce (dm, 1);
126  }
127  return 0;
128 }
129 
131 
132 int
134 {
135  dpo_id_t dpo = DPO_INVALID;
136 
137  if (dm->is_ce)
138  {
140  fib_prefix_t pfx = {
142  .fp_len = 0,
143  .fp_addr.ip4.as_u32 = 0,
144  };
147  }
148  else
149  {
150  dslite_dpo_create (DPO_PROTO_IP6, 0, &dpo);
151  fib_prefix_t pfx = {
153  .fp_len = 128,
154  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
155  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
156  };
159  }
160 
161  dpo_reset (&dpo);
162 
163  dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0];
164  dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1];
165  return 0;
166 }
167 
168 int
170 {
171  dm->aftr_ip4_addr.as_u32 = addr->as_u32;
172  return 0;
173 }
174 
175 int
177 {
178  if (dm->is_ce)
179  {
180  dpo_id_t dpo = DPO_INVALID;
181 
183  fib_prefix_t pfx = {
185  .fp_len = 128,
186  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
187  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
188  };
191 
192  dpo_reset (&dpo);
193 
194  dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0];
195  dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1];
196  }
197  else
198  {
199  return VNET_API_ERROR_FEATURE_DISABLED;
200  }
201 
202  return 0;
203 }
204 
205 int
207 {
208  if (dm->is_ce)
209  {
210  dm->b4_ip4_addr.as_u32 = addr->as_u32;
211  }
212  else
213  {
214  return VNET_API_ERROR_FEATURE_DISABLED;
215  }
216 
217  return 0;
218 }
219 
220 void
222 {
223  dpo_id_t dpo_v4 = DPO_INVALID;
224  fib_prefix_t pfx = {
226  .fp_len = 32,
227  .fp_addr.ip4.as_u32 = addr.as_u32,
228  };
229 
230  if (is_add)
231  {
232  dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
234  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
235  dpo_reset (&dpo_v4);
236  }
237  else
238  {
240  }
241 }
242 
243 u8 *
244 format_dslite_trace (u8 * s, va_list * args)
245 {
246  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
247  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
248  dslite_trace_t *t = va_arg (*args, dslite_trace_t *);
249 
250  s =
251  format (s, "next index %d, session %d", t->next_index, t->session_index);
252 
253  return s;
254 }
255 
256 u8 *
257 format_dslite_ce_trace (u8 * s, va_list * args)
258 {
259  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
260  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
261  dslite_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *);
262 
263  s = format (s, "next index %d", t->next_index);
264 
265  return s;
266 }
267 
269 
270 /* *INDENT-OFF* */
272 {
273  .version = VPP_BUILD_VER,
274  .description = "Dual-Stack Lite",
275 };
276 /* *INDENT-ON* */
277 
278 /*
279  * fd.io coding-style-patch-verification: ON
280  *
281  * Local Variables:
282  * eval: (c-set-style "gnu")
283  * End:
284  */
#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:112
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
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:244
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:279
VLIB_PLUGIN_REGISTER()
add paths without path extensions
Definition: fib_source.h:205
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u32 session_index
Definition: dslite.h:136
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:118
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
ip6_address_t b4_ip6_addr
Definition: dslite.h:107
Aggregate type for a prefix.
Definition: fib_types.h:203
void add_del_dslite_pool_addr_cb(ip4_address_t addr, u8 is_add, void *opaque)
Definition: dslite.c:221
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:206
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:145
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:1582
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:139
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:169
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:65
u32 next_index
Definition: dslite.h:135
int dslite_set_b4_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:176
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: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:28
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:257
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:133
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:171