Annotation of embedaddon/quagga/ripngd/ripng_routemap.c, revision 1.1.1.1
1.1 misho 1: /* RIPng routemap.
2: * Copyright (C) 1999 Kunihiro Ishiguro
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 "if.h"
25: #include "memory.h"
26: #include "prefix.h"
27: #include "routemap.h"
28: #include "command.h"
29: #include "sockunion.h"
30:
31: #include "ripngd/ripngd.h"
32:
33: struct rip_metric_modifier
34: {
35: enum
36: {
37: metric_increment,
38: metric_decrement,
39: metric_absolute
40: } type;
41:
42: u_char metric;
43: };
44:
45:
46: static int
47: ripng_route_match_add (struct vty *vty, struct route_map_index *index,
48: const char *command, const char *arg)
49: {
50: int ret;
51:
52: ret = route_map_add_match (index, command, arg);
53: if (ret)
54: {
55: switch (ret)
56: {
57: case RMAP_RULE_MISSING:
58: vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
59: return CMD_WARNING;
60: case RMAP_COMPILE_ERROR:
61: vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
62: return CMD_WARNING;
63: }
64: }
65: return CMD_SUCCESS;
66: }
67:
68: static int
69: ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
70: const char *command, const char *arg)
71: {
72: int ret;
73:
74: ret = route_map_delete_match (index, command, arg);
75: if (ret)
76: {
77: switch (ret)
78: {
79: case RMAP_RULE_MISSING:
80: vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
81: return CMD_WARNING;
82: case RMAP_COMPILE_ERROR:
83: vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
84: return CMD_WARNING;
85: }
86: }
87: return CMD_SUCCESS;
88: }
89:
90: static int
91: ripng_route_set_add (struct vty *vty, struct route_map_index *index,
92: const char *command, const char *arg)
93: {
94: int ret;
95:
96: ret = route_map_add_set (index, command, arg);
97: if (ret)
98: {
99: switch (ret)
100: {
101: case RMAP_RULE_MISSING:
102: vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
103: return CMD_WARNING;
104: case RMAP_COMPILE_ERROR:
105: vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
106: return CMD_WARNING;
107: }
108: }
109: return CMD_SUCCESS;
110: }
111:
112: static int
113: ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
114: const char *command, const char *arg)
115: {
116: int ret;
117:
118: ret = route_map_delete_set (index, command, arg);
119: if (ret)
120: {
121: switch (ret)
122: {
123: case RMAP_RULE_MISSING:
124: vty_out (vty, "Can't find rule.%s", VTY_NEWLINE);
125: return CMD_WARNING;
126: case RMAP_COMPILE_ERROR:
127: vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE);
128: return CMD_WARNING;
129: }
130: }
131: return CMD_SUCCESS;
132: }
133:
134: /* `match metric METRIC' */
135: /* Match function return 1 if match is success else return zero. */
136: static route_map_result_t
137: route_match_metric (void *rule, struct prefix *prefix,
138: route_map_object_t type, void *object)
139: {
140: u_int32_t *metric;
141: struct ripng_info *rinfo;
142:
143: if (type == RMAP_RIPNG)
144: {
145: metric = rule;
146: rinfo = object;
147:
148: if (rinfo->metric == *metric)
149: return RMAP_MATCH;
150: else
151: return RMAP_NOMATCH;
152: }
153: return RMAP_NOMATCH;
154: }
155:
156: /* Route map `match metric' match statement. `arg' is METRIC value */
157: static void *
158: route_match_metric_compile (const char *arg)
159: {
160: u_int32_t *metric;
161:
162: metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
163: *metric = atoi (arg);
164:
165: if(*metric > 0)
166: return metric;
167:
168: XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
169: return NULL;
170: }
171:
172: /* Free route map's compiled `match metric' value. */
173: static void
174: route_match_metric_free (void *rule)
175: {
176: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
177: }
178:
179: /* Route map commands for metric matching. */
180: static struct route_map_rule_cmd route_match_metric_cmd =
181: {
182: "metric",
183: route_match_metric,
184: route_match_metric_compile,
185: route_match_metric_free
186: };
187:
188: /* `match interface IFNAME' */
189: /* Match function return 1 if match is success else return zero. */
190: static route_map_result_t
191: route_match_interface (void *rule, struct prefix *prefix,
192: route_map_object_t type, void *object)
193: {
194: struct ripng_info *rinfo;
195: struct interface *ifp;
196: char *ifname;
197:
198: if (type == RMAP_RIPNG)
199: {
200: ifname = rule;
201: ifp = if_lookup_by_name(ifname);
202:
203: if (!ifp)
204: return RMAP_NOMATCH;
205:
206: rinfo = object;
207:
208: if (rinfo->ifindex == ifp->ifindex)
209: return RMAP_MATCH;
210: else
211: return RMAP_NOMATCH;
212: }
213: return RMAP_NOMATCH;
214: }
215:
216: /* Route map `match interface' match statement. `arg' is IFNAME value */
217: static void *
218: route_match_interface_compile (const char *arg)
219: {
220: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
221: }
222:
223: static void
224: route_match_interface_free (void *rule)
225: {
226: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
227: }
228:
229: static struct route_map_rule_cmd route_match_interface_cmd =
230: {
231: "interface",
232: route_match_interface,
233: route_match_interface_compile,
234: route_match_interface_free
235: };
236:
237: /* `match tag TAG' */
238: /* Match function return 1 if match is success else return zero. */
239: static route_map_result_t
240: route_match_tag (void *rule, struct prefix *prefix,
241: route_map_object_t type, void *object)
242: {
243: u_short *tag;
244: struct ripng_info *rinfo;
245:
246: if (type == RMAP_RIPNG)
247: {
248: tag = rule;
249: rinfo = object;
250:
251: /* The information stored by rinfo is host ordered. */
252: if (rinfo->tag == *tag)
253: return RMAP_MATCH;
254: else
255: return RMAP_NOMATCH;
256: }
257: return RMAP_NOMATCH;
258: }
259:
260: /* Route map `match tag' match statement. `arg' is TAG value */
261: static void *
262: route_match_tag_compile (const char *arg)
263: {
264: u_short *tag;
265:
266: tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
267: *tag = atoi (arg);
268:
269: return tag;
270: }
271:
272: /* Free route map's compiled `match tag' value. */
273: static void
274: route_match_tag_free (void *rule)
275: {
276: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
277: }
278:
279: /* Route map commands for tag matching. */
280: static struct route_map_rule_cmd route_match_tag_cmd =
281: {
282: "tag",
283: route_match_tag,
284: route_match_tag_compile,
285: route_match_tag_free
286: };
287:
288: /* `set metric METRIC' */
289:
290: /* Set metric to attribute. */
291: static route_map_result_t
292: route_set_metric (void *rule, struct prefix *prefix,
293: route_map_object_t type, void *object)
294: {
295: if (type == RMAP_RIPNG)
296: {
297: struct rip_metric_modifier *mod;
298: struct ripng_info *rinfo;
299:
300: mod = rule;
301: rinfo = object;
302:
303: if (mod->type == metric_increment)
304: rinfo->metric_out += mod->metric;
305: else if (mod->type == metric_decrement)
306: rinfo->metric_out-= mod->metric;
307: else if (mod->type == metric_absolute)
308: rinfo->metric_out = mod->metric;
309:
310: if (rinfo->metric_out < 1)
311: rinfo->metric_out = 1;
312: if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
313: rinfo->metric_out = RIPNG_METRIC_INFINITY;
314:
315: rinfo->metric_set = 1;
316: }
317: return RMAP_OKAY;
318: }
319:
320: /* set metric compilation. */
321: static void *
322: route_set_metric_compile (const char *arg)
323: {
324: int len;
325: const char *pnt;
326: int type;
327: long metric;
328: char *endptr = NULL;
329: struct rip_metric_modifier *mod;
330:
331: len = strlen (arg);
332: pnt = arg;
333:
334: if (len == 0)
335: return NULL;
336:
337: /* Examine first character. */
338: if (arg[0] == '+')
339: {
340: type = metric_increment;
341: pnt++;
342: }
343: else if (arg[0] == '-')
344: {
345: type = metric_decrement;
346: pnt++;
347: }
348: else
349: type = metric_absolute;
350:
351: /* Check beginning with digit string. */
352: if (*pnt < '0' || *pnt > '9')
353: return NULL;
354:
355: /* Convert string to integer. */
356: metric = strtol (pnt, &endptr, 10);
357:
358: if (metric == LONG_MAX || *endptr != '\0')
359: return NULL;
360: /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
361: /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
362: if (metric < 0)
363: return NULL;
364:
365: mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
366: sizeof (struct rip_metric_modifier));
367: mod->type = type;
368: mod->metric = metric;
369:
370: return mod;
371: }
372:
373: /* Free route map's compiled `set metric' value. */
374: static void
375: route_set_metric_free (void *rule)
376: {
377: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
378: }
379:
380: static struct route_map_rule_cmd route_set_metric_cmd =
381: {
382: "metric",
383: route_set_metric,
384: route_set_metric_compile,
385: route_set_metric_free,
386: };
387:
388: /* `set ipv6 next-hop local IP_ADDRESS' */
389:
390: /* Set nexthop to object. ojbect must be pointer to struct attr. */
391: static route_map_result_t
392: route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
393: route_map_object_t type, void *object)
394: {
395: struct in6_addr *address;
396: struct ripng_info *rinfo;
397:
398: if(type == RMAP_RIPNG)
399: {
400: /* Fetch routemap's rule information. */
401: address = rule;
402: rinfo = object;
403:
404: /* Set next hop value. */
405: rinfo->nexthop_out = *address;
406: }
407:
408: return RMAP_OKAY;
409: }
410:
411: /* Route map `ipv6 nexthop local' compile function. Given string is converted
412: to struct in6_addr structure. */
413: static void *
414: route_set_ipv6_nexthop_local_compile (const char *arg)
415: {
416: int ret;
417: struct in6_addr *address;
418:
419: address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
420:
421: ret = inet_pton (AF_INET6, arg, address);
422:
423: if (ret == 0)
424: {
425: XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
426: return NULL;
427: }
428:
429: return address;
430: }
431:
432: /* Free route map's compiled `ipv6 nexthop local' value. */
433: static void
434: route_set_ipv6_nexthop_local_free (void *rule)
435: {
436: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
437: }
438:
439: /* Route map commands for ipv6 nexthop local set. */
440: static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
441: {
442: "ipv6 next-hop local",
443: route_set_ipv6_nexthop_local,
444: route_set_ipv6_nexthop_local_compile,
445: route_set_ipv6_nexthop_local_free
446: };
447:
448: /* `set tag TAG' */
449:
450: /* Set tag to object. ojbect must be pointer to struct attr. */
451: static route_map_result_t
452: route_set_tag (void *rule, struct prefix *prefix,
453: route_map_object_t type, void *object)
454: {
455: u_short *tag;
456: struct ripng_info *rinfo;
457:
458: if(type == RMAP_RIPNG)
459: {
460: /* Fetch routemap's rule information. */
461: tag = rule;
462: rinfo = object;
463:
464: /* Set next hop value. */
465: rinfo->tag_out = *tag;
466: }
467:
468: return RMAP_OKAY;
469: }
470:
471: /* Route map `tag' compile function. Given string is converted
472: to u_short. */
473: static void *
474: route_set_tag_compile (const char *arg)
475: {
476: u_short *tag;
477:
478: tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
479: *tag = atoi (arg);
480:
481: return tag;
482: }
483:
484: /* Free route map's compiled `ip nexthop' value. */
485: static void
486: route_set_tag_free (void *rule)
487: {
488: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
489: }
490:
491: /* Route map commands for tag set. */
492: static struct route_map_rule_cmd route_set_tag_cmd =
493: {
494: "tag",
495: route_set_tag,
496: route_set_tag_compile,
497: route_set_tag_free
498: };
499:
500: #define MATCH_STR "Match values from routing table\n"
501: #define SET_STR "Set values in destination routing protocol\n"
502:
503: DEFUN (match_metric,
504: match_metric_cmd,
505: "match metric <0-4294967295>",
506: MATCH_STR
507: "Match metric of route\n"
508: "Metric value\n")
509: {
510: return ripng_route_match_add (vty, vty->index, "metric", argv[0]);
511: }
512:
513: DEFUN (no_match_metric,
514: no_match_metric_cmd,
515: "no match metric",
516: NO_STR
517: MATCH_STR
518: "Match metric of route\n")
519: {
520: if (argc == 0)
521: return ripng_route_match_delete (vty, vty->index, "metric", NULL);
522:
523: return ripng_route_match_delete (vty, vty->index, "metric", argv[0]);
524: }
525:
526: ALIAS (no_match_metric,
527: no_match_metric_val_cmd,
528: "no match metric <0-4294967295>",
529: NO_STR
530: MATCH_STR
531: "Match metric of route\n"
532: "Metric value\n")
533:
534: DEFUN (match_interface,
535: match_interface_cmd,
536: "match interface WORD",
537: MATCH_STR
538: "Match first hop interface of route\n"
539: "Interface name\n")
540: {
541: return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
542: }
543:
544: DEFUN (no_match_interface,
545: no_match_interface_cmd,
546: "no match interface",
547: NO_STR
548: MATCH_STR
549: "Match first hop interface of route\n")
550: {
551: if (argc == 0)
552: return ripng_route_match_delete (vty, vty->index, "interface", NULL);
553:
554: return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
555: }
556:
557: ALIAS (no_match_interface,
558: no_match_interface_val_cmd,
559: "no match interface WORD",
560: NO_STR
561: MATCH_STR
562: "Match first hop interface of route\n"
563: "Interface name\n")
564:
565: DEFUN (match_tag,
566: match_tag_cmd,
567: "match tag <0-65535>",
568: MATCH_STR
569: "Match tag of route\n"
570: "Metric value\n")
571: {
572: return ripng_route_match_add (vty, vty->index, "tag", argv[0]);
573: }
574:
575: DEFUN (no_match_tag,
576: no_match_tag_cmd,
577: "no match tag",
578: NO_STR
579: MATCH_STR
580: "Match tag of route\n")
581: {
582: if (argc == 0)
583: return ripng_route_match_delete (vty, vty->index, "tag", NULL);
584:
585: return ripng_route_match_delete (vty, vty->index, "tag", argv[0]);
586: }
587:
588: ALIAS (no_match_tag,
589: no_match_tag_val_cmd,
590: "no match tag <0-65535>",
591: NO_STR
592: MATCH_STR
593: "Match tag of route\n"
594: "Metric value\n")
595:
596: /* set functions */
597:
598: DEFUN (set_metric,
599: set_metric_cmd,
600: "set metric <0-4294967295>",
601: "Set value\n"
602: "Metric value for destination routing protocol\n"
603: "Metric value\n")
604: {
605: return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
606: }
607:
608: DEFUN (no_set_metric,
609: no_set_metric_cmd,
610: "no set metric",
611: NO_STR
612: SET_STR
613: "Metric value for destination routing protocol\n")
614: {
615: if (argc == 0)
616: return ripng_route_set_delete (vty, vty->index, "metric", NULL);
617:
618: return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
619: }
620:
621: ALIAS (no_set_metric,
622: no_set_metric_val_cmd,
623: "no set metric <0-4294967295>",
624: NO_STR
625: SET_STR
626: "Metric value for destination routing protocol\n"
627: "Metric value\n")
628:
629: DEFUN (set_ipv6_nexthop_local,
630: set_ipv6_nexthop_local_cmd,
631: "set ipv6 next-hop local X:X::X:X",
632: SET_STR
633: IPV6_STR
634: "IPv6 next-hop address\n"
635: "IPv6 local address\n"
636: "IPv6 address of next hop\n")
637: {
638: union sockunion su;
639: int ret;
640:
641: ret = str2sockunion (argv[0], &su);
642: if (ret < 0)
643: {
644: vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE);
645: return CMD_WARNING;
646: }
647:
648: return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
649: }
650:
651: DEFUN (no_set_ipv6_nexthop_local,
652: no_set_ipv6_nexthop_local_cmd,
653: "no set ipv6 next-hop local",
654: NO_STR
655: SET_STR
656: IPV6_STR
657: "IPv6 next-hop address\n"
658: "IPv6 local address\n")
659: {
660: if (argc == 0)
661: return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
662:
663: return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
664: }
665:
666: ALIAS (no_set_ipv6_nexthop_local,
667: no_set_ipv6_nexthop_local_val_cmd,
668: "no set ipv6 next-hop local X:X::X:X",
669: NO_STR
670: SET_STR
671: IPV6_STR
672: "IPv6 next-hop address\n"
673: "IPv6 local address\n"
674: "IPv6 address of next hop\n")
675:
676: DEFUN (set_tag,
677: set_tag_cmd,
678: "set tag <0-65535>",
679: SET_STR
680: "Tag value for routing protocol\n"
681: "Tag value\n")
682: {
683: return ripng_route_set_add (vty, vty->index, "tag", argv[0]);
684: }
685:
686: DEFUN (no_set_tag,
687: no_set_tag_cmd,
688: "no set tag",
689: NO_STR
690: SET_STR
691: "Tag value for routing protocol\n")
692: {
693: if (argc == 0)
694: return ripng_route_set_delete (vty, vty->index, "tag", NULL);
695:
696: return ripng_route_set_delete (vty, vty->index, "tag", argv[0]);
697: }
698:
699: ALIAS (no_set_tag,
700: no_set_tag_val_cmd,
701: "no set tag <0-65535>",
702: NO_STR
703: SET_STR
704: "Tag value for routing protocol\n"
705: "Tag value\n")
706:
707: void
708: ripng_route_map_reset ()
709: {
710: /* XXX ??? */
711: ;
712: }
713:
714: void
715: ripng_route_map_init ()
716: {
717: route_map_init ();
718: route_map_init_vty ();
719:
720: route_map_install_match (&route_match_metric_cmd);
721: route_map_install_match (&route_match_interface_cmd);
722: route_map_install_match (&route_match_tag_cmd);
723:
724: route_map_install_set (&route_set_metric_cmd);
725: route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
726: route_map_install_set (&route_set_tag_cmd);
727:
728: install_element (RMAP_NODE, &match_metric_cmd);
729: install_element (RMAP_NODE, &no_match_metric_cmd);
730: install_element (RMAP_NODE, &no_match_metric_val_cmd);
731: install_element (RMAP_NODE, &match_interface_cmd);
732: install_element (RMAP_NODE, &no_match_interface_cmd);
733: install_element (RMAP_NODE, &no_match_interface_val_cmd);
734: install_element (RMAP_NODE, &match_tag_cmd);
735: install_element (RMAP_NODE, &no_match_tag_cmd);
736: install_element (RMAP_NODE, &no_match_tag_val_cmd);
737:
738: install_element (RMAP_NODE, &set_metric_cmd);
739: install_element (RMAP_NODE, &no_set_metric_cmd);
740: install_element (RMAP_NODE, &no_set_metric_val_cmd);
741: install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
742: install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
743: install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
744: install_element (RMAP_NODE, &set_tag_cmd);
745: install_element (RMAP_NODE, &no_set_tag_cmd);
746: install_element (RMAP_NODE, &no_set_tag_val_cmd);
747: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>