]> git.proxmox.com Git - mirror_frr.git/blame - zebra/zebra_routemap.c
zebra: show routes in a specified VRF or all VRFs
[mirror_frr.git] / zebra / zebra_routemap.c
CommitLineData
5921ef9a
PJ
1/* zebra routemap.
2 * Copyright (C) 2006 IBM Corporation
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra 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 * GNU Zebra 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
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "memory.h"
25#include "prefix.h"
26#include "rib.h"
27#include "routemap.h"
28#include "command.h"
29#include "filter.h"
30#include "plist.h"
fb018d25 31#include "nexthop.h"
5921ef9a
PJ
32
33#include "zebra/zserv.h"
518f0eb1 34#include "zebra/debug.h"
9f0ea7d4 35#include "zebra/zebra_rnh.h"
6baf7bb8 36#include "zebra/zebra_routemap.h"
518f0eb1
DS
37
38static u_int32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
39static struct thread *zebra_t_rmap_update = NULL;
40char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
9f0ea7d4
DS
41/* NH Tracking route map */
42char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1]; /* "any" == ZEBRA_ROUTE_MAX */
518f0eb1
DS
43
44extern struct zebra_t zebrad;
9f0ea7d4
DS
45struct nh_rmap_obj
46{
47 struct nexthop *nexthop;
48 u_int32_t source_protocol;
49 int metric;
ca84c8ef 50 u_short tag;
9f0ea7d4
DS
51};
52
53static void zebra_route_map_set_delay_timer(u_int32_t value);
5921ef9a
PJ
54
55/* Add zebra route map rule */
56static int
57zebra_route_match_add(struct vty *vty, struct route_map_index *index,
518f0eb1
DS
58 const char *command, const char *arg,
59 route_map_event_t type)
5921ef9a
PJ
60{
61 int ret;
62
63 ret = route_map_add_match (index, command, arg);
64 if (ret)
65 {
66 switch (ret)
67 {
68 case RMAP_RULE_MISSING:
5e3edbf5 69 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
5921ef9a
PJ
70 return CMD_WARNING;
71 case RMAP_COMPILE_ERROR:
5e3edbf5 72 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
5921ef9a
PJ
73 return CMD_WARNING;
74 }
75 }
518f0eb1
DS
76
77 if (type != RMAP_EVENT_MATCH_ADDED)
78 {
79 route_map_upd8_dependency (type, arg, index->map->name);
80 }
5921ef9a
PJ
81 return CMD_SUCCESS;
82}
83
84/* Delete zebra route map rule. */
85static int
86zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
518f0eb1
DS
87 const char *command, const char *arg,
88 route_map_event_t type)
5921ef9a
PJ
89{
90 int ret;
4e3afb14 91 char *dep_name = NULL;
518f0eb1
DS
92 const char *tmpstr;
93 char *rmap_name = NULL;
94
95 if (type != RMAP_EVENT_MATCH_DELETED)
96 {
97 /* ignore the mundane, the types without any dependency */
98 if (arg == NULL)
99 {
100 if ((tmpstr = route_map_get_match_arg(index, command)) != NULL)
101 dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
102 }
4e3afb14
DS
103 else
104 {
105 dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
106 }
518f0eb1
DS
107 rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
108 }
5921ef9a
PJ
109
110 ret = route_map_delete_match (index, command, arg);
111 if (ret)
112 {
113 switch (ret)
114 {
115 case RMAP_RULE_MISSING:
5e3edbf5 116 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
5921ef9a
PJ
117 return CMD_WARNING;
118 case RMAP_COMPILE_ERROR:
5e3edbf5 119 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
5921ef9a
PJ
120 return CMD_WARNING;
121 }
122 }
518f0eb1
DS
123
124 if (type != RMAP_EVENT_MATCH_DELETED && dep_name)
125 route_map_upd8_dependency(type, dep_name, rmap_name);
126
4e3afb14 127 if (dep_name)
518f0eb1
DS
128 XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
129 if (rmap_name)
130 XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
131
5921ef9a
PJ
132 return CMD_SUCCESS;
133}
134
135/* Add zebra route map rule. */
136static int
137zebra_route_set_add (struct vty *vty, struct route_map_index *index,
138 const char *command, const char *arg)
139{
140 int ret;
141
142 ret = route_map_add_set (index, command, arg);
143 if (ret)
144 {
145 switch (ret)
146 {
147 case RMAP_RULE_MISSING:
5e3edbf5 148 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
5921ef9a
PJ
149 return CMD_WARNING;
150 case RMAP_COMPILE_ERROR:
5e3edbf5 151 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
5921ef9a
PJ
152 return CMD_WARNING;
153 }
154 }
155 return CMD_SUCCESS;
156}
157
158/* Delete zebra route map rule. */
159static int
160zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
161 const char *command, const char *arg)
162{
163 int ret;
164
165 ret = route_map_delete_set (index, command, arg);
166 if (ret)
167 {
168 switch (ret)
169 {
170 case RMAP_RULE_MISSING:
5e3edbf5 171 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
5921ef9a
PJ
172 return CMD_WARNING;
173 case RMAP_COMPILE_ERROR:
5e3edbf5 174 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
5921ef9a
PJ
175 return CMD_WARNING;
176 }
177 }
178 return CMD_SUCCESS;
179}
180
ca84c8ef
DS
181/* 'match tag TAG'
182 * Match function return 1 if match is success else return 0
183 */
184static route_map_result_t
185route_match_tag (void *rule, struct prefix *prefix,
186 route_map_object_t type, void *object)
187{
188 u_short *tag;
189 struct nh_rmap_obj *nh_data;
190
191 if (type == RMAP_ZEBRA)
192 {
193 tag = rule;
194 nh_data = object;
195
196 if (nh_data->tag == *tag)
197 return RMAP_MATCH;
198 }
199 return RMAP_NOMATCH;
200}
201
202/* Route map 'match tag' match statement. 'arg' is TAG value */
203static void *
204route_match_tag_compile (const char *arg)
205{
206 u_short *tag;
207 u_short tmp;
208
209 /* tag value shoud be integer. */
210 if (! all_digit (arg))
211 return NULL;
212
213 tmp = atoi(arg);
214 if (tmp < 1)
215 return NULL;
216
217 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
218
219 if (!tag)
220 return tag;
221
222 *tag = tmp;
223
224 return tag;
225}
226
227/* Free route map's compiled 'match tag' value. */
228static void
229route_match_tag_free (void *rule)
230{
231 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
232}
233
234/* Route map commands for tag matching */
235struct route_map_rule_cmd route_match_tag_cmd =
236{
237 "tag",
238 route_match_tag,
239 route_match_tag_compile,
240 route_match_tag_free
241};
242
6b0655a2 243
5921ef9a
PJ
244/* `match interface IFNAME' */
245/* Match function return 1 if match is success else return zero. */
246static route_map_result_t
247route_match_interface (void *rule, struct prefix *prefix,
248 route_map_object_t type, void *object)
249{
9f0ea7d4 250 struct nh_rmap_obj *nh_data;
5921ef9a
PJ
251 char *ifname = rule;
252 unsigned int ifindex;
253
254 if (type == RMAP_ZEBRA)
255 {
256 if (strcasecmp(ifname, "any") == 0)
257 return RMAP_MATCH;
258 ifindex = ifname2ifindex(ifname);
259 if (ifindex == 0)
260 return RMAP_NOMATCH;
9f0ea7d4
DS
261 nh_data = object;
262 if (!nh_data || !nh_data->nexthop)
5921ef9a 263 return RMAP_NOMATCH;
9f0ea7d4 264 if (nh_data->nexthop->ifindex == ifindex)
5921ef9a
PJ
265 return RMAP_MATCH;
266 }
267 return RMAP_NOMATCH;
268}
269
270/* Route map `match interface' match statement. `arg' is IFNAME value */
271static void *
272route_match_interface_compile (const char *arg)
273{
274 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
275}
276
277/* Free route map's compiled `match interface' value. */
278static void
279route_match_interface_free (void *rule)
280{
281 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
282}
283
284/* Route map commands for interface matching */
285struct route_map_rule_cmd route_match_interface_cmd =
286{
287 "interface",
288 route_match_interface,
289 route_match_interface_compile,
290 route_match_interface_free
291};
292
293DEFUN (match_interface,
294 match_interface_cmd,
295 "match interface WORD",
296 MATCH_STR
297 "match first hop interface of route\n"
298 "Interface name\n")
299{
518f0eb1 300 return zebra_route_match_add (vty, vty->index, "interface", argv[0],
9f0ea7d4 301 RMAP_EVENT_MATCH_ADDED);
5921ef9a
PJ
302}
303
304DEFUN (no_match_interface,
305 no_match_interface_cmd,
306 "no match interface",
307 NO_STR
308 MATCH_STR
309 "Match first hop interface of route\n")
310{
311 if (argc == 0)
518f0eb1 312 return zebra_route_match_delete (vty, vty->index, "interface", NULL, RMAP_EVENT_MATCH_DELETED);
5921ef9a 313
518f0eb1 314 return zebra_route_match_delete (vty, vty->index, "interface", argv[0], RMAP_EVENT_MATCH_DELETED);
5921ef9a
PJ
315}
316
317ALIAS (no_match_interface,
318 no_match_interface_val_cmd,
319 "no match interface WORD",
320 NO_STR
321 MATCH_STR
322 "Match first hop interface of route\n"
323 "Interface name\n")
324
ca84c8ef
DS
325DEFUN (match_tag,
326 match_tag_cmd,
327 "match tag <1-65535>",
328 MATCH_STR
329 "Match tag of route\n"
330 "Tag value\n")
331{
332 return zebra_route_match_add (vty, vty->index, "tag", argv[0],
333 RMAP_EVENT_MATCH_ADDED);
334}
335
336DEFUN (no_match_tag,
337 no_match_tag_cmd,
338 "no match tag",
339 NO_STR
340 MATCH_STR
341 "Match tag of route\n")
342{
343 if (argc == 0)
344 return zebra_route_match_delete (vty, vty->index, "tag", NULL,
345 RMAP_EVENT_MATCH_DELETED);
346
347 return zebra_route_match_delete (vty, vty->index, "tag", argv[0],
348 RMAP_EVENT_MATCH_DELETED);
349}
350
351ALIAS (no_match_tag,
352 no_match_tag_val_cmd,
353 "no match tag <1-65535>",
354 NO_STR
355 MATCH_STR
356 "Match tag of route\n")
357
5921ef9a
PJ
358DEFUN (match_ip_next_hop,
359 match_ip_next_hop_cmd,
360 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
361 MATCH_STR
362 IP_STR
363 "Match next-hop address of route\n"
364 "IP access-list number\n"
365 "IP access-list number (expanded range)\n"
366 "IP Access-list name\n")
367{
518f0eb1 368 return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0], RMAP_EVENT_FILTER_ADDED);
5921ef9a
PJ
369}
370
371DEFUN (no_match_ip_next_hop,
372 no_match_ip_next_hop_cmd,
373 "no match ip next-hop",
374 NO_STR
375 MATCH_STR
376 IP_STR
377 "Match next-hop address of route\n")
378{
379 if (argc == 0)
518f0eb1
DS
380 return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL,
381 RMAP_EVENT_FILTER_DELETED);
5921ef9a 382
518f0eb1
DS
383 return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0],
384 RMAP_EVENT_FILTER_DELETED);
5921ef9a
PJ
385}
386
387ALIAS (no_match_ip_next_hop,
388 no_match_ip_next_hop_val_cmd,
389 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
390 NO_STR
391 MATCH_STR
392 IP_STR
393 "Match next-hop address of route\n"
394 "IP access-list number\n"
395 "IP access-list number (expanded range)\n"
396 "IP Access-list name\n")
397
398DEFUN (match_ip_next_hop_prefix_list,
399 match_ip_next_hop_prefix_list_cmd,
400 "match ip next-hop prefix-list WORD",
401 MATCH_STR
402 IP_STR
403 "Match next-hop address of route\n"
404 "Match entries of prefix-lists\n"
405 "IP prefix-list name\n")
406{
518f0eb1
DS
407 return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list",
408 argv[0], RMAP_EVENT_PLIST_ADDED);
5921ef9a
PJ
409}
410
411DEFUN (no_match_ip_next_hop_prefix_list,
412 no_match_ip_next_hop_prefix_list_cmd,
413 "no match ip next-hop prefix-list",
414 NO_STR
415 MATCH_STR
416 IP_STR
417 "Match next-hop address of route\n"
418 "Match entries of prefix-lists\n")
419{
420 if (argc == 0)
518f0eb1
DS
421 return zebra_route_match_delete (vty, vty->index,
422 "ip next-hop prefix-list", NULL,
423 RMAP_EVENT_PLIST_DELETED);
5921ef9a 424
518f0eb1
DS
425 return zebra_route_match_delete (vty, vty->index,
426 "ip next-hop prefix-list", argv[0],
427 RMAP_EVENT_PLIST_DELETED);
5921ef9a
PJ
428}
429
430ALIAS (no_match_ip_next_hop_prefix_list,
431 no_match_ip_next_hop_prefix_list_val_cmd,
432 "no match ip next-hop prefix-list WORD",
433 NO_STR
434 MATCH_STR
435 IP_STR
436 "Match next-hop address of route\n"
437 "Match entries of prefix-lists\n"
438 "IP prefix-list name\n")
439
440DEFUN (match_ip_address,
441 match_ip_address_cmd,
442 "match ip address (<1-199>|<1300-2699>|WORD)",
443 MATCH_STR
444 IP_STR
445 "Match address of route\n"
446 "IP access-list number\n"
447 "IP access-list number (expanded range)\n"
448 "IP Access-list name\n")
449
450{
518f0eb1
DS
451 return zebra_route_match_add (vty, vty->index, "ip address", argv[0],
452 RMAP_EVENT_FILTER_ADDED);
5921ef9a
PJ
453}
454
455DEFUN (no_match_ip_address,
456 no_match_ip_address_cmd,
457 "no match ip address",
458 NO_STR
459 MATCH_STR
460 IP_STR
461 "Match address of route\n")
462{
463 if (argc == 0)
518f0eb1
DS
464 return zebra_route_match_delete (vty, vty->index, "ip address", NULL,
465 RMAP_EVENT_FILTER_DELETED);
5921ef9a 466
518f0eb1
DS
467 return zebra_route_match_delete (vty, vty->index, "ip address", argv[0],
468 RMAP_EVENT_FILTER_DELETED);
5921ef9a
PJ
469}
470
471ALIAS (no_match_ip_address,
472 no_match_ip_address_val_cmd,
473 "no match ip address (<1-199>|<1300-2699>|WORD)",
474 NO_STR
475 MATCH_STR
476 IP_STR
477 "Match address of route\n"
478 "IP access-list number\n"
479 "IP access-list number (expanded range)\n"
480 "IP Access-list name\n")
481
482DEFUN (match_ip_address_prefix_list,
483 match_ip_address_prefix_list_cmd,
484 "match ip address prefix-list WORD",
485 MATCH_STR
486 IP_STR
487 "Match address of route\n"
488 "Match entries of prefix-lists\n"
489 "IP prefix-list name\n")
490{
518f0eb1
DS
491 return zebra_route_match_add (vty, vty->index, "ip address prefix-list",
492 argv[0], RMAP_EVENT_PLIST_ADDED);
5921ef9a
PJ
493}
494
495DEFUN (no_match_ip_address_prefix_list,
496 no_match_ip_address_prefix_list_cmd,
497 "no match ip address prefix-list",
498 NO_STR
499 MATCH_STR
500 IP_STR
501 "Match address of route\n"
502 "Match entries of prefix-lists\n")
503{
504 if (argc == 0)
518f0eb1
DS
505 return zebra_route_match_delete (vty, vty->index,
506 "ip address prefix-list", NULL,
507 RMAP_EVENT_PLIST_DELETED);
5921ef9a 508
518f0eb1
DS
509 return zebra_route_match_delete (vty, vty->index,
510 "ip address prefix-list", argv[0],
511 RMAP_EVENT_PLIST_DELETED);
5921ef9a
PJ
512}
513
514ALIAS (no_match_ip_address_prefix_list,
515 no_match_ip_address_prefix_list_val_cmd,
516 "no match ip address prefix-list WORD",
517 NO_STR
518 MATCH_STR
519 IP_STR
520 "Match address of route\n"
521 "Match entries of prefix-lists\n"
522 "IP prefix-list name\n")
523
9f0ea7d4
DS
524DEFUN (match_ip_address_prefix_len,
525 match_ip_address_prefix_len_cmd,
526 "match ip address prefix-len NUMBER",
527 MATCH_STR
528 IP_STR
529 "Match prefix length of ip address\n"
530 "Match prefix length of ip address\n"
531 "Prefix length\n")
532{
533 return zebra_route_match_add (vty, vty->index, "ip address prefix-len",
534 argv[0], RMAP_EVENT_MATCH_ADDED);
535}
536
537DEFUN (no_match_ip_address_prefix_len,
538 no_match_ip_address_prefix_len_cmd,
539 "no match ip address prefix-len",
540 NO_STR
541 MATCH_STR
542 IP_STR
543 "Match prefixlen of ip address of route\n"
544 "prefix length of ip address\n")
545{
546 if (argc == 0)
547 return zebra_route_match_delete (vty, vty->index,
548 "ip address prefix-len", NULL,
549 RMAP_EVENT_MATCH_DELETED);
550
551 return zebra_route_match_delete (vty, vty->index,
552 "ip address prefix-len", argv[0],
553 RMAP_EVENT_MATCH_DELETED);
554}
555
556ALIAS (no_match_ip_address_prefix_len,
557 no_match_ip_address_prefix_len_val_cmd,
558 "no match ip address prefix-len NUMBER",
559 NO_STR
560 MATCH_STR
561 IP_STR
562 "Match prefixlen of ip address of route\n"
563 "prefix length of ip address\n")
564
565DEFUN (match_ip_nexthop_prefix_len,
566 match_ip_nexthop_prefix_len_cmd,
567 "match ip next-hop prefix-len NUMBER",
568 MATCH_STR
569 IP_STR
570 "Match prefixlen of nexthop ip address\n"
571 "Match prefixlen of given nexthop\n"
572 "Prefix length\n")
573{
574 return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-len",
575 argv[0], RMAP_EVENT_MATCH_ADDED);
576}
577
578DEFUN (no_match_ip_nexthop_prefix_len,
579 no_match_ip_nexthop_prefix_len_cmd,
580 "no match ip next-hop prefix-len",
581 NO_STR
582 MATCH_STR
583 IP_STR
584 "Match prefixlen of nexthop ip address\n"
585 "Match prefix length of nexthop\n")
586{
587 if (argc == 0)
588 return zebra_route_match_delete (vty, vty->index,
589 "ip next-hop prefix-len", NULL,
590 RMAP_EVENT_MATCH_DELETED);
591
592 return zebra_route_match_delete (vty, vty->index,
593 "ip next-hop prefix-len", argv[0],
594 RMAP_EVENT_MATCH_DELETED);
595}
596
597ALIAS (no_match_ip_nexthop_prefix_len,
598 no_match_ip_nexthop_prefix_len_val_cmd,
599 "no match ip next-hop prefix-len NUMBER",
600 MATCH_STR
601 "Match prefixlen of ip address of route\n"
602 "prefix length of ip address\n")
603
604DEFUN (match_source_protocol,
605 match_source_protocol_cmd,
606 "match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
607 MATCH_STR
608 "Match protocol via which the route was learnt\n")
609{
610 int i;
611
612 i = proto_name2num(argv[0]);
613 if (i < 0)
614 {
615 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
616 VTY_NEWLINE);
617 return CMD_WARNING;
618 }
619 return zebra_route_match_add (vty, vty->index, "source-protocol",
620 argv[0], RMAP_EVENT_MATCH_ADDED);
621}
622
623DEFUN (no_match_source_protocol,
624 no_match_source_protocol_cmd,
625 "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)",
626 NO_STR
627 MATCH_STR
628 "No match protocol via which the route was learnt\n")
629{
630 int i;
631
632 if (argc >= 1)
633 {
634 i = proto_name2num(argv[0]);
635 if (i < 0)
636 {
637 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
638 VTY_NEWLINE);
639 return CMD_WARNING;
640 }
641 }
642 return zebra_route_match_delete (vty, vty->index,
643 "source-protocol", argv[0] ? argv[0] : NULL,
644 RMAP_EVENT_MATCH_DELETED);
645}
646
5921ef9a
PJ
647/* set functions */
648
649DEFUN (set_src,
650 set_src_cmd,
0aabccc0 651 "set src (A.B.C.D|X:X::X:X)",
5921ef9a
PJ
652 SET_STR
653 "src address for route\n"
654 "src address\n")
655{
0aabccc0
DD
656 union g_addr src;
657 struct interface *pif = NULL;
658 int family;
659 struct prefix p;
5921ef9a 660
0aabccc0
DD
661 if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1)
662 {
663 if (inet_pton(AF_INET6, argv[0], &src.ipv6) != 1)
664 {
665 vty_out (vty, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE);
666 return CMD_WARNING;
667 }
668
669 p.family = family = AF_INET6;
670 p.u.prefix6 = src.ipv6;
671 p.prefixlen = IPV6_MAX_BITLEN;
672 }
673 else
674 {
675 p.family = family = AF_INET;
676 p.u.prefix4 = src.ipv4;
677 p.prefixlen = IPV4_MAX_BITLEN;
678 }
679
680 if (!zebra_check_addr(&p))
681 {
682 vty_out (vty, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE);
683 return CMD_WARNING;
684 }
685
686 if (family == AF_INET)
687 pif = if_lookup_exact_address ((void *)&src.ipv4, AF_INET);
688 else if (family == AF_INET6)
689 pif = if_lookup_exact_address ((void *)&src.ipv6, AF_INET6);
690
691 if (!pif)
5921ef9a
PJ
692 {
693 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
694 return CMD_WARNING;
695 }
5921ef9a
PJ
696 return zebra_route_set_add (vty, vty->index, "src", argv[0]);
697}
698
699DEFUN (no_set_src,
700 no_set_src_cmd,
0aabccc0 701 "no set src {A.B.C.D|X:X::X:X}",
5921ef9a
PJ
702 NO_STR
703 SET_STR
704 "Source address for route\n")
705{
706 if (argc == 0)
707 return zebra_route_set_delete (vty, vty->index, "src", NULL);
708
709 return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
710}
711
518f0eb1
DS
712DEFUN (zebra_route_map_timer,
713 zebra_route_map_timer_cmd,
714 "zebra route-map delay-timer <0-600>",
9f0ea7d4
DS
715 "Time to wait before route-map updates are processed\n"
716 "0 means event-driven updates are disabled\n")
518f0eb1
DS
717{
718 u_int32_t rmap_delay_timer;
719
720 VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[0], 0, 600);
721 zebra_route_map_set_delay_timer(rmap_delay_timer);
722
723 return (CMD_SUCCESS);
724}
725
726DEFUN (no_zebra_route_map_timer,
727 no_zebra_route_map_timer_cmd,
728 "no zebra route-map delay-timer",
729 NO_STR
9f0ea7d4 730 "Time to wait before route-map updates are processed\n"
518f0eb1
DS
731 "Reset delay-timer to default value, 30 secs\n")
732{
733 zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER);
734
735 return (CMD_SUCCESS);
736}
737
738DEFUN (ip_protocol,
739 ip_protocol_cmd,
9f0ea7d4
DS
740 "ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
741 IP_STR
742 "Filter routing info exchanged between zebra and protocol\n"
743 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
518f0eb1
DS
744 "Route map name\n")
745{
746 int i;
747
748 if (strcasecmp(argv[0], "any") == 0)
749 i = ZEBRA_ROUTE_MAX;
750 else
751 i = proto_name2num(argv[0]);
752 if (i < 0)
753 {
754 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
755 VTY_NEWLINE);
756 return CMD_WARNING;
757 }
758 if (proto_rm[AFI_IP][i])
759 {
760 if (strcmp(proto_rm[AFI_IP][i], argv[1]) == 0)
761 return CMD_SUCCESS;
762
763 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
764 }
765 proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
b84c7253 766
767 if (IS_ZEBRA_DEBUG_RIB)
768 zlog_debug ("%s: calling rib_update", __func__);
769
518f0eb1
DS
770 rib_update();
771 return CMD_SUCCESS;
772}
773
774DEFUN (no_ip_protocol,
775 no_ip_protocol_cmd,
9f0ea7d4 776 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA,
518f0eb1 777 NO_STR
9f0ea7d4
DS
778 IP_STR
779 "Stop filtering routing info between zebra and protocol\n"
780 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
781 "Protocol from which to stop filtering routes\n")
518f0eb1
DS
782{
783 int i;
784
785 if (strcasecmp(argv[0], "any") == 0)
786 i = ZEBRA_ROUTE_MAX;
787 else
788 i = proto_name2num(argv[0]);
789 if (i < 0)
790 {
791 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
792 VTY_NEWLINE);
793 return CMD_WARNING;
794 }
795 if (!proto_rm[AFI_IP][i])
796 return CMD_SUCCESS;
797
9f0ea7d4
DS
798 if ((argc == 2 && strcmp(argv[1], proto_rm[AFI_IP][i]) == 0) ||
799 (argc < 2))
800 {
801 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
802 proto_rm[AFI_IP][i] = NULL;
b84c7253 803
804 if (IS_ZEBRA_DEBUG_RIB)
805 zlog_debug ("%s: calling rib_update", __func__);
806
9f0ea7d4
DS
807 rib_update();
808 }
518f0eb1
DS
809 return CMD_SUCCESS;
810}
811
9f0ea7d4
DS
812ALIAS (no_ip_protocol,
813 no_ip_protocol_val_cmd,
814 "no ip protocol " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
815 NO_STR
816 IP_STR
817 "Stop filtering routing info between zebra and protocol\n"
818 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
819 "route map name")
820
518f0eb1
DS
821DEFUN (show_ip_protocol,
822 show_ip_protocol_cmd,
823 "show ip protocol",
824 SHOW_STR
825 IP_STR
826 "IP protocol filtering status\n")
827{
828 int i;
829
830 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
831 vty_out(vty, "------------------------%s", VTY_NEWLINE);
832 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
833 {
834 if (proto_rm[AFI_IP][i])
835 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
836 proto_rm[AFI_IP][i],
837 VTY_NEWLINE);
838 else
839 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
840 }
841 if (proto_rm[AFI_IP][i])
842 vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP][i],
843 VTY_NEWLINE);
844 else
845 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
846
847 return CMD_SUCCESS;
848}
849
0aabccc0
DD
850DEFUN (ipv6_protocol,
851 ipv6_protocol_cmd,
852 "ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
853 IP6_STR
854 "Filter IPv6 routing info exchanged between zebra and protocol\n"
855 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
856 "Route map name\n")
857{
858 int i;
0aabccc0
DD
859
860 if (strcasecmp(argv[0], "any") == 0)
861 i = ZEBRA_ROUTE_MAX;
862 else
863 i = proto_name2num(argv[0]);
864 if (i < 0)
865 {
866 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
867 VTY_NEWLINE);
868 return CMD_WARNING;
869 }
870 if (proto_rm[AFI_IP6][i])
871 {
872 if (strcmp(proto_rm[AFI_IP6][i], argv[1]) == 0)
873 return CMD_SUCCESS;
874
875 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
876 }
877 proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
b84c7253 878
879 if (IS_ZEBRA_DEBUG_RIB)
880 zlog_debug ("%s: calling rib_update", __func__);
881
0aabccc0
DD
882 rib_update();
883 return CMD_SUCCESS;
884}
885
886DEFUN (no_ipv6_protocol,
887 no_ipv6_protocol_cmd,
888 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA,
889 NO_STR
890 IP6_STR
891 "Stop filtering IPv6 routing info between zebra and protocol\n"
892 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
893 "Protocol from which to stop filtering routes\n")
894{
895 int i;
0aabccc0
DD
896
897 if (strcasecmp(argv[0], "any") == 0)
898 i = ZEBRA_ROUTE_MAX;
899 else
900 i = proto_name2num(argv[0]);
901 if (i < 0)
902 {
903 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
904 VTY_NEWLINE);
905 return CMD_WARNING;
906 }
907 if (!proto_rm[AFI_IP6][i])
908 return CMD_SUCCESS;
909
910 if ((argc == 2 && strcmp(argv[1], proto_rm[AFI_IP6][i]) == 0) ||
911 (argc < 2))
912 {
913 XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
914 proto_rm[AFI_IP6][i] = NULL;
b84c7253 915
916 if (IS_ZEBRA_DEBUG_RIB)
917 zlog_debug ("%s: calling rib_update", __func__);
918
0aabccc0
DD
919 rib_update();
920 }
921 return CMD_SUCCESS;
922}
923
924ALIAS (no_ipv6_protocol,
925 no_ipv6_protocol_val_cmd,
926 "no ipv6 protocol " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
927 NO_STR
928 IP6_STR
929 "Stop filtering IPv6 routing info between zebra and protocol\n"
930 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
931 "route map name")
932
933DEFUN (show_ipv6_protocol,
934 show_ipv6_protocol_cmd,
935 "show ipv6 protocol",
936 SHOW_STR
937 IP6_STR
938 "IPv6 protocol filtering status\n")
939{
940 int i;
941
942 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
943 vty_out(vty, "------------------------%s", VTY_NEWLINE);
944 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
945 {
946 if (proto_rm[AFI_IP6][i])
947 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
948 proto_rm[AFI_IP6][i],
949 VTY_NEWLINE);
950 else
951 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
952 }
953 if (proto_rm[AFI_IP6][i])
954 vty_out (vty, "%-10s : %-10s%s", "any", proto_rm[AFI_IP6][i],
955 VTY_NEWLINE);
956 else
957 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
958
959 return CMD_SUCCESS;
960}
961
9f0ea7d4
DS
962DEFUN (ip_protocol_nht_rmap,
963 ip_protocol_nht_rmap_cmd,
964 "ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
965 IP_STR
966 "Filter Next Hop tracking route resolution\n"
967 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
968 "Route map name\n")
969{
970 int i;
971
972 if (strcasecmp(argv[0], "any") == 0)
973 i = ZEBRA_ROUTE_MAX;
974 else
975 i = proto_name2num(argv[0]);
976 if (i < 0)
977 {
978 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
979 VTY_NEWLINE);
980 return CMD_WARNING;
981 }
982 if (nht_rm[AFI_IP][i])
983 {
984 if (strcmp(nht_rm[AFI_IP][i], argv[1]) == 0)
985 return CMD_SUCCESS;
986
987 XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
988 }
989
990 nht_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
078430f6 991 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
9f0ea7d4
DS
992
993 return CMD_SUCCESS;
994}
995
996DEFUN (no_ip_protocol_nht_rmap,
997 no_ip_protocol_nht_rmap_cmd,
998 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA,
999 NO_STR
1000 IP_STR
1001 "Filter Next Hop tracking route resolution\n"
1002 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA)
1003{
1004 int i;
1005
1006 if (strcasecmp(argv[0], "any") == 0)
1007 i = ZEBRA_ROUTE_MAX;
1008 else
1009 i = proto_name2num(argv[0]);
1010 if (i < 0)
1011 {
1012 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
1013 VTY_NEWLINE);
1014 return CMD_WARNING;
1015 }
1016 if (!nht_rm[AFI_IP][i])
1017 return CMD_SUCCESS;
1018
1019 if ((argc == 2 && strcmp(argv[1], nht_rm[AFI_IP][i]) == 0) ||
1020 (argc < 2))
1021 {
1022 XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
1023 nht_rm[AFI_IP][i] = NULL;
078430f6 1024 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
9f0ea7d4
DS
1025 }
1026 return CMD_SUCCESS;
1027}
1028
1029ALIAS (no_ip_protocol_nht_rmap,
1030 no_ip_protocol_nht_rmap_val_cmd,
1031 "no ip nht " QUAGGA_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
1032 IP_STR
1033 "Filter Next Hop tracking route resolution\n"
1034 QUAGGA_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
1035 "Route map name\n")
1036
1037DEFUN (show_ip_protocol_nht,
1038 show_ip_protocol_nht_cmd,
1039 "show ip nht route-map",
1040 SHOW_STR
1041 IP_STR
1042 "IP Next Hop tracking filtering status\n")
1043{
1044 int i;
1045
1046 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1047 vty_out(vty, "------------------------%s", VTY_NEWLINE);
1048 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1049 {
1050 if (nht_rm[AFI_IP][i])
1051 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1052 nht_rm[AFI_IP][i],
1053 VTY_NEWLINE);
1054 else
1055 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1056 }
1057 if (nht_rm[AFI_IP][i])
1058 vty_out (vty, "%-10s : %-10s%s", "any", nht_rm[AFI_IP][i],
1059 VTY_NEWLINE);
1060 else
1061 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1062
1063 return CMD_SUCCESS;
1064}
1065
1066DEFUN (ipv6_protocol_nht_rmap,
1067 ipv6_protocol_nht_rmap_cmd,
1068 "ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
1069 IP6_STR
1070 "Filter Next Hop tracking route resolution\n"
1071 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1072 "Route map name\n")
1073{
1074 int i;
1075
1076 if (strcasecmp(argv[0], "any") == 0)
1077 i = ZEBRA_ROUTE_MAX;
1078 else
1079 i = proto_name2num(argv[0]);
1080 if (i < 0)
1081 {
1082 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
1083 VTY_NEWLINE);
1084 return CMD_WARNING;
1085 }
1086 if (nht_rm[AFI_IP6][i])
1087 XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
1088 nht_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
078430f6 1089 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
9f0ea7d4
DS
1090
1091 return CMD_SUCCESS;
1092}
1093
1094DEFUN (no_ipv6_protocol_nht_rmap,
1095 no_ipv6_protocol_nht_rmap_cmd,
1096 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA,
1097 NO_STR
1098 IP6_STR
1099 "Filter Next Hop tracking route resolution\n"
1100 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA)
1101{
1102 int i;
1103
1104 if (strcasecmp(argv[0], "any") == 0)
1105 i = ZEBRA_ROUTE_MAX;
1106 else
1107 i = proto_name2num(argv[0]);
1108 if (i < 0)
1109 {
1110 vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "",
1111 VTY_NEWLINE);
1112 return CMD_WARNING;
1113 }
1114 if (nht_rm[AFI_IP6][i])
1115 XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
1116
1117 if ((argc == 2 && strcmp(argv[1], nht_rm[AFI_IP6][i]) == 0) ||
1118 (argc < 2))
1119 {
1120 XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
1121 nht_rm[AFI_IP6][i] = NULL;
078430f6 1122 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
9f0ea7d4
DS
1123 }
1124
1125 return CMD_SUCCESS;
1126}
1127
1128ALIAS (no_ipv6_protocol_nht_rmap,
1129 no_ipv6_protocol_nht_rmap_val_cmd,
1130 "no ipv6 nht " QUAGGA_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
1131 NO_STR
1132 IP6_STR
1133 "Filter Next Hop tracking route resolution\n"
1134 QUAGGA_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
1135 "Route map name\n")
1136
1137DEFUN (show_ipv6_protocol_nht,
1138 show_ipv6_protocol_nht_cmd,
1139 "show ipv6 nht route-map",
1140 SHOW_STR
1141 IP6_STR
1142 "IPv6 protocol Next Hop filtering status\n")
1143{
1144 int i;
1145
1146 vty_out(vty, "Protocol : route-map %s", VTY_NEWLINE);
1147 vty_out(vty, "------------------------%s", VTY_NEWLINE);
1148 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1149 {
1150 if (nht_rm[AFI_IP6][i])
1151 vty_out (vty, "%-10s : %-10s%s", zebra_route_string(i),
1152 nht_rm[AFI_IP6][i],
1153 VTY_NEWLINE);
1154 else
1155 vty_out (vty, "%-10s : none%s", zebra_route_string(i), VTY_NEWLINE);
1156 }
1157 if (nht_rm[AFI_IP][i])
1158 vty_out (vty, "%-10s : %-10s%s", "any", nht_rm[AFI_IP6][i],
1159 VTY_NEWLINE);
1160 else
1161 vty_out (vty, "%-10s : none%s", "any", VTY_NEWLINE);
1162
1163 return CMD_SUCCESS;
1164}
1165
5921ef9a
PJ
1166/*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
1167
1168/* `match ip next-hop IP_ACCESS_LIST' */
1169
1170/* Match function return 1 if match is success else return zero. */
1171static route_map_result_t
1172route_match_ip_next_hop (void *rule, struct prefix *prefix,
1173 route_map_object_t type, void *object)
1174{
1175 struct access_list *alist;
9f0ea7d4 1176 struct nh_rmap_obj *nh_data;
5921ef9a
PJ
1177 struct prefix_ipv4 p;
1178
1179 if (type == RMAP_ZEBRA)
1180 {
9f0ea7d4
DS
1181 nh_data = object;
1182 if (!nh_data)
1183 return RMAP_DENYMATCH;
1184
1185 switch (nh_data->nexthop->type) {
5921ef9a
PJ
1186 case NEXTHOP_TYPE_IFINDEX:
1187 case NEXTHOP_TYPE_IFNAME:
fa713d9e
CF
1188 /* Interface routes can't match ip next-hop */
1189 return RMAP_NOMATCH;
5921ef9a
PJ
1190 case NEXTHOP_TYPE_IPV4_IFINDEX:
1191 case NEXTHOP_TYPE_IPV4_IFNAME:
5921ef9a
PJ
1192 case NEXTHOP_TYPE_IPV4:
1193 p.family = AF_INET;
9f0ea7d4 1194 p.prefix = nh_data->nexthop->gate.ipv4;
5921ef9a
PJ
1195 p.prefixlen = IPV4_MAX_BITLEN;
1196 break;
1197 default:
1198 return RMAP_NOMATCH;
1199 }
1200 alist = access_list_lookup (AFI_IP, (char *) rule);
1201 if (alist == NULL)
1202 return RMAP_NOMATCH;
1203
1204 return (access_list_apply (alist, &p) == FILTER_DENY ?
1205 RMAP_NOMATCH : RMAP_MATCH);
1206 }
1207 return RMAP_NOMATCH;
1208}
1209
1210/* Route map `ip next-hop' match statement. `arg' should be
1211 access-list name. */
1212static void *
1213route_match_ip_next_hop_compile (const char *arg)
1214{
1215 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1216}
1217
1218/* Free route map's compiled `. */
1219static void
1220route_match_ip_next_hop_free (void *rule)
1221{
1222 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1223}
1224
1225/* Route map commands for ip next-hop matching. */
1226static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
1227{
1228 "ip next-hop",
1229 route_match_ip_next_hop,
1230 route_match_ip_next_hop_compile,
1231 route_match_ip_next_hop_free
1232};
6b0655a2 1233
5921ef9a
PJ
1234/* `match ip next-hop prefix-list PREFIX_LIST' */
1235
1236static route_map_result_t
1237route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
1238 route_map_object_t type, void *object)
1239{
1240 struct prefix_list *plist;
9f0ea7d4 1241 struct nh_rmap_obj *nh_data;
5921ef9a
PJ
1242 struct prefix_ipv4 p;
1243
1244 if (type == RMAP_ZEBRA)
1245 {
9f0ea7d4
DS
1246 nh_data = (struct nh_rmap_obj *)object;
1247 if (!nh_data)
1248 return RMAP_DENYMATCH;
1249
1250 switch (nh_data->nexthop->type) {
5921ef9a
PJ
1251 case NEXTHOP_TYPE_IFINDEX:
1252 case NEXTHOP_TYPE_IFNAME:
fa713d9e
CF
1253 /* Interface routes can't match ip next-hop */
1254 return RMAP_NOMATCH;
5921ef9a
PJ
1255 case NEXTHOP_TYPE_IPV4_IFINDEX:
1256 case NEXTHOP_TYPE_IPV4_IFNAME:
5921ef9a
PJ
1257 case NEXTHOP_TYPE_IPV4:
1258 p.family = AF_INET;
9f0ea7d4 1259 p.prefix = nh_data->nexthop->gate.ipv4;
5921ef9a
PJ
1260 p.prefixlen = IPV4_MAX_BITLEN;
1261 break;
1262 default:
1263 return RMAP_NOMATCH;
1264 }
1265 plist = prefix_list_lookup (AFI_IP, (char *) rule);
1266 if (plist == NULL)
1267 return RMAP_NOMATCH;
1268
1269 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
1270 RMAP_NOMATCH : RMAP_MATCH);
1271 }
1272 return RMAP_NOMATCH;
1273}
1274
1275static void *
1276route_match_ip_next_hop_prefix_list_compile (const char *arg)
1277{
1278 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1279}
1280
1281static void
1282route_match_ip_next_hop_prefix_list_free (void *rule)
1283{
1284 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1285}
1286
1287static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
1288{
1289 "ip next-hop prefix-list",
1290 route_match_ip_next_hop_prefix_list,
1291 route_match_ip_next_hop_prefix_list_compile,
1292 route_match_ip_next_hop_prefix_list_free
1293};
6b0655a2 1294
5921ef9a
PJ
1295/* `match ip address IP_ACCESS_LIST' */
1296
1297/* Match function should return 1 if match is success else return
1298 zero. */
1299static route_map_result_t
1300route_match_ip_address (void *rule, struct prefix *prefix,
1301 route_map_object_t type, void *object)
1302{
1303 struct access_list *alist;
1304
1305 if (type == RMAP_ZEBRA)
1306 {
1307 alist = access_list_lookup (AFI_IP, (char *) rule);
1308 if (alist == NULL)
1309 return RMAP_NOMATCH;
1310
1311 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1312 RMAP_NOMATCH : RMAP_MATCH);
1313 }
1314 return RMAP_NOMATCH;
1315}
1316
1317/* Route map `ip address' match statement. `arg' should be
1318 access-list name. */
1319static void *
1320route_match_ip_address_compile (const char *arg)
1321{
1322 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1323}
1324
1325/* Free route map's compiled `ip address' value. */
1326static void
1327route_match_ip_address_free (void *rule)
1328{
1329 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1330}
1331
1332/* Route map commands for ip address matching. */
1333static struct route_map_rule_cmd route_match_ip_address_cmd =
1334{
1335 "ip address",
1336 route_match_ip_address,
1337 route_match_ip_address_compile,
1338 route_match_ip_address_free
1339};
6b0655a2 1340
5921ef9a
PJ
1341/* `match ip address prefix-list PREFIX_LIST' */
1342
1343static route_map_result_t
1344route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
1345 route_map_object_t type, void *object)
1346{
1347 struct prefix_list *plist;
1348
1349 if (type == RMAP_ZEBRA)
1350 {
1351 plist = prefix_list_lookup (AFI_IP, (char *) rule);
1352 if (plist == NULL)
1353 return RMAP_NOMATCH;
1354
1355 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1356 RMAP_NOMATCH : RMAP_MATCH);
1357 }
1358 return RMAP_NOMATCH;
1359}
1360
1361static void *
1362route_match_ip_address_prefix_list_compile (const char *arg)
1363{
1364 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1365}
1366
1367static void
1368route_match_ip_address_prefix_list_free (void *rule)
1369{
1370 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1371}
1372
1373static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
1374{
1375 "ip address prefix-list",
1376 route_match_ip_address_prefix_list,
1377 route_match_ip_address_prefix_list_compile,
1378 route_match_ip_address_prefix_list_free
1379};
1380
6b0655a2 1381
9f0ea7d4
DS
1382/* `match ip address prefix-len PREFIXLEN' */
1383
1384static route_map_result_t
1385route_match_ip_address_prefix_len (void *rule, struct prefix *prefix,
1386 route_map_object_t type, void *object)
1387{
1388 u_int32_t *prefixlen = (u_int32_t *)rule;
1389
1390 if (type == RMAP_ZEBRA)
1391 {
1392 return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH);
1393 }
1394 return RMAP_NOMATCH;
1395}
1396
1397static void *
1398route_match_ip_address_prefix_len_compile (const char *arg)
1399{
1400 u_int32_t *prefix_len;
1401 char *endptr = NULL;
1402 unsigned long tmpval;
1403
1404 /* prefix len value shoud be integer. */
1405 if (! all_digit (arg))
1406 return NULL;
1407
1408 errno = 0;
1409 tmpval = strtoul (arg, &endptr, 10);
1410 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
1411 return NULL;
1412
1413 prefix_len = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1414
1415 if (!prefix_len)
1416 return prefix_len;
1417
1418 *prefix_len = tmpval;
1419 return prefix_len;
1420}
1421
1422static void
1423route_match_ip_address_prefix_len_free (void *rule)
1424{
1425 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1426}
1427
1428static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd =
1429{
1430 "ip address prefix-len",
1431 route_match_ip_address_prefix_len,
1432 route_match_ip_address_prefix_len_compile,
1433 route_match_ip_address_prefix_len_free
1434};
1435
1436
1437/* `match ip nexthop prefix-len PREFIXLEN' */
1438
1439static route_map_result_t
1440route_match_ip_nexthop_prefix_len (void *rule, struct prefix *prefix,
1441 route_map_object_t type, void *object)
1442{
1443 u_int32_t *prefixlen = (u_int32_t *)rule;
1444 struct nh_rmap_obj *nh_data;
1445 struct prefix_ipv4 p;
1446
1447 if (type == RMAP_ZEBRA)
1448 {
1449 nh_data = (struct nh_rmap_obj *)object;
1450 if (!nh_data || !nh_data->nexthop)
1451 return RMAP_DENYMATCH;
1452
1453 switch (nh_data->nexthop->type) {
1454 case NEXTHOP_TYPE_IFINDEX:
1455 case NEXTHOP_TYPE_IFNAME:
1456 /* Interface routes can't match ip next-hop */
1457 return RMAP_NOMATCH;
1458 case NEXTHOP_TYPE_IPV4_IFINDEX:
1459 case NEXTHOP_TYPE_IPV4_IFNAME:
1460 case NEXTHOP_TYPE_IPV4:
1461 p.family = AF_INET;
1462 p.prefix = nh_data->nexthop->gate.ipv4;
1463 p.prefixlen = IPV4_MAX_BITLEN;
1464 break;
1465 default:
1466 return RMAP_NOMATCH;
1467 }
1468 return ((p.prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH);
1469 }
1470 return RMAP_NOMATCH;
1471}
1472
1473static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd =
1474{
1475 "ip next-hop prefix-len",
1476 route_match_ip_nexthop_prefix_len,
1477 route_match_ip_address_prefix_len_compile, /* reuse */
1478 route_match_ip_address_prefix_len_free /* reuse */
1479};
1480
1481/* `match source-protocol PROTOCOL' */
1482
1483static route_map_result_t
1484route_match_source_protocol (void *rule, struct prefix *prefix,
1485 route_map_object_t type, void *object)
1486{
1487 u_int32_t *rib_type = (u_int32_t *)rule;
1488 struct nh_rmap_obj *nh_data;
1489
1490 if (type == RMAP_ZEBRA)
1491 {
1492 nh_data = (struct nh_rmap_obj *)object;
1493 if (!nh_data)
1494 return RMAP_DENYMATCH;
1495
1496 return ((nh_data->source_protocol == *rib_type)
1497 ? RMAP_MATCH : RMAP_NOMATCH);
1498 }
1499 return RMAP_NOMATCH;
1500}
1501
1502static void *
1503route_match_source_protocol_compile (const char *arg)
1504{
1505 u_int32_t *rib_type;
1506 int i;
1507
1508 i = proto_name2num(arg);
1509 rib_type = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1510
1511 *rib_type = i;
1512
1513 return rib_type;
1514}
1515
1516static void
1517route_match_source_protocol_free (void *rule)
1518{
1519 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1520}
1521
1522static struct route_map_rule_cmd route_match_source_protocol_cmd =
1523{
1524 "source-protocol",
1525 route_match_source_protocol,
1526 route_match_source_protocol_compile,
1527 route_match_source_protocol_free
1528};
1529
5921ef9a
PJ
1530/* `set src A.B.C.D' */
1531
1532/* Set src. */
1533static route_map_result_t
1534route_set_src (void *rule, struct prefix *prefix,
1535 route_map_object_t type, void *object)
1536{
9f0ea7d4
DS
1537 struct nh_rmap_obj *nh_data;
1538
5921ef9a
PJ
1539 if (type == RMAP_ZEBRA)
1540 {
9f0ea7d4 1541 nh_data = (struct nh_rmap_obj *)object;
c52ef59f 1542 nh_data->nexthop->rmap_src = *(union g_addr *)rule;
5921ef9a
PJ
1543 }
1544 return RMAP_OKAY;
1545}
1546
1547/* set src compilation. */
1548static void *
1549route_set_src_compile (const char *arg)
1550{
5921ef9a
PJ
1551 union g_addr src, *psrc;
1552
0aabccc0 1553 if (
09303314 1554#ifdef HAVE_IPV6
0aabccc0 1555 (inet_pton(AF_INET6, arg, &src.ipv6) == 1) ||
09303314 1556#endif /* HAVE_IPV6 */
0aabccc0
DD
1557 (src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1)))
1558 {
1559 psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
1560 *psrc = src;
1561 return psrc;
1562 }
1563 return NULL;
5921ef9a
PJ
1564}
1565
1566/* Free route map's compiled `set src' value. */
1567static void
1568route_set_src_free (void *rule)
1569{
1570 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1571}
1572
1573/* Set src rule structure. */
1574static struct route_map_rule_cmd route_set_src_cmd =
1575{
1576 "src",
1577 route_set_src,
1578 route_set_src_compile,
1579 route_set_src_free,
1580};
1581
518f0eb1
DS
1582static int
1583zebra_route_map_update_timer (struct thread *thread)
1584{
1585 zebra_t_rmap_update = NULL;
1586
1587 if (IS_ZEBRA_DEBUG_EVENT)
1588 zlog_debug("Event driven route-map update triggered");
1589
b84c7253 1590 if (IS_ZEBRA_DEBUG_RIB)
1591 zlog_debug ("%s: calling rib_update", __func__);
1592
518f0eb1 1593 rib_update();
078430f6
DS
1594 zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
1595 zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
9f0ea7d4
DS
1596
1597 return (0);
518f0eb1
DS
1598}
1599
9f0ea7d4 1600static void
518f0eb1
DS
1601zebra_route_map_set_delay_timer(u_int32_t value)
1602{
1603 zebra_rmap_update_timer = value;
1604 if (!value && zebra_t_rmap_update)
1605 {
1606 /* Event driven route map updates is being disabled */
1607 /* But there's a pending timer. Fire it off now */
1608 thread_cancel(zebra_t_rmap_update);
1609 zebra_route_map_update_timer(zebra_t_rmap_update);
1610 }
1611}
1612
1613void
1614zebra_route_map_write_delay_timer (struct vty *vty)
1615{
1616 if (vty && (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER))
1617 vty_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer,
1618 VTY_NEWLINE);
1619 return;
1620}
1621
1622route_map_result_t
1623zebra_route_map_check (int family, int rib_type, struct prefix *p,
ca84c8ef 1624 struct nexthop *nexthop, u_short tag)
518f0eb1
DS
1625{
1626 struct route_map *rmap = NULL;
1627 route_map_result_t ret = RMAP_MATCH;
9f0ea7d4
DS
1628 struct nh_rmap_obj nh_obj;
1629
1630 nh_obj.nexthop = nexthop;
1631 nh_obj.source_protocol = rib_type;
1632 nh_obj.metric = 0;
ca84c8ef 1633 nh_obj.tag = tag;
518f0eb1
DS
1634
1635 if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
1636 rmap = route_map_lookup_by_name (proto_rm[family][rib_type]);
1637 if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
1638 rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
1639 if (rmap) {
9f0ea7d4
DS
1640 ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
1641 }
1642
1643 return (ret);
1644}
1645
1646route_map_result_t
1647zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
1648 struct rib * rib, struct nexthop *nexthop)
1649{
1650 struct route_map *rmap = NULL;
1651 route_map_result_t ret = RMAP_MATCH;
1652 struct nh_rmap_obj nh_obj;
1653
1654 nh_obj.nexthop = nexthop;
1655 nh_obj.source_protocol = rib->type;
1656 nh_obj.metric = rib->metric;
ca84c8ef 1657 nh_obj.tag = rib->tag;
9f0ea7d4
DS
1658
1659 if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
1660 rmap = route_map_lookup_by_name (nht_rm[family][client_proto]);
1661 if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
1662 rmap = route_map_lookup_by_name (nht_rm[family][ZEBRA_ROUTE_MAX]);
1663 if (rmap) {
1664 ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
518f0eb1
DS
1665 }
1666
1667 return (ret);
1668}
1669
1670static void
9f0ea7d4 1671zebra_route_map_mark_update (const char *rmap_name)
518f0eb1
DS
1672{
1673 /* rmap_update_timer of 0 means don't do route updates */
1674 if (zebra_rmap_update_timer && !zebra_t_rmap_update)
1675 zebra_t_rmap_update =
1676 thread_add_timer(zebrad.master, zebra_route_map_update_timer, NULL,
1677 zebra_rmap_update_timer);
1678}
1679
1680static void
1681zebra_route_map_add (const char *rmap_name)
1682{
1683 zebra_route_map_mark_update(rmap_name);
1684 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
1685}
1686
1687static void
1688zebra_route_map_delete (const char *rmap_name)
1689{
1690 zebra_route_map_mark_update(rmap_name);
1691 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
1692}
1693
1694static void
1695zebra_route_map_event (route_map_event_t event, const char *rmap_name)
1696{
1697 zebra_route_map_mark_update(rmap_name);
1698 route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
1699}
1700
1701/* ip protocol configuration write function */
6baf7bb8
DS
1702void
1703zebra_routemap_config_write_protocol (struct vty *vty)
518f0eb1
DS
1704{
1705 int i;
1706
1707 for (i=0;i<ZEBRA_ROUTE_MAX;i++)
1708 {
1709 if (proto_rm[AFI_IP][i])
1710 vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i),
1711 proto_rm[AFI_IP][i], VTY_NEWLINE);
9f0ea7d4 1712
0aabccc0
DD
1713 if (proto_rm[AFI_IP6][i])
1714 vty_out (vty, "ipv6 protocol %s route-map %s%s", zebra_route_string(i),
1715 proto_rm[AFI_IP6][i], VTY_NEWLINE);
1716
9f0ea7d4
DS
1717 if (nht_rm[AFI_IP][i])
1718 vty_out (vty, "ip nht %s route-map %s%s", zebra_route_string(i),
1719 nht_rm[AFI_IP][i], VTY_NEWLINE);
1720
1721 if (nht_rm[AFI_IP6][i])
1722 vty_out (vty, "ipv6 nht %s route-map %s%s", zebra_route_string(i),
1723 nht_rm[AFI_IP6][i], VTY_NEWLINE);
518f0eb1 1724 }
9f0ea7d4 1725
518f0eb1
DS
1726 if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
1727 vty_out (vty, "ip protocol %s route-map %s%s", "any",
1728 proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
1729
0aabccc0
DD
1730 if (proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX])
1731 vty_out (vty, "ipv6 protocol %s route-map %s%s", "any",
1732 proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
1733
9f0ea7d4
DS
1734 if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX])
1735 vty_out (vty, "ip nht %s route-map %s%s", "any",
1736 nht_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
1737
1738 if (nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX])
1739 vty_out (vty, "ipv6 nht %s route-map %s%s", "any",
1740 nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE);
1741
518f0eb1
DS
1742 if (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER)
1743 vty_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer,
1744 VTY_NEWLINE);
518f0eb1 1745}
518f0eb1 1746
5921ef9a
PJ
1747void
1748zebra_route_map_init ()
1749{
518f0eb1
DS
1750 install_element (CONFIG_NODE, &ip_protocol_cmd);
1751 install_element (CONFIG_NODE, &no_ip_protocol_cmd);
9f0ea7d4 1752 install_element (CONFIG_NODE, &no_ip_protocol_val_cmd);
518f0eb1
DS
1753 install_element (VIEW_NODE, &show_ip_protocol_cmd);
1754 install_element (ENABLE_NODE, &show_ip_protocol_cmd);
0aabccc0
DD
1755 install_element (CONFIG_NODE, &ipv6_protocol_cmd);
1756 install_element (CONFIG_NODE, &no_ipv6_protocol_cmd);
1757 install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd);
1758 install_element (VIEW_NODE, &show_ipv6_protocol_cmd);
1759 install_element (ENABLE_NODE, &show_ipv6_protocol_cmd);
9f0ea7d4
DS
1760 install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
1761 install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
1762 install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd);
1763 install_element (VIEW_NODE, &show_ip_protocol_nht_cmd);
1764 install_element (ENABLE_NODE, &show_ip_protocol_nht_cmd);
1765 install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd);
1766 install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd);
1767 install_element (ENABLE_NODE, &no_ipv6_protocol_nht_rmap_val_cmd);
1768 install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd);
1769 install_element (ENABLE_NODE, &show_ipv6_protocol_nht_cmd);
518f0eb1
DS
1770 install_element (CONFIG_NODE, &zebra_route_map_timer_cmd);
1771 install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd);
1772
5921ef9a
PJ
1773 route_map_init ();
1774 route_map_init_vty ();
1775
518f0eb1
DS
1776 route_map_add_hook (zebra_route_map_add);
1777 route_map_delete_hook (zebra_route_map_delete);
1778 route_map_event_hook (zebra_route_map_event);
1779
ca84c8ef 1780 route_map_install_match (&route_match_tag_cmd);
5921ef9a
PJ
1781 route_map_install_match (&route_match_interface_cmd);
1782 route_map_install_match (&route_match_ip_next_hop_cmd);
1783 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
1784 route_map_install_match (&route_match_ip_address_cmd);
1785 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
9f0ea7d4
DS
1786 route_map_install_match (&route_match_ip_address_prefix_len_cmd);
1787 route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd);
1788 route_map_install_match (&route_match_source_protocol_cmd);
5921ef9a
PJ
1789/* */
1790 route_map_install_set (&route_set_src_cmd);
1791/* */
ca84c8ef
DS
1792 install_element (RMAP_NODE, &match_tag_cmd);
1793 install_element (RMAP_NODE, &no_match_tag_cmd);
1794 install_element (RMAP_NODE, &no_match_tag_val_cmd);
5921ef9a
PJ
1795 install_element (RMAP_NODE, &match_interface_cmd);
1796 install_element (RMAP_NODE, &no_match_interface_cmd);
1797 install_element (RMAP_NODE, &no_match_interface_val_cmd);
1798 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
1799 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
1800 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
1801 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
1802 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
1803 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
1804 install_element (RMAP_NODE, &match_ip_address_cmd);
1805 install_element (RMAP_NODE, &no_match_ip_address_cmd);
1806 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
1807 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
1808 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
1809 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
9f0ea7d4
DS
1810 install_element (RMAP_NODE, &match_ip_nexthop_prefix_len_cmd);
1811 install_element (RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd);
1812 install_element (RMAP_NODE, &no_match_ip_nexthop_prefix_len_val_cmd);
1813 install_element (RMAP_NODE, &match_ip_address_prefix_len_cmd);
1814 install_element (RMAP_NODE, &no_match_ip_address_prefix_len_cmd);
1815 install_element (RMAP_NODE, &no_match_ip_address_prefix_len_val_cmd);
1816 install_element (RMAP_NODE, &match_source_protocol_cmd);
1817 install_element (RMAP_NODE, &no_match_source_protocol_cmd);
1818 /* */
5921ef9a
PJ
1819 install_element (RMAP_NODE, &set_src_cmd);
1820 install_element (RMAP_NODE, &no_set_src_cmd);
1821}