]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * Route map function of ospfd. | |
3 | * Copyright (C) 2000 IP Infusion Inc. | |
4 | * | |
5 | * Written by Toshiaki Takada. | |
6 | * | |
7 | * This file is part of GNU Zebra. | |
8 | * | |
9 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2, or (at your option) any | |
12 | * later version. | |
13 | * | |
14 | * GNU Zebra is distributed in the hope that it will be useful, but | |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | * General Public License for more details. | |
18 | * | |
896014f4 DL |
19 | * You should have received a copy of the GNU General Public License along |
20 | * with this program; see the file COPYING; if not, write to the Free Software | |
21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 22 | */ |
23 | ||
24 | #include <zebra.h> | |
25 | ||
26 | #include "memory.h" | |
27 | #include "prefix.h" | |
28 | #include "table.h" | |
82f97584 | 29 | #include "vty.h" |
718e3744 | 30 | #include "routemap.h" |
31 | #include "command.h" | |
32 | #include "log.h" | |
33 | #include "plist.h" | |
1306c09a | 34 | #include "vrf.h" |
718e3744 | 35 | |
36 | #include "ospfd/ospfd.h" | |
37 | #include "ospfd/ospf_asbr.h" | |
38 | #include "ospfd/ospf_interface.h" | |
39 | #include "ospfd/ospf_lsa.h" | |
40 | #include "ospfd/ospf_route.h" | |
41 | #include "ospfd/ospf_zebra.h" | |
42 | ||
43 | /* Hook function for updating route_map assignment. */ | |
4dadc291 | 44 | static void |
6c835671 | 45 | ospf_route_map_update (const char *name) |
718e3744 | 46 | { |
73ffb25b | 47 | struct ospf *ospf; |
718e3744 | 48 | int type; |
49 | ||
50 | /* If OSPF instatnce does not exist, return right now. */ | |
73ffb25b | 51 | ospf = ospf_lookup (); |
52 | if (ospf == NULL) | |
718e3744 | 53 | return; |
54 | ||
55 | /* Update route-map */ | |
56 | for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) | |
57 | { | |
7c8ff89e DS |
58 | struct list *red_list; |
59 | struct listnode *node; | |
60 | struct ospf_redist *red; | |
61 | ||
62 | red_list = ospf->redist[type]; | |
63 | if (!red_list) | |
64 | continue; | |
65 | ||
66 | for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) | |
67 | { | |
68 | if (ROUTEMAP_NAME (red) | |
69 | && strcmp (ROUTEMAP_NAME (red), name) == 0) | |
70 | { | |
71 | /* Keep old route-map. */ | |
72 | struct route_map *old = ROUTEMAP (red); | |
73 | ||
74 | /* Update route-map. */ | |
75 | ROUTEMAP (red) = | |
76 | route_map_lookup_by_name (ROUTEMAP_NAME (red)); | |
77 | ||
78 | /* No update for this distribute type. */ | |
79 | if (old == NULL && ROUTEMAP (red) == NULL) | |
80 | continue; | |
81 | ||
82 | ospf_distribute_list_update (ospf, type, red->instance); | |
83 | } | |
84 | } | |
718e3744 | 85 | } |
86 | } | |
87 | ||
4dadc291 | 88 | static void |
6c835671 | 89 | ospf_route_map_event (route_map_event_t event, const char *name) |
718e3744 | 90 | { |
73ffb25b | 91 | struct ospf *ospf; |
718e3744 | 92 | int type; |
93 | ||
94 | /* If OSPF instatnce does not exist, return right now. */ | |
73ffb25b | 95 | ospf = ospf_lookup (); |
96 | if (ospf == NULL) | |
718e3744 | 97 | return; |
98 | ||
718e3744 | 99 | for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) |
100 | { | |
7c8ff89e DS |
101 | struct list *red_list; |
102 | struct listnode *node; | |
103 | struct ospf_redist *red; | |
104 | ||
105 | red_list = ospf->redist[type]; | |
106 | if (!red_list) | |
107 | continue; | |
108 | ||
109 | for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) | |
718e3744 | 110 | { |
7c8ff89e DS |
111 | if (ROUTEMAP_NAME (red) && ROUTEMAP (red) |
112 | && !strcmp (ROUTEMAP_NAME (red), name)) | |
113 | { | |
114 | ospf_distribute_list_update (ospf, type, red->instance); | |
115 | } | |
718e3744 | 116 | } |
117 | } | |
118 | } | |
119 | ||
120 | /* Delete rip route map rule. */ | |
4dadc291 | 121 | static int |
cdc2d765 | 122 | ospf_route_match_delete (struct vty *vty, |
6c835671 | 123 | const char *command, const char *arg) |
718e3744 | 124 | { |
cdc2d765 | 125 | VTY_DECLVAR_CONTEXT(route_map_index, index); |
718e3744 | 126 | int ret; |
127 | ||
128 | ret = route_map_delete_match (index, command, arg); | |
129 | if (ret) | |
130 | { | |
131 | switch (ret) | |
132 | { | |
133 | case RMAP_RULE_MISSING: | |
5e3edbf5 | 134 | vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE); |
718e3744 | 135 | return CMD_WARNING; |
718e3744 | 136 | case RMAP_COMPILE_ERROR: |
5e3edbf5 | 137 | vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE); |
718e3744 | 138 | return CMD_WARNING; |
718e3744 | 139 | } |
140 | } | |
141 | ||
142 | return CMD_SUCCESS; | |
143 | } | |
144 | ||
4dadc291 | 145 | static int |
cdc2d765 | 146 | ospf_route_match_add (struct vty *vty, |
6c835671 | 147 | const char *command, const char *arg) |
cdc2d765 DL |
148 | { |
149 | VTY_DECLVAR_CONTEXT(route_map_index, index); | |
718e3744 | 150 | int ret; |
151 | ||
152 | ret = route_map_add_match (index, command, arg); | |
153 | if (ret) | |
154 | { | |
155 | switch (ret) | |
156 | { | |
157 | case RMAP_RULE_MISSING: | |
5e3edbf5 | 158 | vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE); |
718e3744 | 159 | return CMD_WARNING; |
718e3744 | 160 | case RMAP_COMPILE_ERROR: |
5e3edbf5 | 161 | vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE); |
718e3744 | 162 | return CMD_WARNING; |
718e3744 | 163 | } |
164 | } | |
165 | ||
166 | return CMD_SUCCESS; | |
167 | } | |
168 | ||
718e3744 | 169 | /* `match ip netxthop ' */ |
170 | /* Match function return 1 if match is success else return zero. */ | |
4dadc291 | 171 | static route_map_result_t |
718e3744 | 172 | route_match_ip_nexthop (void *rule, struct prefix *prefix, |
173 | route_map_object_t type, void *object) | |
174 | { | |
175 | struct access_list *alist; | |
176 | struct external_info *ei = object; | |
177 | struct prefix_ipv4 p; | |
178 | ||
179 | if (type == RMAP_OSPF) | |
180 | { | |
181 | p.family = AF_INET; | |
182 | p.prefix = ei->nexthop; | |
183 | p.prefixlen = IPV4_MAX_BITLEN; | |
184 | ||
185 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
186 | if (alist == NULL) | |
187 | return RMAP_NOMATCH; | |
188 | ||
189 | return (access_list_apply (alist, &p) == FILTER_DENY ? | |
190 | RMAP_NOMATCH : RMAP_MATCH); | |
191 | } | |
192 | return RMAP_NOMATCH; | |
193 | } | |
194 | ||
195 | /* Route map `ip next-hop' match statement. `arg' should be | |
196 | access-list name. */ | |
4dadc291 | 197 | static void * |
6c835671 | 198 | route_match_ip_nexthop_compile (const char *arg) |
718e3744 | 199 | { |
200 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
201 | } | |
202 | ||
203 | /* Free route map's compiled `ip address' value. */ | |
4dadc291 | 204 | static void |
718e3744 | 205 | route_match_ip_nexthop_free (void *rule) |
206 | { | |
207 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
208 | } | |
209 | ||
210 | /* Route map commands for metric matching. */ | |
211 | struct route_map_rule_cmd route_match_ip_nexthop_cmd = | |
212 | { | |
213 | "ip next-hop", | |
214 | route_match_ip_nexthop, | |
215 | route_match_ip_nexthop_compile, | |
216 | route_match_ip_nexthop_free | |
217 | }; | |
218 | ||
219 | /* `match ip next-hop prefix-list PREFIX_LIST' */ | |
220 | ||
4dadc291 | 221 | static route_map_result_t |
718e3744 | 222 | route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, |
223 | route_map_object_t type, void *object) | |
224 | { | |
225 | struct prefix_list *plist; | |
226 | struct external_info *ei = object; | |
227 | struct prefix_ipv4 p; | |
228 | ||
229 | if (type == RMAP_OSPF) | |
230 | { | |
231 | p.family = AF_INET; | |
232 | p.prefix = ei->nexthop; | |
233 | p.prefixlen = IPV4_MAX_BITLEN; | |
234 | ||
235 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
236 | if (plist == NULL) | |
237 | return RMAP_NOMATCH; | |
238 | ||
239 | return (prefix_list_apply (plist, &p) == PREFIX_DENY ? | |
240 | RMAP_NOMATCH : RMAP_MATCH); | |
241 | } | |
242 | return RMAP_NOMATCH; | |
243 | } | |
244 | ||
4dadc291 | 245 | static void * |
6c835671 | 246 | route_match_ip_next_hop_prefix_list_compile (const char *arg) |
718e3744 | 247 | { |
248 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
249 | } | |
250 | ||
4dadc291 | 251 | static void |
718e3744 | 252 | route_match_ip_next_hop_prefix_list_free (void *rule) |
253 | { | |
254 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
255 | } | |
256 | ||
257 | struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = | |
258 | { | |
259 | "ip next-hop prefix-list", | |
260 | route_match_ip_next_hop_prefix_list, | |
261 | route_match_ip_next_hop_prefix_list_compile, | |
262 | route_match_ip_next_hop_prefix_list_free | |
263 | }; | |
264 | ||
265 | /* `match ip address IP_ACCESS_LIST' */ | |
266 | /* Match function should return 1 if match is success else return | |
267 | zero. */ | |
4dadc291 | 268 | static route_map_result_t |
718e3744 | 269 | route_match_ip_address (void *rule, struct prefix *prefix, |
270 | route_map_object_t type, void *object) | |
271 | { | |
272 | struct access_list *alist; | |
273 | /* struct prefix_ipv4 match; */ | |
274 | ||
275 | if (type == RMAP_OSPF) | |
276 | { | |
277 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
278 | if (alist == NULL) | |
279 | return RMAP_NOMATCH; | |
280 | ||
281 | return (access_list_apply (alist, prefix) == FILTER_DENY ? | |
282 | RMAP_NOMATCH : RMAP_MATCH); | |
283 | } | |
284 | return RMAP_NOMATCH; | |
285 | } | |
286 | ||
287 | /* Route map `ip address' match statement. `arg' should be | |
288 | access-list name. */ | |
4dadc291 | 289 | static void * |
6c835671 | 290 | route_match_ip_address_compile (const char *arg) |
718e3744 | 291 | { |
292 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
293 | } | |
294 | ||
295 | /* Free route map's compiled `ip address' value. */ | |
4dadc291 | 296 | static void |
718e3744 | 297 | route_match_ip_address_free (void *rule) |
298 | { | |
299 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
300 | } | |
301 | ||
302 | /* Route map commands for ip address matching. */ | |
303 | struct route_map_rule_cmd route_match_ip_address_cmd = | |
304 | { | |
305 | "ip address", | |
306 | route_match_ip_address, | |
307 | route_match_ip_address_compile, | |
308 | route_match_ip_address_free | |
309 | }; | |
310 | ||
311 | /* `match ip address prefix-list PREFIX_LIST' */ | |
4dadc291 | 312 | static route_map_result_t |
718e3744 | 313 | route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, |
314 | route_map_object_t type, void *object) | |
315 | { | |
316 | struct prefix_list *plist; | |
317 | ||
318 | if (type == RMAP_OSPF) | |
319 | { | |
320 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
321 | if (plist == NULL) | |
322 | return RMAP_NOMATCH; | |
323 | ||
324 | return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? | |
325 | RMAP_NOMATCH : RMAP_MATCH); | |
326 | } | |
327 | return RMAP_NOMATCH; | |
328 | } | |
329 | ||
4dadc291 | 330 | static void * |
6c835671 | 331 | route_match_ip_address_prefix_list_compile (const char *arg) |
718e3744 | 332 | { |
333 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
334 | } | |
335 | ||
4dadc291 | 336 | static void |
718e3744 | 337 | route_match_ip_address_prefix_list_free (void *rule) |
338 | { | |
339 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
340 | } | |
341 | ||
342 | struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = | |
343 | { | |
344 | "ip address prefix-list", | |
345 | route_match_ip_address_prefix_list, | |
346 | route_match_ip_address_prefix_list_compile, | |
347 | route_match_ip_address_prefix_list_free | |
348 | }; | |
349 | ||
350 | /* `match interface IFNAME' */ | |
351 | /* Match function should return 1 if match is success else return | |
352 | zero. */ | |
4dadc291 | 353 | static route_map_result_t |
718e3744 | 354 | route_match_interface (void *rule, struct prefix *prefix, |
355 | route_map_object_t type, void *object) | |
356 | { | |
357 | struct interface *ifp; | |
358 | struct external_info *ei; | |
359 | ||
360 | if (type == RMAP_OSPF) | |
361 | { | |
362 | ei = object; | |
1306c09a | 363 | ifp = if_lookup_by_name ((char *)rule, VRF_DEFAULT); |
718e3744 | 364 | |
365 | if (ifp == NULL || ifp->ifindex != ei->ifindex) | |
366 | return RMAP_NOMATCH; | |
367 | ||
368 | return RMAP_MATCH; | |
369 | } | |
370 | return RMAP_NOMATCH; | |
371 | } | |
372 | ||
373 | /* Route map `interface' match statement. `arg' should be | |
374 | interface name. */ | |
4dadc291 | 375 | static void * |
6c835671 | 376 | route_match_interface_compile (const char *arg) |
718e3744 | 377 | { |
378 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
379 | } | |
380 | ||
381 | /* Free route map's compiled `interface' value. */ | |
4dadc291 | 382 | static void |
718e3744 | 383 | route_match_interface_free (void *rule) |
384 | { | |
385 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
386 | } | |
387 | ||
388 | /* Route map commands for ip address matching. */ | |
389 | struct route_map_rule_cmd route_match_interface_cmd = | |
390 | { | |
391 | "interface", | |
392 | route_match_interface, | |
393 | route_match_interface_compile, | |
394 | route_match_interface_free | |
395 | }; | |
396 | ||
0d9551dc DS |
397 | /* Match function return 1 if match is success else return zero. */ |
398 | static route_map_result_t | |
399 | route_match_tag (void *rule, struct prefix *prefix, | |
400 | route_map_object_t type, void *object) | |
401 | { | |
dc9ffce8 | 402 | route_tag_t *tag; |
0d9551dc DS |
403 | struct external_info *ei; |
404 | ||
405 | if (type == RMAP_OSPF) | |
406 | { | |
407 | tag = rule; | |
408 | ei = object; | |
409 | ||
410 | return ((ei->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH); | |
411 | } | |
412 | ||
413 | return RMAP_NOMATCH; | |
414 | } | |
415 | ||
0d9551dc | 416 | /* Route map commands for tag matching. */ |
dc9ffce8 | 417 | static struct route_map_rule_cmd route_match_tag_cmd = |
0d9551dc DS |
418 | { |
419 | "tag", | |
420 | route_match_tag, | |
dc9ffce8 CF |
421 | route_map_rule_tag_compile, |
422 | route_map_rule_tag_free, | |
0d9551dc DS |
423 | }; |
424 | ||
425 | ||
718e3744 | 426 | /* `set metric METRIC' */ |
427 | /* Set metric to attribute. */ | |
4dadc291 | 428 | static route_map_result_t |
718e3744 | 429 | route_set_metric (void *rule, struct prefix *prefix, |
430 | route_map_object_t type, void *object) | |
431 | { | |
432 | u_int32_t *metric; | |
433 | struct external_info *ei; | |
434 | ||
435 | if (type == RMAP_OSPF) | |
436 | { | |
437 | /* Fetch routemap's rule information. */ | |
438 | metric = rule; | |
439 | ei = object; | |
440 | ||
441 | /* Set metric out value. */ | |
442 | ei->route_map_set.metric = *metric; | |
443 | } | |
444 | return RMAP_OKAY; | |
445 | } | |
446 | ||
447 | /* set metric compilation. */ | |
4dadc291 | 448 | static void * |
6c835671 | 449 | route_set_metric_compile (const char *arg) |
718e3744 | 450 | { |
451 | u_int32_t *metric; | |
fbc043a8 | 452 | int32_t ret; |
718e3744 | 453 | |
5e3edbf5 DS |
454 | /* OSPF doesn't support the +/- in |
455 | set metric <+/-metric> check | |
456 | Ignore the +/- component */ | |
457 | if (! all_digit (arg)) | |
ed2eb093 DS |
458 | { |
459 | if ((strncmp (arg, "+", 1) == 0 || strncmp (arg, "-", 1) == 0) && | |
460 | all_digit (arg+1)) | |
461 | { | |
462 | zlog_warn ("OSPF does not support 'set metric +/-'"); | |
463 | arg++; | |
464 | } | |
465 | else | |
466 | { | |
467 | return NULL; | |
468 | } | |
469 | } | |
718e3744 | 470 | metric = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); |
fbc043a8 | 471 | ret = atoi (arg); |
718e3744 | 472 | |
fbc043a8 AC |
473 | if (ret >= 0) |
474 | { | |
475 | *metric = (u_int32_t)ret; | |
476 | return metric; | |
477 | } | |
718e3744 | 478 | |
479 | XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); | |
480 | return NULL; | |
481 | } | |
482 | ||
483 | /* Free route map's compiled `set metric' value. */ | |
4dadc291 | 484 | static void |
718e3744 | 485 | route_set_metric_free (void *rule) |
486 | { | |
487 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
488 | } | |
489 | ||
490 | /* Set metric rule structure. */ | |
491 | struct route_map_rule_cmd route_set_metric_cmd = | |
492 | { | |
493 | "metric", | |
494 | route_set_metric, | |
495 | route_set_metric_compile, | |
496 | route_set_metric_free, | |
497 | }; | |
498 | ||
499 | /* `set metric-type TYPE' */ | |
500 | /* Set metric-type to attribute. */ | |
4dadc291 | 501 | static route_map_result_t |
718e3744 | 502 | route_set_metric_type (void *rule, struct prefix *prefix, |
503 | route_map_object_t type, void *object) | |
504 | { | |
505 | u_int32_t *metric_type; | |
506 | struct external_info *ei; | |
507 | ||
508 | if (type == RMAP_OSPF) | |
509 | { | |
510 | /* Fetch routemap's rule information. */ | |
511 | metric_type = rule; | |
512 | ei = object; | |
513 | ||
514 | /* Set metric out value. */ | |
515 | ei->route_map_set.metric_type = *metric_type; | |
516 | } | |
517 | return RMAP_OKAY; | |
518 | } | |
519 | ||
520 | /* set metric-type compilation. */ | |
4dadc291 | 521 | static void * |
6c835671 | 522 | route_set_metric_type_compile (const char *arg) |
718e3744 | 523 | { |
524 | u_int32_t *metric_type; | |
525 | ||
526 | metric_type = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); | |
527 | if (strcmp (arg, "type-1") == 0) | |
528 | *metric_type = EXTERNAL_METRIC_TYPE_1; | |
529 | else if (strcmp (arg, "type-2") == 0) | |
530 | *metric_type = EXTERNAL_METRIC_TYPE_2; | |
531 | ||
532 | if (*metric_type == EXTERNAL_METRIC_TYPE_1 || | |
533 | *metric_type == EXTERNAL_METRIC_TYPE_2) | |
534 | return metric_type; | |
535 | ||
536 | XFREE (MTYPE_ROUTE_MAP_COMPILED, metric_type); | |
537 | return NULL; | |
538 | } | |
539 | ||
540 | /* Free route map's compiled `set metric-type' value. */ | |
4dadc291 | 541 | static void |
718e3744 | 542 | route_set_metric_type_free (void *rule) |
543 | { | |
544 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
545 | } | |
546 | ||
547 | /* Set metric rule structure. */ | |
548 | struct route_map_rule_cmd route_set_metric_type_cmd = | |
549 | { | |
550 | "metric-type", | |
551 | route_set_metric_type, | |
552 | route_set_metric_type_compile, | |
553 | route_set_metric_type_free, | |
554 | }; | |
555 | ||
0d9551dc DS |
556 | static route_map_result_t |
557 | route_set_tag (void *rule, struct prefix *prefix, | |
558 | route_map_object_t type, void *object) | |
559 | { | |
dc9ffce8 | 560 | route_tag_t *tag; |
0d9551dc DS |
561 | struct external_info *ei; |
562 | ||
563 | if (type == RMAP_OSPF) | |
564 | { | |
565 | tag = rule; | |
566 | ei = object; | |
567 | ||
568 | /* Set tag value */ | |
569 | ei->tag=*tag; | |
570 | } | |
571 | ||
572 | return RMAP_OKAY; | |
573 | } | |
574 | ||
0d9551dc | 575 | /* Route map commands for tag set. */ |
dc9ffce8 | 576 | static struct route_map_rule_cmd route_set_tag_cmd = |
0d9551dc DS |
577 | { |
578 | "tag", | |
579 | route_set_tag, | |
dc9ffce8 CF |
580 | route_map_rule_tag_compile, |
581 | route_map_rule_tag_free, | |
0d9551dc DS |
582 | }; |
583 | ||
718e3744 | 584 | DEFUN (match_ip_nexthop, |
585 | match_ip_nexthop_cmd, | |
6147e2c6 | 586 | "match ip next-hop <(1-199)|(1300-2699)|WORD>", |
718e3744 | 587 | MATCH_STR |
588 | IP_STR | |
589 | "Match next-hop address of route\n" | |
590 | "IP access-list number\n" | |
591 | "IP access-list number (expanded range)\n" | |
592 | "IP access-list name\n") | |
593 | { | |
8d769265 | 594 | int idx_acl = 3; |
cdc2d765 | 595 | return ospf_route_match_add (vty, "ip next-hop", argv[idx_acl]->arg); |
718e3744 | 596 | } |
597 | ||
598 | DEFUN (no_match_ip_nexthop, | |
599 | no_match_ip_nexthop_cmd, | |
692b4c65 | 600 | "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]", |
718e3744 | 601 | NO_STR |
602 | MATCH_STR | |
603 | IP_STR | |
692b4c65 QY |
604 | "Match next-hop address of route\n" |
605 | "IP access-list number\n" | |
606 | "IP access-list number (expanded range)\n" | |
607 | "IP access-list name\n") | |
718e3744 | 608 | { |
692b4c65 | 609 | char *al = (argc == 5) ? argv[4]->arg : NULL; |
cdc2d765 | 610 | return ospf_route_match_delete (vty, "ip next-hop", al); |
718e3744 | 611 | } |
612 | ||
718e3744 | 613 | DEFUN (set_metric_type, |
614 | set_metric_type_cmd, | |
6147e2c6 | 615 | "set metric-type <type-1|type-2>", |
718e3744 | 616 | SET_STR |
617 | "Type of metric for destination routing protocol\n" | |
73ffb25b | 618 | "OSPF[6] external type 1 metric\n" |
619 | "OSPF[6] external type 2 metric\n") | |
718e3744 | 620 | { |
692b4c65 | 621 | char *ext = argv[2]->text; |
cdc2d765 DL |
622 | return generic_set_add (vty, VTY_GET_CONTEXT(route_map_index), |
623 | "metric-type", ext); | |
718e3744 | 624 | } |
625 | ||
626 | DEFUN (no_set_metric_type, | |
627 | no_set_metric_type_cmd, | |
692b4c65 | 628 | "no set metric-type [<type-1|type-2>]", |
718e3744 | 629 | NO_STR |
630 | SET_STR | |
ff788d08 | 631 | "Type of metric for destination routing protocol\n" |
692b4c65 | 632 | "OSPF[6] external type 1 metric\n" |
ff788d08 | 633 | "OSPF[6] external type 2 metric\n") |
718e3744 | 634 | { |
692b4c65 | 635 | char *ext = (argc == 4) ? argv[3]->text : NULL; |
cdc2d765 DL |
636 | return generic_set_delete (vty, VTY_GET_CONTEXT(route_map_index), |
637 | "metric-type", ext); | |
0d9551dc DS |
638 | } |
639 | ||
718e3744 | 640 | /* Route-map init */ |
641 | void | |
642 | ospf_route_map_init (void) | |
643 | { | |
644 | route_map_init (); | |
718e3744 | 645 | |
646 | route_map_add_hook (ospf_route_map_update); | |
647 | route_map_delete_hook (ospf_route_map_update); | |
648 | route_map_event_hook (ospf_route_map_event); | |
82f97584 DW |
649 | |
650 | route_map_match_interface_hook (generic_match_add); | |
651 | route_map_no_match_interface_hook (generic_match_delete); | |
652 | ||
653 | route_map_match_ip_address_hook (generic_match_add); | |
654 | route_map_no_match_ip_address_hook (generic_match_delete); | |
655 | ||
656 | route_map_match_ip_address_prefix_list_hook (generic_match_add); | |
657 | route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); | |
658 | ||
659 | route_map_match_ip_next_hop_prefix_list_hook (generic_match_add); | |
660 | route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete); | |
661 | ||
662 | route_map_match_tag_hook (generic_match_add); | |
663 | route_map_no_match_tag_hook (generic_match_delete); | |
664 | ||
665 | route_map_set_metric_hook (generic_set_add); | |
666 | route_map_no_set_metric_hook (generic_set_delete); | |
667 | ||
668 | route_map_set_tag_hook (generic_set_add); | |
669 | route_map_no_set_tag_hook (generic_set_delete); | |
718e3744 | 670 | |
671 | route_map_install_match (&route_match_ip_nexthop_cmd); | |
672 | route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); | |
673 | route_map_install_match (&route_match_ip_address_cmd); | |
674 | route_map_install_match (&route_match_ip_address_prefix_list_cmd); | |
675 | route_map_install_match (&route_match_interface_cmd); | |
0d9551dc | 676 | route_map_install_match (&route_match_tag_cmd); |
718e3744 | 677 | |
678 | route_map_install_set (&route_set_metric_cmd); | |
679 | route_map_install_set (&route_set_metric_type_cmd); | |
0d9551dc | 680 | route_map_install_set (&route_set_tag_cmd); |
718e3744 | 681 | |
682 | install_element (RMAP_NODE, &match_ip_nexthop_cmd); | |
683 | install_element (RMAP_NODE, &no_match_ip_nexthop_cmd); | |
82f97584 | 684 | |
718e3744 | 685 | install_element (RMAP_NODE, &set_metric_type_cmd); |
686 | install_element (RMAP_NODE, &no_set_metric_type_cmd); | |
718e3744 | 687 | } |