File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_apiserver.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:40 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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