]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_routemap.c
all: removed all DEFUN command stomps
[mirror_frr.git] / ripd / rip_routemap.c
CommitLineData
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 37struct 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 51static void
98b718a9 52rip_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 69static route_map_result_t
718e3744 70route_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 95static void *
98b718a9 96route_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 111static void
718e3744 112route_match_metric_free (void *rule)
113{
114 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
115}
116
117/* Route map commands for metric matching. */
118struct 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 128static route_map_result_t
718e3744 129route_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 156static void *
98b718a9 157route_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 163static void
718e3744 164route_match_interface_free (void *rule)
165{
166 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
167}
168
169/* Route map commands for interface matching. */
170struct 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 181static route_map_result_t
718e3744 182route_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 208static void *
98b718a9 209route_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 215static void
718e3744 216route_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 222static 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 232static route_map_result_t
718e3744 233route_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 257static void *
98b718a9 258route_match_ip_next_hop_prefix_list_compile (const char *arg)
718e3744 259{
260 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
261}
262
dc63bfd4 263static void
718e3744 264route_match_ip_next_hop_prefix_list_free (void *rule)
265{
266 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
267}
268
dc63bfd4 269static 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 281static route_map_result_t
718e3744 282route_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 301static void *
98b718a9 302route_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 308static void
718e3744 309route_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 315static 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 325static route_map_result_t
718e3744 326route_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 343static void *
98b718a9 344route_match_ip_address_prefix_list_compile (const char *arg)
718e3744 345{
346 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
347}
348
dc63bfd4 349static void
718e3744 350route_match_ip_address_prefix_list_free (void *rule)
351{
352 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
353}
354
dc63bfd4 355static 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 365static route_map_result_t
16705130 366route_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 387static void *
98b718a9 388route_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 412static void
16705130 413route_match_tag_free (void *rule)
414{
415 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
416}
417
418/* Route map commands for tag matching. */
419struct 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 430static route_map_result_t
718e3744 431route_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 460static void *
98b718a9 461route_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 511static void
718e3744 512route_set_metric_free (void *rule)
513{
514 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
515}
516
517/* Set metric rule structure. */
dc63bfd4 518static 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 529static route_map_result_t
718e3744 530route_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 551static void *
98b718a9 552route_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 571static void
718e3744 572route_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 578static 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 589static route_map_result_t
16705130 590route_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 611static void *
98b718a9 612route_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 623static void
16705130 624route_set_tag_free (void *rule)
625{
626 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
627}
628
629/* Route map commands for tag set. */
dc63bfd4 630static 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 641void
642rip_route_map_reset ()
643{
644 ;
645}
646
647/* Route-map init */
648void
649rip_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}