FD.io VPP  v18.07-34-g55fbdb9
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 
71 }
72 
73 void
75 {
76  dm->is_ce = (set != 0);
77 }
78 
79 int
81 {
82  dpo_id_t dpo = DPO_INVALID;
83 
84  if (dm->is_ce)
85  {
87  fib_prefix_t pfx = {
89  .fp_len = 0,
90  .fp_addr.ip4.as_u32 = 0,
91  };
94  }
95  else
96  {
98  fib_prefix_t pfx = {
100  .fp_len = 128,
101  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
102  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
103  };
106  }
107 
108  dpo_reset (&dpo);
109 
110  dm->aftr_ip6_addr.as_u64[0] = addr->as_u64[0];
111  dm->aftr_ip6_addr.as_u64[1] = addr->as_u64[1];
112  return 0;
113 }
114 
115 int
117 {
118  dm->aftr_ip4_addr.as_u32 = addr->as_u32;
119  return 0;
120 }
121 
122 int
124 {
125  if (dm->is_ce)
126  {
127  dpo_id_t dpo = DPO_INVALID;
128 
130  fib_prefix_t pfx = {
132  .fp_len = 128,
133  .fp_addr.ip6.as_u64[0] = addr->as_u64[0],
134  .fp_addr.ip6.as_u64[1] = addr->as_u64[1],
135  };
138 
139  dpo_reset (&dpo);
140 
141  dm->b4_ip6_addr.as_u64[0] = addr->as_u64[0];
142  dm->b4_ip6_addr.as_u64[1] = addr->as_u64[1];
143  }
144  else
145  {
146  return VNET_API_ERROR_FEATURE_DISABLED;
147  }
148 
149  return 0;
150 }
151 
152 int
154 {
155  if (dm->is_ce)
156  {
157  dm->b4_ip4_addr.as_u32 = addr->as_u32;
158  }
159  else
160  {
161  return VNET_API_ERROR_FEATURE_DISABLED;
162  }
163 
164  return 0;
165 }
166 
167 int
169 {
171  snat_address_t *a = 0;
172  int i = 0;
173  dpo_id_t dpo_v4 = DPO_INVALID;
174  fib_prefix_t pfx = {
176  .fp_len = 32,
177  .fp_addr.ip4.as_u32 = addr->as_u32,
178  };
179 
180  for (i = 0; i < vec_len (dm->addr_pool); i++)
181  {
182  if (dm->addr_pool[i].addr.as_u32 == addr->as_u32)
183  {
184  a = dm->addr_pool + i;
185  break;
186  }
187  }
188  if (is_add)
189  {
190  if (a)
191  return VNET_API_ERROR_VALUE_EXIST;
192  vec_add2 (dm->addr_pool, a, 1);
193  a->addr = *addr;
194 #define _(N, i, n, s) \
195  clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); \
196  a->busy_##n##_ports = 0; \
197  vec_validate_init_empty (a->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0);
199 #undef _
200  dslite_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
202  FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
203  dpo_reset (&dpo_v4);
204  }
205  else
206  {
207  if (!a)
208  return VNET_API_ERROR_NO_SUCH_ENTRY;
209 #define _(N, id, n, s) \
210  clib_bitmap_free (a->busy_##n##_port_bitmap); \
211  vec_free (a->busy_##n##_ports_per_thread);
213 #undef _
215  vec_del1 (dm->addr_pool, i);
216  }
217  return 0;
218 }
219 
220 u8 *
221 format_dslite_trace (u8 * s, va_list * args)
222 {
223  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
224  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
225  dslite_trace_t *t = va_arg (*args, dslite_trace_t *);
226 
227  s =
228  format (s, "next index %d, session %d", t->next_index, t->session_index);
229 
230  return s;
231 }
232 
233 u8 *
234 format_dslite_ce_trace (u8 * s, va_list * args)
235 {
236  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
237  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
238  dslite_ce_trace_t *t = va_arg (*args, dslite_ce_trace_t *);
239 
240  s = format (s, "next index %d", t->next_index);
241 
242  return s;
243 }
244 
245 /*
246  * fd.io coding-style-patch-verification: ON
247  *
248  * Local Variables:
249  * eval: (c-set-style "gnu")
250  * End:
251  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
void dslite_set_ce(dslite_main_t *dm, u8 set)
Definition: dslite.c:74
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:197
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:79
void dslite_init(vlib_main_t *vm)
Definition: dslite.c:22
a
Definition: bitmap.h:538
u16 port_per_thread
Definition: dslite.h:89
u8 * format_dslite_trace(u8 *s, va_list *args)
Definition: dslite.c:221
u64 as_u64[2]
Definition: ip6_packet.h:51
ip4_address_t aftr_ip4_addr
Definition: dslite.h:82
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:562
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u32 session_index
Definition: dslite.h:99
clib_bihash_16_8_t b4_hash
Definition: dslite.h:67
vhost_vring_addr_t addr
Definition: vhost_user.h:116
unsigned char u8
Definition: types.h:56
u32 first_worker_index
Definition: dslite.h:88
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:83
A high priority source a plugin can use.
Definition: fib_entry.h:62
Aggregrate type for a prefix.
Definition: fib_types.h:188
u32 num_workers
Definition: dslite.h:87
unsigned int u32
Definition: types.h:88
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:63
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:806
snat_address_t * addr_pool
Definition: dslite.h:86
int dslite_add_del_pool_addr(dslite_main_t *dm, ip4_address_t *addr, u8 is_add)
Definition: dslite.c:168
int dslite_set_b4_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:153
void dslite_dpo_module_init(void)
Definition: dslite_dpo.c:117
ip6_address_t aftr_ip6_addr
Definition: dslite.h:81
vlib_main_t * vm
Definition: buffer.c:294
ip4_address_t b4_ip4_addr
Definition: dslite.h:84
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
uword * thread_registrations_by_name
Definition: threads.h:297
ip4_address_t addr
Definition: nat.h:195
dslite_per_thread_data_t * per_thread_data
Definition: dslite.h:85
int dslite_set_aftr_ip4_addr(dslite_main_t *dm, ip4_address_t *addr)
Definition: dslite.c:116
u32 next_index
Definition: dslite.h:98
#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:123
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:234
clib_bihash_24_8_t in2out
Definition: dslite.h:64
int dslite_set_aftr_ip6_addr(dslite_main_t *dm, ip6_address_t *addr)
Definition: dslite.c:80