]> git.proxmox.com Git - mirror_frr.git/blame - pbrd/pbr_vty.c
pbrd: remove json options
[mirror_frr.git] / pbrd / pbr_vty.c
CommitLineData
e5c83d9b
DS
1/*
2 * PBR - vty code
3 * Copyright (C) 2018 Cumulus Networks, Inc.
4 * Donald Sharp
5 *
6 * FRR is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * FRR is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <zebra.h>
21
22#include "vty.h"
23#include "command.h"
24#include "prefix.h"
25#include "vrf.h"
26#include "nexthop.h"
27#include "nexthop_group.h"
28#include "log.h"
e5c83d9b
DS
29#include "debug.h"
30
31#include "pbrd/pbr_nht.h"
32#include "pbrd/pbr_map.h"
33#include "pbrd/pbr_zebra.h"
34#include "pbrd/pbr_vty.h"
e5c83d9b
DS
35#include "pbrd/pbr_debug.h"
36#ifndef VTYSH_EXTRACT_PL
37#include "pbrd/pbr_vty_clippy.c"
38#endif
39
9a55f79a 40DEFUN_NOSH(pbr_map, pbr_map_cmd, "pbr-map WORD seq (1-700)",
e5c83d9b
DS
41 "Create pbr-map or enter pbr-map command mode\n"
42 "The name of the PBR MAP\n"
43 "Sequence to insert in existing pbr-map entry\n"
44 "Sequence number\n")
45{
46 const char *pbrm_name = argv[1]->arg;
47 uint32_t seqno = atoi(argv[3]->arg);
48 struct pbr_map_sequence *pbrms;
49
50 pbrms = pbrms_get(pbrm_name, seqno);
51 VTY_PUSH_CONTEXT(PBRMAP_NODE, pbrms);
52
53 return CMD_SUCCESS;
54}
55
9a55f79a 56DEFUN_NOSH(no_pbr_map, no_pbr_map_cmd, "no pbr-map WORD [seq (1-700)]",
e5c83d9b
DS
57 NO_STR
58 "Delete pbr-map\n"
59 "The name of the PBR MAP\n"
60 "Sequence to delete from existing pbr-map entry\n"
61 "Sequence number\n")
62{
63 const char *pbrm_name = argv[2]->arg;
64 uint32_t seqno = 0;
65 struct pbr_map *pbrm = pbrm_find(pbrm_name);
e5c83d9b
DS
66 struct pbr_map_sequence *pbrms;
67 struct listnode *node, *next_node;
68
69 if (argc > 3)
70 seqno = atoi(argv[4]->arg);
71
72 if (!pbrm) {
73 vty_out(vty, "pbr-map %s not found\n", pbrm_name);
74 return CMD_SUCCESS;
75 }
76
b13e5ad6
DS
77 for (ALL_LIST_ELEMENTS(pbrm->seqnumbers, node, next_node, pbrms)) {
78 if (seqno && pbrms->seqno != seqno)
79 continue;
e5c83d9b 80
b13e5ad6
DS
81 pbr_map_delete(pbrms);
82 }
e5c83d9b
DS
83
84 return CMD_SUCCESS;
85}
86
7bec514c
QY
87DEFPY(pbr_set_table_range,
88 pbr_set_table_range_cmd,
89 "[no] pbr table range (10000-4294966272)$lb (10000-4294966272)$ub",
90 NO_STR
91 PBR_STR
92 "Set table ID range\n"
93 "Set table ID range\n"
94 "Lower bound for table ID range\n"
95 "Upper bound for table ID range\n")
96{
97 /* upper bound is 2^32 - 2^10 */
98 int ret = CMD_WARNING;
99
100 /* validate given bounds */
101 if (lb > ub)
102 vty_out(vty, "%% Lower bound must be less than upper bound\n");
103 else if (ub - lb < 10)
104 vty_out(vty, "%% Range breadth must be at least 10\n");
105 else {
106 ret = CMD_SUCCESS;
107 pbr_nht_set_tableid_range((uint32_t) lb, (uint32_t) ub);
108 }
109
110 return ret;
111}
112
113
e5c83d9b
DS
114DEFPY(pbr_map_match_src, pbr_map_match_src_cmd,
115 "[no] match src-ip <A.B.C.D/M|X:X::X:X/M>$prefix",
116 NO_STR
117 "Match the rest of the command\n"
118 "Choose the src ip or ipv6 prefix to use\n"
119 "v4 Prefix\n"
120 "v6 Prefix\n")
121{
122 struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
e5c83d9b 123
49027ce8
DS
124 pbrms->family = prefix->family;
125
e5c83d9b 126 if (!no) {
b8eb036f
DS
127 if (prefix_same(pbrms->src, prefix))
128 return CMD_SUCCESS;
129
e5c83d9b
DS
130 if (!pbrms->src)
131 pbrms->src = prefix_new();
132 prefix_copy(pbrms->src, prefix);
133 } else {
134 prefix_free(pbrms->src);
135 pbrms->src = 0;
136 }
137
b13e5ad6 138 pbr_map_check(pbrms);
e5c83d9b
DS
139
140 return CMD_SUCCESS;
141}
142
143DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd,
144 "[no] match dst-ip <A.B.C.D/M|X:X::X:X/M>$prefix",
145 NO_STR
146 "Match the rest of the command\n"
147 "Choose the src ip or ipv6 prefix to use\n"
148 "v4 Prefix\n"
149 "v6 Prefix\n")
150{
151 struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
e5c83d9b 152
49027ce8
DS
153 pbrms->family = prefix->family;
154
e5c83d9b 155 if (!no) {
b8eb036f
DS
156 if (prefix_same(pbrms->dst, prefix))
157 return CMD_SUCCESS;
158
e5c83d9b
DS
159 if (!pbrms->dst)
160 pbrms->dst = prefix_new();
161 prefix_copy(pbrms->dst, prefix);
162 } else {
163 prefix_free(pbrms->dst);
b13e5ad6 164 pbrms->dst = NULL;
e5c83d9b
DS
165 }
166
b13e5ad6 167 pbr_map_check(pbrms);
e5c83d9b
DS
168
169 return CMD_SUCCESS;
170}
171
172DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd,
173 "[no] set nexthop-group NAME$name",
174 NO_STR
175 "Set for the PBR-MAP\n"
176 "nexthop-group to use\n"
177 "The name of the nexthop-group\n")
178{
179 struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
180 struct nexthop_group_cmd *nhgc;
e5c83d9b 181
e042a421
DS
182 if (pbrms->nhg) {
183 vty_out(vty,
184 "A `set nexthop XX` command already exists, please remove that first\n");
3a9210c2 185 return CMD_WARNING_CONFIG_FAILED;
e042a421
DS
186 }
187
e5c83d9b
DS
188 nhgc = nhgc_find(name);
189 if (!nhgc) {
190 vty_out(vty, "Specified nexthop-group %s does not exist\n",
191 name);
192 vty_out(vty, "PBR-MAP will not be applied until it is created\n");
193 }
194
195 if (no) {
196 if (pbrms->nhgrp_name && strcmp(name, pbrms->nhgrp_name) == 0)
b13e5ad6 197 pbr_map_delete_nexthop_group(pbrms);
e5c83d9b
DS
198 else {
199 vty_out(vty,
200 "Nexthop Group specified: %s does not exist to remove",
201 name);
3a9210c2 202 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
203 }
204 } else {
205 if (pbrms->nhgrp_name) {
206 if (strcmp(name, pbrms->nhgrp_name) != 0) {
207 vty_out(vty,
208 "Please delete current nexthop group before modifying current one");
3a9210c2 209 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
210 }
211
212 return CMD_SUCCESS;
213 }
214 pbrms->nhgrp_name = XSTRDUP(MTYPE_TMP, name);
b13e5ad6 215 pbr_map_check(pbrms);
e5c83d9b
DS
216 }
217
e5c83d9b
DS
218 return CMD_SUCCESS;
219}
220
221DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd,
222 "[no] set nexthop <A.B.C.D|X:X::X:X>$addr [INTERFACE]$intf [nexthop-vrf NAME$name]",
223 NO_STR
224 "Set for the PBR-MAP\n"
225 "Specify one of the nexthops in this map\n"
226 "v4 Address\n"
227 "v6 Address\n"
228 "Interface to use\n"
229 "If the nexthop is in a different vrf tell us\n"
230 "The nexthop-vrf Name\n")
231{
232 struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence);
233 struct vrf *vrf;
234 struct nexthop nhop;
235 struct nexthop *nh;
e5c83d9b
DS
236
237 if (pbrms->nhgrp_name) {
238 vty_out(vty,
239 "Please unconfigure the nexthop group before adding an individual nexthop");
3a9210c2 240 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
241 }
242
243 if (name)
244 vrf = vrf_lookup_by_name(name);
245 else
246 vrf = vrf_lookup_by_id(VRF_DEFAULT);
247
248 if (!vrf) {
249 vty_out(vty, "Specified: %s is non-existent\n", name);
3a9210c2 250 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
251 }
252
253 memset(&nhop, 0, sizeof(nhop));
254 nhop.vrf_id = vrf->vrf_id;
255
10a00758
DS
256 /*
257 * Make SA happy. CLIPPY is not going to give us a NULL
258 * addr.
259 */
260 assert(addr);
e5c83d9b
DS
261 if (addr->sa.sa_family == AF_INET) {
262 nhop.gate.ipv4.s_addr = addr->sin.sin_addr.s_addr;
263 if (intf) {
264 nhop.type = NEXTHOP_TYPE_IPV4_IFINDEX;
265 nhop.ifindex = ifname2ifindex(intf, vrf->vrf_id);
266 if (nhop.ifindex == IFINDEX_INTERNAL) {
267 vty_out(vty,
268 "Specified Intf %s does not exist in vrf: %s\n",
269 intf, vrf->name);
3a9210c2 270 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
271 }
272 } else
273 nhop.type = NEXTHOP_TYPE_IPV4;
274 } else {
275 memcpy(&nhop.gate.ipv6, &addr->sin6.sin6_addr, 16);
276 if (intf) {
277 nhop.type = NEXTHOP_TYPE_IPV6_IFINDEX;
278 nhop.ifindex = ifname2ifindex(intf, vrf->vrf_id);
279 if (nhop.ifindex == IFINDEX_INTERNAL) {
280 vty_out(vty,
281 "Specified Intf %s does not exist in vrf: %s\n",
282 intf, vrf->name);
3a9210c2 283 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b 284 }
cafec8da
DS
285 } else {
286 if (IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) {
287 vty_out(vty,
288 "Specified a v6 LL with no interface, rejecting\n");
289 return CMD_WARNING_CONFIG_FAILED;
290 }
e5c83d9b 291 nhop.type = NEXTHOP_TYPE_IPV6;
cafec8da 292 }
e5c83d9b
DS
293 }
294
295 if (pbrms->nhg)
296 nh = nexthop_exists(pbrms->nhg, &nhop);
297 else {
06210d1f 298 char buf[PBR_NHC_NAMELEN];
e5c83d9b
DS
299
300 if (no) {
301 vty_out(vty, "No nexthops to delete");
3a9210c2 302 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
303 }
304
305 pbrms->nhg = nexthop_group_new();
306 pbrms->internal_nhg_name =
307 XSTRDUP(MTYPE_TMP,
308 pbr_nht_nexthop_make_name(pbrms->parent->name,
06210d1f 309 PBR_NHC_NAMELEN,
e5c83d9b
DS
310 pbrms->seqno,
311 buf));
312 nh = NULL;
313 }
314
315 if (no) {
b13e5ad6
DS
316 if (nh)
317 pbr_nht_delete_individual_nexthop(pbrms);
e5c83d9b
DS
318 } else if (!nh) {
319
320 if (pbrms->nhg->nexthop) {
321 vty_out(vty,
322 "If you would like more than one nexthop please use nexthop-groups");
3a9210c2 323 return CMD_WARNING_CONFIG_FAILED;
e5c83d9b
DS
324 }
325
326 /* must be adding new nexthop since !no and !nexthop_exists */
327 nh = nexthop_new();
328
329 memcpy(nh, &nhop, sizeof(nhop));
330 nexthop_add(&pbrms->nhg->nexthop, nh);
331
b13e5ad6
DS
332 pbr_nht_add_individual_nexthop(pbrms);
333 pbr_map_check(pbrms);
e5c83d9b
DS
334 }
335
336 return CMD_SUCCESS;
337}
338
e5c83d9b
DS
339DEFPY (pbr_policy,
340 pbr_policy_cmd,
341 "[no] pbr-policy NAME$mapname",
342 NO_STR
343 "Policy to use\n"
344 "Name of the pbr-map to apply\n")
345{
346 VTY_DECLVAR_CONTEXT(interface, ifp);
347 struct pbr_map *pbrm, *old_pbrm;
348 struct pbr_interface *pbr_ifp = ifp->info;
349
350 pbrm = pbrm_find(mapname);
351
b13e5ad6 352 if (!pbr_ifp) {
d6416967
QY
353 /* we don't want one and we don't have one, so... */
354 if (no)
355 return CMD_SUCCESS;
356
357 /* Some one could have fat fingered the interface name */
b13e5ad6
DS
358 pbr_ifp = pbr_if_new(ifp);
359 }
360
e5c83d9b
DS
361 if (no) {
362 if (strcmp(pbr_ifp->mapname, mapname) == 0) {
5f504f14 363 pbr_ifp->mapname[0] = '\0';
e5c83d9b
DS
364 if (pbrm)
365 pbr_map_interface_delete(pbrm, ifp);
366 }
367 } else {
5f504f14
QY
368 if (strcmp(pbr_ifp->mapname, "") != 0) {
369 old_pbrm = pbrm_find(pbr_ifp->mapname);
370 if (old_pbrm)
371 pbr_map_interface_delete(old_pbrm, ifp);
e5c83d9b 372 }
5f504f14
QY
373 snprintf(pbr_ifp->mapname, sizeof(pbr_ifp->mapname),
374 "%s", mapname);
375 if (pbrm)
376 pbr_map_add_interface(pbrm, ifp);
e5c83d9b
DS
377 }
378
379 return CMD_SUCCESS;
380}
381
382DEFPY (show_pbr,
383 show_pbr_cmd,
ef18ed6e 384 "show pbr",
e5c83d9b 385 SHOW_STR
ef18ed6e 386 "Policy Based Routing\n")
e5c83d9b
DS
387{
388 pbr_nht_write_table_range(vty);
389 pbr_nht_write_rule_range(vty);
390
391 return CMD_SUCCESS;
392}
393
394DEFPY (show_pbr_map,
395 show_pbr_map_cmd,
ef18ed6e 396 "show pbr map [NAME$name] [detail$detail]",
e5c83d9b
DS
397 SHOW_STR
398 "Policy Based Routing\n"
399 "PBR Map\n"
400 "PBR Map Name\n"
ef18ed6e 401 "Detailed information\n")
e5c83d9b
DS
402{
403 struct pbr_map_sequence *pbrms;
404 struct pbr_map *pbrm;
405 struct listnode *node;
406 char buf[PREFIX_STRLEN];
407 char rbuf[64];
408
409 RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) {
410 if (name && strcmp(name, pbrm->name) != 0)
411 continue;
412
413 vty_out(vty, " pbr-map %s valid: %d\n", pbrm->name,
414 pbrm->valid);
415
416 for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) {
417 if (pbrms->reason)
418 pbr_map_reason_string(pbrms->reason, rbuf,
419 sizeof(rbuf));
420 vty_out(vty,
37c606ff 421 " Seq: %u rule: %u Installed: %" PRIu64 "(%u) Reason: %s\n",
e5c83d9b
DS
422 pbrms->seqno, pbrms->ruleno, pbrms->installed,
423 pbrms->unique, pbrms->reason ? rbuf : "Valid");
424
425 if (pbrms->src)
426 vty_out(vty, "\tSRC Match: %s\n",
427 prefix2str(pbrms->src, buf,
428 sizeof(buf)));
429 if (pbrms->dst)
430 vty_out(vty, "\tDST Match: %s\n",
431 prefix2str(pbrms->dst, buf,
432 sizeof(buf)));
433
434 if (pbrms->nhgrp_name) {
435 vty_out(vty,
436 "\tNexthop-Group: %s(%u) Installed: %u(%d)\n",
437 pbrms->nhgrp_name,
438 pbr_nht_get_table(pbrms->nhgrp_name),
439 pbrms->nhs_installed,
440 pbr_nht_get_installed(
441 pbrms->nhgrp_name));
442 } else if (pbrms->nhg) {
443 vty_out(vty, " ");
444 nexthop_group_write_nexthop(
445 vty, pbrms->nhg->nexthop);
446 vty_out(vty,
447 "\tInstalled: %u(%d) Tableid: %d\n",
448 pbrms->nhs_installed,
449 pbr_nht_get_installed(
450 pbrms->internal_nhg_name),
451 pbr_nht_get_table(
452 pbrms->internal_nhg_name));
453 } else {
454 vty_out(vty,
455 "\tNexthop-Group: Unknown Installed: 0(0)\n");
456 }
457 }
458 }
459 return CMD_SUCCESS;
460}
461
462DEFPY(show_pbr_nexthop_group,
463 show_pbr_nexthop_group_cmd,
464 "show pbr nexthop-groups [WORD$word]",
465 SHOW_STR
466 "Policy Based Routing\n"
467 "Nexthop Groups\n"
468 "Optional Name of the nexthop group\n")
469{
470 pbr_nht_show_nexthop_group(vty, word);
471
472 return CMD_SUCCESS;
473}
474
475DEFPY (show_pbr_interface,
476 show_pbr_interface_cmd,
ef18ed6e 477 "show pbr interface [NAME$name]",
e5c83d9b
DS
478 SHOW_STR
479 "Policy Based Routing\n"
480 "PBR Interface\n"
ef18ed6e 481 "PBR Interface Name\n")
e5c83d9b 482{
d3765386 483 struct interface *ifp;
e5c83d9b
DS
484 struct vrf *vrf;
485 struct pbr_interface *pbr_ifp;
486
487 RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
488 FOR_ALL_INTERFACES(vrf, ifp) {
489 struct pbr_map *pbrm;
490
1c33fb1d
DS
491 if (!ifp->info)
492 continue;
493
e5c83d9b
DS
494 if (name && strcmp(ifp->name, name) != 0)
495 continue;
496
497 pbr_ifp = ifp->info;
498
499 if (strcmp(pbr_ifp->mapname, "") == 0)
500 continue;
501
502 pbrm = pbrm_find(pbr_ifp->mapname);
503 vty_out(vty, " %s(%d) with pbr-policy %s", ifp->name,
504 ifp->ifindex, pbr_ifp->mapname);
505 if (!pbrm)
506 vty_out(vty, " (map doesn't exist)");
507 vty_out(vty, "\n");
508 }
509 }
510
511 return CMD_SUCCESS;
512}
513
e14f43cc 514/* PBR debugging CLI ------------------------------------------------------- */
e14f43cc
QY
515
516static struct cmd_node debug_node = {DEBUG_NODE, "", 1};
517
518DEFPY(debug_pbr,
519 debug_pbr_cmd,
520 "[no] debug pbr [{map$map|zebra$zebra|nht$nht|events$events}]",
521 NO_STR
522 DEBUG_STR
523 "Policy Based Routing\n"
524 "Policy maps\n"
525 "PBRD <-> Zebra communications\n"
526 "Nexthop tracking\n"
527 "Events\n")
528{
529 uint32_t mode = DEBUG_NODE2MODE(vty->node);
530
531 if (map)
532 DEBUG_MODE_SET(&pbr_dbg_map, mode, !no);
533 if (zebra)
534 DEBUG_MODE_SET(&pbr_dbg_zebra, mode, !no);
535 if (nht)
536 DEBUG_MODE_SET(&pbr_dbg_nht, mode, !no);
537 if (events)
538 DEBUG_MODE_SET(&pbr_dbg_event, mode, !no);
539
540 /* no specific debug --> act on all of them */
541 if (strmatch(argv[argc - 1]->text, "pbr"))
542 pbr_debug_set_all(mode, !no);
543
544 return CMD_SUCCESS;
545}
546
547DEFUN_NOSH(show_debugging_pbr,
548 show_debugging_pbr_cmd,
549 "show debugging [pbr]",
550 SHOW_STR
551 DEBUG_STR
552 "Policy Based Routing\n")
553{
554 vty_out(vty, "PBR debugging status:\n");
555
556 pbr_debug_config_write_helper(vty, false);
557
558 return CMD_SUCCESS;
559}
560
e14f43cc
QY
561/* ------------------------------------------------------------------------- */
562
563
e5c83d9b
DS
564static struct cmd_node interface_node = {
565 INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */
566};
567
568static int pbr_interface_config_write(struct vty *vty)
569{
570 struct interface *ifp;
571 struct vrf *vrf;
572
573 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
574 FOR_ALL_INTERFACES (vrf, ifp) {
575 if (vrf->vrf_id == VRF_DEFAULT)
576 vty_frame(vty, "interface %s\n", ifp->name);
577 else
578 vty_frame(vty, "interface %s vrf %s\n",
579 ifp->name, vrf->name);
580
581 pbr_map_write_interfaces(vty, ifp);
582
583 vty_endframe(vty, "!\n");
584 }
585 }
586
587 return 1;
588}
589
590/* PBR map node structure. */
591static struct cmd_node pbr_map_node = {PBRMAP_NODE, "%s(config-pbr-map)# ", 1};
592
593static int pbr_vty_map_config_write_sequence(struct vty *vty,
594 struct pbr_map *pbrm,
595 struct pbr_map_sequence *pbrms)
596{
597 char buff[PREFIX_STRLEN];
598
5e44f18f 599 vty_out(vty, "pbr-map %s seq %u\n", pbrm->name, pbrms->seqno);
e5c83d9b
DS
600
601 if (pbrms->src)
602 vty_out(vty, " match src-ip %s\n",
d3765386 603 prefix2str(pbrms->src, buff, sizeof(buff)));
e5c83d9b
DS
604
605 if (pbrms->dst)
606 vty_out(vty, " match dst-ip %s\n",
d3765386 607 prefix2str(pbrms->dst, buff, sizeof(buff)));
e5c83d9b
DS
608
609 if (pbrms->nhgrp_name)
610 vty_out(vty, " set nexthop-group %s\n", pbrms->nhgrp_name);
611
612 if (pbrms->nhg) {
57cdafc4 613 vty_out(vty, " set ");
e5c83d9b
DS
614 nexthop_group_write_nexthop(vty, pbrms->nhg->nexthop);
615 }
616
5e44f18f 617 vty_out(vty, "!\n");
e5c83d9b
DS
618 return 1;
619}
620
621static int pbr_vty_map_config_write(struct vty *vty)
622{
623 struct pbr_map *pbrm;
624
625 pbr_nht_write_table_range(vty);
626 pbr_nht_write_rule_range(vty);
627
628 RB_FOREACH(pbrm, pbr_map_entry_head, &pbr_maps) {
629 struct pbr_map_sequence *pbrms;
630 struct listnode *node;
631
d3765386 632 for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms))
e5c83d9b 633 pbr_vty_map_config_write_sequence(vty, pbrm, pbrms);
e5c83d9b
DS
634 }
635
636 return 1;
637}
638
639void pbr_vty_init(void)
640{
641 install_node(&interface_node,
642 pbr_interface_config_write);
643 if_cmd_init();
644
645 install_node(&pbr_map_node,
646 pbr_vty_map_config_write);
647
e14f43cc
QY
648 /* debug */
649 install_node(&debug_node, pbr_debug_config_write);
650 install_element(VIEW_NODE, &debug_pbr_cmd);
651 install_element(CONFIG_NODE, &debug_pbr_cmd);
652 install_element(VIEW_NODE, &show_debugging_pbr_cmd);
653
e5c83d9b
DS
654 install_default(PBRMAP_NODE);
655
656 install_element(CONFIG_NODE, &pbr_map_cmd);
657 install_element(CONFIG_NODE, &no_pbr_map_cmd);
7bec514c 658 install_element(CONFIG_NODE, &pbr_set_table_range_cmd);
e5c83d9b 659 install_element(INTERFACE_NODE, &pbr_policy_cmd);
e5c83d9b
DS
660 install_element(PBRMAP_NODE, &pbr_map_match_src_cmd);
661 install_element(PBRMAP_NODE, &pbr_map_match_dst_cmd);
662 install_element(PBRMAP_NODE, &pbr_map_nexthop_group_cmd);
663 install_element(PBRMAP_NODE, &pbr_map_nexthop_cmd);
664 install_element(VIEW_NODE, &show_pbr_cmd);
665 install_element(VIEW_NODE, &show_pbr_map_cmd);
666 install_element(VIEW_NODE, &show_pbr_interface_cmd);
667 install_element(VIEW_NODE, &show_pbr_nexthop_group_cmd);
e5c83d9b 668}