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