]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - ospfd/ospf_apiserver.c
New upstream version 1.2.4
[quagga-debian.git] / ospfd / ospf_apiserver.c
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