FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
nat66_cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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  * @file
17  * @brief NAT66 CLI
18  */
19 
20 #include <nat/nat66/nat66.h>
21 #include <vnet/fib/fib_table.h>
22 
23 #define NAT66_EXPECTED_ARGUMENT "expected required argument(s)"
24 #define NAT66_PLUGIN_DISABLED "error plugin disabled"
25 
26 #define CHECK_ENABLED() \
27  do \
28  { \
29  if (PREDICT_FALSE (!nat66_main.enabled)) \
30  { \
31  return clib_error_return (0, NAT66_PLUGIN_DISABLED); \
32  } \
33  } \
34  while (0)
35 
36 static clib_error_t *
38  vlib_cli_command_t *cmd)
39 {
41  unformat_input_t _line_input, *line_input = &_line_input;
42  clib_error_t *error = 0;
43 
44  u32 outside_vrf = 0;
45  u8 enable_set = 0, enable = 0;
46 
47  if (!unformat_user (input, unformat_line_input, line_input))
49 
50  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
51  {
52  if (unformat (line_input, "outside-vrf %u", &outside_vrf))
53  ;
54  else if (!enable_set)
55  {
56  enable_set = 1;
57  if (unformat (line_input, "disable"))
58  ;
59  else if (unformat (line_input, "enable"))
60  enable = 1;
61  }
62  else
63  {
64  error = clib_error_return (0, "unknown input '%U'",
65  format_unformat_error, line_input);
66  goto done;
67  }
68  }
69 
70  if (!enable_set)
71  {
72  error = clib_error_return (0, "expected enable | disable");
73  goto done;
74  }
75 
76  if (enable)
77  {
78  if (nm->enabled)
79  {
80  error = clib_error_return (0, "already enabled");
81  goto done;
82  }
83 
84  if (nat66_plugin_enable (outside_vrf) != 0)
85  error = clib_error_return (0, "enable failed");
86  }
87  else
88  {
89  if (!nm->enabled)
90  {
91  error = clib_error_return (0, "already disabled");
92  goto done;
93  }
94 
95  if (nat66_plugin_disable () != 0)
96  error = clib_error_return (0, "disable failed");
97  }
98 
99 done:
100  unformat_free (line_input);
101  return error;
102 }
103 
104 static clib_error_t *
106  unformat_input_t * input,
107  vlib_cli_command_t * cmd)
108 {
109  unformat_input_t _line_input, *line_input = &_line_input;
110  vnet_main_t *vnm = vnet_get_main ();
111  clib_error_t *error = 0;
113  u32 *inside_sw_if_indices = 0;
114  u32 *outside_sw_if_indices = 0;
115  u8 is_add = 1;
116  int i, rv;
117 
118  CHECK_ENABLED ();
119 
120  if (!unformat_user (input, unformat_line_input, line_input))
122 
123  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
124  {
125  if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
126  vnm, &sw_if_index))
127  vec_add1 (inside_sw_if_indices, sw_if_index);
128  else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
129  vnm, &sw_if_index))
130  vec_add1 (outside_sw_if_indices, sw_if_index);
131  else if (unformat (line_input, "del"))
132  is_add = 0;
133  else
134  {
135  error = clib_error_return (0, "unknown input '%U'",
136  format_unformat_error, line_input);
137  goto done;
138  }
139  }
140 
141  if (vec_len (inside_sw_if_indices))
142  {
143  for (i = 0; i < vec_len (inside_sw_if_indices); i++)
144  {
145  sw_if_index = inside_sw_if_indices[i];
146  rv = nat66_interface_add_del (sw_if_index, 1, is_add);
147  switch (rv)
148  {
149  case VNET_API_ERROR_NO_SUCH_ENTRY:
150  error =
151  clib_error_return (0, "%U NAT66 feature not enabled.",
154  goto done;
155  case VNET_API_ERROR_VALUE_EXIST:
156  error =
157  clib_error_return (0, "%U NAT66 feature already enabled.",
160  goto done;
161  case VNET_API_ERROR_INVALID_VALUE:
162  case VNET_API_ERROR_INVALID_VALUE_2:
163  error =
165  "%U NAT66 feature enable/disable failed.",
168  goto done;
169  default:
170  break;
171 
172  }
173  }
174  }
175 
176  if (vec_len (outside_sw_if_indices))
177  {
178  for (i = 0; i < vec_len (outside_sw_if_indices); i++)
179  {
180  sw_if_index = outside_sw_if_indices[i];
181  rv = nat66_interface_add_del (sw_if_index, 0, is_add);
182  switch (rv)
183  {
184  case VNET_API_ERROR_NO_SUCH_ENTRY:
185  error =
186  clib_error_return (0, "%U NAT66 feature not enabled.",
189  goto done;
190  case VNET_API_ERROR_VALUE_EXIST:
191  error =
192  clib_error_return (0, "%U NAT66 feature already enabled.",
195  goto done;
196  case VNET_API_ERROR_INVALID_VALUE:
197  case VNET_API_ERROR_INVALID_VALUE_2:
198  error =
200  "%U NAT66 feature enable/disable failed.",
203  goto done;
204  default:
205  break;
206 
207  }
208  }
209  }
210 
211 done:
212  unformat_free (line_input);
213  vec_free (inside_sw_if_indices);
214  vec_free (outside_sw_if_indices);
215 
216  return error;
217 }
218 
219 static int
221 {
222  vlib_main_t *vm = ctx;
223  vnet_main_t *vnm = vnet_get_main ();
225  vnet_get_sw_interface (vnm, i->sw_if_index),
226  nat66_interface_is_inside (i) ? "in" : "out");
227  return 0;
228 }
229 
230 static clib_error_t *
232  vlib_cli_command_t * cmd)
233 {
234  CHECK_ENABLED ();
235  vlib_cli_output (vm, "NAT66 interfaces:");
237  return 0;
238 }
239 
240 static clib_error_t *
242  unformat_input_t * input,
243  vlib_cli_command_t * cmd)
244 {
245  unformat_input_t _line_input, *line_input = &_line_input;
246  clib_error_t *error = 0;
247  ip6_address_t l_addr, e_addr;
248  u32 vrf_id = 0;
249  u8 is_add = 1;
250  int rv;
251 
252  CHECK_ENABLED ();
253 
254  if (!unformat_user (input, unformat_line_input, line_input))
256 
257  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
258  {
259  if (unformat (line_input, "local %U external %U",
260  unformat_ip6_address, &l_addr,
261  unformat_ip6_address, &e_addr))
262  ;
263  else if (unformat (line_input, "vrf %u", &vrf_id))
264  ;
265  else if (unformat (line_input, "del"))
266  is_add = 0;
267  else
268  {
269  error = clib_error_return (0, "unknown input: '%U'",
270  format_unformat_error, line_input);
271  goto done;
272  }
273  }
274 
275  rv = nat66_static_mapping_add_del (&l_addr, &e_addr, vrf_id, is_add);
276 
277  switch (rv)
278  {
279  case VNET_API_ERROR_NO_SUCH_ENTRY:
280  error = clib_error_return (0, "NAT66 static mapping entry not exist.");
281  goto done;
282  case VNET_API_ERROR_VALUE_EXIST:
283  error = clib_error_return (0, "NAT66 static mapping entry exist.");
284  goto done;
285  default:
286  break;
287  }
288 
289 done:
290  unformat_free (line_input);
291 
292  return error;
293 }
294 
295 static int
297 {
299  vlib_main_t *vm = ctx;
300  fib_table_t *fib;
301  vlib_counter_t vc;
302 
304  if (!fib)
305  return -1;
306 
307  vlib_get_combined_counter (&nm->session_counters, sm - nm->sm, &vc);
308 
309  vlib_cli_output (vm, " local %U external %U vrf %d",
312  vlib_cli_output (vm, " total pkts %lld, total bytes %lld", vc.packets,
313  vc.bytes);
314 
315  return 0;
316 }
317 
318 static clib_error_t *
320  unformat_input_t * input,
321  vlib_cli_command_t * cmd)
322 {
323  CHECK_ENABLED ();
324  vlib_cli_output (vm, "NAT66 static mappings:");
326  return 0;
327 }
328 
329 /*?
330  * @cliexpar
331  * @cliexstart{nat66}
332  * To enable NAT66 plugin
333  * vpp# nat66 enable
334  * To disable NAT66 plugin
335  * vpp# nat66 disable
336  * To enable NAT66 plugin with outside-vrf id 10
337  * vpp# nat66 enable outside-vrf 10
338  * @cliexend
339 ?*/
341  .path = "nat66",
342  .short_help = "nat66 <enable [outside-vrf <vrf-id>]>|disable",
344 };
345 
346 /*?
347  * @cliexpar
348  * @cliexstart{set interface nat66}
349  * Enable/disable NAT66 feature on the interface.
350  * To enable NAT66 feature with local (IPv6) network interface
351  * GigabitEthernet0/8/0 and external (IPv4) network interface
352  * GigabitEthernet0/a/0 use:
353  * vpp# set interface nat66 in GigabitEthernet0/8/0 out GigabitEthernet0/a/0
354  * @cliexend
355 ?*/
357  .path = "set interface nat66",
358  .short_help = "set interface nat66 in|out <intfc> [del]",
360 };
361 
362 /*?
363  * @cliexpar
364  * @cliexstart{show nat66 interfaces}
365  * Show interfaces with NAT66 feature.
366  * To show interfaces with NAT66 feature use:
367  * vpp# show nat66 interfaces
368  * NAT66 interfaces:
369  * GigabitEthernet0/8/0 in
370  * GigabitEthernet0/a/0 out
371  * @cliexend
372 ?*/
374  .path = "show nat66 interfaces",
375  .short_help = "show nat66 interfaces",
377 };
378 
379 /*?
380  * @cliexpar
381  * @cliexstart{nat66 add static mapping}
382  * Add/delete NAT66 static mapping entry.
383  * To add NAT66 static mapping entry use:
384  * vpp# nat66 add static mapping local fd01:1::4 external 2001:db8:c000:223::
385  * vpp# nat66 add static mapping local fd01:1::2 external 2001:db8:c000:221:: vrf 10
386  * @cliexend
387 ?*/
389  .path = "nat66 add static mapping",
390  .short_help = "nat66 add static mapping local <ip6-addr> external <ip6-addr>"
391  " [vfr <table-id>] [del]",
393 };
394 
395 /*?
396  * @cliexpar
397  * @cliexstart{show nat66 static mappings}
398  * Show NAT66 static mappings.
399  * To show NAT66 static mappings use:
400  * vpp# show nat66 static mappings
401  * NAT66 static mappings:
402  * local fd01:1::4 external 2001:db8:c000:223:: vrf 0
403  * local fd01:1::2 external 2001:db8:c000:221:: vrf 10
404  * @cliexend
405 ?*/
407  .path = "show nat66 static mappings",
408  .short_help = "show nat66 static mappings",
410 };
411 
412 /*
413  * fd.io coding-style-patch-verification: ON
414  *
415  * Local Variables:
416  * eval: (c-set-style "gnu")
417  * End:
418  */
nat66_interface_add_del
int nat66_interface_add_del(u32 sw_if_index, u8 is_inside, u8 is_add)
Definition: nat66.c:156
set_interface_nat66_command
static vlib_cli_command_t set_interface_nat66_command
(constructor) VLIB_CLI_COMMAND (set_interface_nat66_command)
Definition: nat66_cli.c:356
nat66_enable_disable_command
static vlib_cli_command_t nat66_enable_disable_command
(constructor) VLIB_CLI_COMMAND (nat66_enable_disable_command)
Definition: nat66_cli.c:340
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
nat66_static_mapping_t::e_addr
ip6_address_t e_addr
Definition: nat66.h:29
nat66_interfaces_walk
void nat66_interfaces_walk(nat66_interface_walk_fn_t fn, void *ctx)
Definition: nat66.c:202
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
nat66_static_mapping_t::l_addr
ip6_address_t l_addr
Definition: nat66.h:28
nat66_cli_interface_walk
static int nat66_cli_interface_walk(nat66_interface_t *i, void *ctx)
Definition: nat66_cli.c:220
show_nat66_static_mappings_command
static vlib_cli_command_t show_nat66_static_mappings_command
(constructor) VLIB_CLI_COMMAND (show_nat66_static_mappings_command)
Definition: nat66_cli.c:406
nat66_plugin_enable
int nat66_plugin_enable(u32 outside_vrf)
Definition: nat66.c:86
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
fib_table.h
nat66_static_mapping_t::fib_index
u32 fib_index
Definition: nat66.h:30
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
show_nat66_interfaces_command
static vlib_cli_command_t show_nat66_interfaces_command
(constructor) VLIB_CLI_COMMAND (show_nat66_interfaces_command)
Definition: nat66_cli.c:373
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
nat66_enable_disable_command_fn
static clib_error_t * nat66_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat66_cli.c:37
nat66_static_mappings_walk
void nat66_static_mappings_walk(nat66_static_mapping_walk_fn_t fn, void *ctx)
Definition: nat66.c:320
unformat_input_t
struct _unformat_input_t unformat_input_t
error
Definition: cJSON.c:88
nat66_static_mapping_add_del
int nat66_static_mapping_add_del(ip6_address_t *l_addr, ip6_address_t *e_addr, u32 vrf_id, u8 is_add)
Definition: nat66.c:239
nat66_add_del_static_mapping_command_fn
static clib_error_t * nat66_add_del_static_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat66_cli.c:241
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
fib_table_t_
A protocol Independent FIB table.
Definition: fib_table.h:71
nat66_cli_static_mapping_walk
static int nat66_cli_static_mapping_walk(nat66_static_mapping_t *sm, void *ctx)
Definition: nat66_cli.c:296
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
nat44_ei_main_s::enabled
u8 enabled
Definition: nat44_ei.h:470
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
fib_table_t_::ft_table_id
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
vlib_counter_t
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
nat66_interface_feature_command_fn
static clib_error_t * nat66_interface_feature_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat66_cli.c:105
CHECK_ENABLED
#define CHECK_ENABLED()
Definition: nat66_cli.c:26
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
nat66_main_t
Definition: nat66.h:58
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
vlib_counter_t::packets
counter_t packets
packet counter
Definition: counter_types.h:28
NAT66_EXPECTED_ARGUMENT
#define NAT66_EXPECTED_ARGUMENT
Definition: nat66_cli.c:23
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
vlib_get_combined_counter
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:272
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
nat66_show_interfaces_command_fn
static clib_error_t * nat66_show_interfaces_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat66_cli.c:231
show_nat66_add_del_static_mapping_command
static vlib_cli_command_t show_nat66_add_del_static_mapping_command
(constructor) VLIB_CLI_COMMAND (show_nat66_add_del_static_mapping_command)
Definition: nat66_cli.c:388
nat66_plugin_disable
int nat66_plugin_disable()
Definition: nat66.c:108
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:459
fib_table_get
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
u32
unsigned int u32
Definition: types.h:88
vlib_counter_t::bytes
counter_t bytes
byte counter
Definition: counter_types.h:29
FIB_PROTOCOL_IP6
@ FIB_PROTOCOL_IP6
Definition: fib_types.h:37
nat66_interface_is_inside
#define nat66_interface_is_inside(i)
Definition: nat66.h:55
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
nat66_main
nat66_main_t nat66_main
Definition: nat66.c:25
nm
nat44_ei_main_t * nm
Definition: nat44_ei_hairpinning.c:413
vlib_main_t
Definition: main.h:102
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
unformat_ip6_address
unformat_function_t unformat_ip6_address
Definition: format.h:89
rv
int __clib_unused rv
Definition: application.c:491
nat66_interface_t
Definition: nat66.h:47
vrf_id
u32 vrf_id
Definition: nat44_ed.api:1053
nat66.h
NAT66 global declarations.
vlib_cli_command_t
Definition: cli.h:92
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
nat66_static_mapping_t
Definition: nat66.h:26
nat66_show_static_mappings_command_fn
static clib_error_t * nat66_show_static_mappings_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat66_cli.c:319
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
format_vnet_sw_interface_name
format_function_t format_vnet_sw_interface_name
Definition: interface_funcs.h:453