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