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