File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_apiserver.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

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