FD.io VPP  v19.01.1-17-ge106252
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;
29  u32 translation_buckets = 1024;
30  u32 translation_memory_size = 128 << 20;
31  u32 b4_buckets = 128;
32  u32 b4_memory_size = 64 << 20;
33 
34  dm->first_worker_index = 0;
35  dm->num_workers = 0;
36 
37  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
38  if (p)
39  {
40  tr = (vlib_thread_registration_t *) p[0];
41  if (tr)
42  {
43  dm->num_workers = tr->count;
45  }
46  }
47 
48  if (dm->num_workers)
49  dm->port_per_thread = (0xffff - 1024) / dm->num_workers;
50  else
51  dm->port_per_thread = 0xffff - 1024;
52 
54 
55  /* *INDENT-OFF* */
57  {
58  clib_bihash_init_24_8 (&td->in2out, "in2out", translation_buckets,
59  translation_memory_size);
60 
61  clib_bihash_init_8_8 (&td->out2in, "out2in", translation_buckets,
62  translation_memory_size);
63 
64  clib_bihash_init_16_8 (&td->b4_hash, "b4s", b4_buckets, b4_memory_size);
65  }
66  /* *INDENT-ON* */
67 
68  dm->is_ce = 0;
69 
70  /* Init counters */
71  dm->total_b4s.name = "total-b4s";
72  dm->total_b4s.stat_segment_name = "/dslite/total-b4s";
75  dm->total_sessions.name = "total-sessions";
76  dm->total_sessions.stat_segment_name = "/dslite/total-sessions";
79 
81 }
82 
83 void
85 {
86  dm->is_ce = (set != 0);
87 }
88 
89 int
91 {
92  dpo_id_t dpo = DPO_INVALID;
93 
94  if (dm->is_ce)
95  {
97  fib_prefix_t pfx = {
99  .fp_len = 0,
100  .fp_addr.ip4.as_u32 = 0,
101  };
104  }
105  else
106  {
107  dslite_dpo_create (DPO_PROTO_IP6, 0, &dpo);
108  fib_prefix_t pfx = {
110  .fp_len = 128,
111  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
112  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
113  };
116  }
117 
118  dpo_reset (&dpo);
119 
120  dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0];
121  dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1];
122  return 0;
123 }
124 
125 int
127 {
128  dm->aftr_ip4_addr.as_u32 = addr->as_u32;
129  return 0;
130 }
131 
132 int
134 {
135  if (dm->is_ce)
136  {
137  dpo_id_t dpo = DPO_INVALID;
138 
140  fib_prefix_t pfx = {
142  .fp_len = 128,
143  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
144  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
145  };
148 
149  dpo_reset (&dpo);
150 
151  dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0];
152  dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1];
153  }
154  else
155  {
156  return VNET_API_ERROR_FEATURE_DISABLED;
157  }
158 
159  return 0;
160 }
161 
162 int
164 {
165  if (dm->is_ce)
166  {
167  dm->b4_ip4_addr.as_u32 = addr->as_u32;
168  }
169  else
170  {
171  return VNET_API_ERROR_FEATURE_DISABLED;
172  }
173 
174  return 0;
175 }
176 
177 int
179 {
181  snat_address_t *a = 0;
182  int i = 0;
183  dpo_id_t dpo_v4 = DPO_INVALID;
184  fib_prefix_t pfx = {
186  .fp_len = 32,
187  .fp_addr.ip4.as_u32 = addr->as_u32,
188  };
189 
190  for (i = 0; i < vec_len (dm->addr_pool); i++)
191  {
192  if (dm->addr_pool[i].addr.as_u32 == addr->as_u32)
193  {
194  a = dm->addr_pool + i;
195  break;
196  }
197  }
198  if (is_add)
199  {
200  if (a)
201  return VNET_API_ERROR_VALUE_EXIST;
202  vec_add2 (dm->addr_pool, a, 1);
203  a->addr = *addr;
204 #define _(N, i, n, s) \
205  clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); \
206  a->busy_##n##_ports = 0; \
207  vec_validate_init_empty (a->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0);
209 #undef _
210  dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
212  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
213  dpo_reset (&dpo_v4);
214  }
215  else
216  {
217  if (!a)
218  return VNET_API_ERROR_NO_SUCH_ENTRY;
219 #define _(N, id, n, s) \
220  clib_bitmap_free (a->busy_##n##_port_bitmap); \
221  vec_free (a->busy_##n##_ports_per_thread);
223 #undef _
225  vec_del1 (dm->addr_pool, i);
226  }
227  return 0;
228 }
229 
230 u8 *
231 format_dslite_trace (u8 * s, va_list * args)
232 {
233  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
234  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
235  dslite_trace_t *t = va_arg (*args, dslite_trace_t *);
236 
237  s =
238  format (s, "next index %d, session %d", t->next_index, t->session_index);
239 
240  return s;
241 }
242 
243 u8 *
244 format_dslite_ce_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_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *);
249 
250  s = format (s, "next index %d", t->next_index);
251 
252  return s;
253 }
254 
255 /*
256  * fd.io coding-style-patch-verification: ON
257  *
258  * Local Variables:
259  * eval: (c-set-style "gnu")
260  * End:
261  */
#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:84
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:231
u64 as_u64[2]
Definition: ip6_packet.h:51
ip4_address_t aftr_ip4_addr
Definition: dslite.h:81
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:564
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u32 session_index
Definition: dslite.h:102
clib_bihash_16_8_t b4_hash
Definition: dslite.h:66
vhost_vring_addr_t addr
Definition: vhost_user.h:121
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:62
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:168
Definition: fib_entry.h:279
clib_bihash_8_8_t out2in
Definition: dslite.h:62
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:808
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:178
int dslite_set_b4_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:163
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:301
ip4_address_t b4_ip4_addr
Definition: dslite.h:83
dslite_main_t dslite_main
Definition: dslite.c:19
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:91
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:288
vlib_simple_counter_main_t total_b4s
Definition: dslite.h:91
ip4_address_t addr
Definition: nat.h:243
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:126
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:65
u32 next_index
Definition: dslite.h:101
#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:133
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:195
#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:231
#define vec_foreach(var, vec)
Vector iterator.
u8 * format_dslite_ce_trace(u8 *s, va_list *args)
Definition: dslite.c:244
clib_bihash_24_8_t in2out
Definition: dslite.h:63
int dslite_set_aftr_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:90