File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_apiserver.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>