]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* RIPv2 routemap. |
2 | * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org> | |
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 "routemap.h" | |
27 | #include "command.h" | |
28 | #include "filter.h" | |
29 | #include "log.h" | |
30 | #include "sockunion.h" /* for inet_aton () */ | |
31 | #include "plist.h" | |
32 | ||
33 | #include "ripd/ripd.h" | |
34 | ||
35 | /* Add rip route map rule. */ | |
36 | int | |
37 | rip_route_match_add (struct vty *vty, struct route_map_index *index, | |
38 | char *command, char *arg) | |
39 | { | |
40 | int ret; | |
41 | ||
42 | ret = route_map_add_match (index, command, arg); | |
43 | if (ret) | |
44 | { | |
45 | switch (ret) | |
46 | { | |
47 | case RMAP_RULE_MISSING: | |
48 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
49 | return CMD_WARNING; | |
50 | break; | |
51 | case RMAP_COMPILE_ERROR: | |
52 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
53 | return CMD_WARNING; | |
54 | break; | |
55 | } | |
56 | } | |
57 | return CMD_SUCCESS; | |
58 | } | |
59 | ||
60 | /* Delete rip route map rule. */ | |
61 | int | |
62 | rip_route_match_delete (struct vty *vty, struct route_map_index *index, | |
63 | char *command, char *arg) | |
64 | { | |
65 | int ret; | |
66 | ||
67 | ret = route_map_delete_match (index, command, arg); | |
68 | if (ret) | |
69 | { | |
70 | switch (ret) | |
71 | { | |
72 | case RMAP_RULE_MISSING: | |
73 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
74 | return CMD_WARNING; | |
75 | break; | |
76 | case RMAP_COMPILE_ERROR: | |
77 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
78 | return CMD_WARNING; | |
79 | break; | |
80 | } | |
81 | } | |
82 | return CMD_SUCCESS; | |
83 | } | |
84 | ||
85 | /* Add rip route map rule. */ | |
86 | int | |
87 | rip_route_set_add (struct vty *vty, struct route_map_index *index, | |
88 | char *command, char *arg) | |
89 | { | |
90 | int ret; | |
91 | ||
92 | ret = route_map_add_set (index, command, arg); | |
93 | if (ret) | |
94 | { | |
95 | switch (ret) | |
96 | { | |
97 | case RMAP_RULE_MISSING: | |
98 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
99 | return CMD_WARNING; | |
100 | break; | |
101 | case RMAP_COMPILE_ERROR: | |
102 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
103 | return CMD_WARNING; | |
104 | break; | |
105 | } | |
106 | } | |
107 | return CMD_SUCCESS; | |
108 | } | |
109 | ||
110 | /* Delete rip route map rule. */ | |
111 | int | |
112 | rip_route_set_delete (struct vty *vty, struct route_map_index *index, | |
113 | char *command, char *arg) | |
114 | { | |
115 | int ret; | |
116 | ||
117 | ret = route_map_delete_set (index, command, arg); | |
118 | if (ret) | |
119 | { | |
120 | switch (ret) | |
121 | { | |
122 | case RMAP_RULE_MISSING: | |
123 | vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE); | |
124 | return CMD_WARNING; | |
125 | break; | |
126 | case RMAP_COMPILE_ERROR: | |
127 | vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE); | |
128 | return CMD_WARNING; | |
129 | break; | |
130 | } | |
131 | } | |
132 | return CMD_SUCCESS; | |
133 | } | |
134 | ||
135 | /* Hook function for updating route_map assignment. */ | |
136 | void | |
137 | rip_route_map_update () | |
138 | { | |
139 | int i; | |
140 | ||
141 | if (rip) | |
142 | { | |
143 | for (i = 0; i < ZEBRA_ROUTE_MAX; i++) | |
144 | { | |
145 | if (rip->route_map[i].name) | |
146 | rip->route_map[i].map = | |
147 | route_map_lookup_by_name (rip->route_map[i].name); | |
148 | } | |
149 | } | |
150 | } | |
151 | \f | |
152 | /* `match metric METRIC' */ | |
153 | /* Match function return 1 if match is success else return zero. */ | |
154 | route_map_result_t | |
155 | route_match_metric (void *rule, struct prefix *prefix, | |
156 | route_map_object_t type, void *object) | |
157 | { | |
158 | u_int32_t *metric; | |
159 | struct rip_info *rinfo; | |
160 | ||
161 | if (type == RMAP_RIP) | |
162 | { | |
163 | metric = rule; | |
164 | rinfo = object; | |
165 | ||
166 | if (rinfo->metric == *metric) | |
167 | return RMAP_MATCH; | |
168 | else | |
169 | return RMAP_NOMATCH; | |
170 | } | |
171 | return RMAP_NOMATCH; | |
172 | } | |
173 | ||
174 | /* Route map `match metric' match statement. `arg' is METRIC value */ | |
175 | void * | |
176 | route_match_metric_compile (char *arg) | |
177 | { | |
178 | u_int32_t *metric; | |
179 | ||
180 | metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); | |
181 | *metric = atoi (arg); | |
182 | ||
183 | if(*metric > 0) | |
184 | return metric; | |
185 | ||
186 | XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); | |
187 | return NULL; | |
188 | } | |
189 | ||
190 | /* Free route map's compiled `match metric' value. */ | |
191 | void | |
192 | route_match_metric_free (void *rule) | |
193 | { | |
194 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
195 | } | |
196 | ||
197 | /* Route map commands for metric matching. */ | |
198 | struct route_map_rule_cmd route_match_metric_cmd = | |
199 | { | |
200 | "metric", | |
201 | route_match_metric, | |
202 | route_match_metric_compile, | |
203 | route_match_metric_free | |
204 | }; | |
205 | ||
206 | /* `match interface IFNAME' */ | |
207 | /* Match function return 1 if match is success else return zero. */ | |
208 | route_map_result_t | |
209 | route_match_interface (void *rule, struct prefix *prefix, | |
210 | route_map_object_t type, void *object) | |
211 | { | |
212 | struct rip_info *rinfo; | |
213 | struct interface *ifp; | |
214 | char *ifname; | |
215 | ||
216 | if (type == RMAP_RIP) | |
217 | { | |
218 | ifname = rule; | |
219 | ifp = if_lookup_by_name(ifname); | |
220 | ||
221 | if (!ifp) | |
222 | return RMAP_NOMATCH; | |
223 | ||
224 | rinfo = object; | |
225 | ||
226 | if (rinfo->ifindex_out == ifp->ifindex) | |
227 | return RMAP_MATCH; | |
228 | else | |
229 | return RMAP_NOMATCH; | |
230 | } | |
231 | return RMAP_NOMATCH; | |
232 | } | |
233 | ||
234 | /* Route map `match interface' match statement. `arg' is IFNAME value */ | |
235 | /* XXX I don`t know if I need to check does interface exist? */ | |
236 | void * | |
237 | route_match_interface_compile (char *arg) | |
238 | { | |
239 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
240 | } | |
241 | ||
242 | /* Free route map's compiled `match interface' value. */ | |
243 | void | |
244 | route_match_interface_free (void *rule) | |
245 | { | |
246 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
247 | } | |
248 | ||
249 | /* Route map commands for interface matching. */ | |
250 | struct route_map_rule_cmd route_match_interface_cmd = | |
251 | { | |
252 | "interface", | |
253 | route_match_interface, | |
254 | route_match_interface_compile, | |
255 | route_match_interface_free | |
256 | }; | |
257 | ||
258 | /* `match ip next-hop IP_ACCESS_LIST' */ | |
259 | ||
260 | /* Match function return 1 if match is success else return zero. */ | |
261 | route_map_result_t | |
262 | route_match_ip_next_hop (void *rule, struct prefix *prefix, | |
263 | route_map_object_t type, void *object) | |
264 | { | |
265 | struct access_list *alist; | |
266 | struct rip_info *rinfo; | |
267 | struct prefix_ipv4 p; | |
268 | ||
269 | if (type == RMAP_RIP) | |
270 | { | |
271 | rinfo = object; | |
272 | p.family = AF_INET; | |
273 | p.prefix = rinfo->nexthop; | |
274 | p.prefixlen = IPV4_MAX_BITLEN; | |
275 | ||
276 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
277 | if (alist == NULL) | |
278 | return RMAP_NOMATCH; | |
279 | ||
280 | return (access_list_apply (alist, &p) == FILTER_DENY ? | |
281 | RMAP_NOMATCH : RMAP_MATCH); | |
282 | } | |
283 | return RMAP_NOMATCH; | |
284 | } | |
285 | ||
286 | /* Route map `ip next-hop' match statement. `arg' should be | |
287 | access-list name. */ | |
288 | void * | |
289 | route_match_ip_next_hop_compile (char *arg) | |
290 | { | |
291 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
292 | } | |
293 | ||
294 | /* Free route map's compiled `. */ | |
295 | void | |
296 | route_match_ip_next_hop_free (void *rule) | |
297 | { | |
298 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
299 | } | |
300 | ||
301 | /* Route map commands for ip next-hop matching. */ | |
302 | struct route_map_rule_cmd route_match_ip_next_hop_cmd = | |
303 | { | |
304 | "ip next-hop", | |
305 | route_match_ip_next_hop, | |
306 | route_match_ip_next_hop_compile, | |
307 | route_match_ip_next_hop_free | |
308 | }; | |
309 | \f | |
310 | /* `match ip next-hop prefix-list PREFIX_LIST' */ | |
311 | ||
312 | route_map_result_t | |
313 | route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, | |
314 | route_map_object_t type, void *object) | |
315 | { | |
316 | struct prefix_list *plist; | |
317 | struct rip_info *rinfo; | |
318 | struct prefix_ipv4 p; | |
319 | ||
320 | if (type == RMAP_RIP) | |
321 | { | |
322 | rinfo = object; | |
323 | p.family = AF_INET; | |
324 | p.prefix = rinfo->nexthop; | |
325 | p.prefixlen = IPV4_MAX_BITLEN; | |
326 | ||
327 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
328 | if (plist == NULL) | |
329 | return RMAP_NOMATCH; | |
330 | ||
331 | return (prefix_list_apply (plist, &p) == PREFIX_DENY ? | |
332 | RMAP_NOMATCH : RMAP_MATCH); | |
333 | } | |
334 | return RMAP_NOMATCH; | |
335 | } | |
336 | ||
337 | void * | |
338 | route_match_ip_next_hop_prefix_list_compile (char *arg) | |
339 | { | |
340 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
341 | } | |
342 | ||
343 | void | |
344 | route_match_ip_next_hop_prefix_list_free (void *rule) | |
345 | { | |
346 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
347 | } | |
348 | ||
349 | struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = | |
350 | { | |
351 | "ip next-hop prefix-list", | |
352 | route_match_ip_next_hop_prefix_list, | |
353 | route_match_ip_next_hop_prefix_list_compile, | |
354 | route_match_ip_next_hop_prefix_list_free | |
355 | }; | |
356 | \f | |
357 | /* `match ip address IP_ACCESS_LIST' */ | |
358 | ||
359 | /* Match function should return 1 if match is success else return | |
360 | zero. */ | |
361 | route_map_result_t | |
362 | route_match_ip_address (void *rule, struct prefix *prefix, | |
363 | route_map_object_t type, void *object) | |
364 | { | |
365 | struct access_list *alist; | |
366 | ||
367 | if (type == RMAP_RIP) | |
368 | { | |
369 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
370 | if (alist == NULL) | |
371 | return RMAP_NOMATCH; | |
372 | ||
373 | return (access_list_apply (alist, prefix) == FILTER_DENY ? | |
374 | RMAP_NOMATCH : RMAP_MATCH); | |
375 | } | |
376 | return RMAP_NOMATCH; | |
377 | } | |
378 | ||
379 | /* Route map `ip address' match statement. `arg' should be | |
380 | access-list name. */ | |
381 | void * | |
382 | route_match_ip_address_compile (char *arg) | |
383 | { | |
384 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
385 | } | |
386 | ||
387 | /* Free route map's compiled `ip address' value. */ | |
388 | void | |
389 | route_match_ip_address_free (void *rule) | |
390 | { | |
391 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
392 | } | |
393 | ||
394 | /* Route map commands for ip address matching. */ | |
395 | struct route_map_rule_cmd route_match_ip_address_cmd = | |
396 | { | |
397 | "ip address", | |
398 | route_match_ip_address, | |
399 | route_match_ip_address_compile, | |
400 | route_match_ip_address_free | |
401 | }; | |
402 | \f | |
403 | /* `match ip address prefix-list PREFIX_LIST' */ | |
404 | ||
405 | route_map_result_t | |
406 | route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, | |
407 | route_map_object_t type, void *object) | |
408 | { | |
409 | struct prefix_list *plist; | |
410 | ||
411 | if (type == RMAP_RIP) | |
412 | { | |
413 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
414 | if (plist == NULL) | |
415 | return RMAP_NOMATCH; | |
416 | ||
417 | return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? | |
418 | RMAP_NOMATCH : RMAP_MATCH); | |
419 | } | |
420 | return RMAP_NOMATCH; | |
421 | } | |
422 | ||
423 | void * | |
424 | route_match_ip_address_prefix_list_compile (char *arg) | |
425 | { | |
426 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
427 | } | |
428 | ||
429 | void | |
430 | route_match_ip_address_prefix_list_free (void *rule) | |
431 | { | |
432 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
433 | } | |
434 | ||
435 | struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = | |
436 | { | |
437 | "ip address prefix-list", | |
438 | route_match_ip_address_prefix_list, | |
439 | route_match_ip_address_prefix_list_compile, | |
440 | route_match_ip_address_prefix_list_free | |
441 | }; | |
442 | \f | |
443 | /* `set metric METRIC' */ | |
444 | ||
445 | /* Set metric to attribute. */ | |
446 | route_map_result_t | |
447 | route_set_metric (void *rule, struct prefix *prefix, | |
448 | route_map_object_t type, void *object) | |
449 | { | |
450 | u_int32_t *metric; | |
451 | struct rip_info *rinfo; | |
452 | ||
453 | if (type == RMAP_RIP) | |
454 | { | |
455 | /* Fetch routemap's rule information. */ | |
456 | metric = rule; | |
457 | rinfo = object; | |
458 | ||
459 | /* Set metric out value. */ | |
460 | rinfo->metric_out = *metric; | |
461 | rinfo->metric_set = 1; | |
462 | } | |
463 | return RMAP_OKAY; | |
464 | } | |
465 | ||
466 | /* set metric compilation. */ | |
467 | void * | |
468 | route_set_metric_compile (char *arg) | |
469 | { | |
470 | u_int32_t *metric; | |
471 | ||
472 | metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); | |
473 | *metric = atoi (arg); | |
474 | ||
475 | return metric; | |
476 | ||
477 | #if 0 | |
478 | /* To make it consistent to other daemon, metric check is commented | |
479 | out.*/ | |
480 | if (*metric >= 0 && *metric <= 16) | |
481 | return metric; | |
482 | ||
483 | XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); | |
484 | return NULL; | |
485 | #endif /* 0 */ | |
486 | } | |
487 | ||
488 | /* Free route map's compiled `set metric' value. */ | |
489 | void | |
490 | route_set_metric_free (void *rule) | |
491 | { | |
492 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
493 | } | |
494 | ||
495 | /* Set metric rule structure. */ | |
496 | struct route_map_rule_cmd route_set_metric_cmd = | |
497 | { | |
498 | "metric", | |
499 | route_set_metric, | |
500 | route_set_metric_compile, | |
501 | route_set_metric_free, | |
502 | }; | |
503 | ||
504 | /* `set ip next-hop IP_ADDRESS' */ | |
505 | ||
506 | /* Set nexthop to object. ojbect must be pointer to struct attr. */ | |
507 | route_map_result_t | |
508 | route_set_ip_nexthop (void *rule, struct prefix *prefix, | |
509 | route_map_object_t type, void *object) | |
510 | { | |
511 | struct in_addr *address; | |
512 | struct rip_info *rinfo; | |
513 | ||
514 | if(type == RMAP_RIP) | |
515 | { | |
516 | /* Fetch routemap's rule information. */ | |
517 | address = rule; | |
518 | rinfo = object; | |
519 | ||
520 | /* Set next hop value. */ | |
521 | rinfo->nexthop_out = *address; | |
522 | } | |
523 | ||
524 | return RMAP_OKAY; | |
525 | } | |
526 | ||
527 | /* Route map `ip nexthop' compile function. Given string is converted | |
528 | to struct in_addr structure. */ | |
529 | void * | |
530 | route_set_ip_nexthop_compile (char *arg) | |
531 | { | |
532 | int ret; | |
533 | struct in_addr *address; | |
534 | ||
535 | address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); | |
536 | ||
537 | ret = inet_aton (arg, address); | |
538 | ||
539 | if (ret == 0) | |
540 | { | |
541 | XFREE (MTYPE_ROUTE_MAP_COMPILED, address); | |
542 | return NULL; | |
543 | } | |
544 | ||
545 | return address; | |
546 | } | |
547 | ||
548 | /* Free route map's compiled `ip nexthop' value. */ | |
549 | void | |
550 | route_set_ip_nexthop_free (void *rule) | |
551 | { | |
552 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
553 | } | |
554 | ||
555 | /* Route map commands for ip nexthop set. */ | |
556 | struct route_map_rule_cmd route_set_ip_nexthop_cmd = | |
557 | { | |
558 | "ip next-hop", | |
559 | route_set_ip_nexthop, | |
560 | route_set_ip_nexthop_compile, | |
561 | route_set_ip_nexthop_free | |
562 | }; | |
563 | \f | |
564 | #define MATCH_STR "Match values from routing table\n" | |
565 | #define SET_STR "Set values in destination routing protocol\n" | |
566 | ||
567 | DEFUN (match_metric, | |
568 | match_metric_cmd, | |
569 | "match metric <0-4294967295>", | |
570 | MATCH_STR | |
571 | "Match metric of route\n" | |
572 | "Metric value\n") | |
573 | { | |
574 | return rip_route_match_add (vty, vty->index, "metric", argv[0]); | |
575 | } | |
576 | ||
577 | DEFUN (no_match_metric, | |
578 | no_match_metric_cmd, | |
579 | "no match metric", | |
580 | NO_STR | |
581 | MATCH_STR | |
582 | "Match metric of route\n") | |
583 | { | |
584 | if (argc == 0) | |
585 | return rip_route_match_delete (vty, vty->index, "metric", NULL); | |
586 | ||
587 | return rip_route_match_delete (vty, vty->index, "metric", argv[0]); | |
588 | } | |
589 | ||
590 | ALIAS (no_match_metric, | |
591 | no_match_metric_val_cmd, | |
592 | "no match metric <0-4294967295>", | |
593 | NO_STR | |
594 | MATCH_STR | |
595 | "Match metric of route\n" | |
596 | "Metric value\n") | |
597 | ||
598 | DEFUN (match_interface, | |
599 | match_interface_cmd, | |
600 | "match interface WORD", | |
601 | MATCH_STR | |
602 | "Match first hop interface of route\n" | |
603 | "Interface name\n") | |
604 | { | |
605 | return rip_route_match_add (vty, vty->index, "interface", argv[0]); | |
606 | } | |
607 | ||
608 | DEFUN (no_match_interface, | |
609 | no_match_interface_cmd, | |
610 | "no match interface", | |
611 | NO_STR | |
612 | MATCH_STR | |
613 | "Match first hop interface of route\n") | |
614 | { | |
615 | if (argc == 0) | |
616 | return rip_route_match_delete (vty, vty->index, "interface", NULL); | |
617 | ||
618 | return rip_route_match_delete (vty, vty->index, "interface", argv[0]); | |
619 | } | |
620 | ||
621 | ALIAS (no_match_interface, | |
622 | no_match_interface_val_cmd, | |
623 | "no match interface WORD", | |
624 | NO_STR | |
625 | MATCH_STR | |
626 | "Match first hop interface of route\n" | |
627 | "Interface name\n") | |
628 | ||
629 | DEFUN (match_ip_next_hop, | |
630 | match_ip_next_hop_cmd, | |
73ffb25b | 631 | "match ip next-hop (<1-199>|<1300-2699>|WORD)", |
718e3744 | 632 | MATCH_STR |
633 | IP_STR | |
634 | "Match next-hop address of route\n" | |
73ffb25b | 635 | "IP access-list number\n" |
636 | "IP access-list number (expanded range)\n" | |
637 | "IP Access-list name\n") | |
718e3744 | 638 | { |
639 | return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]); | |
640 | } | |
641 | ||
642 | DEFUN (no_match_ip_next_hop, | |
643 | no_match_ip_next_hop_cmd, | |
644 | "no match ip next-hop", | |
645 | NO_STR | |
646 | MATCH_STR | |
647 | IP_STR | |
648 | "Match next-hop address of route\n") | |
649 | { | |
650 | if (argc == 0) | |
651 | return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL); | |
652 | ||
653 | return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]); | |
654 | } | |
655 | ||
656 | ALIAS (no_match_ip_next_hop, | |
657 | no_match_ip_next_hop_val_cmd, | |
73ffb25b | 658 | "no match ip next-hop (<1-199>|<1300-2699>|WORD)", |
718e3744 | 659 | NO_STR |
660 | MATCH_STR | |
661 | IP_STR | |
662 | "Match next-hop address of route\n" | |
73ffb25b | 663 | "IP access-list number\n" |
664 | "IP access-list number (expanded range)\n" | |
665 | "IP Access-list name\n") | |
718e3744 | 666 | |
667 | DEFUN (match_ip_next_hop_prefix_list, | |
668 | match_ip_next_hop_prefix_list_cmd, | |
669 | "match ip next-hop prefix-list WORD", | |
670 | MATCH_STR | |
671 | IP_STR | |
672 | "Match next-hop address of route\n" | |
673 | "Match entries of prefix-lists\n" | |
674 | "IP prefix-list name\n") | |
675 | { | |
676 | return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]); | |
677 | } | |
678 | ||
679 | DEFUN (no_match_ip_next_hop_prefix_list, | |
680 | no_match_ip_next_hop_prefix_list_cmd, | |
681 | "no match ip next-hop prefix-list", | |
682 | NO_STR | |
683 | MATCH_STR | |
684 | IP_STR | |
685 | "Match next-hop address of route\n" | |
686 | "Match entries of prefix-lists\n") | |
687 | { | |
688 | if (argc == 0) | |
689 | return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL); | |
690 | ||
691 | return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]); | |
692 | } | |
693 | ||
694 | ALIAS (no_match_ip_next_hop_prefix_list, | |
695 | no_match_ip_next_hop_prefix_list_val_cmd, | |
696 | "no match ip next-hop prefix-list WORD", | |
697 | NO_STR | |
698 | MATCH_STR | |
699 | IP_STR | |
700 | "Match next-hop address of route\n" | |
701 | "Match entries of prefix-lists\n" | |
702 | "IP prefix-list name\n") | |
703 | ||
73ffb25b | 704 | DEFUN (match_ip_address, |
718e3744 | 705 | match_ip_address_cmd, |
73ffb25b | 706 | "match ip address (<1-199>|<1300-2699>|WORD)", |
718e3744 | 707 | MATCH_STR |
708 | IP_STR | |
709 | "Match address of route\n" | |
73ffb25b | 710 | "IP access-list number\n" |
711 | "IP access-list number (expanded range)\n" | |
712 | "IP Access-list name\n") | |
713 | ||
718e3744 | 714 | { |
715 | return rip_route_match_add (vty, vty->index, "ip address", argv[0]); | |
716 | } | |
717 | ||
718 | DEFUN (no_match_ip_address, | |
719 | no_match_ip_address_cmd, | |
720 | "no match ip address", | |
721 | NO_STR | |
722 | MATCH_STR | |
723 | IP_STR | |
724 | "Match address of route\n") | |
725 | { | |
726 | if (argc == 0) | |
727 | return rip_route_match_delete (vty, vty->index, "ip address", NULL); | |
728 | ||
729 | return rip_route_match_delete (vty, vty->index, "ip address", argv[0]); | |
730 | } | |
731 | ||
73ffb25b | 732 | ALIAS (no_match_ip_address, |
718e3744 | 733 | no_match_ip_address_val_cmd, |
73ffb25b | 734 | "no match ip address (<1-199>|<1300-2699>|WORD)", |
718e3744 | 735 | NO_STR |
736 | MATCH_STR | |
737 | IP_STR | |
738 | "Match address of route\n" | |
73ffb25b | 739 | "IP access-list number\n" |
740 | "IP access-list number (expanded range)\n" | |
741 | "IP Access-list name\n") | |
718e3744 | 742 | |
743 | DEFUN (match_ip_address_prefix_list, | |
744 | match_ip_address_prefix_list_cmd, | |
745 | "match ip address prefix-list WORD", | |
746 | MATCH_STR | |
747 | IP_STR | |
748 | "Match address of route\n" | |
749 | "Match entries of prefix-lists\n" | |
750 | "IP prefix-list name\n") | |
751 | { | |
752 | return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]); | |
753 | } | |
754 | ||
755 | DEFUN (no_match_ip_address_prefix_list, | |
756 | no_match_ip_address_prefix_list_cmd, | |
757 | "no match ip address prefix-list", | |
758 | NO_STR | |
759 | MATCH_STR | |
760 | IP_STR | |
761 | "Match address of route\n" | |
762 | "Match entries of prefix-lists\n") | |
763 | { | |
764 | if (argc == 0) | |
765 | return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL); | |
766 | ||
767 | return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]); | |
768 | } | |
769 | ||
770 | ALIAS (no_match_ip_address_prefix_list, | |
771 | no_match_ip_address_prefix_list_val_cmd, | |
772 | "no match ip address prefix-list WORD", | |
773 | NO_STR | |
774 | MATCH_STR | |
775 | IP_STR | |
776 | "Match address of route\n" | |
777 | "Match entries of prefix-lists\n" | |
778 | "IP prefix-list name\n") | |
779 | ||
780 | /* set functions */ | |
781 | ||
782 | DEFUN (set_metric, | |
783 | set_metric_cmd, | |
784 | "set metric <0-4294967295>", | |
785 | SET_STR | |
786 | "Metric value for destination routing protocol\n" | |
787 | "Metric value\n") | |
788 | { | |
789 | return rip_route_set_add (vty, vty->index, "metric", argv[0]); | |
790 | } | |
791 | ||
792 | DEFUN (no_set_metric, | |
793 | no_set_metric_cmd, | |
794 | "no set metric", | |
795 | NO_STR | |
796 | SET_STR | |
797 | "Metric value for destination routing protocol\n") | |
798 | { | |
799 | if (argc == 0) | |
800 | return rip_route_set_delete (vty, vty->index, "metric", NULL); | |
801 | ||
802 | return rip_route_set_delete (vty, vty->index, "metric", argv[0]); | |
803 | } | |
804 | ||
805 | ALIAS (no_set_metric, | |
806 | no_set_metric_val_cmd, | |
807 | "no set metric <0-4294967295>", | |
808 | NO_STR | |
809 | SET_STR | |
810 | "Metric value for destination routing protocol\n" | |
811 | "Metric value\n") | |
812 | ||
813 | DEFUN (set_ip_nexthop, | |
814 | set_ip_nexthop_cmd, | |
815 | "set ip next-hop A.B.C.D", | |
816 | SET_STR | |
817 | IP_STR | |
818 | "Next hop address\n" | |
819 | "IP address of next hop\n") | |
820 | { | |
821 | union sockunion su; | |
822 | int ret; | |
823 | ||
824 | ret = str2sockunion (argv[0], &su); | |
825 | if (ret < 0) | |
826 | { | |
827 | vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE); | |
828 | return CMD_WARNING; | |
829 | } | |
830 | ||
831 | return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]); | |
832 | } | |
833 | ||
834 | DEFUN (no_set_ip_nexthop, | |
835 | no_set_ip_nexthop_cmd, | |
836 | "no set ip next-hop", | |
837 | NO_STR | |
838 | SET_STR | |
839 | IP_STR | |
840 | "Next hop address\n") | |
841 | { | |
842 | if (argc == 0) | |
843 | return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL); | |
844 | ||
845 | return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]); | |
846 | } | |
847 | ||
848 | ALIAS (no_set_ip_nexthop, | |
849 | no_set_ip_nexthop_val_cmd, | |
850 | "no set ip next-hop A.B.C.D", | |
851 | NO_STR | |
852 | SET_STR | |
853 | IP_STR | |
854 | "Next hop address\n" | |
855 | "IP address of next hop\n") | |
856 | ||
857 | void | |
858 | rip_route_map_reset () | |
859 | { | |
860 | ; | |
861 | } | |
862 | ||
863 | /* Route-map init */ | |
864 | void | |
865 | rip_route_map_init () | |
866 | { | |
867 | route_map_init (); | |
868 | route_map_init_vty (); | |
869 | route_map_add_hook (rip_route_map_update); | |
870 | route_map_delete_hook (rip_route_map_update); | |
871 | ||
872 | route_map_install_match (&route_match_metric_cmd); | |
873 | route_map_install_match (&route_match_interface_cmd); | |
874 | route_map_install_match (&route_match_ip_next_hop_cmd); | |
875 | route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); | |
876 | route_map_install_match (&route_match_ip_address_cmd); | |
877 | route_map_install_match (&route_match_ip_address_prefix_list_cmd); | |
878 | ||
879 | route_map_install_set (&route_set_metric_cmd); | |
880 | route_map_install_set (&route_set_ip_nexthop_cmd); | |
881 | ||
882 | install_element (RMAP_NODE, &match_metric_cmd); | |
883 | install_element (RMAP_NODE, &no_match_metric_cmd); | |
884 | install_element (RMAP_NODE, &no_match_metric_val_cmd); | |
885 | install_element (RMAP_NODE, &match_interface_cmd); | |
886 | install_element (RMAP_NODE, &no_match_interface_cmd); | |
887 | install_element (RMAP_NODE, &no_match_interface_val_cmd); | |
888 | install_element (RMAP_NODE, &match_ip_next_hop_cmd); | |
889 | install_element (RMAP_NODE, &no_match_ip_next_hop_cmd); | |
890 | install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd); | |
891 | install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd); | |
892 | install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd); | |
893 | install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd); | |
894 | install_element (RMAP_NODE, &match_ip_address_cmd); | |
895 | install_element (RMAP_NODE, &no_match_ip_address_cmd); | |
896 | install_element (RMAP_NODE, &no_match_ip_address_val_cmd); | |
897 | install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd); | |
898 | install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd); | |
899 | install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd); | |
900 | ||
901 | install_element (RMAP_NODE, &set_metric_cmd); | |
902 | install_element (RMAP_NODE, &no_set_metric_cmd); | |
903 | install_element (RMAP_NODE, &no_set_metric_val_cmd); | |
904 | install_element (RMAP_NODE, &set_ip_nexthop_cmd); | |
905 | install_element (RMAP_NODE, &no_set_ip_nexthop_cmd); | |
906 | install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd); | |
907 | } |