FD.io VPP  v21.01.1
Vector Packet Processing
nat64_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 
16 #include <vnet/ip/ip_types_api.h>
17 #include <vlibmemory/api.h>
18 #include <nat/nat64/nat64.h>
19 #include <nat/nat64/nat64.api_enum.h>
20 #include <nat/nat64/nat64.api_types.h>
21 #include <vnet/fib/fib_table.h>
22 #include <vnet/ip/ip.h>
23 
24 #define REPLY_MSG_ID_BASE nm->msg_id_base
26 
27 static void
30 {
31  nat64_main_t *nm = &nat64_main;
32  vl_api_nat64_plugin_enable_disable_reply_t *rmp;
33  nat64_config_t c = { 0 };
34  int rv = 0;
35  if (mp->enable)
36  {
37  c.bib_buckets = ntohl (mp->bib_buckets);
38  c.bib_memory_size = ntohl (mp->bib_memory_size);
39  c.st_buckets = ntohl (mp->st_buckets);
40  c.st_memory_size = ntohl (mp->st_memory_size);
41  rv = nat64_plugin_enable (c);
42  }
43  else
44  {
45  rv = nat64_plugin_disable ();
46  }
47  REPLY_MACRO (VL_API_NAT64_PLUGIN_ENABLE_DISABLE_REPLY);
48 }
49 
50 static void
52 {
53  nat64_main_t *nm = &nat64_main;
54  vl_api_nat64_set_timeouts_reply_t *rmp;
55  int rv = 0;
56 
57  nm->udp_timeout = ntohl (mp->udp);
58  nm->tcp_est_timeout = ntohl (mp->tcp_established);
59  nm->tcp_trans_timeout = ntohl (mp->tcp_transitory);
60  nm->icmp_timeout = ntohl (mp->icmp);
61 
62  REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
63 }
64 
65 static void
67 {
68  nat64_main_t *nm = &nat64_main;
70  int rv = 0;
71 
72  /* *INDENT-OFF* */
73  REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
74  ({
75  rmp->udp = htonl (nm->udp_timeout);
76  rmp->tcp_established = htonl (nm->tcp_est_timeout);
77  rmp->tcp_transitory = htonl (nm->tcp_trans_timeout);
78  rmp->icmp = htonl (nm->icmp_timeout);
79  }))
80  /* *INDENT-ON* */
81 }
82 
83 static void
86 {
87  nat64_main_t *nm = &nat64_main;
88  vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
89  int rv = 0;
90  ip4_address_t this_addr;
91  u32 start_host_order, end_host_order;
92  u32 vrf_id;
93  int i, count;
94  u32 *tmp;
95 
96  tmp = (u32 *) mp->start_addr;
97  start_host_order = clib_host_to_net_u32 (tmp[0]);
98  tmp = (u32 *) mp->end_addr;
99  end_host_order = clib_host_to_net_u32 (tmp[0]);
100 
101  count = (end_host_order - start_host_order) + 1;
102 
103  vrf_id = clib_host_to_net_u32 (mp->vrf_id);
104 
105  memcpy (&this_addr.as_u8, mp->start_addr, 4);
106 
107  for (i = 0; i < count; i++)
108  {
109  if ((rv = nat64_add_del_pool_addr (0, &this_addr, vrf_id, mp->is_add)))
110  goto send_reply;
111 
112  increment_v4_address (&this_addr);
113  }
114 
115 send_reply:
116  REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
117 }
118 
119 typedef struct nat64_api_walk_ctx_t_
120 {
125 
126 static int
128 {
129  nat64_main_t *nm = &nat64_main;
131  nat64_api_walk_ctx_t *ctx = arg;
132 
133  rmp = vl_msg_api_alloc (sizeof (*rmp));
134  clib_memset (rmp, 0, sizeof (*rmp));
135  rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + nm->msg_id_base);
136  clib_memcpy (rmp->address, &(a->addr), 4);
137  if (a->fib_index != ~0)
138  {
140  if (!fib)
141  return -1;
142  rmp->vrf_id = ntohl (fib->ft_table_id);
143  }
144  else
145  rmp->vrf_id = ~0;
146  rmp->context = ctx->context;
147 
148  vl_api_send_msg (ctx->reg, (u8 *) rmp);
149 
150  return 0;
151 }
152 
153 static void
155 {
157 
159  if (!reg)
160  return;
161 
163  .reg = reg,
164  .context = mp->context,
165  };
166 
168 }
169 
170 static void
172  mp)
173 {
174  nat64_main_t *nm = &nat64_main;
175  vl_api_nat64_add_del_interface_reply_t *rmp;
176  int rv = 0;
177 
179 
180  rv =
182  mp->flags & NAT_API_IS_INSIDE, mp->is_add);
183 
185 
186  REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
187 }
188 
189 static int
191 {
192  nat64_main_t *nm = &nat64_main;
194  nat64_api_walk_ctx_t *ctx = arg;
195 
196  rmp = vl_msg_api_alloc (sizeof (*rmp));
197  clib_memset (rmp, 0, sizeof (*rmp));
198  rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + nm->msg_id_base);
199  rmp->sw_if_index = ntohl (i->sw_if_index);
200 
202  rmp->flags |= NAT_API_IS_INSIDE;
204  rmp->flags |= NAT_API_IS_OUTSIDE;
205 
206  rmp->context = ctx->context;
207 
208  vl_api_send_msg (ctx->reg, (u8 *) rmp);
209 
210  return 0;
211 }
212 
213 static void
215 {
217 
219  if (!reg)
220  return;
221 
223  .reg = reg,
224  .context = mp->context,
225  };
226 
228 }
229 
230 static void
233 {
234  nat64_main_t *nm = &nat64_main;
235  vl_api_nat64_add_del_static_bib_reply_t *rmp;
236  ip6_address_t in_addr;
237  ip4_address_t out_addr;
238  int rv = 0;
239 
240  memcpy (&in_addr.as_u8, mp->i_addr, 16);
241  memcpy (&out_addr.as_u8, mp->o_addr, 4);
242 
243  rv =
244  nat64_add_del_static_bib_entry (&in_addr, &out_addr,
245  clib_net_to_host_u16 (mp->i_port),
246  clib_net_to_host_u16 (mp->o_port),
247  mp->proto,
248  clib_net_to_host_u32 (mp->vrf_id),
249  mp->is_add);
250 
251  REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
252 }
253 
254 static int
255 nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
256 {
257  nat64_main_t *nm = &nat64_main;
259  nat64_api_walk_ctx_t *ctx = arg;
260  fib_table_t *fib;
261 
262  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
263  if (!fib)
264  return -1;
265 
266  rmp = vl_msg_api_alloc (sizeof (*rmp));
267  clib_memset (rmp, 0, sizeof (*rmp));
268  rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + nm->msg_id_base);
269  rmp->context = ctx->context;
270  clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
271  clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
272  rmp->i_port = bibe->in_port;
273  rmp->o_port = bibe->out_port;
274  rmp->vrf_id = ntohl (fib->ft_table_id);
275  rmp->proto = bibe->proto;
276  if (bibe->is_static)
277  rmp->flags |= NAT_API_IS_STATIC;
278  rmp->ses_num = ntohl (bibe->ses_num);
279 
280  vl_api_send_msg (ctx->reg, (u8 *) rmp);
281 
282  return 0;
283 }
284 
285 static void
287 {
288  nat64_main_t *nm = &nat64_main;
290  nat64_db_t *db;
291 
293  if (!reg)
294  return;
295 
297  .reg = reg,
298  .context = mp->context,
299  };
300 
301  /* *INDENT-OFF* */
302  vec_foreach (db, nm->db)
303  nat64_db_bib_walk (db, mp->proto, nat64_api_bib_walk, &ctx);
304  /* *INDENT-ON* */
305 }
306 
307 static int
308 nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
309 {
310  nat64_main_t *nm = &nat64_main;
312  nat64_api_walk_ctx_t *ctx = arg;
313  nat64_db_bib_entry_t *bibe;
314  fib_table_t *fib;
315 
316  bibe = nat64_db_bib_entry_by_index (ctx->db, ste->proto, ste->bibe_index);
317  if (!bibe)
318  return -1;
319 
320  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
321  if (!fib)
322  return -1;
323 
324  rmp = vl_msg_api_alloc (sizeof (*rmp));
325  clib_memset (rmp, 0, sizeof (*rmp));
326  rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + nm->msg_id_base);
327  rmp->context = ctx->context;
328  clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
329  clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
330  rmp->il_port = bibe->in_port;
331  rmp->ol_port = bibe->out_port;
332  clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
333  clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
334  rmp->il_port = ste->r_port;
335  rmp->vrf_id = ntohl (fib->ft_table_id);
336  rmp->proto = ste->proto;
337 
338  vl_api_send_msg (ctx->reg, (u8 *) rmp);
339 
340  return 0;
341 }
342 
343 static void
345 {
346  nat64_main_t *nm = &nat64_main;
348  nat64_db_t *db;
349 
351  if (!reg)
352  return;
353 
355  .reg = reg,
356  .context = mp->context,
357  };
358 
359  /* *INDENT-OFF* */
360  vec_foreach (db, nm->db)
361  {
362  ctx.db = db;
363  nat64_db_st_walk (db, mp->proto, nat64_api_st_walk, &ctx);
364  }
365  /* *INDENT-ON* */
366 }
367 
368 static void
370 {
371  nat64_main_t *nm = &nat64_main;
372  vl_api_nat64_add_del_prefix_reply_t *rmp;
373  ip6_address_t prefix;
374  int rv = 0;
375 
376  memcpy (&prefix.as_u8, mp->prefix.address, 16);
377 
378  rv =
379  nat64_add_del_prefix (&prefix, mp->prefix.len,
380  clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
381  REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
382 }
383 
384 static int
386 {
387  nat64_main_t *nm = &nat64_main;
389  nat64_api_walk_ctx_t *ctx = arg;
390 
391  rmp = vl_msg_api_alloc (sizeof (*rmp));
392  clib_memset (rmp, 0, sizeof (*rmp));
393  rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + nm->msg_id_base);
394  clib_memcpy (rmp->prefix.address, &(p->prefix), 16);
395  rmp->prefix.len = p->plen;
396  rmp->vrf_id = ntohl (p->vrf_id);
397  rmp->context = ctx->context;
398 
399  vl_api_send_msg (ctx->reg, (u8 *) rmp);
400 
401  return 0;
402 }
403 
404 static void
406 {
408 
410  if (!reg)
411  return;
412 
414  .reg = reg,
415  .context = mp->context,
416  };
417 
419 }
420 
421 static void
424 {
425  nat64_main_t *nm = &nat64_main;
426  vl_api_nat64_add_del_interface_addr_reply_t *rmp;
427  u32 sw_if_index = ntohl (mp->sw_if_index);
428  int rv = 0;
429 
431 
432  rv = nat64_add_interface_address (sw_if_index, mp->is_add);
433 
435 
436  REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_ADDR_REPLY);
437 }
438 
439 /* API definitions */
440 #include <vnet/format_fns.h>
441 #include <nat/nat64/nat64.api.c>
442 
443 /* Set up the API message handling tables */
444 clib_error_t *
446 {
447  nat64_main_t *nm = &nat64_main;
449  return 0;
450 }
451 
452 /*
453  * fd.io coding-style-patch-verification: ON
454  *
455  * Local Variables:
456  * eval: (c-set-style "gnu")
457  * End:
458  */
Dump NAT64 prefix.
Definition: nat64.api:289
NAT64 interface details response.
Definition: nat64.api:162
nat64_db_t * db
BIB and session DB per thread.
Definition: nat64.h:137
u16 msg_id_base
Definition: nat64.h:119
u32 icmp_timeout
Definition: nat64.h:154
NAT64 BIB details response.
Definition: nat64.api:218
static void vl_api_nat64_st_dump_t_handler(vl_api_nat64_st_dump_t *mp)
Definition: nat64_api.c:344
a
Definition: bitmap.h:544
#define ntohs(x)
Definition: af_xdp.bpf.c:29
ip6_address_t prefix
Definition: nat64.h:73
#define REPLY_MACRO2(t, body)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vl_api_nat_config_flags_t flags
Definition: nat64.api:226
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
u32 st_buckets
Definition: nat64_db.h:29
static void vl_api_nat64_prefix_dump_t_handler(vl_api_nat64_prefix_dump_t *mp)
Definition: nat64_api.c:405
static void vl_api_nat64_plugin_enable_disable_t_handler(vl_api_nat64_plugin_enable_disable_t *mp)
Definition: nat64_api.c:29
vl_api_ip6_prefix_t prefix
Definition: nat64.api:301
#define nat64_interface_is_inside(i)
Check if NAT64 interface is inside.
Definition: nat64.h:483
static void vl_api_nat64_add_del_static_bib_t_handler(vl_api_nat64_add_del_static_bib_t *mp)
Definition: nat64_api.c:232
u32 vrf_id
Definition: nat44.api:1029
vlib_main_t * vm
Definition: in2out_ed.c:1580
u32 tcp_trans_timeout
Definition: nat64.h:155
vl_api_ip4_address_t or_addr
Definition: nat64.api:264
static void vl_api_nat64_add_del_prefix_t_handler(vl_api_nat64_add_del_prefix_t *mp)
Definition: nat64_api.c:369
vl_api_prefix_t prefix
Definition: ip.api:144
int nat64_add_interface_address(u32 sw_if_index, int is_add)
NAT64 pool address from specific (DHCP addressed) interface.
Definition: nat64.c:455
static void vl_api_nat64_interface_dump_t_handler(vl_api_nat64_interface_dump_t *mp)
Definition: nat64_api.c:214
u32 st_memory_size
Definition: nat64_db.h:30
Add/delete NAT64 pool address from specific interfce.
Definition: nat64.api:311
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
Enable/disable NAT64 feature on the interface.
Definition: nat64.api:137
#define clib_memcpy(d, s, n)
Definition: string.h:180
static int nat64_api_interface_walk(nat64_interface_t *i, void *arg)
Definition: nat64_api.c:190
vl_api_interface_index_t sw_if_index
Definition: nat64.api:315
vl_api_nat_config_flags_t flags
Definition: nat64.api:141
vl_api_ip6_address_t ir_addr
Definition: nat64.api:263
vl_api_ip4_address_t o_addr
Definition: nat64.api:183
Dump NAT64 session table.
Definition: nat64.api:239
vl_api_ip6_address_t i_addr
Definition: nat64.api:182
u32 tcp_est_timeout
Definition: nat64.h:156
unsigned int u32
Definition: types.h:88
static int nat64_api_bib_walk(nat64_db_bib_entry_t *bibe, void *arg)
Definition: nat64_api.c:255
Get values of timeouts for NAT64 sessions (seconds)
Definition: nat64.api:70
u32 udp_timeout
values of various timeouts
Definition: nat64.h:153
u32 fib_index
Definition: nat64.h:95
static int nat64_api_pool_walk(nat64_address_t *a, void *arg)
Definition: nat64_api.c:127
Add/delete address range to NAT64 pool.
Definition: nat64.api:100
long ctx[MAX_CONNS]
Definition: main.c:144
Dump NAT64 pool addresses.
Definition: nat64.api:113
static void vl_api_nat64_get_timeouts_t_handler(vl_api_nat64_get_timeouts_t *mp)
Definition: nat64_api.c:66
Add/del NAT64 prefix.
Definition: nat64.api:277
#define REPLY_MACRO(t)
vl_api_ip6_address_t i_addr
Definition: nat64.api:220
ip4_address_t addr
Definition: nat64.h:94
static int nat64_api_prefix_walk(nat64_prefix_t *p, void *arg)
Definition: nat64_api.c:385
vl_api_ip6_address_t il_addr
Definition: nat64.api:259
static void vl_api_nat64_pool_addr_dump_t_handler(vl_api_nat64_pool_addr_dump_t *mp)
Definition: nat64_api.c:154
Add/delete NAT64 static BIB entry.
Definition: nat64.api:179
clib_error_t * nat64_api_hookup(vlib_main_t *vm)
Definition: nat64_api.c:445
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
vl_api_interface_index_t sw_if_index
Definition: nat64.api:165
static void setup_message_id_table(api_main_t *am)
Definition: bfd_api.c:409
#define BAD_SW_IF_INDEX_LABEL
u32 bib_buckets
Definition: nat64_db.h:27
svmdb_client_t * c
void nat64_pool_addr_walk(nat64_pool_addr_walk_fn_t fn, void *ctx)
Walk NAT64 pool.
Definition: nat64.c:440
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
struct nat64_api_walk_ctx_t_ nat64_api_walk_ctx_t
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
int nat64_add_del_prefix(ip6_address_t *prefix, u8 plen, u32 vrf_id, u8 is_add)
Add/delete NAT64 prefix.
Definition: nat64.c:1206
vl_api_ip4_address_t ol_addr
Definition: nat64.api:260
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
static void increment_v4_address(ip4_address_t *a)
Definition: nat_inlines.h:23
static void vl_api_nat64_add_del_pool_addr_range_t_handler(vl_api_nat64_add_del_pool_addr_range_t *mp)
Definition: nat64_api.c:85
nat64_main_t nat64_main
Definition: nat64.c:27
u32 vrf_id
Definition: nat64.h:75
#define nat64_interface_is_outside(i)
Check if NAT64 interface is outside.
Definition: nat64.h:489
Get values of timeouts for NAT64 sessions reply.
Definition: nat64.api:83
void nat64_db_st_walk(nat64_db_t *db, u8 proto, nat64_db_st_walk_fn_t fn, void *ctx)
Walk NAT64 session table.
Definition: nat64_db.c:341
vl_api_registration_t * reg
Definition: nat64_api.c:121
static void vl_api_nat64_add_del_interface_t_handler(vl_api_nat64_add_del_interface_t *mp)
Definition: nat64_api.c:171
NAT64 pool address details response.
Definition: nat64.api:123
Dump NAT64 prefix details response.
Definition: nat64.api:299
nat64_db_bib_entry_t * nat64_db_bib_entry_by_index(nat64_db_t *db, u8 proto, u32 bibe_index)
Get BIB entry by index and protocol.
Definition: nat64_db.c:318
u32 bib_memory_size
Definition: nat64_db.h:28
int nat64_add_del_pool_addr(u32 thread_index, ip4_address_t *addr, u32 vrf_id, u8 is_add)
Add/delete address to NAT64 pool.
Definition: nat64.c:364
void nat64_prefix_walk(nat64_prefix_walk_fn_t fn, void *ctx)
Walk NAT64 prefixes.
Definition: nat64.c:1256
vl_api_ip4_address_t o_addr
Definition: nat64.api:221
void nat64_interfaces_walk(nat64_interface_walk_fn_t fn, void *ctx)
Walk NAT64 interfaces.
Definition: nat64.c:639
Dump NAT64 BIB.
Definition: nat64.api:200
vl_api_ip4_address_t start_addr
Definition: nat64.api:103
static int nat64_api_st_walk(nat64_db_st_entry_t *ste, void *arg)
Definition: nat64_api.c:308
Dump interfaces with NAT64 feature.
Definition: nat64.api:149
vl_api_interface_index_t sw_if_index
Definition: nat64.api:142
int nat64_plugin_disable()
Definition: nat64.c:1553
int nat64_interface_add_del(u32 sw_if_index, u8 is_inside, u8 is_add)
Enable/disable NAT64 feature on the interface.
Definition: nat64.c:538
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:29
vl_api_ip4_address_t end_addr
Definition: nat64.api:104
nat64_db_t * db
Definition: nat64_api.c:123
int nat64_plugin_enable(nat64_config_t c)
Definition: nat64.c:1516
vl_api_ip6_prefix_t prefix
Definition: nat64.api:280
#define vec_foreach(var, vec)
Vector iterator.
vl_api_ip4_address_t address
Definition: nat64.api:125
u8 count
Definition: dhcp.api:208
Set values of timeouts for NAT64 sessions (seconds)
Definition: nat64.api:57
static void vl_api_nat64_set_timeouts_t_handler(vl_api_nat64_set_timeouts_t *mp)
Definition: nat64_api.c:51
void nat64_db_bib_walk(nat64_db_t *db, u8 proto, nat64_db_bib_walk_fn_t fn, void *ctx)
Walk NAT64 BIB.
Definition: nat64_db.c:267
int nat64_add_del_static_bib_entry(ip6_address_t *in_addr, ip4_address_t *out_addr, u16 in_port, u16 out_port, u8 proto, u32 vrf_id, u8 is_add)
Add/delete static NAT64 BIB entry.
Definition: nat64.c:879
static void vl_api_nat64_add_del_interface_addr_t_handler(vl_api_nat64_add_del_interface_addr_t *mp)
Definition: nat64_api.c:423
Enable/disable NAT64 plugin.
Definition: nat64.api:38
static void vl_api_nat64_bib_dump_t_handler(vl_api_nat64_bib_dump_t *mp)
Definition: nat64_api.c:286
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vl_api_nat_config_flags_t flags
Definition: nat64.api:164
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:71
NAT64 session table details response.
Definition: nat64.api:257