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