1/* Zebra daemon server routine. 2 * Copyright (C) 1997, 98, 99 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 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 * Boston, MA 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23 24#include "prefix.h" 25#include "command.h" 26#include "if.h" 27#include "thread.h" 28#include "stream.h" 29#include "memory.h" 30#include "table.h" 31#include "rib.h" 32#include "network.h" 33#include "sockunion.h" 34#include "log.h" 35#include "zclient.h" 36 37#include "zebra/zserv.h" 38#include "zebra/redistribute.h" 39#include "zebra/debug.h" 40#include "zebra/ipforward.h" 41 42/* Event list of zebra. */ 43enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; 44 45/* Zebra client list. */ 46list client_list; 47 48/* Default rtm_table for all clients */ 49int rtm_table_default = 0; 50 51void zebra_event (enum event event, int sock, struct zserv *client); 52 53/* For logging of zebra meesages. */ 54char *zebra_command_str [] = 55{ 56 "NULL", 57 "ZEBRA_INTERFACE_ADD", 58 "ZEBRA_INTERFACE_DELETE", 59 "ZEBRA_INTERFACE_ADDRESS_ADD", 60 "ZEBRA_INTERFACE_ADDRESS_DELETE", 61 "ZEBRA_INTERFACE_UP", 62 "ZEBRA_INTERFACE_DOWN", 63 "ZEBRA_IPV4_ROUTE_ADD", 64 "ZEBRA_IPV4_ROUTE_DELETE", 65 "ZEBRA_IPV6_ROUTE_ADD", 66 "ZEBRA_IPV6_ROUTE_DELETE", 67 "ZEBRA_REDISTRIBUTE_ADD", 68 "ZEBRA_REDISTRIBUTE_DELETE", 69 "ZEBRA_REDISTRIBUTE_DEFAULT_ADD", 70 "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE", 71 "ZEBRA_IPV4_NEXTHOP_LOOKUP", 72 "ZEBRA_IPV6_NEXTHOP_LOOKUP", 73 "ZEBRA_IPV4_IMPORT_LOOKUP", 74 "ZEBRA_IPV6_IMPORT_LOOKUP" 75}; 76 77/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */ 78int 79zsend_interface_add (struct zserv *client, struct interface *ifp) 80{ 81 struct stream *s; 82 83 /* Check this client need interface information. */ 84 if (! client->ifinfo) 85 return -1; 86 87 s = client->obuf; 88 stream_reset (s); 89 90 /* Place holder for size. */ 91 stream_putw (s, 0); 92 93 /* Message type. */ 94 stream_putc (s, ZEBRA_INTERFACE_ADD); 95 96 /* Interface information. */ 97 stream_put (s, ifp->name, INTERFACE_NAMSIZ); 98 stream_putl (s, ifp->ifindex); 99 stream_putl (s, ifp->flags); 100 stream_putl (s, ifp->metric); 101 stream_putl (s, ifp->mtu); 102 stream_putl (s, ifp->bandwidth); 103#ifdef HAVE_SOCKADDR_DL 104 stream_put (s, &ifp->sdl, sizeof (ifp->sdl)); 105#else 106 stream_putl (s, ifp->hw_addr_len); 107 if (ifp->hw_addr_len) 108 stream_put (s, ifp->hw_addr, ifp->hw_addr_len); 109#endif /* HAVE_SOCKADDR_DL */ 110 111 /* Write packet size. */ 112 stream_putw_at (s, 0, stream_get_endp (s)); 113 114 return writen (client->sock, s->data, stream_get_endp (s)); 115} 116 117/* Interface deletion from zebra daemon. */ 118int 119zsend_interface_delete (struct zserv *client, struct interface *ifp) 120{ 121 struct stream *s; 122 123 /* Check this client need interface information. */ 124 if (! client->ifinfo) 125 return -1; 126 127 s = client->obuf; 128 stream_reset (s); 129 130 /* Packet length placeholder. */ 131 stream_putw (s, 0); 132 133 /* Interface information. */ 134 stream_putc (s, ZEBRA_INTERFACE_DELETE); 135 stream_put (s, ifp->name, INTERFACE_NAMSIZ); 136 stream_putl (s, ifp->ifindex); 137 stream_putl (s, ifp->flags); 138 stream_putl (s, ifp->metric); 139 stream_putl (s, ifp->mtu); 140 stream_putl (s, ifp->bandwidth); 141 142 /* Write packet length. */ 143 stream_putw_at (s, 0, stream_get_endp (s)); 144 145 return writen (client->sock, s->data, stream_get_endp (s)); 146} 147 148/* Interface address is added. Send ZEBRA_INTERFACE_ADDRESS_ADD to the 149 client. */ 150int 151zsend_interface_address_add (struct zserv *client, struct interface *ifp, 152 struct connected *ifc) 153{ 154 int blen; 155 struct stream *s; 156 struct prefix *p; 157 158 /* Check this client need interface information. */ 159 if (! client->ifinfo) 160 return -1; 161 162 s = client->obuf; 163 stream_reset (s); 164 165 /* Place holder for size. */ 166 stream_putw (s, 0); 167 168 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_ADD); 169 stream_putl (s, ifp->ifindex); 170 171 /* Interface address flag. */ 172 stream_putc (s, ifc->flags); 173 174 /* Prefix information. */ 175 p = ifc->address; 176 stream_putc (s, p->family); 177 blen = prefix_blen (p); 178 stream_put (s, &p->u.prefix, blen); 179 stream_putc (s, p->prefixlen); 180 181 /* Destination. */ 182 p = ifc->destination; 183 if (p) 184 stream_put (s, &p->u.prefix, blen); 185 else 186 stream_put (s, NULL, blen); 187 188 /* Write packet size. */ 189 stream_putw_at (s, 0, stream_get_endp (s)); 190 191 return writen (client->sock, s->data, stream_get_endp (s)); 192} 193 194/* Interface address is deleted. Send ZEBRA_INTERFACE_ADDRESS_DELETE 195 to the client. */ 196int 197zsend_interface_address_delete (struct zserv *client, struct interface *ifp, 198 struct connected *ifc) 199{ 200 int blen; 201 struct stream *s; 202 struct prefix *p; 203 204 /* Check this client need interface information. */ 205 if (! client->ifinfo) 206 return -1; 207 208 s = client->obuf; 209 stream_reset (s); 210 211 /* Place holder for size. */ 212 stream_putw (s, 0); 213 214 stream_putc (s, ZEBRA_INTERFACE_ADDRESS_DELETE); 215 stream_putl (s, ifp->ifindex); 216 217 /* Interface address flag. */ 218 stream_putc (s, ifc->flags); 219 220 /* Prefix information. */ 221 p = ifc->address; 222 stream_putc (s, p->family); 223 blen = prefix_blen (p); 224 stream_put (s, &p->u.prefix, blen); 225 226 p = ifc->destination; 227 if (p) 228 stream_put (s, &p->u.prefix, blen); 229 else 230 stream_put (s, NULL, blen); 231 232 /* Write packet size. */ 233 stream_putw_at (s, 0, stream_get_endp (s)); 234 235 return writen (client->sock, s->data, stream_get_endp (s)); 236} 237 238int 239zsend_interface_up (struct zserv *client, struct interface *ifp) 240{ 241 struct stream *s; 242 243 /* Check this client need interface information. */ 244 if (! client->ifinfo) 245 return -1; 246 247 s = client->obuf; 248 stream_reset (s); 249 250 /* Place holder for size. */ 251 stream_putw (s, 0); 252 253 /* Zebra command. */ 254 stream_putc (s, ZEBRA_INTERFACE_UP); 255 256 /* Interface information. */ 257 stream_put (s, ifp->name, INTERFACE_NAMSIZ); 258 stream_putl (s, ifp->ifindex); 259 stream_putl (s, ifp->flags); 260 stream_putl (s, ifp->metric); 261 stream_putl (s, ifp->mtu); 262 stream_putl (s, ifp->bandwidth); 263 264 /* Write packet size. */ 265 stream_putw_at (s, 0, stream_get_endp (s)); 266 267 return writen (client->sock, s->data, stream_get_endp (s)); 268} 269 270int 271zsend_interface_down (struct zserv *client, struct interface *ifp) 272{ 273 struct stream *s; 274 275 /* Check this client need interface information. */ 276 if (! client->ifinfo) 277 return -1; 278 279 s = client->obuf; 280 stream_reset (s); 281 282 /* Place holder for size. */ 283 stream_putw (s, 0); 284 285 /* Zebra command. */ 286 stream_putc (s, ZEBRA_INTERFACE_DOWN); 287 288 /* Interface information. */ 289 stream_put (s, ifp->name, INTERFACE_NAMSIZ); 290 stream_putl (s, ifp->ifindex); 291 stream_putl (s, ifp->flags); 292 stream_putl (s, ifp->metric); 293 stream_putl (s, ifp->mtu); 294 stream_putl (s, ifp->bandwidth); 295 296 /* Write packet size. */ 297 stream_putw_at (s, 0, stream_get_endp (s)); 298 299 return writen (client->sock, s->data, stream_get_endp (s)); 300} 301 302int 303zsend_ipv4_add_multipath (struct zserv *client, struct prefix *p, 304 struct rib *rib) 305{ 306 int psize; 307 struct stream *s; 308 struct nexthop *nexthop; 309 struct in_addr empty; 310 311 empty.s_addr = 0; 312 s = client->obuf; 313 stream_reset (s); 314 315 /* Place holder for size. */ 316 stream_putw (s, 0); 317 318 /* Put command, type and nexthop. */ 319 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD); 320 stream_putc (s, rib->type); 321 stream_putc (s, rib->flags); 322 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC); 323 324 /* Prefix. */ 325 psize = PSIZE (p->prefixlen); 326 stream_putc (s, p->prefixlen); 327 stream_write (s, (u_char *)&p->u.prefix, psize); 328 329 /* Nexthop */ 330 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 331 { 332 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 333 { 334 stream_putc (s, 1); 335 336 if (nexthop->type == NEXTHOP_TYPE_IPV4 337 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) 338 stream_put_in_addr (s, &nexthop->gate.ipv4); 339 else 340 stream_put_in_addr (s, &empty); 341 342 /* Interface index. */ 343 stream_putc (s, 1); 344 stream_putl (s, nexthop->ifindex); 345 346 break; 347 } 348 } 349 350 /* Metric */ 351 stream_putl (s, rib->metric); 352 353 /* Write packet size. */ 354 stream_putw_at (s, 0, stream_get_endp (s)); 355 356 return writen (client->sock, s->data, stream_get_endp (s)); 357} 358 359int 360zsend_ipv4_delete_multipath (struct zserv *client, struct prefix *p, 361 struct rib *rib) 362{ 363 int psize; 364 struct stream *s; 365 struct nexthop *nexthop; 366 struct in_addr empty; 367 368 empty.s_addr = 0; 369 370 s = client->obuf; 371 stream_reset (s); 372 373 /* Place holder for size. */ 374 stream_putw (s, 0); 375 376 /* Put command, type and nexthop. */ 377 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE); 378 stream_putc (s, rib->type); 379 stream_putc (s, rib->flags); 380 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 381 382 /* Prefix. */ 383 psize = PSIZE (p->prefixlen); 384 stream_putc (s, p->prefixlen); 385 stream_write (s, (u_char *)&p->u.prefix, psize); 386 387 /* Nexthop */ 388 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 389 { 390 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 391 { 392 stream_putc (s, 1); 393 394 if (nexthop->type == NEXTHOP_TYPE_IPV4) 395 stream_put_in_addr (s, &nexthop->gate.ipv4); 396 else 397 stream_put_in_addr (s, &empty); 398 399 /* Interface index. */ 400 stream_putc (s, 1); 401 stream_putl (s, nexthop->ifindex); 402 403 break; 404 } 405 } 406 407 /* Write packet size. */ 408 stream_putw_at (s, 0, stream_get_endp (s)); 409 410 return writen (client->sock, s->data, stream_get_endp (s)); 411} 412 413int 414zsend_ipv4_add (struct zserv *client, int type, int flags, 415 struct prefix_ipv4 *p, struct in_addr *nexthop, 416 unsigned int ifindex) 417{ 418 int psize; 419 struct stream *s; 420 421 s = client->obuf; 422 stream_reset (s); 423 424 /* Place holder for size. */ 425 stream_putw (s, 0); 426 427 /* Put command, type and nexthop. */ 428 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD); 429 stream_putc (s, type); 430 stream_putc (s, flags); 431 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 432 433 /* Prefix. */ 434 psize = PSIZE (p->prefixlen); 435 stream_putc (s, p->prefixlen); 436 stream_write (s, (u_char *)&p->prefix, psize); 437 438 /* Nexthop */ 439 stream_putc (s, 1); 440 stream_put_in_addr (s, nexthop); 441 442 /* Interface index. */ 443 stream_putc (s, 1); 444 stream_putl (s, ifindex); 445 446 /* Write packet size. */ 447 stream_putw_at (s, 0, stream_get_endp (s)); 448 449 return writen (client->sock, s->data, stream_get_endp (s)); 450} 451 452int 453zsend_ipv4_delete (struct zserv *client, int type, int flags, 454 struct prefix_ipv4 *p, struct in_addr *nexthop, 455 unsigned int ifindex) 456{ 457 int psize; 458 struct stream *s; 459 460 s = client->obuf; 461 stream_reset (s); 462 463 /* Place holder for size. */ 464 stream_putw (s, 0); 465 466 /* Put command, type and nexthop. */ 467 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE); 468 stream_putc (s, type); 469 stream_putc (s, flags); 470 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 471 472 /* Prefix. */ 473 psize = PSIZE (p->prefixlen); 474 stream_putc (s, p->prefixlen); 475 stream_write (s, (u_char *)&p->prefix, psize); 476 477 /* Nexthop */ 478 stream_putc (s, 1); 479 stream_put_in_addr (s, nexthop); 480 481 /* Interface index. */ 482 stream_putc (s, 1); 483 stream_putl (s, ifindex); 484 485 /* Write packet size. */ 486 stream_putw_at (s, 0, stream_get_endp (s)); 487 488 return writen (client->sock, s->data, stream_get_endp (s)); 489} 490 491#ifdef HAVE_IPV6 492int 493zsend_ipv6_add (struct zserv *client, int type, int flags, 494 struct prefix_ipv6 *p, struct in6_addr *nexthop, 495 unsigned int ifindex) 496{ 497 int psize; 498 struct stream *s; 499 500 s = client->obuf; 501 stream_reset (s); 502 503 /* Place holder for size. */ 504 stream_putw (s, 0); 505 506 /* Put command, type and nexthop. */ 507 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD); 508 stream_putc (s, type); 509 stream_putc (s, flags); 510 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 511 512 /* Prefix. */ 513 psize = PSIZE (p->prefixlen); 514 stream_putc (s, p->prefixlen); 515 stream_write (s, (u_char *)&p->prefix, psize); 516 517 /* Nexthop */ 518 stream_putc (s, 1); 519 stream_write (s, (u_char *)nexthop, 16); 520 521 /* Interface index. */ 522 stream_putc (s, 1); 523 stream_putl (s, ifindex); 524 525 /* Write packet size. */ 526 stream_putw_at (s, 0, stream_get_endp (s)); 527 528 return writen (client->sock, s->data, stream_get_endp (s)); 529} 530 531int 532zsend_ipv6_add_multipath (struct zserv *client, struct prefix *p, 533 struct rib *rib) 534{ 535 int psize; 536 struct stream *s; 537 struct nexthop *nexthop; 538 struct in6_addr empty; 539 540 memset (&empty, 0, sizeof (struct in6_addr)); 541 s = client->obuf; 542 stream_reset (s); 543 544 /* Place holder for size. */ 545 stream_putw (s, 0); 546 547 /* Put command, type and nexthop. */ 548 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD); 549 stream_putc (s, rib->type); 550 stream_putc (s, rib->flags); 551 stream_putc (s, ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX | ZAPI_MESSAGE_METRIC); 552 553 /* Prefix. */ 554 psize = PSIZE (p->prefixlen); 555 stream_putc (s, p->prefixlen); 556 stream_write (s, (u_char *) &p->u.prefix, psize); 557 558 /* Nexthop */ 559 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 560 { 561 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 562 { 563 stream_putc (s, 1); 564 565 if (nexthop->type == NEXTHOP_TYPE_IPV6) 566 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); 567 else 568 stream_write (s, (u_char *) &empty, 16); 569 570 /* Interface index. */ 571 stream_putc (s, 1); 572 stream_putl (s, nexthop->ifindex); 573 574 break; 575 } 576 } 577 578 /* Metric */ 579 stream_putl (s, rib->metric); 580 581 /* Write packet size. */ 582 stream_putw_at (s, 0, stream_get_endp (s)); 583 584 return writen (client->sock, s->data, stream_get_endp (s)); 585} 586 587int 588zsend_ipv6_delete (struct zserv *client, int type, int flags, 589 struct prefix_ipv6 *p, struct in6_addr *nexthop, 590 unsigned int ifindex) 591{ 592 int psize; 593 struct stream *s; 594 595 s = client->obuf; 596 stream_reset (s); 597 598 /* Place holder for size. */ 599 stream_putw (s, 0); 600 601 /* Put command, type and nexthop. */ 602 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); 603 stream_putc (s, type); 604 stream_putc (s, flags); 605 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 606 607 /* Prefix. */ 608 psize = PSIZE (p->prefixlen); 609 stream_putc (s, p->prefixlen); 610 stream_write (s, (u_char *)&p->prefix, psize); 611 612 /* Nexthop */ 613 stream_putc (s, 1); 614 stream_write (s, (u_char *)nexthop, 16); 615 616 /* Interface index. */ 617 stream_putc (s, 1); 618 stream_putl (s, ifindex); 619 620 /* Write packet size. */ 621 stream_putw_at (s, 0, stream_get_endp (s)); 622 623 return writen (client->sock, s->data, stream_get_endp (s)); 624} 625 626int 627zsend_ipv6_delete_multipath (struct zserv *client, struct prefix *p, 628 struct rib *rib) 629{ 630 int psize; 631 struct stream *s; 632 struct nexthop *nexthop; 633 struct in6_addr empty; 634 635 memset (&empty, 0, sizeof (struct in6_addr)); 636 s = client->obuf; 637 stream_reset (s); 638 639 /* Place holder for size. */ 640 stream_putw (s, 0); 641 642 /* Put command, type and nexthop. */ 643 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); 644 stream_putc (s, rib->type); 645 stream_putc (s, rib->flags); 646 stream_putc (s, ZAPI_MESSAGE_NEXTHOP|ZAPI_MESSAGE_IFINDEX); 647 648 /* Prefix. */ 649 psize = PSIZE (p->prefixlen); 650 stream_putc (s, p->prefixlen); 651 stream_write (s, (u_char *)&p->u.prefix, psize); 652 653 /* Nexthop */ 654 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 655 { 656 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 657 { 658 stream_putc (s, 1); 659 660 if (nexthop->type == NEXTHOP_TYPE_IPV6) 661 stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); 662 else 663 stream_write (s, (u_char *) &empty, 16); 664 665 /* Interface index. */ 666 stream_putc (s, 1); 667 stream_putl (s, nexthop->ifindex); 668 669 break; 670 } 671 } 672 673 /* Write packet size. */ 674 stream_putw_at (s, 0, stream_get_endp (s)); 675 676 return writen (client->sock, s->data, stream_get_endp (s)); 677} 678 679int 680zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr) 681{ 682 struct stream *s; 683 struct rib *rib; 684 unsigned long nump; 685 u_char num; 686 struct nexthop *nexthop; 687 688 /* Lookup nexthop. */ 689 rib = rib_match_ipv6 (addr); 690 691 /* Get output stream. */ 692 s = client->obuf; 693 stream_reset (s); 694 695 /* Fill in result. */ 696 stream_putw (s, 0); 697 stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP); 698 stream_put (s, &addr, 16); 699 700 if (rib) 701 { 702 stream_putl (s, rib->metric); 703 num = 0; 704 nump = s->putp; 705 stream_putc (s, 0); 706 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 707 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 708 { 709 stream_putc (s, nexthop->type); 710 switch (nexthop->type) 711 { 712 case ZEBRA_NEXTHOP_IPV6: 713 stream_put (s, &nexthop->gate.ipv6, 16); 714 break; 715 case ZEBRA_NEXTHOP_IPV6_IFINDEX: 716 case ZEBRA_NEXTHOP_IPV6_IFNAME: 717 stream_put (s, &nexthop->gate.ipv6, 16); 718 stream_putl (s, nexthop->ifindex); 719 break; 720 case ZEBRA_NEXTHOP_IFINDEX: 721 case ZEBRA_NEXTHOP_IFNAME: 722 stream_putl (s, nexthop->ifindex); 723 break; 724 } 725 num++; 726 } 727 stream_putc_at (s, nump, num); 728 } 729 else 730 { 731 stream_putl (s, 0); 732 stream_putc (s, 0); 733 } 734 735 stream_putw_at (s, 0, stream_get_endp (s)); 736 737 return writen (client->sock, s->data, stream_get_endp (s)); 738} 739#endif /* HAVE_IPV6 */ 740 741int 742zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr) 743{ 744 struct stream *s; 745 struct rib *rib; 746 unsigned long nump; 747 u_char num; 748 struct nexthop *nexthop; 749 750 /* Lookup nexthop. */ 751 rib = rib_match_ipv4 (addr); 752 753 /* Get output stream. */ 754 s = client->obuf; 755 stream_reset (s); 756 757 /* Fill in result. */ 758 stream_putw (s, 0); 759 stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP); 760 stream_put_in_addr (s, &addr); 761 762 if (rib) 763 { 764 stream_putl (s, rib->metric); 765 num = 0; 766 nump = s->putp; 767 stream_putc (s, 0); 768 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 769 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 770 { 771 stream_putc (s, nexthop->type); 772 switch (nexthop->type) 773 { 774 case ZEBRA_NEXTHOP_IPV4: 775 stream_put_in_addr (s, &nexthop->gate.ipv4); 776 break; 777 case ZEBRA_NEXTHOP_IFINDEX: 778 case ZEBRA_NEXTHOP_IFNAME: 779 stream_putl (s, nexthop->ifindex); 780 break; 781 } 782 num++; 783 } 784 stream_putc_at (s, nump, num); 785 } 786 else 787 { 788 stream_putl (s, 0); 789 stream_putc (s, 0); 790 } 791 792 stream_putw_at (s, 0, stream_get_endp (s)); 793 794 return writen (client->sock, s->data, stream_get_endp (s)); 795} 796 797int 798zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p) 799{ 800 struct stream *s; 801 struct rib *rib; 802 unsigned long nump; 803 u_char num; 804 struct nexthop *nexthop; 805 806 /* Lookup nexthop. */ 807 rib = rib_lookup_ipv4 (p); 808 809 /* Get output stream. */ 810 s = client->obuf; 811 stream_reset (s); 812 813 /* Fill in result. */ 814 stream_putw (s, 0); 815 stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP); 816 stream_put_in_addr (s, &p->prefix); 817 818 if (rib) 819 { 820 stream_putl (s, rib->metric); 821 num = 0; 822 nump = s->putp; 823 stream_putc (s, 0); 824 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) 825 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) 826 { 827 stream_putc (s, nexthop->type); 828 switch (nexthop->type) 829 { 830 case ZEBRA_NEXTHOP_IPV4: 831 stream_put_in_addr (s, &nexthop->gate.ipv4); 832 break; 833 case ZEBRA_NEXTHOP_IFINDEX: 834 case ZEBRA_NEXTHOP_IFNAME: 835 stream_putl (s, nexthop->ifindex); 836 break; 837 } 838 num++; 839 } 840 stream_putc_at (s, nump, num); 841 } 842 else 843 { 844 stream_putl (s, 0); 845 stream_putc (s, 0); 846 } 847 848 stream_putw_at (s, 0, stream_get_endp (s)); 849 850 return writen (client->sock, s->data, stream_get_endp (s)); 851} 852 853/* Register zebra server interface information. Send current all 854 interface and address information. */ 855void 856zread_interface_add (struct zserv *client, u_short length) 857{ 858 listnode ifnode; 859 listnode cnode; 860 struct interface *ifp; 861 struct connected *c; 862 863 /* Interface information is needed. */ 864 client->ifinfo = 1; 865 866 for (ifnode = listhead (iflist); ifnode; ifnode = nextnode (ifnode)) 867 { 868 ifp = getdata (ifnode); 869 870 /* Skip pseudo interface. */ 871 if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) 872 continue; 873 874 zsend_interface_add (client, ifp); 875 876 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) 877 { 878 c = getdata (cnode); 879 if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL)) 880 zsend_interface_address_add (client, ifp, c); 881 } 882 } 883} 884 885/* Unregister zebra server interface information. */ 886void 887zread_interface_delete (struct zserv *client, u_short length) 888{ 889 client->ifinfo = 0; 890} 891 892/* This function support multiple nexthop. */ 893void 894zread_ipv4_add (struct zserv *client, u_short length) 895{ 896 int i; 897 struct rib *rib; 898 struct prefix_ipv4 p; 899 u_char message; 900 struct in_addr nexthop; 901 u_char nexthop_num; 902 u_char nexthop_type; 903 struct stream *s; 904 unsigned int ifindex; 905 u_char ifname_len; 906 907 /* Get input stream. */ 908 s = client->ibuf; 909 910 /* Allocate new rib. */ 911 rib = XMALLOC (MTYPE_RIB, sizeof (struct rib)); 912 memset (rib, 0, sizeof (struct rib)); 913 914 /* Type, flags, message. */ 915 rib->type = stream_getc (s); 916 rib->flags = stream_getc (s); 917 message = stream_getc (s); 918 rib->uptime = time (NULL); 919 920 /* IPv4 prefix. */ 921 memset (&p, 0, sizeof (struct prefix_ipv4)); 922 p.family = AF_INET; 923 p.prefixlen = stream_getc (s); 924 stream_get (&p.prefix, s, PSIZE (p.prefixlen)); 925 926 /* Nexthop parse. */ 927 if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) 928 { 929 nexthop_num = stream_getc (s); 930 931 for (i = 0; i < nexthop_num; i++) 932 { 933 nexthop_type = stream_getc (s); 934 935 switch (nexthop_type) 936 { 937 case ZEBRA_NEXTHOP_IFINDEX: 938 ifindex = stream_getl (s); 939 nexthop_ifindex_add (rib, ifindex); 940 break; 941 case ZEBRA_NEXTHOP_IFNAME: 942 ifname_len = stream_getc (s); 943 stream_forward (s, ifname_len); 944 break; 945 case ZEBRA_NEXTHOP_IPV4: 946 nexthop.s_addr = stream_get_ipv4 (s); 947 nexthop_ipv4_add (rib, &nexthop); 948 break; 949 case ZEBRA_NEXTHOP_IPV6: 950 stream_forward (s, IPV6_MAX_BYTELEN); 951 break; 952 } 953 } 954 } 955 956 /* Distance. */ 957 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) 958 rib->distance = stream_getc (s); 959 960 /* Metric. */ 961 if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) 962 rib->metric = stream_getl (s); 963 964 rib_add_ipv4_multipath (&p, rib); 965} 966 967/* Zebra server IPv4 prefix delete function. */ 968void 969zread_ipv4_delete (struct zserv *client, u_short length) 970{ 971 int i; 972 struct stream *s; 973 struct zapi_ipv4 api; 974 struct in_addr nexthop; 975 unsigned long ifindex; 976 struct prefix_ipv4 p; 977 u_char nexthop_num; 978 u_char nexthop_type; 979 u_char ifname_len; 980 981 s = client->ibuf; 982 ifindex = 0; 983 nexthop.s_addr = 0; 984 985 /* Type, flags, message. */ 986 api.type = stream_getc (s); 987 api.flags = stream_getc (s); 988 api.message = stream_getc (s); 989 990 /* IPv4 prefix. */ 991 memset (&p, 0, sizeof (struct prefix_ipv4)); 992 p.family = AF_INET; 993 p.prefixlen = stream_getc (s); 994 stream_get (&p.prefix, s, PSIZE (p.prefixlen)); 995 996 /* Nexthop, ifindex, distance, metric. */ 997 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) 998 { 999 nexthop_num = stream_getc (s); 1000 1001 for (i = 0; i < nexthop_num; i++) 1002 { 1003 nexthop_type = stream_getc (s); 1004 1005 switch (nexthop_type) 1006 { 1007 case ZEBRA_NEXTHOP_IFINDEX: 1008 ifindex = stream_getl (s); 1009 break; 1010 case ZEBRA_NEXTHOP_IFNAME: 1011 ifname_len = stream_getc (s); 1012 stream_forward (s, ifname_len); 1013 break; 1014 case ZEBRA_NEXTHOP_IPV4: 1015 nexthop.s_addr = stream_get_ipv4 (s); 1016 break; 1017 case ZEBRA_NEXTHOP_IPV6: 1018 stream_forward (s, IPV6_MAX_BYTELEN); 1019 break; 1020 } 1021 } 1022 } 1023 1024 /* Distance. */ 1025 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) 1026 api.distance = stream_getc (s); 1027 else 1028 api.distance = 0; 1029 1030 /* Metric. */ 1031 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) 1032 api.metric = stream_getl (s); 1033 else 1034 api.metric = 0; 1035 1036 rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex, 1037 client->rtm_table); 1038} 1039 1040/* Nexthop lookup for IPv4. */ 1041void 1042zread_ipv4_nexthop_lookup (struct zserv *client, u_short length) 1043{ 1044 struct in_addr addr; 1045 1046 addr.s_addr = stream_get_ipv4 (client->ibuf); 1047 zsend_ipv4_nexthop_lookup (client, addr); 1048} 1049 1050/* Nexthop lookup for IPv4. */ 1051void 1052zread_ipv4_import_lookup (struct zserv *client, u_short length) 1053{ 1054 struct prefix_ipv4 p; 1055 1056 p.family = AF_INET; 1057 p.prefixlen = stream_getc (client->ibuf); 1058 p.prefix.s_addr = stream_get_ipv4 (client->ibuf); 1059 1060 zsend_ipv4_import_lookup (client, &p); 1061} 1062 1063#ifdef HAVE_IPV6 1064/* Zebra server IPv6 prefix add function. */ 1065void 1066zread_ipv6_add (struct zserv *client, u_short length) 1067{ 1068 int i; 1069 struct stream *s; 1070 struct zapi_ipv6 api; 1071 struct in6_addr nexthop; 1072 unsigned long ifindex; 1073 struct prefix_ipv6 p; 1074 1075 s = client->ibuf; 1076 ifindex = 0; 1077 memset (&nexthop, 0, sizeof (struct in6_addr)); 1078 1079 /* Type, flags, message. */ 1080 api.type = stream_getc (s); 1081 api.flags = stream_getc (s); 1082 api.message = stream_getc (s); 1083 1084 /* IPv4 prefix. */ 1085 memset (&p, 0, sizeof (struct prefix_ipv6)); 1086 p.family = AF_INET6; 1087 p.prefixlen = stream_getc (s); 1088 stream_get (&p.prefix, s, PSIZE (p.prefixlen)); 1089 1090 /* Nexthop, ifindex, distance, metric. */ 1091 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) 1092 { 1093 u_char nexthop_type; 1094 1095 api.nexthop_num = stream_getc (s); 1096 for (i = 0; i < api.nexthop_num; i++) 1097 { 1098 nexthop_type = stream_getc (s); 1099 1100 switch (nexthop_type) 1101 { 1102 case ZEBRA_NEXTHOP_IPV6: 1103 stream_get (&nexthop, s, 16); 1104 break; 1105 case ZEBRA_NEXTHOP_IFINDEX: 1106 ifindex = stream_getl (s); 1107 break; 1108 } 1109 } 1110 } 1111 1112 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) 1113 api.distance = stream_getc (s); 1114 else 1115 api.distance = 0; 1116 1117 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) 1118 api.metric = stream_getl (s); 1119 else 1120 api.metric = 0; 1121 1122 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) 1123 rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0); 1124 else 1125 rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0); 1126} 1127 1128/* Zebra server IPv6 prefix delete function. */ 1129void 1130zread_ipv6_delete (struct zserv *client, u_short length) 1131{ 1132 int i; 1133 struct stream *s; 1134 struct zapi_ipv6 api; 1135 struct in6_addr nexthop; 1136 unsigned long ifindex; 1137 struct prefix_ipv6 p; 1138 1139 s = client->ibuf; 1140 ifindex = 0; 1141 memset (&nexthop, 0, sizeof (struct in6_addr)); 1142 1143 /* Type, flags, message. */ 1144 api.type = stream_getc (s); 1145 api.flags = stream_getc (s); 1146 api.message = stream_getc (s); 1147 1148 /* IPv4 prefix. */ 1149 memset (&p, 0, sizeof (struct prefix_ipv6)); 1150 p.family = AF_INET6; 1151 p.prefixlen = stream_getc (s); 1152 stream_get (&p.prefix, s, PSIZE (p.prefixlen)); 1153 1154 /* Nexthop, ifindex, distance, metric. */ 1155 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) 1156 { 1157 u_char nexthop_type; 1158 1159 api.nexthop_num = stream_getc (s); 1160 for (i = 0; i < api.nexthop_num; i++) 1161 { 1162 nexthop_type = stream_getc (s); 1163 1164 switch (nexthop_type) 1165 { 1166 case ZEBRA_NEXTHOP_IPV6: 1167 stream_get (&nexthop, s, 16); 1168 break; 1169 case ZEBRA_NEXTHOP_IFINDEX: 1170 ifindex = stream_getl (s); 1171 break; 1172 } 1173 } 1174 } 1175 1176 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) 1177 api.distance = stream_getc (s); 1178 else 1179 api.distance = 0; 1180 if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) 1181 api.metric = stream_getl (s); 1182 else 1183 api.metric = 0; 1184 1185 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) 1186 rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0); 1187 else 1188 rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0); 1189} 1190 1191void 1192zebra_read_ipv6 (int command, struct zserv *client, u_short length) 1193{ 1194 u_char type; 1195 u_char flags; 1196 struct in6_addr nexthop, *gate; 1197 u_char *lim; 1198 u_char *pnt; 1199 unsigned int ifindex; 1200 1201 pnt = stream_pnt (client->ibuf); 1202 lim = pnt + length; 1203 1204 type = stream_getc (client->ibuf); 1205 flags = stream_getc (client->ibuf); 1206 stream_get (&nexthop, client->ibuf, sizeof (struct in6_addr)); 1207 1208 while (stream_pnt (client->ibuf) < lim) 1209 { 1210 int size; 1211 struct prefix_ipv6 p; 1212 1213 ifindex = stream_getl (client->ibuf); 1214 1215 memset (&p, 0, sizeof (struct prefix_ipv6)); 1216 p.family = AF_INET6; 1217 p.prefixlen = stream_getc (client->ibuf); 1218 size = PSIZE(p.prefixlen); 1219 stream_get (&p.prefix, client->ibuf, size); 1220 1221 if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) 1222 gate = NULL; 1223 else 1224 gate = &nexthop; 1225 1226 if (command == ZEBRA_IPV6_ROUTE_ADD) 1227 rib_add_ipv6 (type, flags, &p, gate, ifindex, 0); 1228 else 1229 rib_delete_ipv6 (type, flags, &p, gate, ifindex, 0); 1230 } 1231} 1232 1233void 1234zread_ipv6_nexthop_lookup (struct zserv *client, u_short length) 1235{ 1236 struct in6_addr addr; 1237 char buf[BUFSIZ]; 1238 1239 stream_get (&addr, client->ibuf, 16); 1240 printf ("DEBUG %s\n", inet_ntop (AF_INET6, &addr, buf, BUFSIZ)); 1241 1242 zsend_ipv6_nexthop_lookup (client, &addr); 1243} 1244#endif /* HAVE_IPV6 */ 1245 1246/* Close zebra client. */ 1247void 1248zebra_client_close (struct zserv *client) 1249{ 1250 /* Close file descriptor. */ 1251 if (client->sock) 1252 { 1253 close (client->sock); 1254 client->sock = -1; 1255 } 1256 1257 /* Free stream buffers. */ 1258 if (client->ibuf) 1259 stream_free (client->ibuf); 1260 if (client->obuf) 1261 stream_free (client->obuf); 1262 1263 /* Release threads. */ 1264 if (client->t_read) 1265 thread_cancel (client->t_read); 1266 if (client->t_write) 1267 thread_cancel (client->t_write); 1268 1269 /* Free client structure. */ 1270 listnode_delete (client_list, client); 1271 XFREE (0, client); 1272} 1273 1274/* Make new client. */ 1275void 1276zebra_client_create (int sock) 1277{ 1278 struct zserv *client; 1279 1280 client = XCALLOC (0, sizeof (struct zserv)); 1281 1282 /* Make client input/output buffer. */ 1283 client->sock = sock; 1284 client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); 1285 client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); 1286 1287 /* Set table number. */ 1288 client->rtm_table = rtm_table_default; 1289 1290 /* Add this client to linked list. */ 1291 listnode_add (client_list, client); 1292 1293 /* Make new read thread. */ 1294 zebra_event (ZEBRA_READ, sock, client); 1295} 1296 1297/* Handler of zebra service request. */ 1298int 1299zebra_client_read (struct thread *thread) 1300{ 1301 int sock; 1302 struct zserv *client; 1303 int nbyte; 1304 u_short length; 1305 u_char command; 1306 1307 /* Get thread data. Reset reading thread because I'm running. */ 1308 sock = THREAD_FD (thread); 1309 client = THREAD_ARG (thread); 1310 client->t_read = NULL; 1311 1312 /* Read length and command. */ 1313 nbyte = stream_read (client->ibuf, sock, 3); 1314 if (nbyte <= 0) 1315 { 1316#ifdef FOX_RIP_DEBUG 1317 if (IS_ZEBRA_DEBUG_EVENT) 1318 zlog_info ("connection closed socket [%d]", sock); 1319#endif /* FOX_RIP_DEBUG */ 1320 zebra_client_close (client); 1321 return -1; 1322 } 1323 length = stream_getw (client->ibuf); 1324 command = stream_getc (client->ibuf); 1325 1326 if (length < 3) 1327 { 1328#ifdef FOX_RIP_DEBUG 1329 if (IS_ZEBRA_DEBUG_EVENT) 1330 zlog_info ("length %d is less than 3 ", length); 1331#endif /* FOX_RIP_DEBUG */ 1332 zebra_client_close (client); 1333 return -1; 1334 } 1335 1336 length -= 3; 1337 1338 /* Read rest of data. */ 1339 if (length) 1340 { 1341 nbyte = stream_read (client->ibuf, sock, length); 1342 if (nbyte <= 0) 1343 { 1344#ifdef FOX_RIP_DEBUG 1345 if (IS_ZEBRA_DEBUG_EVENT) 1346 zlog_info ("connection closed [%d] when reading zebra data", sock); 1347#endif /* FOX_RIP_DEBUG */ 1348 zebra_client_close (client); 1349 return -1; 1350 } 1351 } 1352#ifdef FOX_RIP_DEBUG 1353 /* Debug packet information. */ 1354 if (IS_ZEBRA_DEBUG_EVENT) 1355 zlog_info ("zebra message comes from socket [%d]", sock); 1356 1357 if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) 1358 zlog_info ("zebra message received [%s] %d", 1359 zebra_command_str[command], length); 1360#endif /* FOX_RIP_DEBUG */ 1361 switch (command) 1362 { 1363 case ZEBRA_INTERFACE_ADD: 1364 zread_interface_add (client, length); 1365 break; 1366 case ZEBRA_INTERFACE_DELETE: 1367 zread_interface_delete (client, length); 1368 break; 1369 case ZEBRA_IPV4_ROUTE_ADD: 1370 zread_ipv4_add (client, length); 1371 break; 1372 case ZEBRA_IPV4_ROUTE_DELETE: 1373 zread_ipv4_delete (client, length); 1374 break; 1375#ifdef HAVE_IPV6 1376 case ZEBRA_IPV6_ROUTE_ADD: 1377 zread_ipv6_add (client, length); 1378 break; 1379 case ZEBRA_IPV6_ROUTE_DELETE: 1380 zread_ipv6_delete (client, length); 1381 break; 1382#endif /* HAVE_IPV6 */ 1383 case ZEBRA_REDISTRIBUTE_ADD: 1384 zebra_redistribute_add (command, client, length); 1385 break; 1386 case ZEBRA_REDISTRIBUTE_DELETE: 1387 zebra_redistribute_delete (command, client, length); 1388 break; 1389 case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: 1390 zebra_redistribute_default_add (command, client, length); 1391 break; 1392 case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: 1393 zebra_redistribute_default_delete (command, client, length); 1394 break; 1395 case ZEBRA_IPV4_NEXTHOP_LOOKUP: 1396 zread_ipv4_nexthop_lookup (client, length); 1397 break; 1398#ifdef HAVE_IPV6 1399 case ZEBRA_IPV6_NEXTHOP_LOOKUP: 1400 zread_ipv6_nexthop_lookup (client, length); 1401 break; 1402#endif /* HAVE_IPV6 */ 1403 case ZEBRA_IPV4_IMPORT_LOOKUP: 1404 zread_ipv4_import_lookup (client, length); 1405 break; 1406 default: 1407#ifdef FOX_RIP_DEBUG 1408 zlog_info ("Zebra received unknown command %d", command); 1409#endif /* FOX_RIP_DEBUG */ 1410 break; 1411 } 1412 1413 stream_reset (client->ibuf); 1414 zebra_event (ZEBRA_READ, sock, client); 1415 1416 return 0; 1417} 1418 1419/* Write output buffer to the socket. */ 1420void 1421zebra_write (struct thread *thread) 1422{ 1423 int sock; 1424 struct zserv *client; 1425 1426 /* Thread treatment. */ 1427 sock = THREAD_FD (thread); 1428 client = THREAD_ARG (thread); 1429 client->t_write = NULL; 1430 1431 stream_flush (client->obuf, sock); 1432} 1433 1434/* Accept code of zebra server socket. */ 1435int 1436zebra_accept (struct thread *thread) 1437{ 1438 int accept_sock; 1439 int client_sock; 1440 struct sockaddr_in client; 1441 socklen_t len; 1442 1443 accept_sock = THREAD_FD (thread); 1444 1445 len = sizeof (struct sockaddr_in); 1446 client_sock = accept (accept_sock, (struct sockaddr *) &client, &len); 1447 1448 if (client_sock < 0) 1449 { 1450#ifdef FOX_RIP_DEBUG 1451 zlog_warn ("Can't accept zebra socket: %s", strerror (errno)); 1452#endif /* FOX_RIP_DEBUG */ 1453 return -1; 1454 } 1455 1456 /* Create new zebra client. */ 1457 zebra_client_create (client_sock); 1458 1459 /* Register myself. */ 1460 zebra_event (ZEBRA_SERV, accept_sock, NULL); 1461 1462 return 0; 1463} 1464 1465/* Make zebra's server socket. */ 1466void 1467zebra_serv () 1468{ 1469 int ret; 1470 int accept_sock; 1471 struct sockaddr_in addr; 1472 1473 accept_sock = socket (AF_INET, SOCK_STREAM, 0); 1474 1475 if (accept_sock < 0) 1476 { 1477#ifdef FOX_RIP_DEBUG 1478 zlog_warn ("Can't bind to socket: %s", strerror (errno)); 1479 zlog_warn ("zebra can't provice full functionality due to above error"); 1480#endif /* FOX_RIP_DEBUG */ 1481 return; 1482 } 1483 1484 memset (&addr, 0, sizeof (struct sockaddr_in)); 1485 addr.sin_family = AF_INET; 1486 addr.sin_port = htons (ZEBRA_PORT); 1487#ifdef HAVE_SIN_LEN 1488 addr.sin_len = sizeof (struct sockaddr_in); 1489#endif /* HAVE_SIN_LEN */ 1490 addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); 1491 1492 sockopt_reuseaddr (accept_sock); 1493 sockopt_reuseport (accept_sock); 1494 1495 ret = bind (accept_sock, (struct sockaddr *)&addr, 1496 sizeof (struct sockaddr_in)); 1497 if (ret < 0) 1498 { 1499#ifdef FOX_RIP_DEBUG 1500 zlog_warn ("Can't bind to socket: %s", strerror (errno)); 1501 zlog_warn ("zebra can't provice full functionality due to above error"); 1502#endif /* FOX_RIP_DEBUG */ 1503 close (accept_sock); /* Avoid sd leak. */ 1504 return; 1505 } 1506 1507 ret = listen (accept_sock, 1); 1508 if (ret < 0) 1509 { 1510#ifdef FOX_RIP_DEBUG 1511 zlog_warn ("Can't listen to socket: %s", strerror (errno)); 1512 zlog_warn ("zebra can't provice full functionality due to above error"); 1513#endif /* FOX_RIP_DEBUG */ 1514 close (accept_sock); /* Avoid sd leak. */ 1515 return; 1516 } 1517 1518 zebra_event (ZEBRA_SERV, accept_sock, NULL); 1519} 1520 1521/* For sockaddr_un. */ 1522#include <sys/un.h> 1523 1524/* zebra server UNIX domain socket. */ 1525void 1526zebra_serv_un (char *path) 1527{ 1528 int ret; 1529 int sock, len; 1530 struct sockaddr_un serv; 1531 mode_t old_mask; 1532 1533 /* First of all, unlink existing socket */ 1534 unlink (path); 1535 1536 /* Set umask */ 1537 old_mask = umask (0077); 1538 1539 /* Make UNIX domain socket. */ 1540 sock = socket (AF_UNIX, SOCK_STREAM, 0); 1541 if (sock < 0) 1542 { 1543 perror ("sock"); 1544 return; 1545 } 1546 1547 /* Make server socket. */ 1548 memset (&serv, 0, sizeof (struct sockaddr_un)); 1549 serv.sun_family = AF_UNIX; 1550 strncpy (serv.sun_path, path, strlen (path)); 1551#ifdef HAVE_SUN_LEN 1552 len = serv.sun_len = SUN_LEN(&serv); 1553#else 1554 len = sizeof (serv.sun_family) + strlen (serv.sun_path); 1555#endif /* HAVE_SUN_LEN */ 1556 1557 ret = bind (sock, (struct sockaddr *) &serv, len); 1558 if (ret < 0) 1559 { 1560 perror ("bind"); 1561 close (sock); 1562 return; 1563 } 1564 1565 ret = listen (sock, 5); 1566 if (ret < 0) 1567 { 1568 perror ("listen"); 1569 close (sock); 1570 return; 1571 } 1572 1573 umask (old_mask); 1574 1575 zebra_event (ZEBRA_SERV, sock, NULL); 1576} 1577 1578/* Zebra's event management function. */ 1579extern struct thread_master *master; 1580 1581void 1582zebra_event (enum event event, int sock, struct zserv *client) 1583{ 1584 switch (event) 1585 { 1586 case ZEBRA_SERV: 1587 thread_add_read (master, zebra_accept, client, sock); 1588 break; 1589 case ZEBRA_READ: 1590 client->t_read = 1591 thread_add_read (master, zebra_client_read, client, sock); 1592 break; 1593 case ZEBRA_WRITE: 1594 /**/ 1595 break; 1596 } 1597} 1598 1599 1600#ifdef FOX_CMD_SUPPORT 1601/* Display default rtm_table for all clients. */ 1602DEFUN (show_table, 1603 show_table_cmd, 1604 "show table", 1605 SHOW_STR 1606 "default routing table to use for all clients\n") 1607{ 1608#ifdef FOX_CMD_SUPPORT 1609 vty_out (vty, "table %d%s", rtm_table_default, 1610 VTY_NEWLINE); 1611 return CMD_SUCCESS; 1612#endif /* FOX_CMD_SUPPORT */ 1613} 1614 1615DEFUN (config_table, 1616 config_table_cmd, 1617 "table TABLENO", 1618 "Configure target kernel routing table\n" 1619 "TABLE integer\n") 1620{ 1621 rtm_table_default = strtol (argv[0], (char**)0, 10); 1622 return CMD_SUCCESS; 1623} 1624 1625DEFUN (no_ip_forwarding, 1626 no_ip_forwarding_cmd, 1627 "no ip forwarding", 1628 NO_STR 1629 IP_STR 1630 "Turn off IP forwarding") 1631{ 1632 int ret; 1633 1634 ret = ipforward (); 1635 1636#ifdef FOX_CMD_SUPPORT 1637 if (ret == 0) 1638 { 1639 vty_out (vty, "IP forwarding is already off%s", VTY_NEWLINE); 1640 return CMD_ERR_NOTHING_TODO; 1641 } 1642 1643 ret = ipforward_off (); 1644 if (ret != 0) 1645 { 1646 vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE); 1647 return CMD_WARNING; 1648 } 1649#endif /* FOX_CMD_SUPPORT */ 1650 return CMD_SUCCESS; 1651} 1652 1653/* This command is for debugging purpose. */ 1654DEFUN (show_zebra_client, 1655 show_zebra_client_cmd, 1656 "show zebra client", 1657 SHOW_STR 1658 "Zebra information" 1659 "Client information") 1660{ 1661 listnode node; 1662 struct zserv *client; 1663 1664 for (node = listhead (client_list); node; nextnode (node)) 1665 { 1666 client = getdata (node); 1667 vty_out (vty, "Client fd %d%s", client->sock, VTY_NEWLINE); 1668 } 1669 return CMD_SUCCESS; 1670} 1671#endif /* FOX_CMD_SUPPORT */ 1672/* Table configuration write function. */ 1673int 1674config_write_table (struct vty *vty) 1675{ 1676 1677#ifdef FOX_CMD_SUPPORT 1678 if (rtm_table_default) 1679 vty_out (vty, "table %d%s", rtm_table_default, 1680 VTY_NEWLINE); 1681 #endif /* FOX_CMD_SUPPORT */ 1682 return 0; 1683} 1684 1685/* table node for routing tables. */ 1686struct cmd_node table_node = 1687{ 1688 TABLE_NODE, 1689 "", /* This node has no interface. */ 1690 1 1691}; 1692#ifdef FOX_CMD_SUPPORT 1693/* Only display ip forwarding is enabled or not. */ 1694DEFUN (show_ip_forwarding, 1695 show_ip_forwarding_cmd, 1696 "show ip forwarding", 1697 SHOW_STR 1698 IP_STR 1699 "IP forwarding status\n") 1700{ 1701 int ret; 1702 1703 ret = ipforward (); 1704 1705 if (ret == 0) 1706 vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE); 1707 else 1708 vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE); 1709 return CMD_SUCCESS; 1710} 1711 1712#ifdef HAVE_IPV6 1713/* Only display ipv6 forwarding is enabled or not. */ 1714DEFUN (show_ipv6_forwarding, 1715 show_ipv6_forwarding_cmd, 1716 "show ipv6 forwarding", 1717 SHOW_STR 1718 "IPv6 information\n" 1719 "Forwarding status\n") 1720{ 1721 int ret; 1722 1723 ret = ipforward_ipv6 (); 1724 1725 switch (ret) 1726 { 1727 case -1: 1728 vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE); 1729 break; 1730 case 0: 1731 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); 1732 break; 1733 case 1: 1734 vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE); 1735 break; 1736 default: 1737 vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); 1738 break; 1739 } 1740 return CMD_SUCCESS; 1741} 1742 1743DEFUN (no_ipv6_forwarding, 1744 no_ipv6_forwarding_cmd, 1745 "no ipv6 forwarding", 1746 NO_STR 1747 IP_STR 1748 "Doesn't forward IPv6 protocol packet") 1749{ 1750 int ret; 1751 1752 ret = ipforward_ipv6_off (); 1753 if (ret != 0) 1754 { 1755 vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE); 1756 return CMD_WARNING; 1757 } 1758 1759 return CMD_SUCCESS; 1760} 1761 1762#endif /* HAVE_IPV6 */ 1763#endif /* FOX_CMD_SUPPORT */ 1764/* IPForwarding configuration write function. */ 1765int 1766config_write_forwarding (struct vty *vty) 1767{ 1768#ifdef FOX_CMD_SUPPORT 1769 if (! ipforward ()) 1770 vty_out (vty, "no ip forwarding%s", VTY_NEWLINE); 1771#ifdef HAVE_IPV6 1772 if (! ipforward_ipv6 ()) 1773 vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE); 1774#endif /* HAVE_IPV6 */ 1775 vty_out (vty, "!%s", VTY_NEWLINE); 1776#endif /* FOX_CMD_SUPPORT */ 1777 return 0; 1778} 1779 1780/* table node for routing tables. */ 1781struct cmd_node forwarding_node = 1782{ 1783 FORWARDING_NODE, 1784 "", /* This node has no interface. */ 1785 1 1786}; 1787 1788 1789/* Initialisation of zebra and installation of commands. */ 1790void 1791zebra_init () 1792{ 1793 /* Client list init. */ 1794 client_list = list_new (); 1795 1796 /* Forwarding is on by default. */ 1797 ipforward_on (); 1798#ifdef HAVE_IPV6 1799 ipforward_ipv6_on (); 1800#endif /* HAVE_IPV6 */ 1801 1802 /* Make zebra server socket. */ 1803#ifdef HAVE_TCP_ZEBRA 1804 zebra_serv (); 1805#else 1806 zebra_serv_un (ZEBRA_SERV_PATH); 1807#endif /* HAVE_TCP_ZEBRA */ 1808 1809 /* Install configuration write function. */ 1810 install_node (&table_node, config_write_table); 1811 install_node (&forwarding_node, config_write_forwarding); 1812#ifdef FOX_CMD_SUPPORT 1813 install_element (VIEW_NODE, &show_ip_forwarding_cmd); 1814 install_element (ENABLE_NODE, &show_ip_forwarding_cmd); 1815 install_element (CONFIG_NODE, &no_ip_forwarding_cmd); 1816 install_element (ENABLE_NODE, &show_zebra_client_cmd); 1817 1818#ifdef HAVE_NETLINK 1819 install_element (VIEW_NODE, &show_table_cmd); 1820 install_element (ENABLE_NODE, &show_table_cmd); 1821 install_element (CONFIG_NODE, &config_table_cmd); 1822#endif /* HAVE_NETLINK */ 1823 1824#ifdef HAVE_IPV6 1825 install_element (VIEW_NODE, &show_ipv6_forwarding_cmd); 1826 install_element (ENABLE_NODE, &show_ipv6_forwarding_cmd); 1827 install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd); 1828#endif /* HAVE_IPV6 */ 1829#endif /* FOX_CMD_SUPPORT */ 1830} 1831