blob: e3da27914bd8b27eecbaeac10aebcd9c0aadbe6d [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 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 * ip/ip4_cli.c: ip4 commands
17 *
18 * Copyright (c) 2008 Eliot Dresselhaus
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining
21 * a copy of this software and associated documentation files (the
22 * "Software"), to deal in the Software without restriction, including
23 * without limitation the rights to use, copy, modify, merge, publish,
24 * distribute, sublicense, and/or sell copies of the Software, and to
25 * permit persons to whom the Software is furnished to do so, subject to
26 * the following conditions:
27 *
28 * The above copyright notice and this permission notice shall be
29 * included in all copies or substantial portions of the Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 */
39
40#include <vnet/ip/ip.h>
Klement Sekera896c8962019-06-24 11:52:49 +000041#include <vnet/ip/reass/ip4_full_reass.h>
42#include <vnet/ip/reass/ip6_full_reass.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070043
Billy McFall0683c9c2016-10-13 08:27:31 -040044/**
45 * @file
46 * @brief Set IP Address.
47 *
48 * Configure an IPv4 or IPv6 address for on an interface.
49 */
50
51
Dave Barachd7cb1b52016-12-09 09:52:16 -050052int
53ip4_address_compare (ip4_address_t * a1, ip4_address_t * a2)
54{
55 return clib_net_to_host_u32 (a1->data_u32) -
56 clib_net_to_host_u32 (a2->data_u32);
57}
Ed Warnickecb9cada2015-12-08 15:45:58 -070058
Dave Barachd7cb1b52016-12-09 09:52:16 -050059int
60ip6_address_compare (ip6_address_t * a1, ip6_address_t * a2)
Ed Warnickecb9cada2015-12-08 15:45:58 -070061{
62 int i;
63 for (i = 0; i < ARRAY_LEN (a1->as_u16); i++)
64 {
Dave Barachd7cb1b52016-12-09 09:52:16 -050065 int cmp =
66 clib_net_to_host_u16 (a1->as_u16[i]) -
67 clib_net_to_host_u16 (a2->as_u16[i]);
Ed Warnickecb9cada2015-12-08 15:45:58 -070068 if (cmp != 0)
69 return cmp;
70 }
71 return 0;
72}
73
74VLIB_CLI_COMMAND (set_interface_ip_command, static) = {
75 .path = "set interface ip",
76 .short_help = "IP4/IP6 commands",
77};
78
Dave Barachd7cb1b52016-12-09 09:52:16 -050079void
80ip_del_all_interface_addresses (vlib_main_t * vm, u32 sw_if_index)
Ed Warnickecb9cada2015-12-08 15:45:58 -070081{
Dave Barachd7cb1b52016-12-09 09:52:16 -050082 ip4_main_t *im4 = &ip4_main;
83 ip4_address_t *ip4_addrs = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070084 u32 *ip4_masks = 0;
Dave Barachd7cb1b52016-12-09 09:52:16 -050085 ip6_main_t *im6 = &ip6_main;
86 ip6_address_t *ip6_addrs = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070087 u32 *ip6_masks = 0;
Dave Barachd7cb1b52016-12-09 09:52:16 -050088 ip_interface_address_t *ia;
Ed Warnickecb9cada2015-12-08 15:45:58 -070089 int i;
90
Dave Barachd7cb1b52016-12-09 09:52:16 -050091 foreach_ip_interface_address (&im4->lookup_main, ia, sw_if_index,
Ed Warnickecb9cada2015-12-08 15:45:58 -070092 0 /* honor unnumbered */,
93 ({
94 ip4_address_t * x = (ip4_address_t *)
95 ip_interface_address_get_address (&im4->lookup_main, ia);
96 vec_add1 (ip4_addrs, x[0]);
97 vec_add1 (ip4_masks, ia->address_length);
98 }));
99
Dave Barachd7cb1b52016-12-09 09:52:16 -0500100 foreach_ip_interface_address (&im6->lookup_main, ia, sw_if_index,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700101 0 /* honor unnumbered */,
102 ({
103 ip6_address_t * x = (ip6_address_t *)
104 ip_interface_address_get_address (&im6->lookup_main, ia);
105 vec_add1 (ip6_addrs, x[0]);
106 vec_add1 (ip6_masks, ia->address_length);
107 }));
108
109 for (i = 0; i < vec_len (ip4_addrs); i++)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500110 ip4_add_del_interface_address (vm, sw_if_index, &ip4_addrs[i],
111 ip4_masks[i], 1 /* is_del */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700112 for (i = 0; i < vec_len (ip6_addrs); i++)
Dave Barachd7cb1b52016-12-09 09:52:16 -0500113 ip6_add_del_interface_address (vm, sw_if_index, &ip6_addrs[i],
114 ip6_masks[i], 1 /* is_del */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115
116 vec_free (ip4_addrs);
117 vec_free (ip4_masks);
118 vec_free (ip6_addrs);
119 vec_free (ip6_masks);
120}
121
122static clib_error_t *
Dave Barachb8dca742016-07-01 12:38:11 -0400123ip_address_delete_cleanup (vnet_main_t * vnm, u32 hw_if_index, u32 is_create)
124{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500125 vlib_main_t *vm = vlib_get_main ();
126 vnet_hw_interface_t *hw;
Dave Barachb8dca742016-07-01 12:38:11 -0400127
128 if (is_create)
129 return 0;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500130
Dave Barachb8dca742016-07-01 12:38:11 -0400131 hw = vnet_get_hw_interface (vnm, hw_if_index);
132
133 ip_del_all_interface_addresses (vm, hw->sw_if_index);
134 return 0;
135}
136
137VNET_HW_INTERFACE_ADD_DEL_FUNCTION (ip_address_delete_cleanup);
138
139static clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140add_del_ip_address (vlib_main_t * vm,
Dave Barachd7cb1b52016-12-09 09:52:16 -0500141 unformat_input_t * input, vlib_cli_command_t * cmd)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700142{
Dave Barachd7cb1b52016-12-09 09:52:16 -0500143 vnet_main_t *vnm = vnet_get_main ();
Ed Warnickecb9cada2015-12-08 15:45:58 -0700144 ip4_address_t a4;
145 ip6_address_t a6;
Dave Barachd7cb1b52016-12-09 09:52:16 -0500146 clib_error_t *error = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147 u32 sw_if_index, length, is_del;
148
149 sw_if_index = ~0;
150 is_del = 0;
151
152 if (unformat (input, "del"))
153 is_del = 1;
154
Dave Barachd7cb1b52016-12-09 09:52:16 -0500155 if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700156 {
157 error = clib_error_return (0, "unknown interface `%U'",
158 format_unformat_error, input);
159 goto done;
160 }
161
162 if (is_del && unformat (input, "all"))
163 ip_del_all_interface_addresses (vm, sw_if_index);
164 else if (unformat (input, "%U/%d", unformat_ip4_address, &a4, &length))
165 error = ip4_add_del_interface_address (vm, sw_if_index, &a4, length,
166 is_del);
167 else if (unformat (input, "%U/%d", unformat_ip6_address, &a6, &length))
168 error = ip6_add_del_interface_address (vm, sw_if_index, &a6, length,
169 is_del);
170 else
171 {
172 error = clib_error_return (0, "expected IP4/IP6 address/length `%U'",
173 format_unformat_error, input);
174 goto done;
175 }
176
177
Dave Barachd7cb1b52016-12-09 09:52:16 -0500178done:
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 return error;
180}
Billy McFall0683c9c2016-10-13 08:27:31 -0400181
Keith Burns (alagalah)6ef7bb92016-09-10 14:55:04 -0700182/*?
Billy McFall0683c9c2016-10-13 08:27:31 -0400183 * Add an IP Address to an interface or remove and IP Address from an interface.
184 * The IP Address can be an IPv4 or an IPv6 address. Interfaces may have multiple
185 * IPv4 and IPv6 addresses. There is no concept of primary vs. secondary
186 * interface addresses; they're just addresses.
187 *
188 * To display the addresses associated with a given interface, use the command
189 * '<em>show interface address <interface></em>'.
190 *
191 * Note that the debug CLI does not enforce classful mask-width / addressing
192 * constraints.
Keith Burns (alagalah)6ef7bb92016-09-10 14:55:04 -0700193 *
194 * @cliexpar
Billy McFall0683c9c2016-10-13 08:27:31 -0400195 * @parblock
196 * An example of how to add an IPv4 address to an interface:
197 * @cliexcmd{set interface ip address GigabitEthernet2/0/0 172.16.2.12/24}
198 *
199 * An example of how to add an IPv6 address to an interface:
200 * @cliexcmd{set interface ip address GigabitEthernet2/0/0 @::a:1:1:0:7/126}
201 *
202 * To delete a specific interface ip address:
Benoît Ganne7bed48c2020-10-20 14:36:55 +0200203 * @cliexcmd{set interface ip address del GigabitEthernet2/0/0 172.16.2.12/24}
Billy McFall0683c9c2016-10-13 08:27:31 -0400204 *
205 * To delete all interfaces addresses (IPv4 and IPv6):
Benoît Ganne7bed48c2020-10-20 14:36:55 +0200206 * @cliexcmd{set interface ip address del GigabitEthernet2/0/0 all}
Billy McFall0683c9c2016-10-13 08:27:31 -0400207 * @endparblock
Keith Burns (alagalah)6ef7bb92016-09-10 14:55:04 -0700208 ?*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700209VLIB_CLI_COMMAND (set_interface_ip_address_command, static) = {
210 .path = "set interface ip address",
211 .function = add_del_ip_address,
Matej Klottone0cb0cc2017-02-03 14:48:18 +0100212 .short_help = "set interface ip address [del] <interface> <ip-addr>/<mask> | [all]",
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213};
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214
Klement Sekera4c533132018-02-22 11:41:12 +0100215static clib_error_t *
216set_reassembly_command_fn (vlib_main_t * vm,
217 unformat_input_t * input, vlib_cli_command_t * cmd)
218{
219 vnet_main_t *vnm = vnet_get_main ();
220 unformat_input_t _line_input, *line_input = &_line_input;
221 u32 sw_if_index = ~0;
222 u8 ip4_on = 0;
223 u8 ip6_on = 0;
224
225 /* Get a line of input. */
226 if (!unformat_user (input, unformat_line_input, line_input))
227 {
228 return NULL;
229 }
230
Klement Sekera2926eca2018-04-17 17:48:30 +0200231 if (!unformat_user
232 (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
Klement Sekera4c533132018-02-22 11:41:12 +0100233 {
234 return clib_error_return (0, "Invalid interface name");
235 }
236
Klement Sekera2926eca2018-04-17 17:48:30 +0200237 if (unformat (line_input, "on"))
Klement Sekera4c533132018-02-22 11:41:12 +0100238 {
239 ip4_on = 1;
240 ip6_on = 1;
241 }
Klement Sekera2926eca2018-04-17 17:48:30 +0200242 else if (unformat (line_input, "off"))
Klement Sekera4c533132018-02-22 11:41:12 +0100243 {
244 ip4_on = 0;
245 ip6_on = 0;
246 }
Klement Sekera2926eca2018-04-17 17:48:30 +0200247 else if (unformat (line_input, "ip4"))
Klement Sekera4c533132018-02-22 11:41:12 +0100248 {
249 ip4_on = 1;
250 ip6_on = 0;
251 }
Klement Sekera2926eca2018-04-17 17:48:30 +0200252 else if (unformat (line_input, "ip6"))
Klement Sekera4c533132018-02-22 11:41:12 +0100253 {
254 ip4_on = 0;
255 ip6_on = 1;
256 }
257 else
258 {
259 return clib_error_return (0, "Unknown input `%U'",
260 format_unformat_error, line_input);
261 }
262
263
Klement Sekera896c8962019-06-24 11:52:49 +0000264 vnet_api_error_t rv4 = ip4_full_reass_enable_disable (sw_if_index, ip4_on);
265 vnet_api_error_t rv6 = ip6_full_reass_enable_disable (sw_if_index, ip6_on);
Klement Sekera4c533132018-02-22 11:41:12 +0100266 if (rv4 && rv6)
267 {
268 return clib_error_return (0,
Klement Sekera896c8962019-06-24 11:52:49 +0000269 "`ip4_full_reass_enable_disable' API call failed, rv=%d:%U, "
270 "`ip6_full_reass_enable_disable' API call failed, rv=%d:%U",
Klement Sekera4c533132018-02-22 11:41:12 +0100271 (int) rv4, format_vnet_api_errno, rv4,
272 (int) rv6, format_vnet_api_errno, rv6);
273 }
274 else if (rv4)
275 {
276 return clib_error_return (0,
Klement Sekera896c8962019-06-24 11:52:49 +0000277 "`ip4_full_reass_enable_disable' API call failed, rv=%d:%U",
Klement Sekera4c533132018-02-22 11:41:12 +0100278 (int) rv4, format_vnet_api_errno, rv4);
279 }
280 else if (rv6)
281 {
282 return clib_error_return (0,
Klement Sekera896c8962019-06-24 11:52:49 +0000283 "`ip6_full_reass_enable_disable' API call failed, rv=%d:%U",
Klement Sekera4c533132018-02-22 11:41:12 +0100284 (int) rv6, format_vnet_api_errno, rv6);
285 }
286 return NULL;
287}
288
Klement Sekera4c533132018-02-22 11:41:12 +0100289VLIB_CLI_COMMAND (set_reassembly_command, static) = {
290 .path = "set interface reassembly",
291 .short_help = "set interface reassembly <interface-name> [on|off|ip4|ip6]",
292 .function = set_reassembly_command_fn,
293};
Klement Sekera4c533132018-02-22 11:41:12 +0100294
Ed Warnickecb9cada2015-12-08 15:45:58 -0700295/* Dummy init function to get us linked in. */
Dave Barachd7cb1b52016-12-09 09:52:16 -0500296static clib_error_t *
297ip4_cli_init (vlib_main_t * vm)
298{
299 return 0;
300}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301
302VLIB_INIT_FUNCTION (ip4_cli_init);
Dave Barachd7cb1b52016-12-09 09:52:16 -0500303
304/*
305 * fd.io coding-style-patch-verification: ON
306 *
307 * Local Variables:
308 * eval: (c-set-style "gnu")
309 * End:
310 */