]> git.proxmox.com Git - mirror_frr.git/blob - sharpd/sharp_vty.c
sharpd: Add cli to allow vrf route installation
[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 <nexthop$n|import$import> X:X::X:X$nhop [connected$connected]",
43 "Sharp routing Protocol\n"
44 "Watch for changes\n"
45 "Watch for nexthop changes\n"
46 "Watch for import check changes\n"
47 "The v6 nexthop to signal for watching\n"
48 "Should the route be connected\n")
49 {
50 struct prefix p;
51 bool type_import;
52
53
54 if (n)
55 type_import = false;
56 else
57 type_import = true;
58
59 memset(&p, 0, sizeof(p));
60
61 p.prefixlen = 128;
62 memcpy(&p.u.prefix6, &nhop, 16);
63 p.family = AF_INET6;
64
65 sharp_nh_tracker_get(&p);
66 sharp_zebra_nexthop_watch(&p, type_import, true, !!connected);
67
68 return CMD_SUCCESS;
69 }
70
71 DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
72 "sharp watch <nexthop$n|import$import> A.B.C.D$nhop [connected$connected]",
73 "Sharp routing Protocol\n"
74 "Watch for changes\n"
75 "Watch for nexthop changes\n"
76 "Watch for import check changes\n"
77 "The v4 nexthop to signal for watching\n"
78 "Should the route be connected\n")
79 {
80 struct prefix p;
81 bool type_import;
82
83 memset(&p, 0, sizeof(p));
84
85 if (n)
86 type_import = false;
87 else
88 type_import = true;
89
90 p.prefixlen = 32;
91 p.u.prefix4 = nhop;
92 p.family = AF_INET;
93
94 sharp_nh_tracker_get(&p);
95 sharp_zebra_nexthop_watch(&p, type_import, true, !!connected);
96
97 return CMD_SUCCESS;
98 }
99
100 DEFPY(sharp_nht_data_dump,
101 sharp_nht_data_dump_cmd,
102 "sharp data nexthop",
103 "Sharp routing Protocol\n"
104 "Nexthop information\n"
105 "Data Dump\n")
106 {
107 sharp_nh_tracker_dump(vty);
108
109 return CMD_SUCCESS;
110 }
111
112 DEFPY (install_routes_data_dump,
113 install_routes_data_dump_cmd,
114 "sharp data route",
115 "Sharp routing Protocol\n"
116 "Data about what is going on\n"
117 "Route Install/Removal Information\n")
118 {
119 char buf[PREFIX_STRLEN];
120 struct timeval r;
121
122 timersub(&sg.r.t_end, &sg.r.t_start, &r);
123 vty_out(vty, "Prefix: %s Total: %u %u %u Time: %ld.%ld\n",
124 prefix2str(&sg.r.orig_prefix, buf, sizeof(buf)),
125 sg.r.total_routes,
126 sg.r.installed_routes,
127 sg.r.removed_routes,
128 r.tv_sec, r.tv_usec);
129
130 return CMD_SUCCESS;
131 }
132
133 DEFPY (install_routes,
134 install_routes_cmd,
135 "sharp install routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> <nexthop <A.B.C.D$nexthop4|X:X::X:X$nexthop6>|nexthop-group NAME$nexthop_group> (1-1000000)$routes [instance (0-255)$instance] [repeat (2-1000)$rpt]",
136 "Sharp routing Protocol\n"
137 "install some routes\n"
138 "Routes to install\n"
139 "The vrf we would like to install into if non-default\n"
140 "The NAME of the vrf\n"
141 "v4 Address to start /32 generation at\n"
142 "v6 Address to start /32 generation at\n"
143 "Nexthop to use(Can be an IPv4 or IPv6 address)\n"
144 "V4 Nexthop address to use\n"
145 "V6 Nexthop address to use\n"
146 "Nexthop-Group to use\n"
147 "The Name of the nexthop-group\n"
148 "How many to create\n"
149 "Instance to use\n"
150 "Instance\n"
151 "Should we repeat this command\n"
152 "How many times to repeat this command\n")
153 {
154 struct vrf *vrf;
155 struct prefix prefix;
156 uint32_t rts;
157
158 sg.r.total_routes = routes;
159 sg.r.installed_routes = 0;
160
161 if (rpt >= 2)
162 sg.r.repeat = rpt * 2;
163 else
164 sg.r.repeat = 0;
165
166 memset(&prefix, 0, sizeof(prefix));
167 memset(&sg.r.orig_prefix, 0, sizeof(sg.r.orig_prefix));
168 memset(&sg.r.nhop, 0, sizeof(sg.r.nhop));
169 memset(&sg.r.nhop_group, 0, sizeof(sg.r.nhop_group));
170
171 if (start4.s_addr != 0) {
172 prefix.family = AF_INET;
173 prefix.prefixlen = 32;
174 prefix.u.prefix4 = start4;
175 } else {
176 prefix.family = AF_INET6;
177 prefix.prefixlen = 128;
178 prefix.u.prefix6 = start6;
179 }
180 sg.r.orig_prefix = prefix;
181
182 vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
183 if (!vrf) {
184 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
185 name ? name : VRF_DEFAULT_NAME);
186 return CMD_WARNING;
187 }
188
189 if (nexthop_group) {
190 struct nexthop_group_cmd *nhgc = nhgc_find(nexthop_group);
191 if (!nhgc) {
192 vty_out(vty,
193 "Specified Nexthop Group: %s does not exist\n",
194 nexthop_group);
195 return CMD_WARNING;
196 }
197
198 sg.r.nhop_group.nexthop = nhgc->nhg.nexthop;
199 } else {
200 if (nexthop4.s_addr != INADDR_ANY) {
201 sg.r.nhop.gate.ipv4 = nexthop4;
202 sg.r.nhop.type = NEXTHOP_TYPE_IPV4;
203 } else {
204 sg.r.nhop.gate.ipv6 = nexthop6;
205 sg.r.nhop.type = NEXTHOP_TYPE_IPV6;
206 }
207
208 sg.r.nhop.vrf_id = vrf->vrf_id;
209 sg.r.nhop_group.nexthop = &sg.r.nhop;
210 }
211
212 sg.r.inst = instance;
213 sg.r.vrf_id = vrf->vrf_id;
214 rts = routes;
215 sharp_install_routes_helper(&prefix, sg.r.vrf_id,
216 sg.r.inst, &sg.r.nhop_group, rts);
217
218 return CMD_SUCCESS;
219 }
220
221 DEFPY(vrf_label, vrf_label_cmd,
222 "sharp label <ip$ipv4|ipv6$ipv6> vrf NAME$name label (0-100000)$label",
223 "Sharp Routing Protocol\n"
224 "Give a vrf a label\n"
225 "Pop and forward for IPv4\n"
226 "Pop and forward for IPv6\n"
227 VRF_CMD_HELP_STR
228 "The label to use, 0 specifies remove the label installed from previous\n"
229 "Specified range to use\n")
230 {
231 struct vrf *vrf;
232 afi_t afi = (ipv4) ? AFI_IP : AFI_IP6;
233
234 if (strcmp(name, "default") == 0)
235 vrf = vrf_lookup_by_id(VRF_DEFAULT);
236 else
237 vrf = vrf_lookup_by_name(name);
238
239 if (!vrf) {
240 vty_out(vty, "Unable to find vrf you silly head");
241 return CMD_WARNING_CONFIG_FAILED;
242 }
243
244 if (label == 0)
245 label = MPLS_LABEL_NONE;
246
247 vrf_label_add(vrf->vrf_id, afi, label);
248 return CMD_SUCCESS;
249 }
250
251 DEFPY (remove_routes,
252 remove_routes_cmd,
253 "sharp remove routes [vrf NAME$name] <A.B.C.D$start4|X:X::X:X$start6> (1-1000000)$routes [instance (0-255)$instance]",
254 "Sharp Routing Protocol\n"
255 "Remove some routes\n"
256 "Routes to remove\n"
257 "The vrf we would like to remove from if non-default\n"
258 "The NAME of the vrf\n"
259 "v4 Starting spot\n"
260 "v6 Starting spot\n"
261 "Routes to uninstall\n"
262 "instance to use\n"
263 "Value of instance\n")
264 {
265 struct vrf *vrf;
266 struct prefix prefix;
267
268 sg.r.total_routes = routes;
269 sg.r.removed_routes = 0;
270 uint32_t rts;
271
272 memset(&prefix, 0, sizeof(prefix));
273
274 if (start4.s_addr != 0) {
275 prefix.family = AF_INET;
276 prefix.prefixlen = 32;
277 prefix.u.prefix4 = start4;
278 } else {
279 prefix.family = AF_INET6;
280 prefix.prefixlen = 128;
281 prefix.u.prefix6 = start6;
282 }
283
284 vrf = vrf_lookup_by_name(name ? name : VRF_DEFAULT_NAME);
285 if (!vrf) {
286 vty_out(vty, "The vrf NAME specified: %s does not exist\n",
287 name ? name : VRF_DEFAULT_NAME);
288 return CMD_WARNING;
289 }
290
291 sg.r.inst = instance;
292 sg.r.vrf_id = vrf->vrf_id;
293 rts = routes;
294 sharp_remove_routes_helper(&prefix, sg.r.vrf_id,
295 sg.r.inst, rts);
296
297 return CMD_SUCCESS;
298 }
299
300 DEFUN_NOSH (show_debugging_sharpd,
301 show_debugging_sharpd_cmd,
302 "show debugging [sharp]",
303 SHOW_STR
304 DEBUG_STR
305 "Sharp Information\n")
306 {
307 vty_out(vty, "Sharp debugging status\n");
308
309 return CMD_SUCCESS;
310 }
311
312 void sharp_vty_init(void)
313 {
314 install_element(ENABLE_NODE, &install_routes_data_dump_cmd);
315 install_element(ENABLE_NODE, &install_routes_cmd);
316 install_element(ENABLE_NODE, &remove_routes_cmd);
317 install_element(ENABLE_NODE, &vrf_label_cmd);
318 install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
319 install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
320 install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
321
322 install_element(VIEW_NODE, &show_debugging_sharpd_cmd);
323
324 return;
325 }