VPP-286: Add CLI Command documentation via doxygen comments for vnet/vnet/ip.
[vpp.git] / vnet / vnet / ip / ip46_cli.c
1 /*
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>
41
42 /**
43  * @file
44  * @brief Set IP Address.
45  *
46  * Configure an IPv4 or IPv6 address for on an interface.
47  */
48
49
50 int ip4_address_compare (ip4_address_t * a1, ip4_address_t * a2)
51 { return clib_net_to_host_u32 (a1->data_u32) - clib_net_to_host_u32 (a2->data_u32); }
52
53 int ip6_address_compare (ip6_address_t * a1, ip6_address_t * a2)
54 {
55   int i;
56   for (i = 0; i < ARRAY_LEN (a1->as_u16); i++)
57     {
58       int cmp = clib_net_to_host_u16 (a1->as_u16[i]) - clib_net_to_host_u16 (a2->as_u16[i]);
59       if (cmp != 0)
60         return cmp;
61     }
62   return 0;
63 }
64
65 /* *INDENT-OFF* */
66 VLIB_CLI_COMMAND (set_interface_ip_command, static) = {
67   .path = "set interface ip",
68   .short_help = "IP4/IP6 commands",
69 };
70 /* *INDENT-ON* */
71
72 void ip_del_all_interface_addresses (vlib_main_t *vm, u32 sw_if_index)
73 {
74   ip4_main_t * im4 = &ip4_main;
75   ip4_address_t * ip4_addrs = 0;
76   u32 *ip4_masks = 0;
77   ip6_main_t * im6 = &ip6_main;
78   ip6_address_t * ip6_addrs = 0;
79   u32 *ip6_masks = 0;
80   ip_interface_address_t * ia;
81   int i;
82
83   foreach_ip_interface_address (&im4->lookup_main, ia, sw_if_index, 
84                                 0 /* honor unnumbered */,
85   ({
86     ip4_address_t * x = (ip4_address_t *)
87       ip_interface_address_get_address (&im4->lookup_main, ia);
88     vec_add1 (ip4_addrs, x[0]);
89     vec_add1 (ip4_masks, ia->address_length);
90   }));
91
92   foreach_ip_interface_address (&im6->lookup_main, ia, sw_if_index, 
93                                 0 /* honor unnumbered */,
94   ({
95     ip6_address_t * x = (ip6_address_t *)
96       ip_interface_address_get_address (&im6->lookup_main, ia);
97     vec_add1 (ip6_addrs, x[0]);
98     vec_add1 (ip6_masks, ia->address_length);
99   }));
100
101   for (i = 0; i < vec_len (ip4_addrs); i++)
102     ip4_add_del_interface_address (vm, sw_if_index, &ip4_addrs[i], 
103                                    ip4_masks[i], 1 /* is_del */);
104   for (i = 0; i < vec_len (ip6_addrs); i++)
105     ip6_add_del_interface_address (vm, sw_if_index, &ip6_addrs[i], 
106                                    ip6_masks[i], 1 /* is_del */);
107
108   vec_free (ip4_addrs);
109   vec_free (ip4_masks);
110   vec_free (ip6_addrs);
111   vec_free (ip6_masks);
112 }
113
114 static clib_error_t *
115 ip_address_delete_cleanup (vnet_main_t * vnm, u32 hw_if_index, u32 is_create)
116 {
117   vlib_main_t * vm = vlib_get_main();
118   vnet_hw_interface_t * hw;
119
120   if (is_create)
121     return 0;
122   
123   hw = vnet_get_hw_interface (vnm, hw_if_index);
124
125   ip_del_all_interface_addresses (vm, hw->sw_if_index);
126   return 0;
127 }
128
129 VNET_HW_INTERFACE_ADD_DEL_FUNCTION (ip_address_delete_cleanup);
130
131 static clib_error_t *
132 add_del_ip_address (vlib_main_t * vm,
133                     unformat_input_t * input,
134                     vlib_cli_command_t * cmd)
135 {
136   vnet_main_t * vnm = vnet_get_main();
137   ip4_address_t a4;
138   ip6_address_t a6;
139   clib_error_t * error = 0;
140   u32 sw_if_index, length, is_del;
141
142   sw_if_index = ~0;
143   is_del = 0;
144
145   if (unformat (input, "del"))
146     is_del = 1;
147
148   if (! unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
149     {
150       error = clib_error_return (0, "unknown interface `%U'",
151                                  format_unformat_error, input);
152       goto done;
153     }
154
155   if (is_del && unformat (input, "all"))
156     ip_del_all_interface_addresses (vm, sw_if_index);
157   else if (unformat (input, "%U/%d", unformat_ip4_address, &a4, &length))
158     error = ip4_add_del_interface_address (vm, sw_if_index, &a4, length,
159                                            is_del);
160   else if (unformat (input, "%U/%d", unformat_ip6_address, &a6, &length))
161     error = ip6_add_del_interface_address (vm, sw_if_index, &a6, length,
162                                            is_del);
163   else
164     {
165       error = clib_error_return (0, "expected IP4/IP6 address/length `%U'",
166                                  format_unformat_error, input);
167       goto done;
168     }
169
170
171  done:
172   return error;
173 }
174
175 /*?
176  * Add an IP Address to an interface or remove and IP Address from an interface.
177  * The IP Address can be an IPv4 or an IPv6 address. Interfaces may have multiple
178  * IPv4 and IPv6 addresses. There is no concept of primary vs. secondary
179  * interface addresses; they're just addresses.
180  *
181  * To display the addresses associated with a given interface, use the command
182  * '<em>show interface address <interface></em>'.
183  *
184  * Note that the debug CLI does not enforce classful mask-width / addressing
185  * constraints.
186  *
187  * @cliexpar
188  * @parblock
189  * An example of how to add an IPv4 address to an interface:
190  * @cliexcmd{set interface ip address GigabitEthernet2/0/0 172.16.2.12/24}
191  *
192  * An example of how to add an IPv6 address to an interface:
193  * @cliexcmd{set interface ip address GigabitEthernet2/0/0 @::a:1:1:0:7/126}
194  *
195  * To delete a specific interface ip address:
196  * @cliexcmd{set interface ip address GigabitEthernet2/0/0 172.16.2.12/24 del}
197  *
198  * To delete all interfaces addresses (IPv4 and IPv6):
199  * @cliexcmd{set interface ip address GigabitEthernet2/0/0 del all}
200  * @endparblock
201  ?*/
202 /* *INDENT-OFF* */
203 VLIB_CLI_COMMAND (set_interface_ip_address_command, static) = {
204   .path = "set interface ip address",
205   .function = add_del_ip_address,
206   .short_help = "set interface ip address <interface> [<ip-addr>/<mask> [del]] | [del all]",
207 };
208 /* *INDENT-ON* */
209
210 /* Dummy init function to get us linked in. */
211 static clib_error_t * ip4_cli_init (vlib_main_t * vm)
212 { return 0; }
213
214 VLIB_INIT_FUNCTION (ip4_cli_init);