Annotation of embedaddon/quagga/ripngd/ripng_zebra.c, revision 1.1
1.1 ! misho 1: /*
! 2: * RIPngd and zebra interface.
! 3: * Copyright (C) 1998, 1999 Kunihiro Ishiguro
! 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 "command.h"
! 26: #include "prefix.h"
! 27: #include "stream.h"
! 28: #include "routemap.h"
! 29: #include "zclient.h"
! 30: #include "log.h"
! 31:
! 32: #include "ripngd/ripngd.h"
! 33:
! 34: /* All information about zebra. */
! 35: struct zclient *zclient = NULL;
! 36:
! 37: /* Callback prototypes for zebra client service. */
! 38: int ripng_interface_up (int, struct zclient *, zebra_size_t);
! 39: int ripng_interface_down (int, struct zclient *, zebra_size_t);
! 40: int ripng_interface_add (int, struct zclient *, zebra_size_t);
! 41: int ripng_interface_delete (int, struct zclient *, zebra_size_t);
! 42: int ripng_interface_address_add (int, struct zclient *, zebra_size_t);
! 43: int ripng_interface_address_delete (int, struct zclient *, zebra_size_t);
! 44:
! 45: void
! 46: ripng_zebra_ipv6_add (struct prefix_ipv6 *p, struct in6_addr *nexthop,
! 47: unsigned int ifindex, u_char metric)
! 48: {
! 49: struct zapi_ipv6 api;
! 50:
! 51: if (zclient->redist[ZEBRA_ROUTE_RIPNG])
! 52: {
! 53: api.type = ZEBRA_ROUTE_RIPNG;
! 54: api.flags = 0;
! 55: api.message = 0;
! 56: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 57: api.nexthop_num = 1;
! 58: api.nexthop = &nexthop;
! 59: SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
! 60: api.ifindex_num = 1;
! 61: api.ifindex = &ifindex;
! 62: SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
! 63: api.metric = metric;
! 64:
! 65: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);
! 66: }
! 67: }
! 68:
! 69: void
! 70: ripng_zebra_ipv6_delete (struct prefix_ipv6 *p, struct in6_addr *nexthop,
! 71: unsigned int ifindex)
! 72: {
! 73: struct zapi_ipv6 api;
! 74:
! 75: if (zclient->redist[ZEBRA_ROUTE_RIPNG])
! 76: {
! 77: api.type = ZEBRA_ROUTE_RIPNG;
! 78: api.flags = 0;
! 79: api.message = 0;
! 80: SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
! 81: api.nexthop_num = 1;
! 82: api.nexthop = &nexthop;
! 83: SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
! 84: api.ifindex_num = 1;
! 85: api.ifindex = &ifindex;
! 86:
! 87: zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
! 88: }
! 89: }
! 90:
! 91: /* Zebra route add and delete treatment. */
! 92: static int
! 93: ripng_zebra_read_ipv6 (int command, struct zclient *zclient,
! 94: zebra_size_t length)
! 95: {
! 96: struct stream *s;
! 97: struct zapi_ipv6 api;
! 98: unsigned long ifindex;
! 99: struct in6_addr nexthop;
! 100: struct prefix_ipv6 p;
! 101:
! 102: s = zclient->ibuf;
! 103: ifindex = 0;
! 104: memset (&nexthop, 0, sizeof (struct in6_addr));
! 105:
! 106: /* Type, flags, message. */
! 107: api.type = stream_getc (s);
! 108: api.flags = stream_getc (s);
! 109: api.message = stream_getc (s);
! 110:
! 111: /* IPv6 prefix. */
! 112: memset (&p, 0, sizeof (struct prefix_ipv6));
! 113: p.family = AF_INET6;
! 114: p.prefixlen = stream_getc (s);
! 115: stream_get (&p.prefix, s, PSIZE (p.prefixlen));
! 116:
! 117: /* Nexthop, ifindex, distance, metric. */
! 118: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
! 119: {
! 120: api.nexthop_num = stream_getc (s);
! 121: stream_get (&nexthop, s, 16);
! 122: }
! 123: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
! 124: {
! 125: api.ifindex_num = stream_getc (s);
! 126: ifindex = stream_getl (s);
! 127: }
! 128: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
! 129: api.distance = stream_getc (s);
! 130: else
! 131: api.distance = 0;
! 132: if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
! 133: api.metric = stream_getl (s);
! 134: else
! 135: api.metric = 0;
! 136:
! 137: if (command == ZEBRA_IPV6_ROUTE_ADD)
! 138: ripng_redistribute_add (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop);
! 139: else
! 140: ripng_redistribute_delete (api.type, RIPNG_ROUTE_REDISTRIBUTE, &p, ifindex);
! 141:
! 142: return 0;
! 143: }
! 144:
! 145: void
! 146: ripng_zclient_reset (void)
! 147: {
! 148: zclient_reset (zclient);
! 149: }
! 150:
! 151: static int
! 152: ripng_redistribute_unset (int type)
! 153: {
! 154: if (! zclient->redist[type])
! 155: return CMD_SUCCESS;
! 156:
! 157: zclient->redist[type] = 0;
! 158:
! 159: if (zclient->sock > 0)
! 160: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type);
! 161:
! 162: ripng_redistribute_withdraw (type);
! 163:
! 164: return CMD_SUCCESS;
! 165: }
! 166:
! 167: int
! 168: ripng_redistribute_check (int type)
! 169: {
! 170: return (zclient->redist[type]);
! 171: }
! 172:
! 173: static void
! 174: ripng_redistribute_metric_set (int type, int metric)
! 175: {
! 176: ripng->route_map[type].metric_config = 1;
! 177: ripng->route_map[type].metric = metric;
! 178: }
! 179:
! 180: static int
! 181: ripng_redistribute_metric_unset (int type)
! 182: {
! 183: ripng->route_map[type].metric_config = 0;
! 184: ripng->route_map[type].metric = 0;
! 185: return 0;
! 186: }
! 187:
! 188: static void
! 189: ripng_redistribute_routemap_set (int type, const char *name)
! 190: {
! 191: if (ripng->route_map[type].name)
! 192: free (ripng->route_map[type].name);
! 193:
! 194: ripng->route_map[type].name = strdup (name);
! 195: ripng->route_map[type].map = route_map_lookup_by_name (name);
! 196: }
! 197:
! 198: static void
! 199: ripng_redistribute_routemap_unset (int type)
! 200: {
! 201: if (ripng->route_map[type].name)
! 202: free (ripng->route_map[type].name);
! 203:
! 204: ripng->route_map[type].name = NULL;
! 205: ripng->route_map[type].map = NULL;
! 206: }
! 207:
! 208: /* Redistribution types */
! 209: static struct {
! 210: int type;
! 211: int str_min_len;
! 212: const char *str;
! 213: } redist_type[] = {
! 214: {ZEBRA_ROUTE_KERNEL, 1, "kernel"},
! 215: {ZEBRA_ROUTE_CONNECT, 1, "connected"},
! 216: {ZEBRA_ROUTE_STATIC, 1, "static"},
! 217: {ZEBRA_ROUTE_OSPF6, 1, "ospf6"},
! 218: {ZEBRA_ROUTE_BGP, 1, "bgp"},
! 219: {0, 0, NULL}
! 220: };
! 221:
! 222: void
! 223: ripng_redistribute_clean ()
! 224: {
! 225: int i;
! 226:
! 227: for (i = 0; redist_type[i].str; i++)
! 228: {
! 229: if (zclient->redist[redist_type[i].type])
! 230: {
! 231: if (zclient->sock > 0)
! 232: zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE,
! 233: zclient, redist_type[i].type);
! 234:
! 235: zclient->redist[redist_type[i].type] = 0;
! 236:
! 237: /* Remove the routes from RIPng table. */
! 238: ripng_redistribute_withdraw (redist_type[i].type);
! 239: }
! 240: }
! 241: }
! 242:
! 243: DEFUN (router_zebra,
! 244: router_zebra_cmd,
! 245: "router zebra",
! 246: "Enable a routing process\n"
! 247: "Make connection to zebra daemon\n")
! 248: {
! 249: vty->node = ZEBRA_NODE;
! 250: zclient->enable = 1;
! 251: zclient_start (zclient);
! 252: return CMD_SUCCESS;
! 253: }
! 254:
! 255: DEFUN (no_router_zebra,
! 256: no_router_zebra_cmd,
! 257: "no router zebra",
! 258: NO_STR
! 259: "Disable a routing process\n"
! 260: "Stop connection to zebra daemon\n")
! 261: {
! 262: zclient->enable = 0;
! 263: zclient_stop (zclient);
! 264: return CMD_SUCCESS;
! 265: }
! 266:
! 267: DEFUN (ripng_redistribute_ripng,
! 268: ripng_redistribute_ripng_cmd,
! 269: "redistribute ripng",
! 270: "Redistribute information from another routing protocol\n"
! 271: "RIPng route\n")
! 272: {
! 273: zclient->redist[ZEBRA_ROUTE_RIPNG] = 1;
! 274: return CMD_SUCCESS;
! 275: }
! 276:
! 277: DEFUN (no_ripng_redistribute_ripng,
! 278: no_ripng_redistribute_ripng_cmd,
! 279: "no redistribute ripng",
! 280: NO_STR
! 281: "Redistribute information from another routing protocol\n"
! 282: "RIPng route\n")
! 283: {
! 284: zclient->redist[ZEBRA_ROUTE_RIPNG] = 0;
! 285: return CMD_SUCCESS;
! 286: }
! 287:
! 288: DEFUN (ripng_redistribute_type,
! 289: ripng_redistribute_type_cmd,
! 290: "redistribute (kernel|connected|static|ospf6|bgp)",
! 291: "Redistribute information from another routing protocol\n"
! 292: "Kernel routes\n"
! 293: "Connected\n"
! 294: "Static routes\n"
! 295: "Open Shortest Path First (OSPFv3)\n"
! 296: "Border Gateway Protocol (BGP)\n")
! 297: {
! 298: int i;
! 299:
! 300: for(i = 0; redist_type[i].str; i++)
! 301: {
! 302: if (strncmp (redist_type[i].str, argv[0],
! 303: redist_type[i].str_min_len) == 0)
! 304: {
! 305: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
! 306: return CMD_SUCCESS;
! 307: }
! 308: }
! 309:
! 310: vty_out(vty, "Invalid type %s%s", argv[0],
! 311: VTY_NEWLINE);
! 312:
! 313: return CMD_WARNING;
! 314: }
! 315:
! 316: DEFUN (no_ripng_redistribute_type,
! 317: no_ripng_redistribute_type_cmd,
! 318: "no redistribute (kernel|connected|static|ospf6|bgp)",
! 319: NO_STR
! 320: "Redistribute information from another routing protocol\n"
! 321: "Kernel routes\n"
! 322: "Connected\n"
! 323: "Static routes\n"
! 324: "Open Shortest Path First (OSPFv3)\n"
! 325: "Border Gateway Protocol (BGP)\n")
! 326: {
! 327: int i;
! 328:
! 329: for (i = 0; redist_type[i].str; i++)
! 330: {
! 331: if (strncmp(redist_type[i].str, argv[0],
! 332: redist_type[i].str_min_len) == 0)
! 333: {
! 334: ripng_redistribute_metric_unset (redist_type[i].type);
! 335: ripng_redistribute_routemap_unset (redist_type[i].type);
! 336: return ripng_redistribute_unset (redist_type[i].type);
! 337: }
! 338: }
! 339:
! 340: vty_out(vty, "Invalid type %s%s", argv[0],
! 341: VTY_NEWLINE);
! 342:
! 343: return CMD_WARNING;
! 344: }
! 345:
! 346:
! 347: DEFUN (ripng_redistribute_type_metric,
! 348: ripng_redistribute_type_metric_cmd,
! 349: "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
! 350: "Redistribute information from another routing protocol\n"
! 351: "Kernel routes\n"
! 352: "Connected\n"
! 353: "Static routes\n"
! 354: "Open Shortest Path First (OSPFv3)\n"
! 355: "Border Gateway Protocol (BGP)\n"
! 356: "Metric\n"
! 357: "Metric value\n")
! 358: {
! 359: int i;
! 360: int metric;
! 361:
! 362: metric = atoi (argv[1]);
! 363:
! 364: for (i = 0; redist_type[i].str; i++) {
! 365: if (strncmp(redist_type[i].str, argv[0],
! 366: redist_type[i].str_min_len) == 0)
! 367: {
! 368: ripng_redistribute_metric_set (redist_type[i].type, metric);
! 369: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
! 370: return CMD_SUCCESS;
! 371: }
! 372: }
! 373:
! 374: vty_out(vty, "Invalid type %s%s", argv[0],
! 375: VTY_NEWLINE);
! 376:
! 377: return CMD_WARNING;
! 378: }
! 379:
! 380: ALIAS (no_ripng_redistribute_type,
! 381: no_ripng_redistribute_type_metric_cmd,
! 382: "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16>",
! 383: NO_STR
! 384: "Redistribute information from another routing protocol\n"
! 385: "Kernel routes\n"
! 386: "Connected\n"
! 387: "Static routes\n"
! 388: "Open Shortest Path First (OSPFv3)\n"
! 389: "Border Gateway Protocol (BGP)\n"
! 390: "Metric\n"
! 391: "Metric value\n")
! 392:
! 393: DEFUN (ripng_redistribute_type_routemap,
! 394: ripng_redistribute_type_routemap_cmd,
! 395: "redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
! 396: "Redistribute information from another routing protocol\n"
! 397: "Kernel routes\n"
! 398: "Connected\n"
! 399: "Static routes\n"
! 400: "Open Shortest Path First (OSPFv3)\n"
! 401: "Border Gateway Protocol (BGP)\n"
! 402: "Route map reference\n"
! 403: "Pointer to route-map entries\n")
! 404: {
! 405: int i;
! 406:
! 407: for (i = 0; redist_type[i].str; i++) {
! 408: if (strncmp(redist_type[i].str, argv[0],
! 409: redist_type[i].str_min_len) == 0)
! 410: {
! 411: ripng_redistribute_routemap_set (redist_type[i].type, argv[1]);
! 412: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
! 413: return CMD_SUCCESS;
! 414: }
! 415: }
! 416:
! 417: vty_out(vty, "Invalid type %s%s", argv[0],
! 418: VTY_NEWLINE);
! 419:
! 420: return CMD_WARNING;
! 421: }
! 422:
! 423: ALIAS (no_ripng_redistribute_type,
! 424: no_ripng_redistribute_type_routemap_cmd,
! 425: "no redistribute (kernel|connected|static|ospf6|bgp) route-map WORD",
! 426: NO_STR
! 427: "Redistribute information from another routing protocol\n"
! 428: "Kernel routes\n"
! 429: "Connected\n"
! 430: "Static routes\n"
! 431: "Open Shortest Path First (OSPFv3)\n"
! 432: "Border Gateway Protocol (BGP)\n"
! 433: "Route map reference\n"
! 434: "Pointer to route-map entries\n")
! 435:
! 436: DEFUN (ripng_redistribute_type_metric_routemap,
! 437: ripng_redistribute_type_metric_routemap_cmd,
! 438: "redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
! 439: "Redistribute information from another routing protocol\n"
! 440: "Kernel routes\n"
! 441: "Connected\n"
! 442: "Static routes\n"
! 443: "Open Shortest Path First (OSPFv3)\n"
! 444: "Border Gateway Protocol (BGP)\n"
! 445: "Metric\n"
! 446: "Metric value\n"
! 447: "Route map reference\n"
! 448: "Pointer to route-map entries\n")
! 449: {
! 450: int i;
! 451: int metric;
! 452:
! 453: metric = atoi (argv[1]);
! 454:
! 455: for (i = 0; redist_type[i].str; i++) {
! 456: if (strncmp(redist_type[i].str, argv[0],
! 457: redist_type[i].str_min_len) == 0)
! 458: {
! 459: ripng_redistribute_metric_set (redist_type[i].type, metric);
! 460: ripng_redistribute_routemap_set (redist_type[i].type, argv[2]);
! 461: zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, redist_type[i].type);
! 462: return CMD_SUCCESS;
! 463: }
! 464: }
! 465:
! 466: vty_out(vty, "Invalid type %s%s", argv[0],
! 467: VTY_NEWLINE);
! 468:
! 469: return CMD_WARNING;
! 470: }
! 471:
! 472: ALIAS (no_ripng_redistribute_type,
! 473: no_ripng_redistribute_type_metric_routemap_cmd,
! 474: "no redistribute (kernel|connected|static|ospf6|bgp) metric <0-16> route-map WORD",
! 475: NO_STR
! 476: "Redistribute information from another routing protocol\n"
! 477: "Kernel routes\n"
! 478: "Connected\n"
! 479: "Static routes\n"
! 480: "Open Shortest Path First (OSPFv3)\n"
! 481: "Border Gateway Protocol (BGP)\n"
! 482: "Route map reference\n"
! 483: "Pointer to route-map entries\n")
! 484:
! 485: void
! 486: ripng_redistribute_write (struct vty *vty, int config_mode)
! 487: {
! 488: int i;
! 489:
! 490: for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
! 491: if (i != zclient->redist_default && zclient->redist[i])
! 492: {
! 493: if (config_mode)
! 494: {
! 495: if (ripng->route_map[i].metric_config)
! 496: {
! 497: if (ripng->route_map[i].name)
! 498: vty_out (vty, " redistribute %s metric %d route-map %s%s",
! 499: zebra_route_string(i), ripng->route_map[i].metric,
! 500: ripng->route_map[i].name, VTY_NEWLINE);
! 501: else
! 502: vty_out (vty, " redistribute %s metric %d%s",
! 503: zebra_route_string(i), ripng->route_map[i].metric,
! 504: VTY_NEWLINE);
! 505: }
! 506: else
! 507: {
! 508: if (ripng->route_map[i].name)
! 509: vty_out (vty, " redistribute %s route-map %s%s",
! 510: zebra_route_string(i), ripng->route_map[i].name,
! 511: VTY_NEWLINE);
! 512: else
! 513: vty_out (vty, " redistribute %s%s", zebra_route_string(i),
! 514: VTY_NEWLINE);
! 515: }
! 516: }
! 517: else
! 518: vty_out (vty, " %s", zebra_route_string(i));
! 519: }
! 520: }
! 521:
! 522: /* RIPng configuration write function. */
! 523: static int
! 524: zebra_config_write (struct vty *vty)
! 525: {
! 526: if (! zclient->enable)
! 527: {
! 528: vty_out (vty, "no router zebra%s", VTY_NEWLINE);
! 529: return 1;
! 530: }
! 531: else if (! zclient->redist[ZEBRA_ROUTE_RIPNG])
! 532: {
! 533: vty_out (vty, "router zebra%s", VTY_NEWLINE);
! 534: vty_out (vty, " no redistribute ripng%s", VTY_NEWLINE);
! 535: return 1;
! 536: }
! 537: return 0;
! 538: }
! 539:
! 540: /* Zebra node structure. */
! 541: static struct cmd_node zebra_node =
! 542: {
! 543: ZEBRA_NODE,
! 544: "%s(config-router)# ",
! 545: };
! 546:
! 547: /* Initialize zebra structure and it's commands. */
! 548: void
! 549: zebra_init ()
! 550: {
! 551: /* Allocate zebra structure. */
! 552: zclient = zclient_new ();
! 553: zclient_init (zclient, ZEBRA_ROUTE_RIPNG);
! 554:
! 555: zclient->interface_up = ripng_interface_up;
! 556: zclient->interface_down = ripng_interface_down;
! 557: zclient->interface_add = ripng_interface_add;
! 558: zclient->interface_delete = ripng_interface_delete;
! 559: zclient->interface_address_add = ripng_interface_address_add;
! 560: zclient->interface_address_delete = ripng_interface_address_delete;
! 561: zclient->ipv6_route_add = ripng_zebra_read_ipv6;
! 562: zclient->ipv6_route_delete = ripng_zebra_read_ipv6;
! 563:
! 564: /* Install zebra node. */
! 565: install_node (&zebra_node, zebra_config_write);
! 566:
! 567: /* Install command element for zebra node. */
! 568: install_element (CONFIG_NODE, &router_zebra_cmd);
! 569: install_element (CONFIG_NODE, &no_router_zebra_cmd);
! 570: install_default (ZEBRA_NODE);
! 571: install_element (ZEBRA_NODE, &ripng_redistribute_ripng_cmd);
! 572: install_element (ZEBRA_NODE, &no_ripng_redistribute_ripng_cmd);
! 573:
! 574: /* Install command elements to ripng node */
! 575: install_element (RIPNG_NODE, &ripng_redistribute_type_cmd);
! 576: install_element (RIPNG_NODE, &ripng_redistribute_type_routemap_cmd);
! 577: install_element (RIPNG_NODE, &ripng_redistribute_type_metric_cmd);
! 578: install_element (RIPNG_NODE, &ripng_redistribute_type_metric_routemap_cmd);
! 579: install_element (RIPNG_NODE, &no_ripng_redistribute_type_cmd);
! 580: install_element (RIPNG_NODE, &no_ripng_redistribute_type_routemap_cmd);
! 581: install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_cmd);
! 582: install_element (RIPNG_NODE, &no_ripng_redistribute_type_metric_routemap_cmd);
! 583: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>