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