1/* 2 * Server side of OSPF API. 3 * Copyright (C) 2001, 2002 Ralph Keller 4 * 5 * This file is part of GNU Zebra. 6 * 7 * GNU Zebra is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published 9 * by the Free Software Foundation; either version 2, or (at your 10 * option) any 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 19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 * Boston, MA 02111-1307, USA. 21 */ 22 23#include <zebra.h> 24 25#ifdef SUPPORT_OSPF_API 26#ifndef HAVE_OPAQUE_LSA 27#error "Core Opaque-LSA module must be configured." 28#endif /* HAVE_OPAQUE_LSA */ 29 30#include "linklist.h" 31#include "prefix.h" 32#include "if.h" 33#include "table.h" 34#include "memory.h" 35#include "command.h" 36#include "vty.h" 37#include "stream.h" 38#include "log.h" 39#include "thread.h" 40#include "hash.h" 41#include "sockunion.h" /* for inet_aton() */ 42#include "buffer.h" 43 44#include <sys/types.h> 45 46#include "ospfd/ospfd.h" /* for "struct thread_master" */ 47#include "ospfd/ospf_interface.h" 48#include "ospfd/ospf_ism.h" 49#include "ospfd/ospf_asbr.h" 50#include "ospfd/ospf_lsa.h" 51#include "ospfd/ospf_lsdb.h" 52#include "ospfd/ospf_neighbor.h" 53#include "ospfd/ospf_nsm.h" 54#include "ospfd/ospf_flood.h" 55#include "ospfd/ospf_packet.h" 56#include "ospfd/ospf_spf.h" 57#include "ospfd/ospf_dump.h" 58#include "ospfd/ospf_route.h" 59#include "ospfd/ospf_ase.h" 60#include "ospfd/ospf_zebra.h" 61 62#include "ospfd/ospf_api.h" 63#include "ospfd/ospf_apiserver.h" 64 65/* This is an implementation of an API to the OSPF daemon that allows 66 * external applications to access the OSPF daemon through socket 67 * connections. The application can use this API to inject its own 68 * opaque LSAs and flood them to other OSPF daemons. Other OSPF 69 * daemons then receive these LSAs and inform applications through the 70 * API by sending a corresponding message. The application can also 71 * register to receive all LSA types (in addition to opaque types) and 72 * use this information to reconstruct the OSPF's LSDB. The OSPF 73 * daemon supports multiple applications concurrently. */ 74 75/* List of all active connections. */ 76struct list *apiserver_list; 77 78/* ----------------------------------------------------------- 79 * Functions to lookup interfaces 80 * ----------------------------------------------------------- 81 */ 82 83struct ospf_interface * 84ospf_apiserver_if_lookup_by_addr (struct in_addr address) 85{ 86 struct listnode *node, *nnode; 87 struct ospf_interface *oi; 88 struct ospf *ospf; 89 90 if (!(ospf = ospf_lookup ())) 91 return NULL; 92 93 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) 94 if (oi->type != OSPF_IFTYPE_VIRTUALLINK) 95 if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4)) 96 return oi; 97 98 return NULL; 99} 100 101struct ospf_interface * 102ospf_apiserver_if_lookup_by_ifp (struct interface *ifp) 103{ 104 struct listnode *node, *nnode; 105 struct ospf_interface *oi; 106 struct ospf *ospf; 107 108 if (!(ospf = ospf_lookup ())) 109 return NULL; 110 111 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) 112 if (oi->ifp == ifp) 113 return oi; 114 115 return NULL; 116} 117 118/* ----------------------------------------------------------- 119 * Initialization 120 * ----------------------------------------------------------- 121 */ 122 123unsigned short 124ospf_apiserver_getport (void) 125{ 126 struct servent *sp = getservbyname ("ospfapi", "tcp"); 127 128 return sp ? ntohs (sp->s_port) : OSPF_API_SYNC_PORT; 129} 130 131/* Initialize OSPF API module. Invoked from ospf_opaque_init() */ 132int 133ospf_apiserver_init (void) 134{ 135 int fd; 136 int rc = -1; 137 138 /* Create new socket for synchronous messages. */ 139 fd = ospf_apiserver_serv_sock_family (ospf_apiserver_getport (), AF_INET); 140 141 if (fd < 0) 142 goto out; 143 144 /* Schedule new thread that handles accepted connections. */ 145 ospf_apiserver_event (OSPF_APISERVER_ACCEPT, fd, NULL); 146 147 /* Initialize list that keeps track of all connections. */ 148 apiserver_list = list_new (); 149 150 /* Register opaque-independent call back functions. These functions 151 are invoked on ISM, NSM changes and LSA update and LSA deletes */ 152 rc = 153 ospf_register_opaque_functab (0 /* all LSAs */, 154 0 /* all opaque types */, 155 ospf_apiserver_new_if, 156 ospf_apiserver_del_if, 157 ospf_apiserver_ism_change, 158 ospf_apiserver_nsm_change, 159 NULL, 160 NULL, 161 NULL, 162 NULL, /* ospf_apiserver_show_info */ 163 NULL, /* originator_func */ 164 NULL, /* ospf_apiserver_lsa_refresher */ 165 ospf_apiserver_lsa_update, 166 ospf_apiserver_lsa_delete); 167 if (rc != 0) 168 { 169 zlog_warn ("ospf_apiserver_init: Failed to register opaque type [0/0]"); 170 } 171 172 rc = 0; 173 174out: 175 return rc; 176} 177 178/* Terminate OSPF API module. */ 179void 180ospf_apiserver_term (void) 181{ 182 struct ospf_apiserver *apiserv; 183 184 /* Unregister wildcard [0/0] type */ 185 ospf_delete_opaque_functab (0 /* all LSAs */, 186 0 /* all opaque types */); 187 188 /* 189 * Free all client instances. ospf_apiserver_free removes the node 190 * from the list, so we examine the head of the list anew each time. 191 */ 192 while ( apiserver_list && 193 (apiserv = listgetdata (listhead (apiserver_list))) != NULL) 194 ospf_apiserver_free (apiserv); 195 196 /* Free client list itself */ 197 if (apiserver_list) 198 list_delete (apiserver_list); 199 200 /* Free wildcard list */ 201 /* XXX */ 202} 203 204static struct ospf_apiserver * 205lookup_apiserver (u_char lsa_type, u_char opaque_type) 206{ 207 struct listnode *n1, *n2; 208 struct registered_opaque_type *r; 209 struct ospf_apiserver *apiserv, *found = NULL; 210 211 /* XXX: this approaches O(n**2) */ 212 for (ALL_LIST_ELEMENTS_RO (apiserver_list, n1, apiserv)) 213 { 214 for (ALL_LIST_ELEMENTS_RO (apiserv->opaque_types, n2, r)) 215 if (r->lsa_type == lsa_type && r->opaque_type == opaque_type) 216 { 217 found = apiserv; 218 goto out; 219 } 220 } 221out: 222 return found; 223} 224 225static struct ospf_apiserver * 226lookup_apiserver_by_lsa (struct ospf_lsa *lsa) 227{ 228 struct lsa_header *lsah = lsa->data; 229 struct ospf_apiserver *found = NULL; 230 231 if (IS_OPAQUE_LSA (lsah->type)) 232 { 233 found = lookup_apiserver (lsah->type, 234 GET_OPAQUE_TYPE (ntohl (lsah->id.s_addr))); 235 } 236 return found; 237} 238 239/* ----------------------------------------------------------- 240 * Followings are functions to manage client connections. 241 * ----------------------------------------------------------- 242 */ 243static int 244ospf_apiserver_new_lsa_hook (struct ospf_lsa *lsa) 245{ 246 if (IS_DEBUG_OSPF_EVENT) 247 zlog_debug ("API: Put LSA(%p)[%s] into reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total); 248 return 0; 249} 250 251static int 252ospf_apiserver_del_lsa_hook (struct ospf_lsa *lsa) 253{ 254 if (IS_DEBUG_OSPF_EVENT) 255 zlog_debug ("API: Get LSA(%p)[%s] from reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total); 256 return 0; 257} 258 259/* Allocate new connection structure. */ 260struct ospf_apiserver * 261ospf_apiserver_new (int fd_sync, int fd_async) 262{ 263 struct ospf_apiserver *new = 264 XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct ospf_apiserver)); 265 266 new->filter = 267 XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, sizeof (struct lsa_filter_type)); 268 269 new->fd_sync = fd_sync; 270 new->fd_async = fd_async; 271 272 /* list of registered opaque types that application uses */ 273 new->opaque_types = list_new (); 274 275 /* Initialize temporary strage for LSA instances to be refreshed. */ 276 memset (&new->reserve, 0, sizeof (struct ospf_lsdb)); 277 ospf_lsdb_init (&new->reserve); 278 279 new->reserve.new_lsa_hook = ospf_apiserver_new_lsa_hook; /* debug */ 280 new->reserve.del_lsa_hook = ospf_apiserver_del_lsa_hook; /* debug */ 281 282 new->out_sync_fifo = msg_fifo_new (); 283 new->out_async_fifo = msg_fifo_new (); 284 new->t_sync_read = NULL; 285#ifdef USE_ASYNC_READ 286 new->t_async_read = NULL; 287#endif /* USE_ASYNC_READ */ 288 new->t_sync_write = NULL; 289 new->t_async_write = NULL; 290 291 new->filter->typemask = 0; /* filter all LSAs */ 292 new->filter->origin = ANY_ORIGIN; 293 new->filter->num_areas = 0; 294 295 return new; 296} 297 298void 299ospf_apiserver_event (enum event event, int fd, 300 struct ospf_apiserver *apiserv) 301{ 302 switch (event) 303 { 304 case OSPF_APISERVER_ACCEPT: 305 (void)thread_add_read (master, ospf_apiserver_accept, apiserv, fd); 306 break; 307 case OSPF_APISERVER_SYNC_READ: 308 apiserv->t_sync_read = 309 thread_add_read (master, ospf_apiserver_read, apiserv, fd); 310 break; 311#ifdef USE_ASYNC_READ 312 case OSPF_APISERVER_ASYNC_READ: 313 apiserv->t_async_read = 314 thread_add_read (master, ospf_apiserver_read, apiserv, fd); 315 break; 316#endif /* USE_ASYNC_READ */ 317 case OSPF_APISERVER_SYNC_WRITE: 318 if (!apiserv->t_sync_write) 319 { 320 apiserv->t_sync_write = 321 thread_add_write (master, ospf_apiserver_sync_write, apiserv, fd); 322 } 323 break; 324 case OSPF_APISERVER_ASYNC_WRITE: 325 if (!apiserv->t_async_write) 326 { 327 apiserv->t_async_write = 328 thread_add_write (master, ospf_apiserver_async_write, apiserv, fd); 329 } 330 break; 331 } 332} 333 334/* Free instance. First unregister all opaque types used by 335 application, flush opaque LSAs injected by application 336 from network and close connection. */ 337void 338ospf_apiserver_free (struct ospf_apiserver *apiserv) 339{ 340 struct listnode *node; 341 342 /* Cancel read and write threads. */ 343 if (apiserv->t_sync_read) 344 { 345 thread_cancel (apiserv->t_sync_read); 346 } 347#ifdef USE_ASYNC_READ 348 if (apiserv->t_async_read) 349 { 350 thread_cancel (apiserv->t_async_read); 351 } 352#endif /* USE_ASYNC_READ */ 353 if (apiserv->t_sync_write) 354 { 355 thread_cancel (apiserv->t_sync_write); 356 } 357 358 if (apiserv->t_async_write) 359 { 360 thread_cancel (apiserv->t_async_write); 361 } 362 363 /* Unregister all opaque types that application registered 364 and flush opaque LSAs if still in LSDB. */ 365 366 while ((node = listhead (apiserv->opaque_types)) != NULL) 367 { 368 struct registered_opaque_type *regtype = listgetdata(node); 369 370 ospf_apiserver_unregister_opaque_type (apiserv, regtype->lsa_type, 371 regtype->opaque_type); 372 373 } 374 375 /* Close connections to OSPFd. */ 376 if (apiserv->fd_sync > 0) 377 { 378 close (apiserv->fd_sync); 379 } 380 381 if (apiserv->fd_async > 0) 382 { 383 close (apiserv->fd_async); 384 } 385 386 /* Free fifos */ 387 msg_fifo_free (apiserv->out_sync_fifo); 388 msg_fifo_free (apiserv->out_async_fifo); 389 390 /* Clear temporary strage for LSA instances to be refreshed. */ 391 ospf_lsdb_delete_all (&apiserv->reserve); 392 ospf_lsdb_cleanup (&apiserv->reserve); 393 394 /* Remove from the list of active clients. */ 395 listnode_delete (apiserver_list, apiserv); 396 397 if (IS_DEBUG_OSPF_EVENT) 398 zlog_debug ("API: Delete apiserv(%p), total#(%d)", apiserv, apiserver_list->count); 399 400 /* And free instance. */ 401 XFREE (MTYPE_OSPF_APISERVER, apiserv); 402} 403 404int 405ospf_apiserver_read (struct thread *thread) 406{ 407 struct ospf_apiserver *apiserv; 408 struct msg *msg; 409 int fd; 410 int rc = -1; 411 enum event event; 412 413 apiserv = THREAD_ARG (thread); 414 fd = THREAD_FD (thread); 415 416 if (fd == apiserv->fd_sync) 417 { 418 event = OSPF_APISERVER_SYNC_READ; 419 apiserv->t_sync_read = NULL; 420 421 if (IS_DEBUG_OSPF_EVENT) 422 zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u", 423 inet_ntoa (apiserv->peer_sync.sin_addr), 424 ntohs (apiserv->peer_sync.sin_port)); 425 } 426#ifdef USE_ASYNC_READ 427 else if (fd == apiserv->fd_async) 428 { 429 event = OSPF_APISERVER_ASYNC_READ; 430 apiserv->t_async_read = NULL; 431 432 if (IS_DEBUG_OSPF_EVENT) 433 zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u", 434 inet_ntoa (apiserv->peer_async.sin_addr), 435 ntohs (apiserv->peer_async.sin_port)); 436 } 437#endif /* USE_ASYNC_READ */ 438 else 439 { 440 zlog_warn ("ospf_apiserver_read: Unknown fd(%d)", fd); 441 ospf_apiserver_free (apiserv); 442 goto out; 443 } 444 445 /* Read message from fd. */ 446 msg = msg_read (fd); 447 if (msg == NULL) 448 { 449 zlog_warn 450 ("ospf_apiserver_read: read failed on fd=%d, closing connection", fd); 451 452 /* Perform cleanup. */ 453 ospf_apiserver_free (apiserv); 454 goto out; 455 } 456 457 if (IS_DEBUG_OSPF_EVENT) 458 msg_print (msg); 459 460 /* Dispatch to corresponding message handler. */ 461 rc = ospf_apiserver_handle_msg (apiserv, msg); 462 463 /* Prepare for next message, add read thread. */ 464 ospf_apiserver_event (event, fd, apiserv); 465 466 msg_free (msg); 467 468out: 469 return rc; 470} 471 472int 473ospf_apiserver_sync_write (struct thread *thread) 474{ 475 struct ospf_apiserver *apiserv; 476 struct msg *msg; 477 int fd; 478 int rc = -1; 479 480 apiserv = THREAD_ARG (thread); 481 assert (apiserv); 482 fd = THREAD_FD (thread); 483 484 apiserv->t_sync_write = NULL; 485 486 /* Sanity check */ 487 if (fd != apiserv->fd_sync) 488 { 489 zlog_warn ("ospf_apiserver_sync_write: Unknown fd=%d", fd); 490 goto out; 491 } 492 493 if (IS_DEBUG_OSPF_EVENT) 494 zlog_debug ("API: ospf_apiserver_sync_write: Peer: %s/%u", 495 inet_ntoa (apiserv->peer_sync.sin_addr), 496 ntohs (apiserv->peer_sync.sin_port)); 497 498 /* Check whether there is really a message in the fifo. */ 499 msg = msg_fifo_pop (apiserv->out_sync_fifo); 500 if (!msg) 501 { 502 zlog_warn ("API: ospf_apiserver_sync_write: No message in Sync-FIFO?"); 503 return 0; 504 } 505 506 if (IS_DEBUG_OSPF_EVENT) 507 msg_print (msg); 508 509 rc = msg_write (fd, msg); 510 511 /* Once a message is dequeued, it should be freed anyway. */ 512 msg_free (msg); 513 514 if (rc < 0) 515 { 516 zlog_warn 517 ("ospf_apiserver_sync_write: write failed on fd=%d", fd); 518 goto out; 519 } 520 521 522 /* If more messages are in sync message fifo, schedule write thread. */ 523 if (msg_fifo_head (apiserv->out_sync_fifo)) 524 { 525 ospf_apiserver_event (OSPF_APISERVER_SYNC_WRITE, apiserv->fd_sync, 526 apiserv); 527 } 528 529 out: 530 531 if (rc < 0) 532 { 533 /* Perform cleanup and disconnect with peer */ 534 ospf_apiserver_free (apiserv); 535 } 536 537 return rc; 538} 539 540 541int 542ospf_apiserver_async_write (struct thread *thread) 543{ 544 struct ospf_apiserver *apiserv; 545 struct msg *msg; 546 int fd; 547 int rc = -1; 548 549 apiserv = THREAD_ARG (thread); 550 assert (apiserv); 551 fd = THREAD_FD (thread); 552 553 apiserv->t_async_write = NULL; 554 555 /* Sanity check */ 556 if (fd != apiserv->fd_async) 557 { 558 zlog_warn ("ospf_apiserver_async_write: Unknown fd=%d", fd); 559 goto out; 560 } 561 562 if (IS_DEBUG_OSPF_EVENT) 563 zlog_debug ("API: ospf_apiserver_async_write: Peer: %s/%u", 564 inet_ntoa (apiserv->peer_async.sin_addr), 565 ntohs (apiserv->peer_async.sin_port)); 566 567 /* Check whether there is really a message in the fifo. */ 568 msg = msg_fifo_pop (apiserv->out_async_fifo); 569 if (!msg) 570 { 571 zlog_warn ("API: ospf_apiserver_async_write: No message in Async-FIFO?"); 572 return 0; 573 } 574 575 if (IS_DEBUG_OSPF_EVENT) 576 msg_print (msg); 577 578 rc = msg_write (fd, msg); 579 580 /* Once a message is dequeued, it should be freed anyway. */ 581 msg_free (msg); 582 583 if (rc < 0) 584 { 585 zlog_warn 586 ("ospf_apiserver_async_write: write failed on fd=%d", fd); 587 goto out; 588 } 589 590 591 /* If more messages are in async message fifo, schedule write thread. */ 592 if (msg_fifo_head (apiserv->out_async_fifo)) 593 { 594 ospf_apiserver_event (OSPF_APISERVER_ASYNC_WRITE, apiserv->fd_async, 595 apiserv); 596 } 597 598 out: 599 600 if (rc < 0) 601 { 602 /* Perform cleanup and disconnect with peer */ 603 ospf_apiserver_free (apiserv); 604 } 605 606 return rc; 607} 608 609 610int 611ospf_apiserver_serv_sock_family (unsigned short port, int family) 612{ 613 union sockunion su; 614 int accept_sock; 615 int rc; 616 617 memset (&su, 0, sizeof (union sockunion)); 618 su.sa.sa_family = family; 619 620 /* Make new socket */ 621 accept_sock = sockunion_stream_socket (&su); 622 if (accept_sock < 0) 623 return accept_sock; 624 625 /* This is a server, so reuse address and port */ 626 sockopt_reuseaddr (accept_sock); 627 sockopt_reuseport (accept_sock); 628 629 /* Bind socket to address and given port. */ 630 rc = sockunion_bind (accept_sock, &su, port, NULL); 631 if (rc < 0) 632 { 633 close (accept_sock); /* Close socket */ 634 return rc; 635 } 636 637 /* Listen socket under queue length 3. */ 638 rc = listen (accept_sock, 3); 639 if (rc < 0) 640 { 641 zlog_warn ("ospf_apiserver_serv_sock_family: listen: %s", 642 safe_strerror (errno)); 643 close (accept_sock); /* Close socket */ 644 return rc; 645 } 646 return accept_sock; 647} 648 649 650/* Accept connection request from external applications. For each 651 accepted connection allocate own connection instance. */ 652int 653ospf_apiserver_accept (struct thread *thread) 654{ 655 int accept_sock; 656 int new_sync_sock; 657 int new_async_sock; 658 union sockunion su; 659 struct ospf_apiserver *apiserv; 660 struct sockaddr_in peer_async; 661 struct sockaddr_in peer_sync; 662 unsigned int peerlen; 663 int ret; 664 665 /* THREAD_ARG (thread) is NULL */ 666 accept_sock = THREAD_FD (thread); 667 668 /* Keep hearing on socket for further connections. */ 669 ospf_apiserver_event (OSPF_APISERVER_ACCEPT, accept_sock, NULL); 670 671 memset (&su, 0, sizeof (union sockunion)); 672 /* Accept connection for synchronous messages */ 673 new_sync_sock = sockunion_accept (accept_sock, &su); 674 if (new_sync_sock < 0) 675 { 676 zlog_warn ("ospf_apiserver_accept: accept: %s", safe_strerror (errno)); 677 return -1; 678 } 679 680 /* Get port address and port number of peer to make reverse connection. 681 The reverse channel uses the port number of the peer port+1. */ 682 683 memset(&peer_sync, 0, sizeof(struct sockaddr_in)); 684 peerlen = sizeof (struct sockaddr_in); 685 686 ret = getpeername (new_sync_sock, (struct sockaddr *)&peer_sync, &peerlen); 687 if (ret < 0) 688 { 689 zlog_warn ("ospf_apiserver_accept: getpeername: %s", safe_strerror (errno)); 690 close (new_sync_sock); 691 return -1; 692 } 693 694 if (IS_DEBUG_OSPF_EVENT) 695 zlog_debug ("API: ospf_apiserver_accept: New peer: %s/%u", 696 inet_ntoa (peer_sync.sin_addr), ntohs (peer_sync.sin_port)); 697 698 /* Create new socket for asynchronous messages. */ 699 peer_async = peer_sync; 700 peer_async.sin_port = htons(ntohs(peer_sync.sin_port) + 1); 701 702 /* Check if remote port number to make reverse connection is valid one. */ 703 if (ntohs (peer_async.sin_port) == ospf_apiserver_getport ()) 704 { 705 zlog_warn ("API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?", 706 inet_ntoa (peer_async.sin_addr), ntohs (peer_async.sin_port)); 707 close (new_sync_sock); 708 return -1; 709 } 710 711 new_async_sock = socket (AF_INET, SOCK_STREAM, 0); 712 if (new_async_sock < 0) 713 { 714 zlog_warn ("ospf_apiserver_accept: socket: %s", safe_strerror (errno)); 715 close (new_sync_sock); 716 return -1; 717 } 718 719 ret = connect (new_async_sock, (struct sockaddr *) &peer_async, 720 sizeof (struct sockaddr_in)); 721 722 if (ret < 0) 723 { 724 zlog_warn ("ospf_apiserver_accept: connect: %s", safe_strerror (errno)); 725 close (new_sync_sock); 726 close (new_async_sock); 727 return -1; 728 } 729 730#ifdef USE_ASYNC_READ 731#else /* USE_ASYNC_READ */ 732 /* Make the asynchronous channel write-only. */ 733 ret = shutdown (new_async_sock, SHUT_RD); 734 if (ret < 0) 735 { 736 zlog_warn ("ospf_apiserver_accept: shutdown: %s", safe_strerror (errno)); 737 close (new_sync_sock); 738 close (new_async_sock); 739 return -1; 740 } 741#endif /* USE_ASYNC_READ */ 742 743 /* Allocate new server-side connection structure */ 744 apiserv = ospf_apiserver_new (new_sync_sock, new_async_sock); 745 746 /* Add to active connection list */ 747 listnode_add (apiserver_list, apiserv); 748 apiserv->peer_sync = peer_sync; 749 apiserv->peer_async = peer_async; 750 751 /* And add read threads for new connection */ 752 ospf_apiserver_event (OSPF_APISERVER_SYNC_READ, new_sync_sock, apiserv); 753#ifdef USE_ASYNC_READ 754 ospf_apiserver_event (OSPF_APISERVER_ASYNC_READ, new_async_sock, apiserv); 755#endif /* USE_ASYNC_READ */ 756 757 if (IS_DEBUG_OSPF_EVENT) 758 zlog_debug ("API: New apiserv(%p), total#(%d)", apiserv, apiserver_list->count); 759 760 return 0; 761} 762 763 764/* ----------------------------------------------------------- 765 * Send reply with return code to client application 766 * ----------------------------------------------------------- 767 */ 768 769static int 770ospf_apiserver_send_msg (struct ospf_apiserver *apiserv, struct msg *msg) 771{ 772 struct msg_fifo *fifo; 773 struct msg *msg2; 774 enum event event; 775 int fd; 776 777 switch (msg->hdr.msgtype) 778 { 779 case MSG_REPLY: 780 fifo = apiserv->out_sync_fifo; 781 fd = apiserv->fd_sync; 782 event = OSPF_APISERVER_SYNC_WRITE; 783 break; 784 case MSG_READY_NOTIFY: 785 case MSG_LSA_UPDATE_NOTIFY: 786 case MSG_LSA_DELETE_NOTIFY: 787 case MSG_NEW_IF: 788 case MSG_DEL_IF: 789 case MSG_ISM_CHANGE: 790 case MSG_NSM_CHANGE: 791 fifo = apiserv->out_async_fifo; 792 fd = apiserv->fd_async; 793 event = OSPF_APISERVER_ASYNC_WRITE; 794 break; 795 default: 796 zlog_warn ("ospf_apiserver_send_msg: Unknown message type %d", 797 msg->hdr.msgtype); 798 return -1; 799 } 800 801 /* Make a copy of the message and put in the fifo. Once the fifo 802 gets drained by the write thread, the message will be freed. */ 803 /* NB: Given "msg" is untouched in this function. */ 804 msg2 = msg_dup (msg); 805 806 /* Enqueue message into corresponding fifo queue */ 807 msg_fifo_push (fifo, msg2); 808 809 /* Schedule write thread */ 810 ospf_apiserver_event (event, fd, apiserv); 811 return 0; 812} 813 814int 815ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr, 816 u_char rc) 817{ 818 struct msg *msg = new_msg_reply (seqnr, rc); 819 int ret; 820 821 if (!msg) 822 { 823 zlog_warn ("ospf_apiserver_send_reply: msg_new failed"); 824#ifdef NOTYET 825 /* Cannot allocate new message. What should we do? */ 826 ospf_apiserver_free (apiserv); 827#endif 828 return -1; 829 } 830 831 ret = ospf_apiserver_send_msg (apiserv, msg); 832 msg_free (msg); 833 return ret; 834} 835 836 837/* ----------------------------------------------------------- 838 * Generic message dispatching handler function 839 * ----------------------------------------------------------- 840 */ 841 842int 843ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg) 844{ 845 int rc; 846 847 /* Call corresponding message handler function. */ 848 switch (msg->hdr.msgtype) 849 { 850 case MSG_REGISTER_OPAQUETYPE: 851 rc = ospf_apiserver_handle_register_opaque_type (apiserv, msg); 852 break; 853 case MSG_UNREGISTER_OPAQUETYPE: 854 rc = ospf_apiserver_handle_unregister_opaque_type (apiserv, msg); 855 break; 856 case MSG_REGISTER_EVENT: 857 rc = ospf_apiserver_handle_register_event (apiserv, msg); 858 break; 859 case MSG_SYNC_LSDB: 860 rc = ospf_apiserver_handle_sync_lsdb (apiserv, msg); 861 break; 862 case MSG_ORIGINATE_REQUEST: 863 rc = ospf_apiserver_handle_originate_request (apiserv, msg); 864 break; 865 case MSG_DELETE_REQUEST: 866 rc = ospf_apiserver_handle_delete_request (apiserv, msg); 867 break; 868 default: 869 zlog_warn ("ospf_apiserver_handle_msg: Unknown message type: %d", 870 msg->hdr.msgtype); 871 rc = -1; 872 } 873 return rc; 874} 875 876 877/* ----------------------------------------------------------- 878 * Following are functions for opaque type registration 879 * ----------------------------------------------------------- 880 */ 881 882int 883ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserv, 884 u_char lsa_type, u_char opaque_type) 885{ 886 struct registered_opaque_type *regtype; 887 int (*originator_func) (void *arg); 888 int rc; 889 890 switch (lsa_type) 891 { 892 case OSPF_OPAQUE_LINK_LSA: 893 originator_func = ospf_apiserver_lsa9_originator; 894 break; 895 case OSPF_OPAQUE_AREA_LSA: 896 originator_func = ospf_apiserver_lsa10_originator; 897 break; 898 case OSPF_OPAQUE_AS_LSA: 899 originator_func = ospf_apiserver_lsa11_originator; 900 break; 901 default: 902 zlog_warn ("ospf_apiserver_register_opaque_type: lsa_type(%d)", 903 lsa_type); 904 return OSPF_API_ILLEGALLSATYPE; 905 } 906 907 908 /* Register opaque function table */ 909 /* NB: Duplicated registration will be detected inside the function. */ 910 rc = 911 ospf_register_opaque_functab (lsa_type, opaque_type, 912 NULL, /* ospf_apiserver_new_if */ 913 NULL, /* ospf_apiserver_del_if */ 914 NULL, /* ospf_apiserver_ism_change */ 915 NULL, /* ospf_apiserver_nsm_change */ 916 NULL, 917 NULL, 918 NULL, 919 ospf_apiserver_show_info, 920 originator_func, 921 ospf_apiserver_lsa_refresher, 922 NULL, /* ospf_apiserver_lsa_update */ 923 NULL /* ospf_apiserver_lsa_delete */); 924 925 if (rc != 0) 926 { 927 zlog_warn ("Failed to register opaque type [%d/%d]", 928 lsa_type, opaque_type); 929 return OSPF_API_OPAQUETYPEINUSE; 930 } 931 932 /* Remember the opaque type that application registers so when 933 connection shuts down, we can flush all LSAs of this opaque 934 type. */ 935 936 regtype = 937 XCALLOC (MTYPE_OSPF_APISERVER, sizeof (struct registered_opaque_type)); 938 regtype->lsa_type = lsa_type; 939 regtype->opaque_type = opaque_type; 940 941 /* Add to list of registered opaque types */ 942 listnode_add (apiserv->opaque_types, regtype); 943 944 if (IS_DEBUG_OSPF_EVENT) 945 zlog_debug ("API: Add LSA-type(%d)/Opaque-type(%d) into" 946 " apiserv(%p), total#(%d)", 947 lsa_type, opaque_type, apiserv, 948 listcount (apiserv->opaque_types)); 949 950 return 0; 951} 952 953int 954ospf_apiserver_unregister_opaque_type (struct ospf_apiserver *apiserv, 955 u_char lsa_type, u_char opaque_type) 956{ 957 struct listnode *node, *nnode; 958 struct registered_opaque_type *regtype; 959 960 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) 961 { 962 /* Check if we really registered this opaque type */ 963 if (regtype->lsa_type == lsa_type && 964 regtype->opaque_type == opaque_type) 965 { 966 967 /* Yes, we registered this opaque type. Flush 968 all existing opaque LSAs of this type */ 969 970 ospf_apiserver_flush_opaque_lsa (apiserv, lsa_type, opaque_type); 971 ospf_delete_opaque_functab (lsa_type, opaque_type); 972 973 /* Remove from list of registered opaque types */ 974 listnode_delete (apiserv->opaque_types, regtype); 975 976 if (IS_DEBUG_OSPF_EVENT) 977 zlog_debug ("API: Del LSA-type(%d)/Opaque-type(%d)" 978 " from apiserv(%p), total#(%d)", 979 lsa_type, opaque_type, apiserv, 980 listcount (apiserv->opaque_types)); 981 982 return 0; 983 } 984 } 985 986 /* Opaque type is not registered */ 987 zlog_warn ("Failed to unregister opaque type [%d/%d]", 988 lsa_type, opaque_type); 989 return OSPF_API_OPAQUETYPENOTREGISTERED; 990} 991 992 993static int 994apiserver_is_opaque_type_registered (struct ospf_apiserver *apiserv, 995 u_char lsa_type, u_char opaque_type) 996{ 997 struct listnode *node, *nnode; 998 struct registered_opaque_type *regtype; 999 1000 /* XXX: how many types are there? if few, why not just a bitmap? */ 1001 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) 1002 { 1003 /* Check if we really registered this opaque type */ 1004 if (regtype->lsa_type == lsa_type && 1005 regtype->opaque_type == opaque_type) 1006 { 1007 /* Yes registered */ 1008 return 1; 1009 } 1010 } 1011 /* Not registered */ 1012 return 0; 1013} 1014 1015int 1016ospf_apiserver_handle_register_opaque_type (struct ospf_apiserver *apiserv, 1017 struct msg *msg) 1018{ 1019 struct msg_register_opaque_type *rmsg; 1020 u_char lsa_type; 1021 u_char opaque_type; 1022 int rc = 0; 1023 1024 /* Extract parameters from register opaque type message */ 1025 rmsg = (struct msg_register_opaque_type *) STREAM_DATA (msg->s); 1026 1027 lsa_type = rmsg->lsatype; 1028 opaque_type = rmsg->opaquetype; 1029 1030 rc = ospf_apiserver_register_opaque_type (apiserv, lsa_type, opaque_type); 1031 1032 /* Send a reply back to client including return code */ 1033 rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); 1034 if (rc < 0) 1035 goto out; 1036 1037 /* Now inform application about opaque types that are ready */ 1038 switch (lsa_type) 1039 { 1040 case OSPF_OPAQUE_LINK_LSA: 1041 ospf_apiserver_notify_ready_type9 (apiserv); 1042 break; 1043 case OSPF_OPAQUE_AREA_LSA: 1044 ospf_apiserver_notify_ready_type10 (apiserv); 1045 break; 1046 case OSPF_OPAQUE_AS_LSA: 1047 ospf_apiserver_notify_ready_type11 (apiserv); 1048 break; 1049 } 1050out: 1051 return rc; 1052} 1053 1054 1055/* Notify specific client about all opaque types 9 that are ready. */ 1056void 1057ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv) 1058{ 1059 struct listnode *node, *nnode; 1060 struct listnode *node2, *nnode2; 1061 struct ospf *ospf; 1062 struct ospf_interface *oi; 1063 struct registered_opaque_type *r; 1064 1065 ospf = ospf_lookup (); 1066 1067 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) 1068 { 1069 /* Check if this interface is indeed ready for type 9 */ 1070 if (!ospf_apiserver_is_ready_type9 (oi)) 1071 continue; 1072 1073 /* Check for registered opaque type 9 types */ 1074 /* XXX: loop-de-loop - optimise me */ 1075 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) 1076 { 1077 struct msg *msg; 1078 1079 if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) 1080 { 1081 1082 /* Yes, this opaque type is ready */ 1083 msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA, 1084 r->opaque_type, 1085 oi->address->u.prefix4); 1086 if (!msg) 1087 { 1088 zlog_warn ("apiserver_notify_ready_type9: msg_new failed"); 1089#ifdef NOTYET 1090 /* Cannot allocate new message. What should we do? */ 1091 ospf_apiserver_free (apiserv); 1092#endif 1093 goto out; 1094 } 1095 ospf_apiserver_send_msg (apiserv, msg); 1096 msg_free (msg); 1097 } 1098 } 1099 } 1100 1101out: 1102 return; 1103} 1104 1105 1106/* Notify specific client about all opaque types 10 that are ready. */ 1107void 1108ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv) 1109{ 1110 struct listnode *node, *nnode; 1111 struct listnode *node2, *nnode2; 1112 struct ospf *ospf; 1113 struct ospf_area *area; 1114 1115 ospf = ospf_lookup (); 1116 1117 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) 1118 { 1119 struct registered_opaque_type *r; 1120 1121 if (!ospf_apiserver_is_ready_type10 (area)) 1122 { 1123 continue; 1124 } 1125 1126 /* Check for registered opaque type 10 types */ 1127 /* XXX: loop in loop - optimise me */ 1128 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) 1129 { 1130 struct msg *msg; 1131 1132 if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) 1133 { 1134 /* Yes, this opaque type is ready */ 1135 msg = 1136 new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA, 1137 r->opaque_type, area->area_id); 1138 if (!msg) 1139 { 1140 zlog_warn ("apiserver_notify_ready_type10: msg_new failed"); 1141#ifdef NOTYET 1142 /* Cannot allocate new message. What should we do? */ 1143 ospf_apiserver_free (apiserv); 1144#endif 1145 goto out; 1146 } 1147 ospf_apiserver_send_msg (apiserv, msg); 1148 msg_free (msg); 1149 } 1150 } 1151 } 1152 1153out: 1154 return; 1155} 1156 1157/* Notify specific client about all opaque types 11 that are ready */ 1158void 1159ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv) 1160{ 1161 struct listnode *node, *nnode; 1162 struct ospf *ospf; 1163 struct registered_opaque_type *r; 1164 1165 ospf = ospf_lookup (); 1166 1167 /* Can type 11 be originated? */ 1168 if (!ospf_apiserver_is_ready_type11 (ospf)) 1169 goto out; 1170 1171 /* Check for registered opaque type 11 types */ 1172 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, r)) 1173 { 1174 struct msg *msg; 1175 struct in_addr noarea_id = { .s_addr = 0L }; 1176 1177 if (r->lsa_type == OSPF_OPAQUE_AS_LSA) 1178 { 1179 /* Yes, this opaque type is ready */ 1180 msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA, 1181 r->opaque_type, noarea_id); 1182 1183 if (!msg) 1184 { 1185 zlog_warn ("apiserver_notify_ready_type11: msg_new failed"); 1186#ifdef NOTYET 1187 /* Cannot allocate new message. What should we do? */ 1188 ospf_apiserver_free (apiserv); 1189#endif 1190 goto out; 1191 } 1192 ospf_apiserver_send_msg (apiserv, msg); 1193 msg_free (msg); 1194 } 1195 } 1196 1197out: 1198 return; 1199} 1200 1201int 1202ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv, 1203 struct msg *msg) 1204{ 1205 struct msg_unregister_opaque_type *umsg; 1206 u_char ltype; 1207 u_char otype; 1208 int rc = 0; 1209 1210 /* Extract parameters from unregister opaque type message */ 1211 umsg = (struct msg_unregister_opaque_type *) STREAM_DATA (msg->s); 1212 1213 ltype = umsg->lsatype; 1214 otype = umsg->opaquetype; 1215 1216 rc = ospf_apiserver_unregister_opaque_type (apiserv, ltype, otype); 1217 1218 /* Send a reply back to client including return code */ 1219 rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); 1220 1221 return rc; 1222} 1223 1224 1225/* ----------------------------------------------------------- 1226 * Following are functions for event (filter) registration. 1227 * ----------------------------------------------------------- 1228 */ 1229int 1230ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, 1231 struct msg *msg) 1232{ 1233 struct msg_register_event *rmsg; 1234 int rc; 1235 u_int32_t seqnum; 1236 1237 rmsg = (struct msg_register_event *) STREAM_DATA (msg->s); 1238 1239 /* Get request sequence number */ 1240 seqnum = msg_get_seq (msg); 1241 1242 /* Free existing filter in apiserv. */ 1243 XFREE (MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter); 1244 /* Alloc new space for filter. */ 1245 1246 apiserv->filter = XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, 1247 ntohs (msg->hdr.msglen)); 1248 if (apiserv->filter) 1249 { 1250 /* copy it over. */ 1251 memcpy (apiserv->filter, &rmsg->filter, ntohs (msg->hdr.msglen)); 1252 rc = OSPF_API_OK; 1253 } 1254 else 1255 { 1256 rc = OSPF_API_NOMEMORY; 1257 } 1258 /* Send a reply back to client with return code */ 1259 rc = ospf_apiserver_send_reply (apiserv, seqnum, rc); 1260 return rc; 1261} 1262 1263 1264/* ----------------------------------------------------------- 1265 * Followings are functions for LSDB synchronization. 1266 * ----------------------------------------------------------- 1267 */ 1268 1269static int 1270apiserver_sync_callback (struct ospf_lsa *lsa, void *p_arg, int int_arg) 1271{ 1272 struct ospf_apiserver *apiserv; 1273 int seqnum; 1274 struct msg *msg; 1275 struct param_t 1276 { 1277 struct ospf_apiserver *apiserv; 1278 struct lsa_filter_type *filter; 1279 } 1280 *param; 1281 int rc = -1; 1282 1283 /* Sanity check */ 1284 assert (lsa->data); 1285 assert (p_arg); 1286 1287 param = (struct param_t *) p_arg; 1288 apiserv = param->apiserv; 1289 seqnum = (u_int32_t) int_arg; 1290 1291 /* Check origin in filter. */ 1292 if ((param->filter->origin == ANY_ORIGIN) || 1293 (param->filter->origin == (lsa->flags & OSPF_LSA_SELF))) 1294 { 1295 1296 /* Default area for AS-External and Opaque11 LSAs */ 1297 struct in_addr area_id = { .s_addr = 0L }; 1298 1299 /* Default interface for non Opaque9 LSAs */ 1300 struct in_addr ifaddr = { .s_addr = 0L }; 1301 1302 if (lsa->area) 1303 { 1304 area_id = lsa->area->area_id; 1305 } 1306 if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) 1307 { 1308 ifaddr = lsa->oi->address->u.prefix4; 1309 } 1310 1311 msg = new_msg_lsa_change_notify (MSG_LSA_UPDATE_NOTIFY, 1312 seqnum, 1313 ifaddr, area_id, 1314 lsa->flags & OSPF_LSA_SELF, lsa->data); 1315 if (!msg) 1316 { 1317 zlog_warn ("apiserver_sync_callback: new_msg_update failed"); 1318#ifdef NOTYET 1319 /* Cannot allocate new message. What should we do? */ 1320/* ospf_apiserver_free (apiserv);*//* Do nothing here XXX */ 1321#endif 1322 goto out; 1323 } 1324 1325 /* Send LSA */ 1326 ospf_apiserver_send_msg (apiserv, msg); 1327 msg_free (msg); 1328 } 1329 rc = 0; 1330 1331out: 1332 return rc; 1333} 1334 1335int 1336ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, 1337 struct msg *msg) 1338{ 1339 struct listnode *node, *nnode; 1340 u_int32_t seqnum; 1341 int rc = 0; 1342 struct msg_sync_lsdb *smsg; 1343 struct ospf_apiserver_param_t 1344 { 1345 struct ospf_apiserver *apiserv; 1346 struct lsa_filter_type *filter; 1347 } param; 1348 u_int16_t mask; 1349 struct route_node *rn; 1350 struct ospf_lsa *lsa; 1351 struct ospf *ospf; 1352 struct ospf_area *area; 1353 1354 ospf = ospf_lookup (); 1355 1356 /* Get request sequence number */ 1357 seqnum = msg_get_seq (msg); 1358 /* Set sync msg. */ 1359 smsg = (struct msg_sync_lsdb *) STREAM_DATA (msg->s); 1360 1361 /* Set parameter struct. */ 1362 param.apiserv = apiserv; 1363 param.filter = &smsg->filter; 1364 1365 /* Remember mask. */ 1366 mask = ntohs (smsg->filter.typemask); 1367 1368 /* Iterate over all areas. */ 1369 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) 1370 { 1371 int i; 1372 u_int32_t *area_id = NULL; 1373 1374 /* Compare area_id with area_ids in sync request. */ 1375 if ((i = smsg->filter.num_areas) > 0) 1376 { 1377 /* Let area_id point to the list of area IDs, 1378 * which is at the end of smsg->filter. */ 1379 area_id = (u_int32_t *) (&smsg->filter + 1); 1380 while (i) 1381 { 1382 if (*area_id == area->area_id.s_addr) 1383 { 1384 break; 1385 } 1386 i--; 1387 area_id++; 1388 } 1389 } 1390 else 1391 { 1392 i = 1; 1393 } 1394 1395 /* If area was found, then i>0 here. */ 1396 if (i) 1397 { 1398 /* Check msg type. */ 1399 if (mask & Power2[OSPF_ROUTER_LSA]) 1400 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa) 1401 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1402 if (mask & Power2[OSPF_NETWORK_LSA]) 1403 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) 1404 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1405 if (mask & Power2[OSPF_SUMMARY_LSA]) 1406 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) 1407 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1408 if (mask & Power2[OSPF_ASBR_SUMMARY_LSA]) 1409 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) 1410 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1411 if (mask & Power2[OSPF_OPAQUE_LINK_LSA]) 1412 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) 1413 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1414 if (mask & Power2[OSPF_OPAQUE_AREA_LSA]) 1415 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) 1416 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1417 } 1418 } 1419 1420 /* For AS-external LSAs */ 1421 if (ospf->lsdb) 1422 { 1423 if (mask & Power2[OSPF_AS_EXTERNAL_LSA]) 1424 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) 1425 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1426 } 1427 1428 /* For AS-external opaque LSAs */ 1429 if (ospf->lsdb) 1430 { 1431 if (mask & Power2[OSPF_OPAQUE_AS_LSA]) 1432 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa) 1433 apiserver_sync_callback(lsa, (void *) ¶m, seqnum); 1434 } 1435 1436 /* Send a reply back to client with return code */ 1437 rc = ospf_apiserver_send_reply (apiserv, seqnum, rc); 1438 return rc; 1439} 1440 1441 1442/* ----------------------------------------------------------- 1443 * Followings are functions to originate or update LSA 1444 * from an application. 1445 * ----------------------------------------------------------- 1446 */ 1447 1448/* Create a new internal opaque LSA by taking prototype and filling in 1449 missing fields such as age, sequence number, advertising router, 1450 checksum and so on. The interface parameter is used for type 9 1451 LSAs, area parameter for type 10. Type 11 LSAs do neither need area 1452 nor interface. */ 1453 1454struct ospf_lsa * 1455ospf_apiserver_opaque_lsa_new (struct ospf_area *area, 1456 struct ospf_interface *oi, 1457 struct lsa_header *protolsa) 1458{ 1459 struct stream *s; 1460 struct lsa_header *newlsa; 1461 struct ospf_lsa *new = NULL; 1462 u_char options = 0x0; 1463 u_int16_t length; 1464 1465 struct ospf *ospf; 1466 1467 ospf = ospf_lookup(); 1468 assert(ospf); 1469 1470 /* Create a stream for internal opaque LSA */ 1471 if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL) 1472 { 1473 zlog_warn ("ospf_apiserver_opaque_lsa_new: stream_new failed"); 1474 return NULL; 1475 } 1476 1477 newlsa = (struct lsa_header *) STREAM_DATA (s); 1478 1479 /* XXX If this is a link-local LSA or an AS-external LSA, how do we 1480 have to set options? */ 1481 1482 if (area) 1483 { 1484 options = LSA_OPTIONS_GET (area); 1485 options |= LSA_OPTIONS_NSSA_GET (area); 1486 } 1487 1488 options |= OSPF_OPTION_O; /* Don't forget to set option bit */ 1489 1490 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) 1491 { 1492 zlog_debug ("LSA[Type%d:%s]: Creating an Opaque-LSA instance", 1493 protolsa->type, inet_ntoa (protolsa->id)); 1494 } 1495 1496 /* Set opaque-LSA header fields. */ 1497 lsa_header_set (s, options, protolsa->type, protolsa->id, 1498 ospf->router_id); 1499 1500 /* Set opaque-LSA body fields. */ 1501 stream_put (s, ((u_char *) protolsa) + sizeof (struct lsa_header), 1502 ntohs (protolsa->length) - sizeof (struct lsa_header)); 1503 1504 /* Determine length of LSA. */ 1505 length = stream_get_endp (s); 1506 newlsa->length = htons (length); 1507 1508 /* Create OSPF LSA. */ 1509 if ((new = ospf_lsa_new ()) == NULL) 1510 { 1511 zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_new() ?"); 1512 stream_free (s); 1513 return NULL; 1514 } 1515 1516 if ((new->data = ospf_lsa_data_new (length)) == NULL) 1517 { 1518 zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_data_new() ?"); 1519 ospf_lsa_unlock (&new); 1520 stream_free (s); 1521 return NULL; 1522 } 1523 1524 new->area = area; 1525 new->oi = oi; 1526 1527 SET_FLAG (new->flags, OSPF_LSA_SELF); 1528 memcpy (new->data, newlsa, length); 1529 stream_free (s); 1530 1531 return new; 1532} 1533 1534 1535int 1536ospf_apiserver_is_ready_type9 (struct ospf_interface *oi) 1537{ 1538 /* Type 9 opaque LSA can be originated if there is at least one 1539 active opaque-capable neighbor attached to the outgoing 1540 interface. */ 1541 1542 return (ospf_nbr_count_opaque_capable (oi) > 0); 1543} 1544 1545int 1546ospf_apiserver_is_ready_type10 (struct ospf_area *area) 1547{ 1548 /* Type 10 opaque LSA can be originated if there is at least one 1549 interface belonging to the area that has an active opaque-capable 1550 neighbor. */ 1551 struct listnode *node, *nnode; 1552 struct ospf_interface *oi; 1553 1554 for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) 1555 /* Is there an active neighbor attached to this interface? */ 1556 if (ospf_apiserver_is_ready_type9 (oi)) 1557 return 1; 1558 1559 /* No active neighbor in area */ 1560 return 0; 1561} 1562 1563int 1564ospf_apiserver_is_ready_type11 (struct ospf *ospf) 1565{ 1566 /* Type 11 opaque LSA can be originated if there is at least one interface 1567 that has an active opaque-capable neighbor. */ 1568 struct listnode *node, *nnode; 1569 struct ospf_interface *oi; 1570 1571 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) 1572 /* Is there an active neighbor attached to this interface? */ 1573 if (ospf_apiserver_is_ready_type9 (oi)) 1574 return 1; 1575 1576 /* No active neighbor at all */ 1577 return 0; 1578} 1579 1580 1581int 1582ospf_apiserver_handle_originate_request (struct ospf_apiserver *apiserv, 1583 struct msg *msg) 1584{ 1585 struct msg_originate_request *omsg; 1586 struct lsa_header *data; 1587 struct ospf_lsa *new; 1588 struct ospf_lsa *old; 1589 struct ospf_area *area = NULL; 1590 struct ospf_interface *oi = NULL; 1591 struct ospf_lsdb *lsdb = NULL; 1592 struct ospf *ospf; 1593 int lsa_type, opaque_type; 1594 int ready = 0; 1595 int rc = 0; 1596 1597 ospf = ospf_lookup(); 1598 1599 /* Extract opaque LSA data from message */ 1600 omsg = (struct msg_originate_request *) STREAM_DATA (msg->s); 1601 data = &omsg->data; 1602 1603 /* Determine interface for type9 or area for type10 LSAs. */ 1604 switch (data->type) 1605 { 1606 case OSPF_OPAQUE_LINK_LSA: 1607 oi = ospf_apiserver_if_lookup_by_addr (omsg->ifaddr); 1608 if (!oi) 1609 { 1610 zlog_warn ("apiserver_originate: unknown interface %s", 1611 inet_ntoa (omsg->ifaddr)); 1612 rc = OSPF_API_NOSUCHINTERFACE; 1613 goto out; 1614 } 1615 area = oi->area; 1616 lsdb = area->lsdb; 1617 break; 1618 case OSPF_OPAQUE_AREA_LSA: 1619 area = ospf_area_lookup_by_area_id (ospf, omsg->area_id); 1620 if (!area) 1621 { 1622 zlog_warn ("apiserver_originate: unknown area %s", 1623 inet_ntoa (omsg->area_id)); 1624 rc = OSPF_API_NOSUCHAREA; 1625 goto out; 1626 } 1627 lsdb = area->lsdb; 1628 break; 1629 case OSPF_OPAQUE_AS_LSA: 1630 lsdb = ospf->lsdb; 1631 break; 1632 default: 1633 /* We can only handle opaque types here */ 1634 zlog_warn ("apiserver_originate: Cannot originate non-opaque LSA type %d", 1635 data->type); 1636 rc = OSPF_API_ILLEGALLSATYPE; 1637 goto out; 1638 } 1639 1640 /* Check if we registered this opaque type */ 1641 lsa_type = data->type; 1642 opaque_type = GET_OPAQUE_TYPE (ntohl (data->id.s_addr)); 1643 1644 if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type)) 1645 { 1646 zlog_warn ("apiserver_originate: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type); 1647 rc = OSPF_API_OPAQUETYPENOTREGISTERED; 1648 goto out; 1649 } 1650 1651 /* Make sure that the neighbors are ready before we can originate */ 1652 switch (data->type) 1653 { 1654 case OSPF_OPAQUE_LINK_LSA: 1655 ready = ospf_apiserver_is_ready_type9 (oi); 1656 break; 1657 case OSPF_OPAQUE_AREA_LSA: 1658 ready = ospf_apiserver_is_ready_type10 (area); 1659 break; 1660 case OSPF_OPAQUE_AS_LSA: 1661 ready = ospf_apiserver_is_ready_type11 (ospf); 1662 break; 1663 default: 1664 break; 1665 } 1666 1667 if (!ready) 1668 { 1669 zlog_warn ("Neighbors not ready to originate type %d", data->type); 1670 rc = OSPF_API_NOTREADY; 1671 goto out; 1672 } 1673 1674 /* Create OSPF's internal opaque LSA representation */ 1675 new = ospf_apiserver_opaque_lsa_new (area, oi, data); 1676 if (!new) 1677 { 1678 rc = OSPF_API_NOMEMORY; /* XXX */ 1679 goto out; 1680 } 1681 1682 /* Determine if LSA is new or an update for an existing one. */ 1683 old = ospf_lsdb_lookup (lsdb, new); 1684 1685 if (!old) 1686 { 1687 /* New LSA install in LSDB. */ 1688 rc = ospf_apiserver_originate1 (new); 1689 } 1690 else 1691 { 1692 /* 1693 * Keep the new LSA instance in the "waiting place" until the next 1694 * refresh timing. If several LSA update requests for the same LSID 1695 * have issued by peer, the last one takes effect. 1696 */ 1697 new->lsdb = &apiserv->reserve; 1698 ospf_lsdb_add (&apiserv->reserve, new); 1699 1700 /* Kick the scheduler function. */ 1701 ospf_opaque_lsa_refresh_schedule (old); 1702 } 1703 1704out: 1705 1706 /* Send a reply back to client with return code */ 1707 rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); 1708 return rc; 1709} 1710 1711 1712/* ----------------------------------------------------------- 1713 * Flood an LSA within its flooding scope. 1714 * ----------------------------------------------------------- 1715 */ 1716 1717/* XXX We can probably use ospf_flood_through instead of this function 1718 but then we need the neighbor parameter. If we set nbr to 1719 NULL then ospf_flood_through crashes due to dereferencing NULL. */ 1720 1721void 1722ospf_apiserver_flood_opaque_lsa (struct ospf_lsa *lsa) 1723{ 1724 assert (lsa); 1725 1726 switch (lsa->data->type) 1727 { 1728 case OSPF_OPAQUE_LINK_LSA: 1729 /* Increment counters? XXX */ 1730 1731 /* Flood LSA through local network. */ 1732 ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa); 1733 break; 1734 case OSPF_OPAQUE_AREA_LSA: 1735 /* Update LSA origination count. */ 1736 assert (lsa->area); 1737 lsa->area->ospf->lsa_originate_count++; 1738 1739 /* Flood LSA through area. */ 1740 ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa); 1741 break; 1742 case OSPF_OPAQUE_AS_LSA: 1743 { 1744 struct ospf *ospf; 1745 1746 ospf = ospf_lookup(); 1747 assert(ospf); 1748 1749 /* Increment counters? XXX */ 1750 1751 /* Flood LSA through AS. */ 1752 ospf_flood_through_as (ospf, NULL /*nbr */ , lsa); 1753 break; 1754 } 1755 } 1756} 1757 1758int 1759ospf_apiserver_originate1 (struct ospf_lsa *lsa) 1760{ 1761 struct ospf *ospf; 1762 1763 ospf = ospf_lookup(); 1764 assert(ospf); 1765 1766 /* Install this LSA into LSDB. */ 1767 if (ospf_lsa_install (ospf, lsa->oi, lsa) == NULL) 1768 { 1769 zlog_warn ("ospf_apiserver_originate1: ospf_lsa_install failed"); 1770 return -1; 1771 } 1772 1773 /* Flood LSA within scope */ 1774 1775#ifdef NOTYET 1776 /* 1777 * NB: Modified version of "ospf_flood_though ()" accepts NULL "inbr" 1778 * parameter, and thus it does not cause SIGSEGV error. 1779 */ 1780 ospf_flood_through (NULL /*nbr */ , lsa); 1781#else /* NOTYET */ 1782 1783 ospf_apiserver_flood_opaque_lsa (lsa); 1784#endif /* NOTYET */ 1785 1786 return 0; 1787} 1788 1789 1790/* Opaque LSAs of type 9 on a specific interface can now be 1791 originated. Tell clients that registered type 9. */ 1792int 1793ospf_apiserver_lsa9_originator (void *arg) 1794{ 1795 struct ospf_interface *oi; 1796 1797 oi = (struct ospf_interface *) arg; 1798 if (listcount (apiserver_list) > 0) { 1799 ospf_apiserver_clients_notify_ready_type9 (oi); 1800 } 1801 return 0; 1802} 1803 1804int 1805ospf_apiserver_lsa10_originator (void *arg) 1806{ 1807 struct ospf_area *area; 1808 1809 area = (struct ospf_area *) arg; 1810 if (listcount (apiserver_list) > 0) { 1811 ospf_apiserver_clients_notify_ready_type10 (area); 1812 } 1813 return 0; 1814} 1815 1816int 1817ospf_apiserver_lsa11_originator (void *arg) 1818{ 1819 struct ospf *ospf; 1820 1821 ospf = (struct ospf *) arg; 1822 if (listcount (apiserver_list) > 0) { 1823 ospf_apiserver_clients_notify_ready_type11 (ospf); 1824 } 1825 return 0; 1826} 1827 1828 1829/* Periodically refresh opaque LSAs so that they do not expire in 1830 other routers. */ 1831struct ospf_lsa * 1832ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa) 1833{ 1834 struct ospf_apiserver *apiserv; 1835 struct ospf_lsa *new = NULL; 1836 struct ospf * ospf; 1837 1838 ospf = ospf_lookup(); 1839 assert(ospf); 1840 1841 apiserv = lookup_apiserver_by_lsa (lsa); 1842 if (!apiserv) 1843 { 1844 zlog_warn ("ospf_apiserver_lsa_refresher: LSA[%s]: No apiserver?", dump_lsa_key (lsa)); 1845 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */ 1846 } 1847 1848 if (IS_LSA_MAXAGE (lsa)) 1849 { 1850 ospf_opaque_lsa_flush_schedule (lsa); 1851 goto out; 1852 } 1853 1854 /* Check if updated version of LSA instance has already prepared. */ 1855 new = ospf_lsdb_lookup (&apiserv->reserve, lsa); 1856 if (!new) 1857 { 1858 /* This is a periodic refresh, driven by core OSPF mechanism. */ 1859 new = ospf_apiserver_opaque_lsa_new (lsa->area, lsa->oi, lsa->data); 1860 if (!new) 1861 { 1862 zlog_warn ("ospf_apiserver_lsa_refresher: Cannot create a new LSA?"); 1863 goto out; 1864 } 1865 } 1866 else 1867 { 1868 /* This is a forcible refresh, requested by OSPF-API client. */ 1869 ospf_lsdb_delete (&apiserv->reserve, new); 1870 new->lsdb = NULL; 1871 } 1872 1873 /* Increment sequence number */ 1874 new->data->ls_seqnum = lsa_seqnum_increment (lsa); 1875 1876 /* New LSA is in same area. */ 1877 new->area = lsa->area; 1878 SET_FLAG (new->flags, OSPF_LSA_SELF); 1879 1880 /* Install LSA into LSDB. */ 1881 if (ospf_lsa_install (ospf, new->oi, new) == NULL) 1882 { 1883 zlog_warn ("ospf_apiserver_lsa_refresher: ospf_lsa_install failed"); 1884 ospf_lsa_unlock (&new); 1885 goto out; 1886 } 1887 1888 /* Flood updated LSA through interface, area or AS */ 1889 1890#ifdef NOTYET 1891 ospf_flood_through (NULL /*nbr */ , new); 1892#endif /* NOTYET */ 1893 ospf_apiserver_flood_opaque_lsa (new); 1894 1895 /* Debug logging. */ 1896 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) 1897 { 1898 zlog_debug ("LSA[Type%d:%s]: Refresh Opaque LSA", 1899 new->data->type, inet_ntoa (new->data->id)); 1900 ospf_lsa_header_dump (new->data); 1901 } 1902 1903out: 1904 return new; 1905} 1906 1907 1908/* ----------------------------------------------------------- 1909 * Followings are functions to delete LSAs 1910 * ----------------------------------------------------------- 1911 */ 1912 1913int 1914ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv, 1915 struct msg *msg) 1916{ 1917 struct msg_delete_request *dmsg; 1918 struct ospf_lsa *old; 1919 struct ospf_area *area = NULL; 1920 struct in_addr id; 1921 int lsa_type, opaque_type; 1922 int rc = 0; 1923 struct ospf * ospf; 1924 1925 ospf = ospf_lookup(); 1926 assert(ospf); 1927 1928 /* Extract opaque LSA from message */ 1929 dmsg = (struct msg_delete_request *) STREAM_DATA (msg->s); 1930 1931 /* Lookup area for link-local and area-local opaque LSAs */ 1932 switch (dmsg->lsa_type) 1933 { 1934 case OSPF_OPAQUE_LINK_LSA: 1935 case OSPF_OPAQUE_AREA_LSA: 1936 area = ospf_area_lookup_by_area_id (ospf, dmsg->area_id); 1937 if (!area) 1938 { 1939 zlog_warn ("ospf_apiserver_lsa_delete: unknown area %s", 1940 inet_ntoa (dmsg->area_id)); 1941 rc = OSPF_API_NOSUCHAREA; 1942 goto out; 1943 } 1944 break; 1945 case OSPF_OPAQUE_AS_LSA: 1946 /* AS-external opaque LSAs have no designated area */ 1947 area = NULL; 1948 break; 1949 default: 1950 zlog_warn 1951 ("ospf_apiserver_lsa_delete: Cannot delete non-opaque LSA type %d", 1952 dmsg->lsa_type); 1953 rc = OSPF_API_ILLEGALLSATYPE; 1954 goto out; 1955 } 1956 1957 /* Check if we registered this opaque type */ 1958 lsa_type = dmsg->lsa_type; 1959 opaque_type = dmsg->opaque_type; 1960 1961 if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type)) 1962 { 1963 zlog_warn ("ospf_apiserver_lsa_delete: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type); 1964 rc = OSPF_API_OPAQUETYPENOTREGISTERED; 1965 goto out; 1966 } 1967 1968 /* opaque_id is in network byte order */ 1969 id.s_addr = htonl (SET_OPAQUE_LSID (dmsg->opaque_type, 1970 ntohl (dmsg->opaque_id))); 1971 1972 /* 1973 * Even if the target LSA has once scheduled to flush, it remains in 1974 * the LSDB until it is finally handled by the maxage remover thread. 1975 * Therefore, the lookup function below may return non-NULL result. 1976 */ 1977 old = ospf_lsa_lookup (area, dmsg->lsa_type, id, ospf->router_id); 1978 if (!old) 1979 { 1980 zlog_warn ("ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB", 1981 dmsg->lsa_type, inet_ntoa (id)); 1982 rc = OSPF_API_NOSUCHLSA; 1983 goto out; 1984 } 1985 1986 /* Schedule flushing of LSA from LSDB */ 1987 /* NB: Multiple scheduling will produce a warning message, but harmless. */ 1988 ospf_opaque_lsa_flush_schedule (old); 1989 1990out: 1991 1992 /* Send reply back to client including return code */ 1993 rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc); 1994 return rc; 1995} 1996 1997/* Flush self-originated opaque LSA */ 1998static int 1999apiserver_flush_opaque_type_callback (struct ospf_lsa *lsa, 2000 void *p_arg, int int_arg) 2001{ 2002 struct param_t 2003 { 2004 struct ospf_apiserver *apiserv; 2005 u_char lsa_type; 2006 u_char opaque_type; 2007 } 2008 *param; 2009 2010 /* Sanity check */ 2011 assert (lsa->data); 2012 assert (p_arg); 2013 param = (struct param_t *) p_arg; 2014 2015 /* If LSA matches type and opaque type then delete it */ 2016 if (IS_LSA_SELF (lsa) && lsa->data->type == param->lsa_type 2017 && GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)) == param->opaque_type) 2018 { 2019 ospf_opaque_lsa_flush_schedule (lsa); 2020 } 2021 return 0; 2022} 2023 2024/* Delete self-originated opaque LSAs of a given opaque type. This 2025 function is called when an application unregisters a given opaque 2026 type or a connection to an application closes and all those opaque 2027 LSAs need to be flushed the LSDB. */ 2028void 2029ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv, 2030 u_char lsa_type, u_char opaque_type) 2031{ 2032 struct param_t 2033 { 2034 struct ospf_apiserver *apiserv; 2035 u_char lsa_type; 2036 u_char opaque_type; 2037 } param; 2038 struct listnode *node, *nnode; 2039 struct ospf * ospf; 2040 struct ospf_area *area; 2041 2042 ospf = ospf_lookup(); 2043 assert(ospf); 2044 2045 /* Set parameter struct. */ 2046 param.apiserv = apiserv; 2047 param.lsa_type = lsa_type; 2048 param.opaque_type = opaque_type; 2049 2050 switch (lsa_type) 2051 { 2052 struct route_node *rn; 2053 struct ospf_lsa *lsa; 2054 2055 case OSPF_OPAQUE_LINK_LSA: 2056 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) 2057 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) 2058 apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); 2059 break; 2060 case OSPF_OPAQUE_AREA_LSA: 2061 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) 2062 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) 2063 apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); 2064 break; 2065 case OSPF_OPAQUE_AS_LSA: 2066 LSDB_LOOP (OPAQUE_LINK_LSDB (ospf), rn, lsa) 2067 apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); 2068 break; 2069 default: 2070 break; 2071 } 2072 return; 2073} 2074 2075 2076/* ----------------------------------------------------------- 2077 * Followings are callback functions to handle opaque types 2078 * ----------------------------------------------------------- 2079 */ 2080 2081int 2082ospf_apiserver_new_if (struct interface *ifp) 2083{ 2084 struct ospf_interface *oi; 2085 2086 /* For some strange reason it seems possible that we are invoked 2087 with an interface that has no name. This seems to happen during 2088 initialization. Return if this happens */ 2089 2090 if (ifp->name[0] == '\0') { 2091 /* interface has empty name */ 2092 zlog_warn ("ospf_apiserver_new_if: interface has no name?"); 2093 return 0; 2094 } 2095 2096 /* zlog_warn for debugging */ 2097 zlog_warn ("ospf_apiserver_new_if"); 2098 zlog_warn ("ifp name=%s status=%d index=%d", ifp->name, ifp->status, 2099 ifp->ifindex); 2100 2101 if (ifp->name[0] == '\0') { 2102 /* interface has empty name */ 2103 zlog_warn ("ospf_apiserver_new_if: interface has no name?"); 2104 return 0; 2105 } 2106 2107 oi = ospf_apiserver_if_lookup_by_ifp (ifp); 2108 2109 if (!oi) { 2110 /* This interface is known to Zebra but not to OSPF daemon yet. */ 2111 zlog_warn ("ospf_apiserver_new_if: interface %s not known to OSPFd?", 2112 ifp->name); 2113 return 0; 2114 } 2115 2116 assert (oi); 2117 2118 /* New interface added to OSPF, tell clients about it */ 2119 if (listcount (apiserver_list) > 0) { 2120 ospf_apiserver_clients_notify_new_if (oi); 2121 } 2122 return 0; 2123} 2124 2125int 2126ospf_apiserver_del_if (struct interface *ifp) 2127{ 2128 struct ospf_interface *oi; 2129 2130 /* zlog_warn for debugging */ 2131 zlog_warn ("ospf_apiserver_del_if"); 2132 zlog_warn ("ifp name=%s status=%d index=%d\n", ifp->name, ifp->status, 2133 ifp->ifindex); 2134 2135 oi = ospf_apiserver_if_lookup_by_ifp (ifp); 2136 2137 if (!oi) { 2138 /* This interface is known to Zebra but not to OSPF daemon 2139 anymore. No need to tell clients about it */ 2140 return 0; 2141 } 2142 2143 /* Interface deleted, tell clients about it */ 2144 if (listcount (apiserver_list) > 0) { 2145 ospf_apiserver_clients_notify_del_if (oi); 2146 } 2147 return 0; 2148} 2149 2150void 2151ospf_apiserver_ism_change (struct ospf_interface *oi, int old_state) 2152{ 2153 /* Tell clients about interface change */ 2154 2155 /* zlog_warn for debugging */ 2156 zlog_warn ("ospf_apiserver_ism_change"); 2157 if (listcount (apiserver_list) > 0) { 2158 ospf_apiserver_clients_notify_ism_change (oi); 2159 } 2160 2161 zlog_warn ("oi->ifp->name=%s", oi->ifp->name); 2162 zlog_warn ("old_state=%d", old_state); 2163 zlog_warn ("oi->state=%d", oi->state); 2164} 2165 2166void 2167ospf_apiserver_nsm_change (struct ospf_neighbor *nbr, int old_status) 2168{ 2169 /* Neighbor status changed, tell clients about it */ 2170 zlog_warn ("ospf_apiserver_nsm_change"); 2171 if (listcount (apiserver_list) > 0) { 2172 ospf_apiserver_clients_notify_nsm_change (nbr); 2173 } 2174} 2175 2176void 2177ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa) 2178{ 2179 struct opaque_lsa 2180 { 2181 struct lsa_header header; 2182 u_char data[1]; /* opaque data have variable length. This is start 2183 address */ 2184 }; 2185 struct opaque_lsa *olsa; 2186 int opaquelen; 2187 2188 olsa = (struct opaque_lsa *) lsa->data; 2189 2190 if (VALID_OPAQUE_INFO_LEN (lsa->data)) 2191 opaquelen = ntohs (lsa->data->length) - OSPF_LSA_HEADER_SIZE; 2192 else 2193 opaquelen = 0; 2194 2195 /* Output information about opaque LSAs */ 2196 if (vty != NULL) 2197 { 2198 int i; 2199 vty_out (vty, " Added using OSPF API: %u octets of opaque data %s%s", 2200 opaquelen, 2201 VALID_OPAQUE_INFO_LEN (lsa->data) ? "" : "(Invalid length?)", 2202 VTY_NEWLINE); 2203 vty_out (vty, " Opaque data: "); 2204 2205 for (i = 0; i < opaquelen; i++) 2206 { 2207 vty_out (vty, "0x%x ", olsa->data[i]); 2208 } 2209 vty_out (vty, "%s", VTY_NEWLINE); 2210 } 2211 else 2212 { 2213 int i; 2214 zlog_debug (" Added using OSPF API: %u octets of opaque data %s", 2215 opaquelen, 2216 VALID_OPAQUE_INFO_LEN (lsa-> 2217 data) ? "" : "(Invalid length?)"); 2218 zlog_debug (" Opaque data: "); 2219 2220 for (i = 0; i < opaquelen; i++) 2221 { 2222 zlog_debug ("0x%x ", olsa->data[i]); 2223 } 2224 zlog_debug ("\n"); 2225 } 2226 return; 2227} 2228 2229/* ----------------------------------------------------------- 2230 * Followings are functions to notify clients about events 2231 * ----------------------------------------------------------- 2232 */ 2233 2234/* Send a message to all clients. This is useful for messages 2235 that need to be notified to all clients (such as interface 2236 changes) */ 2237 2238void 2239ospf_apiserver_clients_notify_all (struct msg *msg) 2240{ 2241 struct listnode *node, *nnode; 2242 struct ospf_apiserver *apiserv; 2243 2244 /* Send message to all clients */ 2245 for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) 2246 ospf_apiserver_send_msg (apiserv, msg); 2247} 2248 2249/* An interface is now ready to accept opaque LSAs. Notify all 2250 clients that registered to use this opaque type */ 2251void 2252ospf_apiserver_clients_notify_ready_type9 (struct ospf_interface *oi) 2253{ 2254 struct listnode *node, *nnode; 2255 struct msg *msg; 2256 struct ospf_apiserver *apiserv; 2257 2258 assert (oi); 2259 if (!oi->address) 2260 { 2261 zlog_warn ("Interface has no address?"); 2262 return; 2263 } 2264 2265 if (!ospf_apiserver_is_ready_type9 (oi)) 2266 { 2267 zlog_warn ("Interface not ready for type 9?"); 2268 return; 2269 } 2270 2271 for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) 2272 { 2273 struct listnode *node2, *nnode2; 2274 struct registered_opaque_type *r; 2275 2276 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) 2277 { 2278 if (r->lsa_type == OSPF_OPAQUE_LINK_LSA) 2279 { 2280 msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA, 2281 r->opaque_type, 2282 oi->address->u.prefix4); 2283 if (!msg) 2284 { 2285 zlog_warn 2286 ("ospf_apiserver_clients_notify_ready_type9: new_msg_ready_notify failed"); 2287#ifdef NOTYET 2288 /* Cannot allocate new message. What should we do? */ 2289 ospf_apiserver_free (apiserv); 2290#endif 2291 goto out; 2292 } 2293 2294 ospf_apiserver_send_msg (apiserv, msg); 2295 msg_free (msg); 2296 } 2297 } 2298 } 2299 2300out: 2301 return; 2302} 2303 2304void 2305ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area) 2306{ 2307 struct listnode *node, *nnode; 2308 struct msg *msg; 2309 struct ospf_apiserver *apiserv; 2310 2311 assert (area); 2312 2313 if (!ospf_apiserver_is_ready_type10 (area)) 2314 { 2315 zlog_warn ("Area not ready for type 10?"); 2316 return; 2317 } 2318 2319 for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) 2320 { 2321 struct listnode *node2, *nnode2; 2322 struct registered_opaque_type *r; 2323 2324 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) 2325 { 2326 if (r->lsa_type == OSPF_OPAQUE_AREA_LSA) 2327 { 2328 msg = new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA, 2329 r->opaque_type, area->area_id); 2330 if (!msg) 2331 { 2332 zlog_warn 2333 ("ospf_apiserver_clients_notify_ready_type10: new_msg_ready_nofity failed"); 2334#ifdef NOTYET 2335 /* Cannot allocate new message. What should we do? */ 2336 ospf_apiserver_free (apiserv); 2337#endif 2338 goto out; 2339 } 2340 2341 ospf_apiserver_send_msg (apiserv, msg); 2342 msg_free (msg); 2343 } 2344 } 2345 } 2346 2347out: 2348 return; 2349} 2350 2351 2352void 2353ospf_apiserver_clients_notify_ready_type11 (struct ospf *top) 2354{ 2355 struct listnode *node, *nnode; 2356 struct msg *msg; 2357 struct in_addr id_null = { .s_addr = 0L }; 2358 struct ospf_apiserver *apiserv; 2359 2360 assert (top); 2361 2362 if (!ospf_apiserver_is_ready_type11 (top)) 2363 { 2364 zlog_warn ("AS not ready for type 11?"); 2365 return; 2366 } 2367 2368 for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) 2369 { 2370 struct listnode *node2, *nnode2; 2371 struct registered_opaque_type *r; 2372 2373 for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) 2374 { 2375 if (r->lsa_type == OSPF_OPAQUE_AS_LSA) 2376 { 2377 msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA, 2378 r->opaque_type, id_null); 2379 if (!msg) 2380 { 2381 zlog_warn 2382 ("ospf_apiserver_clients_notify_ready_type11: new_msg_ready_notify failed"); 2383#ifdef NOTYET 2384 /* Cannot allocate new message. What should we do? */ 2385 ospf_apiserver_free (apiserv); 2386#endif 2387 goto out; 2388 } 2389 2390 ospf_apiserver_send_msg (apiserv, msg); 2391 msg_free (msg); 2392 } 2393 } 2394 } 2395 2396out: 2397 return; 2398} 2399 2400void 2401ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi) 2402{ 2403 struct msg *msg; 2404 2405 msg = new_msg_new_if (0, oi->address->u.prefix4, oi->area->area_id); 2406 if (msg != NULL) 2407 { 2408 ospf_apiserver_clients_notify_all (msg); 2409 msg_free (msg); 2410 } 2411} 2412 2413void 2414ospf_apiserver_clients_notify_del_if (struct ospf_interface *oi) 2415{ 2416 struct msg *msg; 2417 2418 msg = new_msg_del_if (0, oi->address->u.prefix4); 2419 if (msg != NULL) 2420 { 2421 ospf_apiserver_clients_notify_all (msg); 2422 msg_free (msg); 2423 } 2424} 2425 2426void 2427ospf_apiserver_clients_notify_ism_change (struct ospf_interface *oi) 2428{ 2429 struct msg *msg; 2430 struct in_addr ifaddr = { .s_addr = 0L }; 2431 struct in_addr area_id = { .s_addr = 0L }; 2432 2433 assert (oi); 2434 assert (oi->ifp); 2435 2436 if (oi->address) 2437 { 2438 ifaddr = oi->address->u.prefix4; 2439 } 2440 if (oi->area) 2441 { 2442 area_id = oi->area->area_id; 2443 } 2444 2445 msg = new_msg_ism_change (0, ifaddr, area_id, oi->state); 2446 if (!msg) 2447 { 2448 zlog_warn ("apiserver_clients_notify_ism_change: msg_new failed"); 2449 return; 2450 } 2451 2452 ospf_apiserver_clients_notify_all (msg); 2453 msg_free (msg); 2454} 2455 2456void 2457ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr) 2458{ 2459 struct msg *msg; 2460 struct in_addr ifaddr = { .s_addr = 0L }; 2461 struct in_addr nbraddr = { .s_addr = 0L }; 2462 2463 assert (nbr); 2464 2465 if (nbr->oi) 2466 { 2467 ifaddr = nbr->oi->address->u.prefix4; 2468 } 2469 2470 nbraddr = nbr->address.u.prefix4; 2471 2472 msg = new_msg_nsm_change (0, ifaddr, nbraddr, nbr->router_id, nbr->state); 2473 if (!msg) 2474 { 2475 zlog_warn ("apiserver_clients_notify_nsm_change: msg_new failed"); 2476 return; 2477 } 2478 2479 ospf_apiserver_clients_notify_all (msg); 2480 msg_free (msg); 2481} 2482 2483static void 2484apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa) 2485{ 2486 struct msg *msg; 2487 struct listnode *node, *nnode; 2488 struct ospf_apiserver *apiserv; 2489 2490 /* Default area for AS-External and Opaque11 LSAs */ 2491 struct in_addr area_id = { .s_addr = 0L }; 2492 2493 /* Default interface for non Opaque9 LSAs */ 2494 struct in_addr ifaddr = { .s_addr = 0L }; 2495 2496 if (lsa->area) 2497 { 2498 area_id = lsa->area->area_id; 2499 } 2500 if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) 2501 { 2502 assert (lsa->oi); 2503 ifaddr = lsa->oi->address->u.prefix4; 2504 } 2505 2506 /* Prepare message that can be sent to clients that have a matching 2507 filter */ 2508 msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */ 2509 ifaddr, area_id, 2510 lsa->flags & OSPF_LSA_SELF, lsa->data); 2511 if (!msg) 2512 { 2513 zlog_warn ("apiserver_clients_lsa_change_notify: msg_new failed"); 2514 return; 2515 } 2516 2517 /* Now send message to all clients with a matching filter */ 2518 for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) 2519 { 2520 struct lsa_filter_type *filter; 2521 u_int16_t mask; 2522 u_int32_t *area; 2523 int i; 2524 2525 /* Check filter for this client. */ 2526 filter = apiserv->filter; 2527 2528 /* Check area IDs in case of non AS-E LSAs. 2529 * If filter has areas (num_areas > 0), 2530 * then one of the areas must match the area ID of this LSA. */ 2531 2532 i = filter->num_areas; 2533 if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) || 2534 (lsa->data->type == OSPF_OPAQUE_AS_LSA)) 2535 { 2536 i = 0; 2537 } 2538 2539 if (i > 0) 2540 { 2541 area = (u_int32_t *) (filter + 1); 2542 while (i) 2543 { 2544 if (*area == area_id.s_addr) 2545 { 2546 break; 2547 } 2548 i--; 2549 area++; 2550 } 2551 } 2552 else 2553 { 2554 i = 1; 2555 } 2556 2557 if (i > 0) 2558 { 2559 /* Area match. Check LSA type. */ 2560 mask = ntohs (filter->typemask); 2561 2562 if (mask & Power2[lsa->data->type]) 2563 { 2564 /* Type also matches. Check origin. */ 2565 if ((filter->origin == ANY_ORIGIN) || 2566 (filter->origin == IS_LSA_SELF (lsa))) 2567 { 2568 ospf_apiserver_send_msg (apiserv, msg); 2569 } 2570 } 2571 } 2572 } 2573 /* Free message since it is not used anymore */ 2574 msg_free (msg); 2575} 2576 2577 2578/* ------------------------------------------------------------- 2579 * Followings are hooks invoked when LSAs are updated or deleted 2580 * ------------------------------------------------------------- 2581 */ 2582 2583 2584static int 2585apiserver_notify_clients_lsa (u_char msgtype, struct ospf_lsa *lsa) 2586{ 2587 struct msg *msg; 2588 /* default area for AS-External and Opaque11 LSAs */ 2589 struct in_addr area_id = { .s_addr = 0L }; 2590 2591 /* default interface for non Opaque9 LSAs */ 2592 struct in_addr ifaddr = { .s_addr = 0L }; 2593 2594 /* Only notify this update if the LSA's age is smaller than 2595 MAXAGE. Otherwise clients would see LSA updates with max age just 2596 before they are deleted from the LSDB. LSA delete messages have 2597 MAXAGE too but should not be filtered. */ 2598 if (IS_LSA_MAXAGE(lsa) && (msgtype == MSG_LSA_UPDATE_NOTIFY)) { 2599 return 0; 2600 } 2601 2602 if (lsa->area) 2603 { 2604 area_id = lsa->area->area_id; 2605 } 2606 if (lsa->data->type == OSPF_OPAQUE_LINK_LSA) 2607 { 2608 ifaddr = lsa->oi->address->u.prefix4; 2609 } 2610 msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */ 2611 ifaddr, area_id, 2612 lsa->flags & OSPF_LSA_SELF, lsa->data); 2613 if (!msg) 2614 { 2615 zlog_warn ("notify_clients_lsa: msg_new failed"); 2616 return -1; 2617 } 2618 /* Notify all clients that new LSA is added/updated */ 2619 apiserver_clients_lsa_change_notify (msgtype, lsa); 2620 2621 /* Clients made their own copies of msg so we can free msg here */ 2622 msg_free (msg); 2623 2624 return 0; 2625} 2626 2627int 2628ospf_apiserver_lsa_update (struct ospf_lsa *lsa) 2629{ 2630 return apiserver_notify_clients_lsa (MSG_LSA_UPDATE_NOTIFY, lsa); 2631} 2632 2633int 2634ospf_apiserver_lsa_delete (struct ospf_lsa *lsa) 2635{ 2636 return apiserver_notify_clients_lsa (MSG_LSA_DELETE_NOTIFY, lsa); 2637} 2638 2639#endif /* SUPPORT_OSPF_API */ 2640 2641