]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* RIPv2 routemap. |
fbf5d033 | 2 | * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com> |
718e3744 | 3 | * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org> |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #include <zebra.h> | |
24 | ||
25 | #include "memory.h" | |
26 | #include "prefix.h" | |
82f97584 | 27 | #include "vty.h" |
718e3744 | 28 | #include "routemap.h" |
29 | #include "command.h" | |
30 | #include "filter.h" | |
31 | #include "log.h" | |
32 | #include "sockunion.h" /* for inet_aton () */ | |
33 | #include "plist.h" | |
34 | ||
35 | #include "ripd/ripd.h" | |
6b0655a2 | 36 | |
16705130 | 37 | struct rip_metric_modifier |
38 | { | |
39 | enum | |
40 | { | |
41 | metric_increment, | |
42 | metric_decrement, | |
43 | metric_absolute | |
44 | } type; | |
45 | ||
46 | u_char metric; | |
47 | }; | |
718e3744 | 48 | |
718e3744 | 49 | /* Hook function for updating route_map assignment. */ |
11dde9c2 | 50 | /* ARGSUSED */ |
dc63bfd4 | 51 | static void |
98b718a9 | 52 | rip_route_map_update (const char *notused) |
718e3744 | 53 | { |
54 | int i; | |
55 | ||
56 | if (rip) | |
57 | { | |
58 | for (i = 0; i < ZEBRA_ROUTE_MAX; i++) | |
59 | { | |
60 | if (rip->route_map[i].name) | |
61 | rip->route_map[i].map = | |
62 | route_map_lookup_by_name (rip->route_map[i].name); | |
63 | } | |
64 | } | |
65 | } | |
6b0655a2 | 66 | |
718e3744 | 67 | /* `match metric METRIC' */ |
68 | /* Match function return 1 if match is success else return zero. */ | |
dc63bfd4 | 69 | static route_map_result_t |
718e3744 | 70 | route_match_metric (void *rule, struct prefix *prefix, |
71 | route_map_object_t type, void *object) | |
72 | { | |
73 | u_int32_t *metric; | |
fbf5d033 | 74 | u_int32_t check; |
718e3744 | 75 | struct rip_info *rinfo; |
76 | ||
77 | if (type == RMAP_RIP) | |
78 | { | |
79 | metric = rule; | |
80 | rinfo = object; | |
81 | ||
fbf5d033 | 82 | /* If external metric is available, the route-map should |
83 | work on this one (for redistribute purpose) */ | |
84 | check = (rinfo->external_metric) ? rinfo->external_metric : | |
85 | rinfo->metric; | |
86 | if (check == *metric) | |
718e3744 | 87 | return RMAP_MATCH; |
88 | else | |
89 | return RMAP_NOMATCH; | |
90 | } | |
91 | return RMAP_NOMATCH; | |
92 | } | |
93 | ||
94 | /* Route map `match metric' match statement. `arg' is METRIC value */ | |
dc63bfd4 | 95 | static void * |
98b718a9 | 96 | route_match_metric_compile (const char *arg) |
718e3744 | 97 | { |
98 | u_int32_t *metric; | |
99 | ||
100 | metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); | |
101 | *metric = atoi (arg); | |
102 | ||
103 | if(*metric > 0) | |
104 | return metric; | |
105 | ||
106 | XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); | |
107 | return NULL; | |
108 | } | |
109 | ||
110 | /* Free route map's compiled `match metric' value. */ | |
dc63bfd4 | 111 | static void |
718e3744 | 112 | route_match_metric_free (void *rule) |
113 | { | |
114 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
115 | } | |
116 | ||
117 | /* Route map commands for metric matching. */ | |
118 | struct route_map_rule_cmd route_match_metric_cmd = | |
119 | { | |
120 | "metric", | |
121 | route_match_metric, | |
122 | route_match_metric_compile, | |
123 | route_match_metric_free | |
124 | }; | |
125 | ||
126 | /* `match interface IFNAME' */ | |
127 | /* Match function return 1 if match is success else return zero. */ | |
dc63bfd4 | 128 | static route_map_result_t |
718e3744 | 129 | route_match_interface (void *rule, struct prefix *prefix, |
130 | route_map_object_t type, void *object) | |
131 | { | |
132 | struct rip_info *rinfo; | |
133 | struct interface *ifp; | |
134 | char *ifname; | |
135 | ||
136 | if (type == RMAP_RIP) | |
137 | { | |
138 | ifname = rule; | |
139 | ifp = if_lookup_by_name(ifname); | |
140 | ||
141 | if (!ifp) | |
142 | return RMAP_NOMATCH; | |
143 | ||
144 | rinfo = object; | |
145 | ||
cf96db1c | 146 | if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex) |
718e3744 | 147 | return RMAP_MATCH; |
148 | else | |
149 | return RMAP_NOMATCH; | |
150 | } | |
151 | return RMAP_NOMATCH; | |
152 | } | |
153 | ||
154 | /* Route map `match interface' match statement. `arg' is IFNAME value */ | |
155 | /* XXX I don`t know if I need to check does interface exist? */ | |
dc63bfd4 | 156 | static void * |
98b718a9 | 157 | route_match_interface_compile (const char *arg) |
718e3744 | 158 | { |
159 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
160 | } | |
161 | ||
162 | /* Free route map's compiled `match interface' value. */ | |
dc63bfd4 | 163 | static void |
718e3744 | 164 | route_match_interface_free (void *rule) |
165 | { | |
166 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
167 | } | |
168 | ||
169 | /* Route map commands for interface matching. */ | |
170 | struct route_map_rule_cmd route_match_interface_cmd = | |
171 | { | |
172 | "interface", | |
173 | route_match_interface, | |
174 | route_match_interface_compile, | |
175 | route_match_interface_free | |
176 | }; | |
177 | ||
178 | /* `match ip next-hop IP_ACCESS_LIST' */ | |
179 | ||
180 | /* Match function return 1 if match is success else return zero. */ | |
dc63bfd4 | 181 | static route_map_result_t |
718e3744 | 182 | route_match_ip_next_hop (void *rule, struct prefix *prefix, |
183 | route_map_object_t type, void *object) | |
184 | { | |
185 | struct access_list *alist; | |
186 | struct rip_info *rinfo; | |
187 | struct prefix_ipv4 p; | |
188 | ||
189 | if (type == RMAP_RIP) | |
190 | { | |
191 | rinfo = object; | |
192 | p.family = AF_INET; | |
dc625e86 | 193 | p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; |
718e3744 | 194 | p.prefixlen = IPV4_MAX_BITLEN; |
195 | ||
196 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
197 | if (alist == NULL) | |
198 | return RMAP_NOMATCH; | |
199 | ||
200 | return (access_list_apply (alist, &p) == FILTER_DENY ? | |
201 | RMAP_NOMATCH : RMAP_MATCH); | |
202 | } | |
203 | return RMAP_NOMATCH; | |
204 | } | |
205 | ||
206 | /* Route map `ip next-hop' match statement. `arg' should be | |
207 | access-list name. */ | |
dc63bfd4 | 208 | static void * |
98b718a9 | 209 | route_match_ip_next_hop_compile (const char *arg) |
718e3744 | 210 | { |
211 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
212 | } | |
213 | ||
214 | /* Free route map's compiled `. */ | |
dc63bfd4 | 215 | static void |
718e3744 | 216 | route_match_ip_next_hop_free (void *rule) |
217 | { | |
218 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
219 | } | |
220 | ||
221 | /* Route map commands for ip next-hop matching. */ | |
dc63bfd4 | 222 | static struct route_map_rule_cmd route_match_ip_next_hop_cmd = |
718e3744 | 223 | { |
224 | "ip next-hop", | |
225 | route_match_ip_next_hop, | |
226 | route_match_ip_next_hop_compile, | |
227 | route_match_ip_next_hop_free | |
228 | }; | |
6b0655a2 | 229 | |
718e3744 | 230 | /* `match ip next-hop prefix-list PREFIX_LIST' */ |
231 | ||
dc63bfd4 | 232 | static route_map_result_t |
718e3744 | 233 | route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, |
234 | route_map_object_t type, void *object) | |
235 | { | |
236 | struct prefix_list *plist; | |
237 | struct rip_info *rinfo; | |
238 | struct prefix_ipv4 p; | |
239 | ||
240 | if (type == RMAP_RIP) | |
241 | { | |
242 | rinfo = object; | |
243 | p.family = AF_INET; | |
dc625e86 | 244 | p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; |
718e3744 | 245 | p.prefixlen = IPV4_MAX_BITLEN; |
246 | ||
247 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
248 | if (plist == NULL) | |
249 | return RMAP_NOMATCH; | |
250 | ||
251 | return (prefix_list_apply (plist, &p) == PREFIX_DENY ? | |
252 | RMAP_NOMATCH : RMAP_MATCH); | |
253 | } | |
254 | return RMAP_NOMATCH; | |
255 | } | |
256 | ||
dc63bfd4 | 257 | static void * |
98b718a9 | 258 | route_match_ip_next_hop_prefix_list_compile (const char *arg) |
718e3744 | 259 | { |
260 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
261 | } | |
262 | ||
dc63bfd4 | 263 | static void |
718e3744 | 264 | route_match_ip_next_hop_prefix_list_free (void *rule) |
265 | { | |
266 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
267 | } | |
268 | ||
dc63bfd4 | 269 | static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = |
718e3744 | 270 | { |
271 | "ip next-hop prefix-list", | |
272 | route_match_ip_next_hop_prefix_list, | |
273 | route_match_ip_next_hop_prefix_list_compile, | |
274 | route_match_ip_next_hop_prefix_list_free | |
275 | }; | |
6b0655a2 | 276 | |
718e3744 | 277 | /* `match ip address IP_ACCESS_LIST' */ |
278 | ||
279 | /* Match function should return 1 if match is success else return | |
280 | zero. */ | |
dc63bfd4 | 281 | static route_map_result_t |
718e3744 | 282 | route_match_ip_address (void *rule, struct prefix *prefix, |
283 | route_map_object_t type, void *object) | |
284 | { | |
285 | struct access_list *alist; | |
286 | ||
287 | if (type == RMAP_RIP) | |
288 | { | |
289 | alist = access_list_lookup (AFI_IP, (char *) rule); | |
290 | if (alist == NULL) | |
291 | return RMAP_NOMATCH; | |
292 | ||
293 | return (access_list_apply (alist, prefix) == FILTER_DENY ? | |
294 | RMAP_NOMATCH : RMAP_MATCH); | |
295 | } | |
296 | return RMAP_NOMATCH; | |
297 | } | |
298 | ||
299 | /* Route map `ip address' match statement. `arg' should be | |
300 | access-list name. */ | |
dc63bfd4 | 301 | static void * |
98b718a9 | 302 | route_match_ip_address_compile (const char *arg) |
718e3744 | 303 | { |
304 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
305 | } | |
306 | ||
307 | /* Free route map's compiled `ip address' value. */ | |
dc63bfd4 | 308 | static void |
718e3744 | 309 | route_match_ip_address_free (void *rule) |
310 | { | |
311 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
312 | } | |
313 | ||
314 | /* Route map commands for ip address matching. */ | |
dc63bfd4 | 315 | static struct route_map_rule_cmd route_match_ip_address_cmd = |
718e3744 | 316 | { |
317 | "ip address", | |
318 | route_match_ip_address, | |
319 | route_match_ip_address_compile, | |
320 | route_match_ip_address_free | |
321 | }; | |
6b0655a2 | 322 | |
718e3744 | 323 | /* `match ip address prefix-list PREFIX_LIST' */ |
324 | ||
dc63bfd4 | 325 | static route_map_result_t |
718e3744 | 326 | route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, |
327 | route_map_object_t type, void *object) | |
328 | { | |
329 | struct prefix_list *plist; | |
330 | ||
331 | if (type == RMAP_RIP) | |
332 | { | |
333 | plist = prefix_list_lookup (AFI_IP, (char *) rule); | |
334 | if (plist == NULL) | |
335 | return RMAP_NOMATCH; | |
336 | ||
337 | return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? | |
338 | RMAP_NOMATCH : RMAP_MATCH); | |
339 | } | |
340 | return RMAP_NOMATCH; | |
341 | } | |
342 | ||
dc63bfd4 | 343 | static void * |
98b718a9 | 344 | route_match_ip_address_prefix_list_compile (const char *arg) |
718e3744 | 345 | { |
346 | return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); | |
347 | } | |
348 | ||
dc63bfd4 | 349 | static void |
718e3744 | 350 | route_match_ip_address_prefix_list_free (void *rule) |
351 | { | |
352 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
353 | } | |
354 | ||
dc63bfd4 | 355 | static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = |
718e3744 | 356 | { |
357 | "ip address prefix-list", | |
358 | route_match_ip_address_prefix_list, | |
359 | route_match_ip_address_prefix_list_compile, | |
360 | route_match_ip_address_prefix_list_free | |
361 | }; | |
16705130 | 362 | |
363 | /* `match tag TAG' */ | |
364 | /* Match function return 1 if match is success else return zero. */ | |
dc63bfd4 | 365 | static route_map_result_t |
16705130 | 366 | route_match_tag (void *rule, struct prefix *prefix, |
367 | route_map_object_t type, void *object) | |
368 | { | |
369 | u_short *tag; | |
370 | struct rip_info *rinfo; | |
371 | ||
372 | if (type == RMAP_RIP) | |
373 | { | |
374 | tag = rule; | |
375 | rinfo = object; | |
376 | ||
377 | /* The information stored by rinfo is host ordered. */ | |
378 | if (rinfo->tag == *tag) | |
379 | return RMAP_MATCH; | |
380 | else | |
381 | return RMAP_NOMATCH; | |
382 | } | |
383 | return RMAP_NOMATCH; | |
384 | } | |
385 | ||
386 | /* Route map `match tag' match statement. `arg' is TAG value */ | |
dc63bfd4 | 387 | static void * |
98b718a9 | 388 | route_match_tag_compile (const char *arg) |
16705130 | 389 | { |
390 | u_short *tag; | |
0d9551dc DS |
391 | u_short tmp; |
392 | ||
393 | /* tag value shoud be integer. */ | |
394 | if (! all_digit (arg)) | |
395 | return NULL; | |
396 | ||
397 | tmp = atoi(arg); | |
398 | if (tmp < 1) | |
399 | return NULL; | |
16705130 | 400 | |
401 | tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); | |
0d9551dc DS |
402 | |
403 | if (!tag) | |
404 | return tag; | |
405 | ||
406 | *tag = tmp; | |
16705130 | 407 | |
408 | return tag; | |
409 | } | |
410 | ||
411 | /* Free route map's compiled `match tag' value. */ | |
dc63bfd4 | 412 | static void |
16705130 | 413 | route_match_tag_free (void *rule) |
414 | { | |
415 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
416 | } | |
417 | ||
418 | /* Route map commands for tag matching. */ | |
419 | struct route_map_rule_cmd route_match_tag_cmd = | |
420 | { | |
421 | "tag", | |
422 | route_match_tag, | |
423 | route_match_tag_compile, | |
424 | route_match_tag_free | |
425 | }; | |
6b0655a2 | 426 | |
718e3744 | 427 | /* `set metric METRIC' */ |
428 | ||
429 | /* Set metric to attribute. */ | |
dc63bfd4 | 430 | static route_map_result_t |
718e3744 | 431 | route_set_metric (void *rule, struct prefix *prefix, |
432 | route_map_object_t type, void *object) | |
433 | { | |
718e3744 | 434 | if (type == RMAP_RIP) |
435 | { | |
16705130 | 436 | struct rip_metric_modifier *mod; |
437 | struct rip_info *rinfo; | |
438 | ||
439 | mod = rule; | |
718e3744 | 440 | rinfo = object; |
16705130 | 441 | |
442 | if (mod->type == metric_increment) | |
443 | rinfo->metric_out += mod->metric; | |
444 | else if (mod->type == metric_decrement) | |
445 | rinfo->metric_out -= mod->metric; | |
446 | else if (mod->type == metric_absolute) | |
447 | rinfo->metric_out = mod->metric; | |
448 | ||
b25ea4d0 | 449 | if ((signed int)rinfo->metric_out < 1) |
16705130 | 450 | rinfo->metric_out = 1; |
451 | if (rinfo->metric_out > RIP_METRIC_INFINITY) | |
452 | rinfo->metric_out = RIP_METRIC_INFINITY; | |
453 | ||
718e3744 | 454 | rinfo->metric_set = 1; |
455 | } | |
456 | return RMAP_OKAY; | |
457 | } | |
458 | ||
459 | /* set metric compilation. */ | |
dc63bfd4 | 460 | static void * |
98b718a9 | 461 | route_set_metric_compile (const char *arg) |
718e3744 | 462 | { |
16705130 | 463 | int len; |
98b718a9 | 464 | const char *pnt; |
16705130 | 465 | int type; |
466 | long metric; | |
467 | char *endptr = NULL; | |
468 | struct rip_metric_modifier *mod; | |
718e3744 | 469 | |
16705130 | 470 | len = strlen (arg); |
471 | pnt = arg; | |
718e3744 | 472 | |
16705130 | 473 | if (len == 0) |
474 | return NULL; | |
718e3744 | 475 | |
16705130 | 476 | /* Examine first character. */ |
477 | if (arg[0] == '+') | |
478 | { | |
479 | type = metric_increment; | |
480 | pnt++; | |
481 | } | |
482 | else if (arg[0] == '-') | |
483 | { | |
484 | type = metric_decrement; | |
485 | pnt++; | |
486 | } | |
487 | else | |
488 | type = metric_absolute; | |
718e3744 | 489 | |
16705130 | 490 | /* Check beginning with digit string. */ |
491 | if (*pnt < '0' || *pnt > '9') | |
492 | return NULL; | |
493 | ||
494 | /* Convert string to integer. */ | |
495 | metric = strtol (pnt, &endptr, 10); | |
496 | ||
497 | if (metric == LONG_MAX || *endptr != '\0') | |
498 | return NULL; | |
499 | if (metric < 0 || metric > RIP_METRIC_INFINITY) | |
500 | return NULL; | |
501 | ||
502 | mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, | |
503 | sizeof (struct rip_metric_modifier)); | |
504 | mod->type = type; | |
505 | mod->metric = metric; | |
506 | ||
507 | return mod; | |
718e3744 | 508 | } |
509 | ||
510 | /* Free route map's compiled `set metric' value. */ | |
dc63bfd4 | 511 | static void |
718e3744 | 512 | route_set_metric_free (void *rule) |
513 | { | |
514 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
515 | } | |
516 | ||
517 | /* Set metric rule structure. */ | |
dc63bfd4 | 518 | static struct route_map_rule_cmd route_set_metric_cmd = |
718e3744 | 519 | { |
520 | "metric", | |
521 | route_set_metric, | |
522 | route_set_metric_compile, | |
523 | route_set_metric_free, | |
524 | }; | |
525 | ||
526 | /* `set ip next-hop IP_ADDRESS' */ | |
527 | ||
528 | /* Set nexthop to object. ojbect must be pointer to struct attr. */ | |
dc63bfd4 | 529 | static route_map_result_t |
718e3744 | 530 | route_set_ip_nexthop (void *rule, struct prefix *prefix, |
531 | route_map_object_t type, void *object) | |
532 | { | |
533 | struct in_addr *address; | |
534 | struct rip_info *rinfo; | |
535 | ||
536 | if(type == RMAP_RIP) | |
537 | { | |
538 | /* Fetch routemap's rule information. */ | |
539 | address = rule; | |
540 | rinfo = object; | |
541 | ||
542 | /* Set next hop value. */ | |
543 | rinfo->nexthop_out = *address; | |
544 | } | |
545 | ||
546 | return RMAP_OKAY; | |
547 | } | |
548 | ||
549 | /* Route map `ip nexthop' compile function. Given string is converted | |
550 | to struct in_addr structure. */ | |
dc63bfd4 | 551 | static void * |
98b718a9 | 552 | route_set_ip_nexthop_compile (const char *arg) |
718e3744 | 553 | { |
554 | int ret; | |
555 | struct in_addr *address; | |
556 | ||
557 | address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); | |
558 | ||
559 | ret = inet_aton (arg, address); | |
560 | ||
561 | if (ret == 0) | |
562 | { | |
563 | XFREE (MTYPE_ROUTE_MAP_COMPILED, address); | |
564 | return NULL; | |
565 | } | |
566 | ||
567 | return address; | |
568 | } | |
569 | ||
570 | /* Free route map's compiled `ip nexthop' value. */ | |
dc63bfd4 | 571 | static void |
718e3744 | 572 | route_set_ip_nexthop_free (void *rule) |
573 | { | |
574 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
575 | } | |
576 | ||
577 | /* Route map commands for ip nexthop set. */ | |
dc63bfd4 | 578 | static struct route_map_rule_cmd route_set_ip_nexthop_cmd = |
718e3744 | 579 | { |
580 | "ip next-hop", | |
581 | route_set_ip_nexthop, | |
582 | route_set_ip_nexthop_compile, | |
583 | route_set_ip_nexthop_free | |
584 | }; | |
16705130 | 585 | |
586 | /* `set tag TAG' */ | |
587 | ||
588 | /* Set tag to object. ojbect must be pointer to struct attr. */ | |
dc63bfd4 | 589 | static route_map_result_t |
16705130 | 590 | route_set_tag (void *rule, struct prefix *prefix, |
591 | route_map_object_t type, void *object) | |
592 | { | |
593 | u_short *tag; | |
594 | struct rip_info *rinfo; | |
595 | ||
596 | if(type == RMAP_RIP) | |
597 | { | |
598 | /* Fetch routemap's rule information. */ | |
599 | tag = rule; | |
600 | rinfo = object; | |
601 | ||
602 | /* Set next hop value. */ | |
603 | rinfo->tag_out = *tag; | |
604 | } | |
605 | ||
606 | return RMAP_OKAY; | |
607 | } | |
608 | ||
609 | /* Route map `tag' compile function. Given string is converted | |
610 | to u_short. */ | |
dc63bfd4 | 611 | static void * |
98b718a9 | 612 | route_set_tag_compile (const char *arg) |
16705130 | 613 | { |
614 | u_short *tag; | |
615 | ||
616 | tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); | |
617 | *tag = atoi (arg); | |
618 | ||
619 | return tag; | |
620 | } | |
621 | ||
622 | /* Free route map's compiled `ip nexthop' value. */ | |
dc63bfd4 | 623 | static void |
16705130 | 624 | route_set_tag_free (void *rule) |
625 | { | |
626 | XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); | |
627 | } | |
628 | ||
629 | /* Route map commands for tag set. */ | |
dc63bfd4 | 630 | static struct route_map_rule_cmd route_set_tag_cmd = |
16705130 | 631 | { |
632 | "tag", | |
633 | route_set_tag, | |
634 | route_set_tag_compile, | |
635 | route_set_tag_free | |
636 | }; | |
6b0655a2 | 637 | |
718e3744 | 638 | #define MATCH_STR "Match values from routing table\n" |
639 | #define SET_STR "Set values in destination routing protocol\n" | |
640 | ||
718e3744 | 641 | void |
642 | rip_route_map_reset () | |
643 | { | |
644 | ; | |
645 | } | |
646 | ||
647 | /* Route-map init */ | |
648 | void | |
649 | rip_route_map_init () | |
650 | { | |
651 | route_map_init (); | |
652 | route_map_init_vty (); | |
653 | route_map_add_hook (rip_route_map_update); | |
654 | route_map_delete_hook (rip_route_map_update); | |
655 | ||
82f97584 DW |
656 | route_map_match_interface_hook (generic_match_add); |
657 | route_map_no_match_interface_hook (generic_match_delete); | |
658 | ||
659 | route_map_match_ip_address_hook (generic_match_add); | |
660 | route_map_no_match_ip_address_hook (generic_match_delete); | |
661 | ||
662 | route_map_match_ip_address_prefix_list_hook (generic_match_add); | |
663 | route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); | |
664 | ||
665 | route_map_match_ip_next_hop_hook (generic_match_add); | |
666 | route_map_no_match_ip_next_hop_hook (generic_match_delete); | |
667 | ||
668 | route_map_match_ip_next_hop_prefix_list_hook (generic_match_add); | |
669 | route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete); | |
670 | ||
671 | route_map_match_metric_hook (generic_match_add); | |
672 | route_map_no_match_metric_hook (generic_match_delete); | |
673 | ||
674 | route_map_match_tag_hook (generic_match_add); | |
675 | route_map_no_match_tag_hook (generic_match_delete); | |
676 | ||
677 | route_map_set_ip_nexthop_hook (generic_set_add); | |
678 | route_map_no_set_ip_nexthop_hook (generic_set_delete); | |
679 | ||
680 | route_map_set_metric_hook (generic_set_add); | |
681 | route_map_no_set_metric_hook (generic_set_delete); | |
682 | ||
683 | route_map_set_tag_hook (generic_set_add); | |
684 | route_map_no_set_tag_hook (generic_set_delete); | |
685 | ||
718e3744 | 686 | route_map_install_match (&route_match_metric_cmd); |
687 | route_map_install_match (&route_match_interface_cmd); | |
688 | route_map_install_match (&route_match_ip_next_hop_cmd); | |
689 | route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); | |
690 | route_map_install_match (&route_match_ip_address_cmd); | |
691 | route_map_install_match (&route_match_ip_address_prefix_list_cmd); | |
16705130 | 692 | route_map_install_match (&route_match_tag_cmd); |
718e3744 | 693 | |
694 | route_map_install_set (&route_set_metric_cmd); | |
695 | route_map_install_set (&route_set_ip_nexthop_cmd); | |
16705130 | 696 | route_map_install_set (&route_set_tag_cmd); |
718e3744 | 697 | } |