Line data Source code
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/dslite.h>
16 :
17 : #define DSLITE_EXPECTED_ARGUMENT "expected required argument(s)"
18 :
19 : static clib_error_t *
20 0 : dslite_add_del_pool_addr_command_fn (vlib_main_t * vm,
21 : unformat_input_t * input,
22 : vlib_cli_command_t * cmd)
23 : {
24 0 : dslite_main_t *dm = &dslite_main;
25 0 : unformat_input_t _line_input, *line_input = &_line_input;
26 : ip4_address_t start_addr, end_addr, this_addr;
27 : u32 start_host_order, end_host_order;
28 : int count, rv;
29 0 : u8 is_add = 1;
30 0 : clib_error_t *error = 0;
31 :
32 : /* Get a line of input. */
33 0 : if (!unformat_user (input, unformat_line_input, line_input))
34 0 : return clib_error_return (0, DSLITE_EXPECTED_ARGUMENT);
35 :
36 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
37 : {
38 0 : if (unformat (line_input, "%U - %U",
39 : unformat_ip4_address, &start_addr,
40 : unformat_ip4_address, &end_addr))
41 : ;
42 0 : else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
43 0 : end_addr = start_addr;
44 0 : else if (unformat (line_input, "del"))
45 0 : is_add = 0;
46 : else
47 : {
48 0 : error = clib_error_return (0, "unknown input '%U'",
49 : format_unformat_error, line_input);
50 0 : goto done;
51 : }
52 : }
53 :
54 0 : start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
55 0 : end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
56 :
57 0 : if (end_host_order < start_host_order)
58 : {
59 0 : error = clib_error_return (0, "end address less than start address");
60 0 : goto done;
61 : }
62 :
63 0 : count = (end_host_order - start_host_order) + 1;
64 0 : this_addr = start_addr;
65 :
66 0 : rv = nat_add_del_ip4_pool_addrs (&dm->pool, this_addr, count, is_add, 0);
67 :
68 0 : switch (rv)
69 : {
70 0 : case VNET_API_ERROR_NO_SUCH_ENTRY:
71 : error =
72 0 : clib_error_return (0, "DS-Lite pool address %U not exist.",
73 : format_ip4_address, &this_addr);
74 0 : break;
75 0 : case VNET_API_ERROR_VALUE_EXIST:
76 : error =
77 0 : clib_error_return (0, "DS-Lite pool address %U exist.",
78 : format_ip4_address, &this_addr);
79 0 : break;
80 : }
81 :
82 0 : done:
83 0 : unformat_free (line_input);
84 :
85 0 : return error;
86 : }
87 :
88 : static clib_error_t *
89 1 : dslite_show_pool_command_fn (vlib_main_t * vm,
90 : unformat_input_t * input,
91 : vlib_cli_command_t * cmd)
92 : {
93 1 : dslite_main_t *dm = &dslite_main;
94 : nat_ip4_pool_addr_t *a;
95 :
96 1 : vlib_cli_output (vm, "DS-Lite pool:");
97 :
98 : /* *INDENT-OFF* */
99 2 : vec_foreach (a, dm->pool.pool_addr)
100 : {
101 1 : vlib_cli_output (vm, "%U", format_ip4_address, &a->addr);
102 : }
103 : /* *INDENT-ON* */
104 1 : return 0;
105 : }
106 :
107 : static clib_error_t *
108 0 : dslite_set_aftr_tunnel_addr_command_fn (vlib_main_t * vm,
109 : unformat_input_t * input,
110 : vlib_cli_command_t * cmd)
111 : {
112 0 : dslite_main_t *dm = &dslite_main;
113 0 : unformat_input_t _line_input, *line_input = &_line_input;
114 : ip6_address_t ip6_addr;
115 : int rv;
116 0 : clib_error_t *error = 0;
117 :
118 : /* Get a line of input. */
119 0 : if (!unformat_user (input, unformat_line_input, line_input))
120 0 : return clib_error_return (0, DSLITE_EXPECTED_ARGUMENT);
121 :
122 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
123 : {
124 0 : if (unformat (line_input, "%U", unformat_ip6_address, &ip6_addr))
125 : ;
126 : else
127 : {
128 0 : error = clib_error_return (0, "unknown input '%U'",
129 : format_unformat_error, line_input);
130 0 : goto done;
131 : }
132 : }
133 :
134 0 : rv = dslite_set_aftr_ip6_addr (dm, &ip6_addr);
135 :
136 0 : if (rv)
137 : error =
138 0 : clib_error_return (0,
139 : "Set DS-Lite AFTR tunnel endpoint address failed.");
140 :
141 0 : done:
142 0 : unformat_free (line_input);
143 :
144 0 : return error;
145 : }
146 :
147 : static clib_error_t *
148 2 : dslite_show_aftr_ip6_addr_command_fn (vlib_main_t * vm,
149 : unformat_input_t * input,
150 : vlib_cli_command_t * cmd)
151 : {
152 2 : dslite_main_t *dm = &dslite_main;
153 :
154 2 : vlib_cli_output (vm, "%U", format_ip6_address, &dm->aftr_ip6_addr);
155 2 : return 0;
156 : }
157 :
158 : static clib_error_t *
159 0 : dslite_set_b4_tunnel_addr_command_fn (vlib_main_t * vm,
160 : unformat_input_t * input,
161 : vlib_cli_command_t * cmd)
162 : {
163 0 : dslite_main_t *dm = &dslite_main;
164 0 : unformat_input_t _line_input, *line_input = &_line_input;
165 : ip6_address_t ip6_addr;
166 : int rv;
167 0 : clib_error_t *error = 0;
168 :
169 : /* Get a line of input. */
170 0 : if (!unformat_user (input, unformat_line_input, line_input))
171 0 : return clib_error_return (0, DSLITE_EXPECTED_ARGUMENT);
172 :
173 0 : while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
174 : {
175 0 : if (unformat (line_input, "%U", unformat_ip6_address, &ip6_addr))
176 : ;
177 : else
178 : {
179 0 : error = clib_error_return (0, "unknown input '%U'",
180 : format_unformat_error, line_input);
181 0 : goto done;
182 : }
183 : }
184 :
185 0 : rv = dslite_set_b4_ip6_addr (dm, &ip6_addr);
186 :
187 0 : if (rv)
188 : error =
189 0 : clib_error_return (0, "Set DS-Lite B4 tunnel endpoint address failed.");
190 :
191 0 : done:
192 0 : unformat_free (line_input);
193 :
194 0 : return error;
195 : }
196 :
197 : static clib_error_t *
198 1 : dslite_show_b4_ip6_addr_command_fn (vlib_main_t * vm,
199 : unformat_input_t * input,
200 : vlib_cli_command_t * cmd)
201 : {
202 1 : dslite_main_t *dm = &dslite_main;
203 :
204 1 : vlib_cli_output (vm, "%U", format_ip6_address, &dm->b4_ip6_addr);
205 1 : return 0;
206 : }
207 :
208 : static u8 *
209 3 : format_dslite_session (u8 * s, va_list * args)
210 : {
211 3 : dslite_session_t *session = va_arg (*args, dslite_session_t *);
212 3 : u32 indent = format_get_indent (s);
213 :
214 3 : s = format (s, "%Uin %U:%u out %U:%u protocol %U\n",
215 : format_white_space, indent + 2,
216 : format_ip4_address, &session->in2out.addr,
217 3 : clib_net_to_host_u16 (session->in2out.port),
218 : format_ip4_address, &session->out2in.addr,
219 3 : clib_net_to_host_u16 (session->out2in.port),
220 3 : format_nat_protocol, session->in2out.proto);
221 3 : s = format (s, "%Utotal pkts %d, total bytes %lld\n",
222 : format_white_space, indent + 4,
223 : session->total_pkts, session->total_bytes);
224 3 : return s;
225 : }
226 :
227 : static u8 *
228 2 : format_dslite_b4 (u8 * s, va_list * args)
229 : {
230 2 : dslite_per_thread_data_t *td = va_arg (*args, dslite_per_thread_data_t *);
231 2 : dslite_b4_t *b4 = va_arg (*args, dslite_b4_t *);
232 : dlist_elt_t *head, *elt;
233 : u32 elt_index, head_index;
234 : u32 session_index;
235 : dslite_session_t *session;
236 :
237 : s =
238 2 : format (s, "B4 %U %d sessions\n", format_ip6_address, &b4->addr,
239 : b4->nsessions);
240 :
241 2 : if (b4->nsessions == 0)
242 0 : return s;
243 :
244 2 : head_index = b4->sessions_per_b4_list_head_index;
245 2 : head = pool_elt_at_index (td->list_pool, head_index);
246 2 : elt_index = head->next;
247 2 : elt = pool_elt_at_index (td->list_pool, elt_index);
248 2 : session_index = elt->value;
249 5 : while (session_index != ~0)
250 : {
251 3 : session = pool_elt_at_index (td->sessions, session_index);
252 3 : s = format (s, "%U", format_dslite_session, session);
253 3 : elt_index = elt->next;
254 3 : elt = pool_elt_at_index (td->list_pool, elt_index);
255 3 : session_index = elt->value;
256 : }
257 :
258 2 : return s;
259 : }
260 :
261 : static clib_error_t *
262 1 : dslite_show_sessions_command_fn (vlib_main_t * vm,
263 : unformat_input_t * input,
264 : vlib_cli_command_t * cmd)
265 : {
266 1 : dslite_main_t *dm = &dslite_main;
267 : dslite_per_thread_data_t *td;
268 : dslite_b4_t *b4;
269 :
270 : /* *INDENT-OFF* */
271 2 : vec_foreach (td, dm->per_thread_data)
272 : {
273 3 : pool_foreach (b4, td->b4s)
274 : {
275 2 : vlib_cli_output (vm, "%U", format_dslite_b4, td, b4);
276 : }
277 : }
278 : /* *INDENT-ON* */
279 :
280 1 : return 0;
281 : }
282 :
283 : /* *INDENT-OFF* */
284 :
285 : /*?
286 : * @cliexpar
287 : * @cliexstart{dslite add pool address}
288 : * Add/delete DS-Lite pool address for AFTR element.
289 : * To add DS-Lite pool address use:
290 : * vpp# dslite add pool address 10.1.1.3
291 : * To add DS-Lite pool address range use:
292 : * vpp# dslite add pool address 10.1.1.5 - 10.1.1.7
293 : * @cliexend
294 : ?*/
295 216887 : VLIB_CLI_COMMAND (dslite_add_pool_address_command, static) = {
296 : .path = "dslite add pool address",
297 : .short_help = "dslite add pool address <ip4-range-start> [- <ip4-range-end>] "
298 : " [del]",
299 : .function = dslite_add_del_pool_addr_command_fn,
300 : };
301 :
302 : /*?
303 : * @cliexpar
304 : * @cliexstart{show dslite pool}
305 : * Show DS-lite pool addresses.
306 : * vpp# show dslite pool
307 : * DS-Lite pool:
308 : * 10.0.0.3
309 : * 10.0.0.5
310 : * 10.0.0.6
311 : * 10.0.0.7
312 : * @cliexend
313 : ?*/
314 216887 : VLIB_CLI_COMMAND (show_dslite_pool_command, static) = {
315 : .path = "show dslite pool",
316 : .short_help = "show dslite pool",
317 : .function = dslite_show_pool_command_fn,
318 : };
319 :
320 : /*?
321 : * @cliexpar
322 : * @cliexstart{dslite set aftr-tunnel-endpoint-address}
323 : * Set IPv6 tunnel endpoint address of the AFTR element.
324 : * To set AFTR tunnel endpoint address use:
325 : * vpp# dslite set aftr-tunnel-endpoint-address 2001:db8:85a3::8a2e:370:1
326 : * @cliexend
327 : ?*/
328 216887 : VLIB_CLI_COMMAND (dslite_set_aftr_tunnel_addr, static) = {
329 : .path = "dslite set aftr-tunnel-endpoint-address",
330 : .short_help = "dslite set aftr-tunnel-endpoint-address <ip6>",
331 : .function = dslite_set_aftr_tunnel_addr_command_fn,
332 : };
333 :
334 : /*?
335 : * @cliexpar
336 : * @cliexstart{show dslite aftr-tunnel-endpoint-address}
337 : * Show IPv6 tunnel endpoint address of the AFTR element.
338 : * vpp# show dslite aftr-tunnel-endpoint-address
339 : * 2001:db8:85a3::8a2e:370:1
340 : * @cliexend
341 : ?*/
342 216887 : VLIB_CLI_COMMAND (dslite_show_aftr_ip6_addr, static) = {
343 : .path = "show dslite aftr-tunnel-endpoint-address",
344 : .short_help = "show dslite aftr-tunnel-endpoint-address",
345 : .function = dslite_show_aftr_ip6_addr_command_fn,
346 : };
347 :
348 : /*?
349 : * @cliexpar
350 : * @cliexstart{dslite set b4-tunnel-endpoint-address}
351 : * Set IPv6 tunnel endpoint address of the B4 element.
352 : * To set B4 tunnel endpoint address use:
353 : * vpp# dslite set b4-tunnel-endpoint-address 2001:db8:62aa::375e:f4c1:1
354 : * @cliexend
355 : ?*/
356 216887 : VLIB_CLI_COMMAND (dslite_set_b4_tunnel_addr, static) = {
357 : .path = "dslite set b4-tunnel-endpoint-address",
358 : .short_help = "dslite set b4-tunnel-endpoint-address <ip6>",
359 : .function = dslite_set_b4_tunnel_addr_command_fn,
360 : };
361 :
362 : /*?
363 : * @cliexpar
364 : * @cliexstart{show dslite b4-tunnel-endpoint-address}
365 : * Show IPv6 tunnel endpoint address of the B4 element.
366 : * vpp# show dslite b4-tunnel-endpoint-address
367 : * 2001:db8:62aa::375e:f4c1:1
368 : * @cliexend
369 : ?*/
370 216887 : VLIB_CLI_COMMAND (dslite_show_b4_ip6_addr, static) = {
371 : .path = "show dslite b4-tunnel-endpoint-address",
372 : .short_help = "show dslite b4-tunnel-endpoint-address",
373 : .function = dslite_show_b4_ip6_addr_command_fn,
374 : };
375 :
376 : /*?
377 : * @cliexpar
378 : * @cliexstart{show dslite sessions}
379 : * Show DS-Lite sessions.
380 : * vpp# show dslite sessions
381 : * B4 fd01:2::2 1 sessions
382 : * in 192.168.1.1:20000 out 10.0.0.3:16253 protocol udp
383 : * total pkts 2, total bytes 136
384 : * B4 fd01:2::3 2 sessions
385 : * in 192.168.1.1:20001 out 10.0.0.3:18995 protocol tcp
386 : * total pkts 2, total bytes 160
387 : * in 192.168.1.1:4000 out 10.0.0.3:53893 protocol icmp
388 : * total pkts 2, total bytes 136
389 : * @cliexend
390 : ?*/
391 216887 : VLIB_CLI_COMMAND (dslite_show_sessions, static) = {
392 : .path = "show dslite sessions",
393 : .short_help = "show dslite sessions",
394 : .function = dslite_show_sessions_command_fn,
395 : };
396 :
397 : /* *INDENT-ON* */
398 :
399 : /*
400 : * fd.io coding-style-patch-verification: ON
401 : *
402 : * Local Variables:
403 : * eval: (c-set-style "gnu")
404 : * End:
405 : */
|