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