]> git.proxmox.com Git - mirror_frr.git/blob - sharpd/sharp_vty.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[mirror_frr.git] / sharpd / sharp_vty.c
1 /*
2 * SHARP - vty code
3 * Copyright (C) Cumulus Networks, Inc.
4 * Donald Sharp
5 *
6 * This file is part of FRR.
7 *
8 * FRR is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * FRR is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 #include <zebra.h>
23
24 #include "vty.h"
25 #include "command.h"
26 #include "prefix.h"
27 #include "nexthop.h"
28 #include "log.h"
29 #include "vrf.h"
30 #include "zclient.h"
31 #include "nexthop_group.h"
32
33 #include "sharpd/sharp_globals.h"
34 #include "sharpd/sharp_zebra.h"
35 #include "sharpd/sharp_nht.h"
36 #include "sharpd/sharp_vty.h"
37 #ifndef VTYSH_EXTRACT_PL
38 #include "sharpd/sharp_vty_clippy.c"
39 #endif
40
41 DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
42 "sharp watch [vrf NAME$vrf_name] <nexthop$n X:X::X:X$nhop|import$import X:X::X:X/M$inhop> [connected$connected]",
43 "Sharp routing Protocol\n"
44 "Watch for changes\n"
45 "The vrf we would like to watch if non-default\n"
46 "The NAME of the vrf\n"
47 "Watch for nexthop changes\n"
48 "The v6 nexthop to signal for watching\n"
49 "Watch for import check changes\n"
50 "The v6 prefix to signal for watching\n"
51 "Should the route be connected\n")
52 {
53 struct vrf *vrf;
54 struct prefix p;
55 bool type_import;
56
57 if (!vrf_name)
58 vrf_name = VRF_DEFAULT_NAME;
59 vrf = vrf_lookup_by_name(vrf_name);
60 if (!vrf) {
61 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
62 vrf_name);
63 return CMD_WARNING;
64 }
65
66 memset(&p, 0, sizeof(p));
67
68 if (n) {
69 type_import = false;
70 p.prefixlen = 128;
71 memcpy(&p.u.prefix6, &nhop, 16);
72 p.family = AF_INET6;
73 } else {
74 type_import = true;
75 p = *(const struct prefix *)inhop;
76 }
77
78 sharp_nh_tracker_get(&p);
79 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
80 true, !!connected);
81
82 return CMD_SUCCESS;
83 }
84
85 DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
86 "sharp watch [vrf NAME$vrf_name] <nexthop$n A.B.C.D$nhop|import$import A.B.C.D/M$inhop> [connected$connected]",
87 "Sharp routing Protocol\n"
88 "Watch for changes\n"
89 "The vrf we would like to watch if non-default\n"
90 "The NAME of the vrf\n"
91 "Watch for nexthop changes\n"
92 "The v4 address to signal for watching\n"
93 "Watch for import check changes\n"
94 "The v4 prefix for import check to watch\n"
95 "Should the route be connected\n")
96 {
97 struct vrf *vrf;
98 struct prefix p;
99 bool type_import;
100
101 if (!vrf_name)
102 vrf_name = VRF_DEFAULT_NAME;
103 vrf = vrf_lookup_by_name(vrf_name);
104 if (!vrf) {
105 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
106 vrf_name);
107 return CMD_WARNING;
108 }
109
110 memset(&p, 0, sizeof(p));
111
112 if (n) {
113 type_import = false;
114 p.prefixlen = 32;
115 p.u.prefix4 = nhop;
116 p.family = AF_INET;
117 }
118 else {
119 type_import = true;
120 p = *(const struct prefix *)inhop;
121 }
122
123 sharp_nh_tracker_get(&p);
124 sharp_zebra_nexthop_watch(&p, vrf->vrf_id, type_import,
125 true, !!connected);
126
127 return CMD_SUCCESS;
128 }
129
130 DEFPY(sharp_nht_data_dump,
131 sharp_nht_data_dump_cmd,
132 "sharp data nexthop",
133 "Sharp routing Protocol\n"
134 "Nexthop information\n"
135 "Data Dump\n")
136 {
137 sharp_nh_tracker_dump(vty);
138
139 return CMD_SUCCESS;
140 }
141
142 DEFPY (install_routes_data_dump,
143 install_routes_data_dump_cmd,
144 "sharp data route",
145 "Sharp routing Protocol\n"
146 "Data about what is going on\n"
147 "Route Install/Removal Information\n")
148 {
149 char buf[PREFIX_STRLEN];
150 struct timeval r;
151
152 timersub(&sg.r.t_end, &sg.r.t_start, &r);
153 vty_out(vty, "Prefix: %s Total: %u %u %u Time: %jd.%ld\n",
154 prefix2str(&sg.r.orig_prefix, buf, sizeof(buf)),
155 sg.r.total_routes,
156 sg.r.installed_routes,
157 sg.r.removed_routes,
158 (intmax_t)r.tv_sec, (long)r.tv_usec);
159
160 return CMD_SUCCESS;
161 }
162
163 DEFPY (install_routes,
164 install_routes_cmd,
165 "sharp install routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NHGNAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
166 "Sharp routing Protocol\n"
167 "install some routes\n"
168 "Routes to install\n"
169 "The vrf we would like to install into if non-default\n"
170 "The NAME of the vrf\n"
171 "v4 Address to start /32 generation at\n"
172 "v6 Address to start /32 generation at\n"
173 "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
174 "V4 Nexthop address to use\n"
175 "V6 Nexthop address to use\n"
176 "Nexthop-Group to use\n"
177 "The Name of the nexthop-group\n"
178 "How many to create\n"
179 "Instance to use\n"
180 "Instance\n"
181 "Should we repeat this command\n"
182 "How many times to repeat this command\n")
183 {
184 struct vrf *vrf;
185 struct prefix prefix;
186 uint32_t rts;
187
188 sg.r.total_routes = routes;
189 sg.r.installed_routes = 0;
190
191 if (rpt >= 2)
192 sg.r.repeat = rpt * 2;
193 else
194 sg.r.repeat = 0;
195
196 memset(&prefix, 0, sizeof(prefix));
197 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
198 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
199 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
200
201 if (start4.s_addr != 0) {
202 prefix.family = AF_INET;
203 prefix.prefixlen = 32;
204 prefix.u.prefix4 = start4;
205 } else {
206 prefix.family = AF_INET6;
207 prefix.prefixlen = 128;
208 prefix.u.prefix6 = start6;
209 }
210 sg.r.orig_prefix = prefix;
211
212 if (!vrf_name)
213 vrf_name = VRF_DEFAULT_NAME;
214
215 vrf = vrf_lookup_by_name(vrf_name);
216 if (!vrf) {
217 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
218 vrf_name);
219 return CMD_WARNING;
220 }
221
222 if (nexthop_group) {
223 struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
224 if (!nhgc) {
225 vty_out(vty,
226 "Specified Nexthop Group: %s does not exist\n",
227 nexthop_group);
228 return CMD_WARNING;
229 }
230
231 sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
232 } else {
233 if (nexthop4.s_addr != INADDR_ANY) {
234 sg.r.nhop.gate.ipv4 = nexthop4;
235 sg.r.nhop.type = NEXTHOP_TYPE_IPV4;
236 } else {
237 sg.r.nhop.gate.ipv6 = nexthop6;
238 sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
239 }
240
241 sg.r.nhop.vrf_id = vrf->vrf_id;
242 sg.r.nhop_group.nexthop = &sg.r.nhop;
243 }
244
245 sg.r.inst = instance;
246 sg.r.vrf_id = vrf->vrf_id;
247 rts = routes;
248 sharp_install_routes_helper(&prefix, sg.r.vrf_id,
249 sg.r.inst, &sg.r.nhop_group, rts);
250
251 return CMD_SUCCESS;
252 }
253
254 DEFPY(vrf_label, vrf_label_cmd,
255 "sharp label <ip$ipv4|ipv6$ipv6> vrf NAME$vrf_name label (0-100000)$label",
256 "Sharp Routing Protocol\n"
257 "Give a vrf a label\n"
258 "Pop and forward for IPv4\n"
259 "Pop and forward for IPv6\n"
260 VRF_CMD_HELP_STR
261 "The label to use, 0 specifies remove the label installed from previous\n"
262 "Specified range to use\n")
263 {
264 struct vrf *vrf;
265 afi_t afi = (ipv4) ? AFI_IP : AFI_IP6;
266
267 if (strcmp(vrf_name, "default") == 0)
268 vrf = vrf_lookup_by_id(VRF_DEFAULT);
269 else
270 vrf = vrf_lookup_by_name(vrf_name);
271
272 if (!vrf) {
273 vty_out(vty, "Unable to find vrf you silly head");
274 return CMD_WARNING_CONFIG_FAILED;
275 }
276
277 if (label == 0)
278 label = MPLS_LABEL_NONE;
279
280 vrf_label_add(vrf->vrf_id, afi, label);
281 return CMD_SUCCESS;
282 }
283
284 DEFPY (remove_routes,
285 remove_routes_cmd,
286 "sharp remove routes [vrf NAME$vrf_name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
287 "Sharp Routing Protocol\n"
288 "Remove some routes\n"
289 "Routes to remove\n"
290 "The vrf we would like to remove from if non-default\n"
291 "The NAME of the vrf\n"
292 "v4 Starting spot\n"
293 "v6 Starting spot\n"
294 "Routes to uninstall\n"
295 "instance to use\n"
296 "Value of instance\n")
297 {
298 struct vrf *vrf;
299 struct prefix prefix;
300
301 sg.r.total_routes = routes;
302 sg.r.removed_routes = 0;
303 uint32_t rts;
304
305 memset(&prefix, 0, sizeof(prefix));
306
307 if (start4.s_addr != 0) {
308 prefix.family = AF_INET;
309 prefix.prefixlen = 32;
310 prefix.u.prefix4 = start4;
311 } else {
312 prefix.family = AF_INET6;
313 prefix.prefixlen = 128;
314 prefix.u.prefix6 = start6;
315 }
316
317 vrf = vrf_lookup_by_name(vrf_name ? vrf_name : VRF_DEFAULT_NAME);
318 if (!vrf) {
319 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
320 vrf_name ? vrf_name : VRF_DEFAULT_NAME);
321 return CMD_WARNING;
322 }
323
324 sg.r.inst = instance;
325 sg.r.vrf_id = vrf->vrf_id;
326 rts = routes;
327 sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
328 sg.r.inst, rts);
329
330 return CMD_SUCCESS;
331 }
332
333 DEFUN_NOSH (show_debugging_sharpd,
334 show_debugging_sharpd_cmd,
335 "show debugging [sharp]",
336 SHOW_STR
337 DEBUG_STR
338 "Sharp Information\n")
339 {
340 vty_out(vty, "Sharp debugging status\n");
341
342 return CMD_SUCCESS;
343 }
344
345 void sharp_vty_init(void)
346 {
347 install_element(ENABLE_NODE, &install_routes_data_dump_cmd);
348 install_element(ENABLE_NODE, &install_routes_cmd);
349 install_element(ENABLE_NODE, &remove_routes_cmd);
350 install_element(ENABLE_NODE, &vrf_label_cmd);
351 install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
352 install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
353 install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
354
355 install_element(VIEW_NODE, &show_debugging_sharpd_cmd);
356
357 return;
358 }