1/* Zebra's client library. 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 7 * it under the terms of the GNU General Public License as published 8 * by the Free Software Foundation; either version 2, or (at your 9 * option) any 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, Boston, 19 * MA 02111-1307, USA. 20 */ 21 22#include <zebra.h> 23 24#include "prefix.h" 25#include "stream.h" 26#include "network.h" 27#include "if.h" 28#include "log.h" 29#include "thread.h" 30#include "zclient.h" 31#include "memory.h" 32#include "table.h" 33 34#include "zebra/rib.h" 35#include "zebra/zserv.h" 36 37/* Zebra client events. */ 38enum event {ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT}; 39 40/* Prototype for event manager. */ 41static void zclient_event (enum event, struct zclient *); 42 43/* This file local debug flag. */ 44int zclient_debug = 0; 45 46/* Allocate zclient structure. */ 47struct zclient * 48zclient_new () 49{ 50 struct zclient *zclient; 51 zclient = XMALLOC (MTYPE_ZCLIENT, sizeof (struct zclient)); 52 memset (zclient, 0, sizeof (struct zclient)); 53 54 zclient->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); 55 zclient->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); 56 57 return zclient; 58} 59 60/* Free zclient structure. */ 61void 62zclient_free (struct zclient *zclient) 63{ 64 XFREE (MTYPE_ZCLIENT, zclient); 65} 66 67/* Initialize zebra client. Argument redist_default is unwanted 68 redistribute route type. */ 69void 70zclient_init (struct zclient *zclient, int redist_default) 71{ 72 int i; 73 74 /* Enable zebra client connection by default. */ 75 zclient->enable = 1; 76 77 /* Set -1 to the default socket value. */ 78 zclient->sock = -1; 79 80 /* Clear redistribution flags. */ 81 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 82 zclient->redist[i] = 0; 83 84 /* Set unwanted redistribute route. bgpd does not need BGP route 85 redistribution. */ 86 zclient->redist_default = redist_default; 87 zclient->redist[redist_default] = 1; 88 89 /* Set default-information redistribute to zero. */ 90 zclient->default_information = 0; 91 92 /* Schedule first zclient connection. */ 93#ifdef FOX_RIP_DEBUG 94 if (zclient_debug) 95 zlog_info ("zclient start scheduled"); 96#endif /* FOX_RIP_DEBUG */ 97 zclient_event (ZCLIENT_SCHEDULE, zclient); 98} 99 100/* Stop zebra client services. */ 101void 102zclient_stop (struct zclient *zclient) 103{ 104 if (zclient_debug) 105#ifdef FOX_RIP_DEBUG 106 zlog_info ("zclient stopped"); 107#endif /* FOX_RIP_DEBUG */ 108 /* Stop threads. */ 109 if (zclient->t_read) 110 { 111 thread_cancel (zclient->t_read); 112 zclient->t_read = NULL; 113 } 114 if (zclient->t_connect) 115 { 116 thread_cancel (zclient->t_connect); 117 zclient->t_connect = NULL; 118 } 119 120 /* Close socket. */ 121 if (zclient->sock >= 0) 122 { 123 close (zclient->sock); 124 zclient->sock = -1; 125 } 126 zclient->fail = 0; 127} 128 129void 130zclient_reset (struct zclient *zclient) 131{ 132 zclient_stop (zclient); 133 zclient_init (zclient, zclient->redist_default); 134} 135 136/* Make socket to zebra daemon. Return zebra socket. */ 137int 138zclient_socket () 139{ 140 int sock; 141 int ret; 142 struct sockaddr_in serv; 143 144 /* We should think about IPv6 connection. */ 145 sock = socket (AF_INET, SOCK_STREAM, 0); 146 if (sock < 0) 147 return -1; 148 149 /* Make server socket. */ 150 memset (&serv, 0, sizeof (struct sockaddr_in)); 151 serv.sin_family = AF_INET; 152 serv.sin_port = htons (ZEBRA_PORT); 153#ifdef HAVE_SIN_LEN 154 serv.sin_len = sizeof (struct sockaddr_in); 155#endif /* HAVE_SIN_LEN */ 156 serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK); 157 158 /* Connect to zebra. */ 159 ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv)); 160 if (ret < 0) 161 { 162 close (sock); 163 return -1; 164 } 165 return sock; 166} 167#ifdef FOX_SUPPORT 168/* For sockaddr_un. */ 169#include <sys/un.h> 170 171int 172zclient_socket_un (char *path) 173{ 174 int ret; 175 int sock, len; 176 struct sockaddr_un addr; 177 178 sock = socket (AF_UNIX, SOCK_STREAM, 0); 179 if (sock < 0) 180 return -1; 181 182 /* Make server socket. */ 183 memset (&addr, 0, sizeof (struct sockaddr_un)); 184 addr.sun_family = AF_UNIX; 185 strncpy (addr.sun_path, path, strlen (path)); 186#ifdef HAVE_SUN_LEN 187 len = addr.sun_len = SUN_LEN(&addr); 188#else 189 len = sizeof (addr.sun_family) + strlen (addr.sun_path); 190#endif /* HAVE_SUN_LEN */ 191 192 ret = connect (sock, (struct sockaddr *) &addr, len); 193 if (ret < 0) 194 { 195 close (sock); 196 return -1; 197 } 198 return sock; 199} 200#endif /* FOX_SUPPORT */ 201/* Send simple Zebra message. */ 202int 203zebra_message_send (struct zclient *zclient, int command) 204{ 205 struct stream *s; 206 207 /* Get zclient output buffer. */ 208 s = zclient->obuf; 209 stream_reset (s); 210 211 /* Send very simple command only Zebra message. */ 212 stream_putw (s, 3); 213 stream_putc (s, command); 214 215 return writen (zclient->sock, s->data, 3); 216} 217 218/* Make connection to zebra daemon. */ 219int 220zclient_start (struct zclient *zclient) 221{ 222 int i; 223 224#ifdef FOX_RIP_DEBUG 225 if (zclient_debug) 226 zlog_info ("zclient_start is called"); 227#endif /* FOX_RIP_DEBUG */ 228 /* zclient is disabled. */ 229 if (! zclient->enable) 230 return 0; 231 232 /* If already connected to the zebra. */ 233 if (zclient->sock >= 0) 234 return 0; 235 236 /* Check connect thread. */ 237 if (zclient->t_connect) 238 return 0; 239 240 /* Make socket. */ 241#ifdef HAVE_TCP_ZEBRA 242 zclient->sock = zclient_socket (); 243#else 244 zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); 245#endif /* HAVE_TCP_ZEBRA */ 246 if (zclient->sock < 0) 247 { 248#ifdef FOX_RIP_DEBUG 249 if (zclient_debug) 250 zlog_info ("zclient connection fail"); 251#endif /* FOX_RIP_DEBUG */ 252 zclient->fail++; 253 zclient_event (ZCLIENT_CONNECT, zclient); 254 return -1; 255 } 256 257 /* Clear fail count. */ 258 zclient->fail = 0; 259 if (zclient_debug){ 260#ifdef FOX_RIP_DEBUG 261 zlog_info ("zclient connect success with socket [%d]", zclient->sock); 262#endif /* FOX_RIP_DEBUG */ 263 } 264 265 /* Create read thread. */ 266 zclient_event (ZCLIENT_READ, zclient); 267 268 /* We need interface information. */ 269 zebra_message_send (zclient, ZEBRA_INTERFACE_ADD); 270 271 /* Flush all redistribute request. */ 272 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 273 if (i != zclient->redist_default && zclient->redist[i]) 274 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, i); 275 276 /* If default information is needed. */ 277 if (zclient->default_information) 278 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD); 279 280 return 0; 281} 282 283/* This function is a wrapper function for calling zclient_start from 284 timer or event thread. */ 285int 286zclient_connect (struct thread *t) 287{ 288 struct zclient *zclient; 289 290 zclient = THREAD_ARG (t); 291 zclient->t_connect = NULL; 292#ifdef FOX_RIP_DEBUG 293 if (zclient_debug) 294 zlog_info ("zclient_connect is called"); 295#endif /* FOX_RIP_DEBUG */ 296 return zclient_start (zclient); 297} 298 299int 300zapi_ipv4_add (struct zclient *zclient, struct prefix_ipv4 *p, 301 struct zapi_ipv4 *api) 302{ 303 int i; 304 int psize; 305 struct stream *s; 306 307 /* Reset stream. */ 308 s = zclient->obuf; 309 stream_reset (s); 310 311 /* Length place holder. */ 312 stream_putw (s, 0); 313 314 /* Put command, type and nexthop. */ 315 stream_putc (s, ZEBRA_IPV4_ROUTE_ADD); 316 stream_putc (s, api->type); 317 stream_putc (s, api->flags); 318 stream_putc (s, api->message); 319 320 /* Put prefix information. */ 321 psize = PSIZE (p->prefixlen); 322 stream_putc (s, p->prefixlen); 323 stream_write (s, (u_char *)&p->prefix, psize); 324 325 /* Nexthop, ifindex, distance and metric information. */ 326 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) 327 { 328 stream_putc (s, api->nexthop_num + api->ifindex_num); 329 330 for (i = 0; i < api->nexthop_num; i++) 331 { 332 stream_putc (s, ZEBRA_NEXTHOP_IPV4); 333 stream_put_in_addr (s, api->nexthop[i]); 334 } 335 for (i = 0; i < api->ifindex_num; i++) 336 { 337 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); 338 stream_putl (s, api->ifindex[i]); 339 } 340 } 341 342 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) 343 stream_putc (s, api->distance); 344 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) 345 stream_putl (s, api->metric); 346 347 /* Put length at the first point of the stream. */ 348 stream_putw_at (s, 0, stream_get_endp (s)); 349 350 return writen (zclient->sock, s->data, stream_get_endp (s)); 351} 352 353int 354zapi_ipv4_delete (struct zclient *zclient, struct prefix_ipv4 *p, 355 struct zapi_ipv4 *api) 356{ 357 int i; 358 int psize; 359 struct stream *s; 360 361 /* Reset stream. */ 362 s = zclient->obuf; 363 stream_reset (s); 364 365 /* Length place holder. */ 366 stream_putw (s, 0); 367 368 /* Put command, type and nexthop. */ 369 stream_putc (s, ZEBRA_IPV4_ROUTE_DELETE); 370 stream_putc (s, api->type); 371 stream_putc (s, api->flags); 372 stream_putc (s, api->message); 373 374 /* Put prefix information. */ 375 psize = PSIZE (p->prefixlen); 376 stream_putc (s, p->prefixlen); 377 stream_write (s, (u_char *)&p->prefix, psize); 378 379 /* Nexthop, ifindex, distance and metric information. */ 380 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) 381 { 382 stream_putc (s, api->nexthop_num + api->ifindex_num); 383 384 for (i = 0; i < api->nexthop_num; i++) 385 { 386 stream_putc (s, ZEBRA_NEXTHOP_IPV4); 387 stream_put_in_addr (s, api->nexthop[i]); 388 } 389 for (i = 0; i < api->ifindex_num; i++) 390 { 391 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); 392 stream_putl (s, api->ifindex[i]); 393 } 394 } 395 396 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) 397 stream_putc (s, api->distance); 398 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) 399 stream_putl (s, api->metric); 400 401 /* Put length at the first point of the stream. */ 402 stream_putw_at (s, 0, stream_get_endp (s)); 403 404 return writen (zclient->sock, s->data, stream_get_endp (s)); 405} 406 407#ifdef HAVE_IPV6 408int 409zapi_ipv6_add (struct zclient *zclient, struct prefix_ipv6 *p, 410 struct zapi_ipv6 *api) 411{ 412 int i; 413 int psize; 414 struct stream *s; 415 416 /* Reset stream. */ 417 s = zclient->obuf; 418 stream_reset (s); 419 420 /* Length place holder. */ 421 stream_putw (s, 0); 422 423 /* Put command, type and nexthop. */ 424 stream_putc (s, ZEBRA_IPV6_ROUTE_ADD); 425 stream_putc (s, api->type); 426 stream_putc (s, api->flags); 427 stream_putc (s, api->message); 428 429 /* Put prefix information. */ 430 psize = PSIZE (p->prefixlen); 431 stream_putc (s, p->prefixlen); 432 stream_write (s, (u_char *)&p->prefix, psize); 433 434 /* Nexthop, ifindex, distance and metric information. */ 435 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) 436 { 437 stream_putc (s, api->nexthop_num + api->ifindex_num); 438 439 for (i = 0; i < api->nexthop_num; i++) 440 { 441 stream_putc (s, ZEBRA_NEXTHOP_IPV6); 442 stream_write (s, (u_char *)api->nexthop[i], 16); 443 } 444 for (i = 0; i < api->ifindex_num; i++) 445 { 446 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); 447 stream_putl (s, api->ifindex[i]); 448 } 449 } 450 451 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) 452 stream_putc (s, api->distance); 453 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) 454 stream_putl (s, api->metric); 455 456 /* Put length at the first point of the stream. */ 457 stream_putw_at (s, 0, stream_get_endp (s)); 458 459 return writen (zclient->sock, s->data, stream_get_endp (s)); 460} 461 462int 463zapi_ipv6_delete (struct zclient *zclient, struct prefix_ipv6 *p, 464 struct zapi_ipv6 *api) 465{ 466 int i; 467 int psize; 468 struct stream *s; 469 470 /* Reset stream. */ 471 s = zclient->obuf; 472 stream_reset (s); 473 474 /* Length place holder. */ 475 stream_putw (s, 0); 476 477 /* Put command, type and nexthop. */ 478 stream_putc (s, ZEBRA_IPV6_ROUTE_DELETE); 479 stream_putc (s, api->type); 480 stream_putc (s, api->flags); 481 stream_putc (s, api->message); 482 483 /* Put prefix information. */ 484 psize = PSIZE (p->prefixlen); 485 stream_putc (s, p->prefixlen); 486 stream_write (s, (u_char *)&p->prefix, psize); 487 488 /* Nexthop, ifindex, distance and metric information. */ 489 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) 490 { 491 stream_putc (s, api->nexthop_num + api->ifindex_num); 492 493 for (i = 0; i < api->nexthop_num; i++) 494 { 495 stream_putc (s, ZEBRA_NEXTHOP_IPV6); 496 stream_write (s, (u_char *)api->nexthop[i], 16); 497 } 498 for (i = 0; i < api->ifindex_num; i++) 499 { 500 stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); 501 stream_putl (s, api->ifindex[i]); 502 } 503 } 504 505 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_DISTANCE)) 506 stream_putc (s, api->distance); 507 if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) 508 stream_putl (s, api->metric); 509 510 /* Put length at the first point of the stream. */ 511 stream_putw_at (s, 0, stream_get_endp (s)); 512 513 return writen (zclient->sock, s->data, stream_get_endp (s)); 514} 515 516#endif /* HAVE_IPV6 */ 517 518int 519zebra_redistribute_send (int command, int sock, int type) 520{ 521 int ret; 522 struct stream *s; 523 524 s = stream_new (ZEBRA_MAX_PACKET_SIZ); 525 526 /* Total length of the messages. */ 527 stream_putw (s, 4); 528 529 stream_putc (s, command); 530 stream_putc (s, type); 531 532 ret = writen (sock, s->data, 4); 533 534 stream_free (s); 535 536 return ret; 537} 538 539/* Interface addition from zebra daemon. */ 540struct interface * 541zebra_interface_add_read (struct stream *s) 542{ 543 struct interface *ifp; 544 u_char ifname_tmp[INTERFACE_NAMSIZ]; 545 546 /* Read interface name. */ 547 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); 548 549 /* Lookup this by interface name. */ 550 ifp = if_lookup_by_name (ifname_tmp); 551 552 /* If such interface does not exist, make new one. */ 553 if (! ifp) 554 { 555 ifp = if_create (); 556 strncpy (ifp->name, ifname_tmp, IFNAMSIZ); 557 } 558 559 /* Read interface's index. */ 560 ifp->ifindex = stream_getl (s); 561 562 /* Read interface's value. */ 563 ifp->flags = stream_getl (s); 564 ifp->metric = stream_getl (s); 565 ifp->mtu = stream_getl (s); 566 ifp->bandwidth = stream_getl (s); 567#ifdef HAVE_SOCKADDR_DL 568 stream_get (&ifp->sdl, s, sizeof (ifp->sdl)); 569#else 570 ifp->hw_addr_len = stream_getl (s); 571 if (ifp->hw_addr_len) 572 stream_get (ifp->hw_addr, s, ifp->hw_addr_len); 573#endif /* HAVE_SOCKADDR_DL */ 574 575 return ifp; 576} 577 578/* Read interface up/down msg from zebra daemon. */ 579struct interface * 580zebra_interface_state_read (struct stream *s) 581{ 582 struct interface *ifp; 583 u_char ifname_tmp[INTERFACE_NAMSIZ]; 584 585 /* Read interface name. */ 586 stream_get (ifname_tmp, s, INTERFACE_NAMSIZ); 587 588 /* Lookup this by interface index. */ 589 ifp = if_lookup_by_name (ifname_tmp); 590 591 /* If such interface does not exist, indicate an error */ 592 if (! ifp) 593 return NULL; 594 595 /* Read interface's index. */ 596 ifp->ifindex = stream_getl (s); 597 598 /* Read interface's value. */ 599 ifp->flags = stream_getl (s); 600 ifp->metric = stream_getl (s); 601 ifp->mtu = stream_getl (s); 602 ifp->bandwidth = stream_getl (s); 603 604 return ifp; 605} 606 607struct connected * 608zebra_interface_address_add_read (struct stream *s) 609{ 610 unsigned int ifindex; 611 struct interface *ifp; 612 struct connected *ifc; 613 struct prefix *p; 614 int family; 615 int plen; 616 617 /* Get interface index. */ 618 ifindex = stream_getl (s); 619 620 /* Lookup index. */ 621 ifp = if_lookup_by_index (ifindex); 622 if (ifp == NULL) 623 { 624#ifdef FOX_RIP_DEBUG 625 zlog_warn ("zebra_interface_address_add_read: Can't find interface by ifindex: %d ", ifindex); 626#endif /* FOX_RIP_DEBUG */ 627 return NULL; 628 } 629 630 /* Allocate new connected address. */ 631 ifc = connected_new (); 632 ifc->ifp = ifp; 633 634 /* Fetch flag. */ 635 ifc->flags = stream_getc (s); 636 637 /* Fetch interface address. */ 638 p = prefix_new (); 639 family = p->family = stream_getc (s); 640 641 plen = prefix_blen (p); 642 stream_get (&p->u.prefix, s, plen); 643 p->prefixlen = stream_getc (s); 644 ifc->address = p; 645 646 /* Fetch destination address. */ 647 p = prefix_new (); 648 stream_get (&p->u.prefix, s, plen); 649 p->family = family; 650 651 ifc->destination = p; 652 653 p = ifc->address; 654 655 /* Add connected address to the interface. */ 656 listnode_add (ifp->connected, ifc); 657 658 return ifc; 659} 660 661struct connected * 662zebra_interface_address_delete_read (struct stream *s) 663{ 664 unsigned int ifindex; 665 struct interface *ifp; 666 struct connected *ifc; 667 struct prefix p; 668 struct prefix d; 669 int family; 670 int len; 671 u_char flags; 672 673 /* Get interface index. */ 674 ifindex = stream_getl (s); 675 676 /* Lookup index. */ 677 ifp = if_lookup_by_index (ifindex); 678 if (ifp == NULL) 679 { 680#ifdef FOX_RIP_DEBUG 681 zlog_warn ("zebra_interface_address_delete_read: Can't find interface by ifindex: %d ", ifindex); 682#endif /* FOX_RIP_DEBUG */ 683 return NULL; 684 } 685 686 /* Fetch flag. */ 687 flags = stream_getc (s); 688 689 /* Fetch interface address. */ 690 family = p.family = stream_getc (s); 691 692 len = prefix_blen (&p); 693 stream_get (&p.u.prefix, s, len); 694 p.prefixlen = stream_getc (s); 695 696 /* Fetch destination address. */ 697 stream_get (&d.u.prefix, s, len); 698 d.family = family; 699 700 ifc = connected_delete_by_prefix (ifp, &p); 701 702 return ifc; 703} 704 705/* Zebra client message read function. */ 706int 707zclient_read (struct thread *thread) 708{ 709 int ret; 710 int nbytes; 711 int sock; 712 zebra_size_t length; 713 zebra_command_t command; 714 struct zclient *zclient; 715 716 /* Get socket to zebra. */ 717 sock = THREAD_FD (thread); 718 zclient = THREAD_ARG (thread); 719 zclient->t_read = NULL; 720 721 /* Clear input buffer. */ 722 stream_reset (zclient->ibuf); 723 724 /* Read zebra header. */ 725 nbytes = stream_read (zclient->ibuf, sock, ZEBRA_HEADER_SIZE); 726 727 /* zebra socket is closed. */ 728 if (nbytes == 0) 729 { 730#ifdef FOX_RIP_DEBUG 731 if (zclient_debug) 732 zlog_info ("zclient connection closed socket [%d].", sock); 733#endif /* FOX_RIP_DEBUG */ 734 zclient->fail++; 735 zclient_stop (zclient); 736 zclient_event (ZCLIENT_CONNECT, zclient); 737 return -1; 738 } 739 740 /* zebra read error. */ 741 if (nbytes < 0 || nbytes != ZEBRA_HEADER_SIZE) 742 { 743#ifdef FOX_RIP_DEBUG 744 if (zclient_debug) 745 zlog_info ("Can't read all packet (length %d).", nbytes); 746#endif /* FOX_RIP_DEBUG */ 747 zclient->fail++; 748 zclient_stop (zclient); 749 zclient_event (ZCLIENT_CONNECT, zclient); 750 return -1; 751 } 752 753 /* Fetch length and command. */ 754 length = stream_getw (zclient->ibuf); 755 command = stream_getc (zclient->ibuf); 756 757 /* Length check. */ 758 if (length >= zclient->ibuf->size) 759 { 760 stream_free (zclient->ibuf); 761 zclient->ibuf = stream_new (length + 1); 762 } 763 length -= ZEBRA_HEADER_SIZE; 764 765 /* Read rest of zebra packet. */ 766 nbytes = stream_read (zclient->ibuf, sock, length); 767 if (nbytes != length) 768 { 769#ifdef FOX_RIP_DEBUG 770 if (zclient_debug) 771 zlog_info ("zclient connection closed socket [%d].", sock); 772#endif /* FOX_RIP_DEBUG */ 773 zclient->fail++; 774 zclient_stop (zclient); 775 zclient_event (ZCLIENT_CONNECT, zclient); 776 return -1; 777 } 778 779 switch (command) 780 { 781 case ZEBRA_INTERFACE_ADD: 782 if (zclient->interface_add) 783 ret = (*zclient->interface_add) (command, zclient, length); 784 break; 785 case ZEBRA_INTERFACE_DELETE: 786 if (zclient->interface_delete) 787 ret = (*zclient->interface_delete) (command, zclient, length); 788 break; 789 case ZEBRA_INTERFACE_ADDRESS_ADD: 790 if (zclient->interface_address_add) 791 ret = (*zclient->interface_address_add) (command, zclient, length); 792 break; 793 case ZEBRA_INTERFACE_ADDRESS_DELETE: 794 if (zclient->interface_address_delete) 795 ret = (*zclient->interface_address_delete) (command, zclient, length); 796 break; 797 case ZEBRA_INTERFACE_UP: 798 if (zclient->interface_up) 799 ret = (*zclient->interface_up) (command, zclient, length); 800 break; 801 case ZEBRA_INTERFACE_DOWN: 802 if (zclient->interface_down) 803 ret = (*zclient->interface_down) (command, zclient, length); 804 break; 805 case ZEBRA_IPV4_ROUTE_ADD: 806 if (zclient->ipv4_route_add) 807 ret = (*zclient->ipv4_route_add) (command, zclient, length); 808 break; 809 case ZEBRA_IPV4_ROUTE_DELETE: 810 if (zclient->ipv4_route_delete) 811 ret = (*zclient->ipv4_route_delete) (command, zclient, length); 812 break; 813#ifdef HAVE_IPV6 814 case ZEBRA_IPV6_ROUTE_ADD: 815 if (zclient->ipv6_route_add) 816 ret = (*zclient->ipv6_route_add) (command, zclient, length); 817 break; 818 case ZEBRA_IPV6_ROUTE_DELETE: 819 if (zclient->ipv6_route_delete) 820 ret = (*zclient->ipv6_route_delete) (command, zclient, length); 821 break; 822#endif /* HAVE_IPV6 */ 823 default: 824 break; 825 } 826 827 /* Register read thread. */ 828 zclient_event (ZCLIENT_READ, zclient); 829 830 return 0; 831} 832 833void 834zclient_redistribute_set (struct zclient *zclient, int type) 835{ 836 if (zclient->redist[type]) 837 return; 838 839 zclient->redist[type] = 1; 840 841 if (zclient->sock > 0) 842 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type); 843} 844 845void 846zclient_redistribute_unset (struct zclient *zclient, int type) 847{ 848 if (! zclient->redist[type]) 849 return; 850 851 zclient->redist[type] = 0; 852 853 if (zclient->sock > 0) 854 zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type); 855} 856 857void 858zclient_redistribute_default_set (struct zclient *zclient) 859{ 860 if (zclient->default_information) 861 return; 862 863 zclient->default_information = 1; 864 865 if (zclient->sock > 0) 866 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD); 867} 868 869void 870zclient_redistribute_default_unset (struct zclient *zclient) 871{ 872 if (! zclient->default_information) 873 return; 874 875 zclient->default_information = 0; 876 877 if (zclient->sock > 0) 878 zebra_message_send (zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE); 879} 880 881extern struct thread_master *master; 882 883static void 884zclient_event (enum event event, struct zclient *zclient) 885{ 886 switch (event) 887 { 888 case ZCLIENT_SCHEDULE: 889 if (! zclient->t_connect) 890 zclient->t_connect = 891 thread_add_event (master, zclient_connect, zclient, 0); 892 break; 893 case ZCLIENT_CONNECT: 894 if (zclient->fail >= 10) 895 return; 896#ifdef FOX_RIP_DEBUG 897 if (zclient_debug) 898 zlog_info ("zclient connect schedule interval is %d", 899 zclient->fail < 3 ? 10 : 60); 900#endif /* FOX_RIP_DEBUG */ 901 if (! zclient->t_connect) 902 zclient->t_connect = 903 thread_add_timer (master, zclient_connect, zclient, 904 zclient->fail < 3 ? 10 : 60); 905 break; 906 case ZCLIENT_READ: 907 zclient->t_read = 908 thread_add_read (master, zclient_read, zclient, zclient->sock); 909 break; 910 } 911} 912