Annotation of embedaddon/quagga/isisd/isis_routemap.c, revision 1.1.1.4
1.1 misho 1: /*
1.1.1.4 ! misho 2: * IS-IS Rout(e)ing protocol - isis_routemap.c
1.1 misho 3: *
1.1.1.4 ! misho 4: * Copyright (C) 2013-2015 Christian Franke <chris@opensourcerouting.org>
1.1 misho 5: *
6: * This program is free software; you can redistribute it and/or modify it
1.1.1.4 ! misho 7: * under the terms of the GNU General Public License as published by the Free
1.1 misho 8: * Software Foundation; either version 2 of the License, or (at your option)
9: * any later version.
10: *
11: * This program is distributed in the hope that it will be useful,but WITHOUT
12: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14: * more details.
15:
16: * You should have received a copy of the GNU General Public License along
17: * with this program; if not, write to the Free Software Foundation, Inc.,
18: * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19: */
1.1.1.4 ! misho 20:
1.1 misho 21: #include <zebra.h>
22:
1.1.1.4 ! misho 23: #include "command.h"
! 24: #include "filter.h"
! 25: #include "hash.h"
! 26: #include "if.h"
1.1 misho 27: #include "linklist.h"
28: #include "log.h"
29: #include "memory.h"
30: #include "prefix.h"
1.1.1.4 ! misho 31: #include "plist.h"
1.1 misho 32: #include "routemap.h"
1.1.1.4 ! misho 33: #include "table.h"
! 34: #include "thread.h"
! 35: #include "vty.h"
1.1 misho 36:
37: #include "isis_constants.h"
38: #include "isis_common.h"
1.1.1.2 misho 39: #include "isis_flags.h"
1.1 misho 40: #include "dict.h"
41: #include "isisd.h"
42: #include "isis_misc.h"
43: #include "isis_adjacency.h"
44: #include "isis_circuit.h"
45: #include "isis_tlv.h"
46: #include "isis_pdu.h"
47: #include "isis_lsp.h"
48: #include "isis_spf.h"
49: #include "isis_route.h"
50: #include "isis_zebra.h"
1.1.1.4 ! misho 51: #include "isis_routemap.h"
1.1 misho 52:
1.1.1.4 ! misho 53: static route_map_result_t
! 54: route_match_ip_address(void *rule, struct prefix *prefix,
! 55: route_map_object_t type, void *object)
! 56: {
! 57: struct access_list *alist;
1.1 misho 58:
1.1.1.4 ! misho 59: if (type != RMAP_ISIS)
! 60: return RMAP_NOMATCH;
1.1 misho 61:
1.1.1.4 ! misho 62: alist = access_list_lookup(AFI_IP, (char*)rule);
! 63: if (access_list_apply(alist, prefix) != FILTER_DENY)
! 64: return RMAP_MATCH;
1.1 misho 65:
1.1.1.4 ! misho 66: return RMAP_NOMATCH;
! 67: }
! 68:
! 69: static void *
! 70: route_match_ip_address_compile(const char *arg)
! 71: {
! 72: return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
! 73: }
! 74:
! 75: static void
! 76: route_match_ip_address_free(void *rule)
! 77: {
! 78: XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
! 79: }
! 80:
! 81: static struct route_map_rule_cmd route_match_ip_address_cmd =
! 82: {
! 83: "ip address",
! 84: route_match_ip_address,
! 85: route_match_ip_address_compile,
! 86: route_match_ip_address_free
! 87: };
! 88:
! 89: /* ------------------------------------------------------------*/
! 90:
! 91: static route_map_result_t
! 92: route_match_ip_address_prefix_list(void *rule, struct prefix *prefix,
! 93: route_map_object_t type, void *object)
! 94: {
! 95: struct prefix_list *plist;
! 96:
! 97: if (type != RMAP_ISIS)
! 98: return RMAP_NOMATCH;
! 99:
! 100: plist = prefix_list_lookup(AFI_IP, (char*)rule);
! 101: if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
! 102: return RMAP_MATCH;
! 103:
! 104: return RMAP_NOMATCH;
! 105: }
! 106:
! 107: static void *
! 108: route_match_ip_address_prefix_list_compile(const char *arg)
! 109: {
! 110: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 111: }
! 112:
! 113: static void
! 114: route_match_ip_address_prefix_list_free (void *rule)
! 115: {
! 116: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 117: }
! 118:
! 119: struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
! 120: {
! 121: "ip address prefix-list",
! 122: route_match_ip_address_prefix_list,
! 123: route_match_ip_address_prefix_list_compile,
! 124: route_match_ip_address_prefix_list_free
! 125: };
! 126:
! 127: /* ------------------------------------------------------------*/
! 128:
! 129: static route_map_result_t
! 130: route_match_ipv6_address(void *rule, struct prefix *prefix,
! 131: route_map_object_t type, void *object)
! 132: {
! 133: struct access_list *alist;
! 134:
! 135: if (type != RMAP_ISIS)
! 136: return RMAP_NOMATCH;
! 137:
! 138: alist = access_list_lookup(AFI_IP6, (char*)rule);
! 139: if (access_list_apply(alist, prefix) != FILTER_DENY)
! 140: return RMAP_MATCH;
! 141:
! 142: return RMAP_NOMATCH;
! 143: }
! 144:
! 145: static void *
! 146: route_match_ipv6_address_compile(const char *arg)
! 147: {
! 148: return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
! 149: }
! 150:
! 151: static void
! 152: route_match_ipv6_address_free(void *rule)
! 153: {
! 154: XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
! 155: }
! 156:
! 157: static struct route_map_rule_cmd route_match_ipv6_address_cmd =
! 158: {
! 159: "ipv6 address",
! 160: route_match_ipv6_address,
! 161: route_match_ipv6_address_compile,
! 162: route_match_ipv6_address_free
! 163: };
! 164:
! 165: /* ------------------------------------------------------------*/
! 166:
! 167: static route_map_result_t
! 168: route_match_ipv6_address_prefix_list(void *rule, struct prefix *prefix,
! 169: route_map_object_t type, void *object)
! 170: {
! 171: struct prefix_list *plist;
! 172:
! 173: if (type != RMAP_ISIS)
! 174: return RMAP_NOMATCH;
! 175:
! 176: plist = prefix_list_lookup(AFI_IP6, (char*)rule);
! 177: if (prefix_list_apply(plist, prefix) != PREFIX_DENY)
! 178: return RMAP_MATCH;
! 179:
! 180: return RMAP_NOMATCH;
! 181: }
! 182:
! 183: static void *
! 184: route_match_ipv6_address_prefix_list_compile(const char *arg)
! 185: {
! 186: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 187: }
! 188:
! 189: static void
! 190: route_match_ipv6_address_prefix_list_free (void *rule)
! 191: {
! 192: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 193: }
! 194:
! 195: struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1.1 misho 196: {
1.1.1.4 ! misho 197: "ipv6 address prefix-list",
! 198: route_match_ipv6_address_prefix_list,
! 199: route_match_ipv6_address_prefix_list_compile,
! 200: route_match_ipv6_address_prefix_list_free
! 201: };
! 202:
! 203: /* ------------------------------------------------------------*/
! 204:
! 205: static route_map_result_t
! 206: route_set_metric(void *rule, struct prefix *prefix,
! 207: route_map_object_t type, void *object)
! 208: {
! 209: uint32_t *metric;
! 210: struct isis_ext_info *info;
! 211:
! 212: if (type == RMAP_ISIS)
! 213: {
! 214: metric = rule;
! 215: info = object;
! 216:
! 217: info->metric = *metric;
! 218: }
! 219: return RMAP_OKAY;
! 220: }
! 221:
! 222: static void *
! 223: route_set_metric_compile(const char *arg)
! 224: {
! 225: unsigned long metric;
! 226: char *endp;
! 227: uint32_t *ret;
! 228:
! 229: metric = strtoul(arg, &endp, 10);
! 230: if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC)
! 231: return NULL;
1.1 misho 232:
1.1.1.4 ! misho 233: ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(ret));
! 234: *ret = metric;
! 235:
! 236: return ret;
! 237: }
! 238:
! 239: static void
! 240: route_set_metric_free(void *rule)
! 241: {
! 242: XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
! 243: }
! 244:
! 245: static struct route_map_rule_cmd route_set_metric_cmd =
! 246: {
! 247: "metric",
! 248: route_set_metric,
! 249: route_set_metric_compile,
! 250: route_set_metric_free
! 251: };
! 252:
! 253: /* ------------------------------------------------------------*/
! 254:
! 255: static int
! 256: isis_route_match_add(struct vty *vty, struct route_map_index *index,
! 257: const char *command, const char *arg)
! 258: {
! 259: int ret;
1.1 misho 260:
1.1.1.4 ! misho 261: ret = route_map_add_match (index, command, arg);
! 262: if (ret)
1.1 misho 263: {
1.1.1.4 ! misho 264: switch (ret)
! 265: {
! 266: case RMAP_RULE_MISSING:
! 267: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
! 268: return CMD_WARNING;
! 269: case RMAP_COMPILE_ERROR:
! 270: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
! 271: return CMD_WARNING;
! 272: }
1.1 misho 273: }
1.1.1.4 ! misho 274: return CMD_SUCCESS;
1.1 misho 275: }
276:
1.1.1.4 ! misho 277: static int
! 278: isis_route_match_delete(struct vty *vty, struct route_map_index *index,
! 279: const char *command, const char *arg)
1.1 misho 280: {
1.1.1.4 ! misho 281: int ret;
! 282:
! 283: ret = route_map_delete_match (index, command, arg);
! 284: if (ret)
! 285: {
! 286: switch (ret)
! 287: {
! 288: case RMAP_RULE_MISSING:
! 289: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
! 290: return CMD_WARNING;
! 291: case RMAP_COMPILE_ERROR:
! 292: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
! 293: return CMD_WARNING;
! 294: }
! 295: }
! 296: return CMD_SUCCESS;
! 297: }
1.1 misho 298:
1.1.1.4 ! misho 299: static int
! 300: isis_route_set_add(struct vty *vty, struct route_map_index *index,
! 301: const char *command, const char *arg)
! 302: {
! 303: int ret;
1.1 misho 304:
1.1.1.4 ! misho 305: ret = route_map_add_set(index, command, arg);
! 306: if (ret)
1.1 misho 307: {
1.1.1.4 ! misho 308: switch (ret)
! 309: {
! 310: case RMAP_RULE_MISSING:
! 311: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
! 312: return CMD_WARNING;
! 313: case RMAP_COMPILE_ERROR:
! 314: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
! 315: return CMD_WARNING;
! 316: }
1.1 misho 317: }
1.1.1.4 ! misho 318:
! 319: return CMD_SUCCESS;
! 320: }
! 321:
! 322: static int
! 323: isis_route_set_delete (struct vty *vty, struct route_map_index *index,
! 324: const char *command, const char *arg)
! 325: {
! 326: int ret;
! 327:
! 328: ret = route_map_delete_set (index, command, arg);
! 329: if (ret)
! 330: {
! 331: switch (ret)
! 332: {
! 333: case RMAP_RULE_MISSING:
! 334: vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
! 335: return CMD_WARNING;
! 336: case RMAP_COMPILE_ERROR:
! 337: vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
! 338: return CMD_WARNING;
! 339: }
! 340: }
! 341:
! 342: return CMD_SUCCESS;
! 343: }
! 344:
! 345: /* ------------------------------------------------------------*/
! 346:
! 347: DEFUN(match_ip_address,
! 348: match_ip_address_cmd,
! 349: "match ip address (<1-199>|<1300-2699>|WORD)",
! 350: MATCH_STR
! 351: IP_STR
! 352: "Match address of route\n"
! 353: "IP access-list number\n"
! 354: "IP access-list number (expanded range)\n"
! 355: "IP Access-list name\n")
! 356: {
! 357: return isis_route_match_add(vty, vty->index, "ip address", argv[0]);
! 358: }
! 359:
! 360: DEFUN(no_match_ip_address,
! 361: no_match_ip_address_val_cmd,
! 362: "no match ip address (<1-199>|<1300-2699>|WORD)",
! 363: NO_STR
! 364: MATCH_STR
! 365: IP_STR
! 366: "Match address of route\n"
! 367: "IP access-list number\n"
! 368: "IP access-list number (expanded range)\n"
! 369: "IP Access-list name\n")
! 370: {
! 371: if (argc == 0)
! 372: return isis_route_match_delete(vty, vty->index, "ip address", NULL);
! 373: return isis_route_match_delete(vty, vty->index, "ip address", argv[0]);
! 374: }
! 375:
! 376: ALIAS(no_match_ip_address,
! 377: no_match_ip_address_cmd,
! 378: "no match ip address",
! 379: NO_STR
! 380: MATCH_STR
! 381: IP_STR
! 382: "Match address of route\n"
! 383: );
! 384:
! 385: /* ------------------------------------------------------------*/
! 386:
! 387: DEFUN(match_ip_address_prefix_list,
! 388: match_ip_address_prefix_list_cmd,
! 389: "match ip address prefix-list WORD",
! 390: MATCH_STR
! 391: IP_STR
! 392: "Match address of route\n"
! 393: "Match entries of prefix-lists\n"
! 394: "IP prefix-list name\n")
! 395: {
! 396: return isis_route_match_add(vty, vty->index, "ip address prefix-list", argv[0]);
! 397: }
! 398:
! 399: DEFUN(no_match_ip_address_prefix_list,
! 400: no_match_ip_address_prefix_list_cmd,
! 401: "no match ip address prefix-list",
! 402: NO_STR
! 403: MATCH_STR
! 404: IP_STR
! 405: "Match address of route\n"
! 406: "Match entries of prefix-lists\n")
! 407: {
! 408: if (argc == 0)
! 409: return isis_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
! 410: return isis_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
1.1 misho 411: }
412:
1.1.1.4 ! misho 413: ALIAS(no_match_ip_address_prefix_list,
! 414: no_match_ip_address_prefix_list_val_cmd,
! 415: "no match ip address prefix-list WORD",
! 416: NO_STR
! 417: MATCH_STR
! 418: IP_STR
! 419: "Match address of route\n"
! 420: "Match entries of prefix-lists\n"
! 421: "IP prefix-list name\n"
! 422: );
! 423:
! 424: /* ------------------------------------------------------------*/
! 425:
! 426: DEFUN(match_ipv6_address,
! 427: match_ipv6_address_cmd,
! 428: "match ipv6 address WORD",
! 429: MATCH_STR
! 430: IPV6_STR
! 431: "Match IPv6 address of route\n"
! 432: "IPv6 access-list name\n")
! 433: {
! 434: return isis_route_match_add(vty, vty->index, "ipv6 address", argv[0]);
! 435: }
! 436:
! 437: DEFUN(no_match_ipv6_address,
! 438: no_match_ipv6_address_val_cmd,
! 439: "no match ipv6 address WORD",
! 440: NO_STR
! 441: MATCH_STR
! 442: IPV6_STR
! 443: "Match IPv6 address of route\n"
! 444: "IPv6 access-list name\n")
! 445: {
! 446: if (argc == 0)
! 447: return isis_route_match_delete(vty, vty->index, "ipv6 address", NULL);
! 448: return isis_route_match_delete(vty, vty->index, "ipv6 address", argv[0]);
! 449: }
! 450:
! 451: ALIAS(no_match_ipv6_address,
! 452: no_match_ipv6_address_cmd,
! 453: "no match ipv6 address",
! 454: NO_STR
! 455: MATCH_STR
! 456: IPV6_STR
! 457: "Match IPv6 address of route\n"
! 458: );
! 459:
! 460: /* ------------------------------------------------------------*/
! 461:
! 462: DEFUN(match_ipv6_address_prefix_list,
! 463: match_ipv6_address_prefix_list_cmd,
! 464: "match ipv6 address prefix-list WORD",
! 465: MATCH_STR
! 466: IPV6_STR
! 467: "Match address of route\n"
! 468: "Match entries of prefix-lists\n"
! 469: "IP prefix-list name\n")
! 470: {
! 471: return isis_route_match_add(vty, vty->index, "ipv6 address prefix-list", argv[0]);
! 472: }
! 473:
! 474: DEFUN(no_match_ipv6_address_prefix_list,
! 475: no_match_ipv6_address_prefix_list_cmd,
! 476: "no match ipv6 address prefix-list",
! 477: NO_STR
! 478: MATCH_STR
! 479: IPV6_STR
! 480: "Match address of route\n"
! 481: "Match entries of prefix-lists\n")
! 482: {
! 483: if (argc == 0)
! 484: return isis_route_match_delete (vty, vty->index, "ipv6 address prefix-list", NULL);
! 485: return isis_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
! 486: }
! 487:
! 488: ALIAS(no_match_ipv6_address_prefix_list,
! 489: no_match_ipv6_address_prefix_list_val_cmd,
! 490: "no match ipv6 address prefix-list WORD",
! 491: NO_STR
! 492: MATCH_STR
! 493: IPV6_STR
! 494: "Match address of route\n"
! 495: "Match entries of prefix-lists\n"
! 496: "IP prefix-list name\n"
! 497: );
! 498:
! 499: /* ------------------------------------------------------------*/
! 500:
! 501: /* set metric already exists e.g. in the ospf routemap. vtysh doesn't cope well with different
! 502: * commands at the same node, therefore add set metric with the same 32-bit range as ospf and
! 503: * verify that the input is a valid isis metric */
! 504: DEFUN(set_metric,
! 505: set_metric_cmd,
! 506: "set metric <0-4294967295>",
! 507: SET_STR
! 508: "Metric vale for destination routing protocol\n"
! 509: "Metric value\n")
! 510: {
! 511: return isis_route_set_add(vty, vty->index, "metric", argv[0]);
! 512: }
! 513:
! 514: DEFUN(no_set_metric,
! 515: no_set_metric_val_cmd,
! 516: "no set metric <0-4294967295>",
! 517: NO_STR
! 518: SET_STR
! 519: "Metric value for destination routing protocol\n"
! 520: "Metric value\n")
! 521: {
! 522: if (argc == 0)
! 523: return isis_route_set_delete(vty, vty->index, "metric", NULL);
! 524: return isis_route_set_delete(vty, vty->index, "metric", argv[0]);
! 525: }
! 526:
! 527: ALIAS(no_set_metric,
! 528: no_set_metric_cmd,
! 529: "no set metric",
! 530: NO_STR
! 531: SET_STR
! 532: "Metric vale for destination routing protocol\n"
! 533: );
! 534:
1.1 misho 535: void
1.1.1.4 ! misho 536: isis_route_map_init(void)
1.1 misho 537: {
1.1.1.4 ! misho 538: route_map_init();
! 539: route_map_init_vty();
1.1 misho 540:
1.1.1.4 ! misho 541: route_map_install_match(&route_match_ip_address_cmd);
! 542: install_element(RMAP_NODE, &match_ip_address_cmd);
! 543: install_element(RMAP_NODE, &no_match_ip_address_val_cmd);
! 544: install_element(RMAP_NODE, &no_match_ip_address_cmd);
! 545:
! 546: route_map_install_match(&route_match_ip_address_prefix_list_cmd);
! 547: install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
! 548: install_element(RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
! 549: install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
! 550:
! 551: route_map_install_match(&route_match_ipv6_address_cmd);
! 552: install_element(RMAP_NODE, &match_ipv6_address_cmd);
! 553: install_element(RMAP_NODE, &no_match_ipv6_address_val_cmd);
! 554: install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
! 555:
! 556: route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
! 557: install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
! 558: install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_val_cmd);
! 559: install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
! 560:
! 561: route_map_install_set(&route_set_metric_cmd);
! 562: install_element(RMAP_NODE, &set_metric_cmd);
! 563: install_element(RMAP_NODE, &no_set_metric_val_cmd);
! 564: install_element(RMAP_NODE, &no_set_metric_cmd);
1.1 misho 565: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>