/*
 * Server side of OSPF API.
 * Copyright (C) 2001, 2002 Ralph Keller
 *
 * This file is part of GNU Zebra.
 * 
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <zebra.h>

#ifdef SUPPORT_OSPF_API
#ifndef HAVE_OPAQUE_LSA
#error "Core Opaque-LSA module must be configured."
#endif /* HAVE_OPAQUE_LSA */

#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "memory.h"
#include "command.h"
#include "vty.h"
#include "stream.h"
#include "log.h"
#include "thread.h"
#include "hash.h"
#include "sockunion.h"		/* for inet_aton() */
#include "buffer.h"

#include <sys/types.h>

#include "ospfd/ospfd.h"        /* for "struct thread_master" */
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_spf.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_route.h"
#include "ospfd/ospf_ase.h"
#include "ospfd/ospf_zebra.h"

#include "ospfd/ospf_api.h"
#include "ospfd/ospf_apiserver.h"

/* This is an implementation of an API to the OSPF daemon that allows
 * external applications to access the OSPF daemon through socket
 * connections. The application can use this API to inject its own
 * opaque LSAs and flood them to other OSPF daemons. Other OSPF
 * daemons then receive these LSAs and inform applications through the
 * API by sending a corresponding message. The application can also
 * register to receive all LSA types (in addition to opaque types) and
 * use this information to reconstruct the OSPF's LSDB. The OSPF
 * daemon supports multiple applications concurrently.  */

/* List of all active connections. */
list apiserver_list;

/* -----------------------------------------------------------
 * Functions to lookup interfaces
 * -----------------------------------------------------------
 */

struct ospf_interface *
ospf_apiserver_if_lookup_by_addr (struct in_addr address)
{
  listnode node;
  struct ospf_interface *oi;
  struct ospf *ospf;

  if (!(ospf = ospf_lookup ()))
    return NULL;

  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      if ((oi = getdata (node)) != NULL
	  && oi->type != OSPF_IFTYPE_VIRTUALLINK)
	{
	  if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
	    return oi;
	}
    }
  return NULL;
}

struct ospf_interface *
ospf_apiserver_if_lookup_by_ifp (struct interface *ifp)
{
  listnode node;
  struct ospf_interface *oi;
  struct ospf *ospf;

  if (!(ospf = ospf_lookup ()));
    return NULL;

  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      if ((oi = getdata (node)) && oi->ifp == ifp)
	{
	  return oi;
	}
    }
  return NULL;
}

/* -----------------------------------------------------------
 * Initialization
 * -----------------------------------------------------------
 */

unsigned short
ospf_apiserver_getport (void)
{
  struct servent *sp = getservbyname ("ospfapi", "tcp");

  return sp ? ntohs (sp->s_port) : OSPF_API_SYNC_PORT;
}

/* Initialize OSPF API module. Invoked from ospf_opaque_init() */
int
ospf_apiserver_init (void)
{
  int fd;
  int rc = -1;

  /* Create new socket for synchronous messages. */
  fd = ospf_apiserver_serv_sock_family (ospf_apiserver_getport (), AF_INET);

  if (fd < 0)
    goto out;

  /* Schedule new thread that handles accepted connections. */
  ospf_apiserver_event (OSPF_APISERVER_ACCEPT, fd, NULL);

  /* Initialize list that keeps track of all connections. */
  apiserver_list = list_new ();

  /* Register opaque-independent call back functions. These functions
     are invoked on ISM, NSM changes and LSA update and LSA deletes */
  rc =
    ospf_register_opaque_functab (0 /* all LSAs */, 
				  0 /* all opaque types */,
				  ospf_apiserver_new_if,
				  ospf_apiserver_del_if,
				  ospf_apiserver_ism_change,
				  ospf_apiserver_nsm_change,
				  NULL,
				  NULL,
				  NULL,
				  NULL, /* ospf_apiserver_show_info */
				  NULL, /* originator_func */
				  NULL, /* ospf_apiserver_lsa_refresher */
				  ospf_apiserver_lsa_update,
				  ospf_apiserver_lsa_delete);
  if (rc != 0)
    {
      zlog_warn ("ospf_apiserver_init: Failed to register opaque type [0/0]");
    }

  rc = 0;

out:
  return rc;
}

/* Terminate OSPF API module. */
void
ospf_apiserver_term (void)
{
  listnode node;

  /* Unregister wildcard [0/0] type */
  ospf_delete_opaque_functab (0 /* all LSAs */, 
			      0 /* all opaque types */);

  /* Free all client instances */
  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv =
	(struct ospf_apiserver *) getdata (node);
      ospf_apiserver_free (apiserv);
    }

  /* Free client list itself */
  list_delete (apiserver_list);

  /* Free wildcard list */
  /* XXX  */
}

static struct ospf_apiserver *
lookup_apiserver (u_char lsa_type, u_char opaque_type)
{
  listnode n1, n2;
  struct registered_opaque_type *r;
  struct ospf_apiserver *apiserv, *found = NULL;

  for (n1 = listhead (apiserver_list); n1; nextnode (n1))
    {
      apiserv = (struct ospf_apiserver *) getdata (n1);

      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  r = (struct registered_opaque_type *) getdata (n2);

          if (r->lsa_type == lsa_type && r->opaque_type == opaque_type)
            {
              found = apiserv;
              goto out;
            }
	}
    }
out:
  return found;
}

static struct ospf_apiserver *
lookup_apiserver_by_lsa (struct ospf_lsa *lsa)
{
  struct lsa_header *lsah = lsa->data;
  struct ospf_apiserver *found = NULL;

  if (IS_OPAQUE_LSA (lsah->type))
    {
      found = lookup_apiserver (lsah->type,
                                GET_OPAQUE_TYPE (ntohl (lsah->id.s_addr)));
    }
  return found;
}

/* -----------------------------------------------------------
 * Followings are functions to manage client connections.
 * -----------------------------------------------------------
 */
static int
ospf_apiserver_new_lsa_hook (struct ospf_lsa *lsa)
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: Put LSA(%p)[%s] into reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total);
  return 0;
}

static int
ospf_apiserver_del_lsa_hook (struct ospf_lsa *lsa)
{
  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: Get LSA(%p)[%s] from reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total);
  return 0;
}

/* Allocate new connection structure. */
struct ospf_apiserver *
ospf_apiserver_new (int fd_sync, int fd_async)
{
  struct ospf_apiserver *new =
    XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct ospf_apiserver));

  new->filter =
    XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, sizeof (struct lsa_filter_type));

  new->fd_sync = fd_sync;
  new->fd_async = fd_async;

  /* list of registered opaque types that application uses */
  new->opaque_types = list_new ();

  /* Initialize temporary strage for LSA instances to be refreshed. */
  memset (&new->reserve, 0, sizeof (struct ospf_lsdb));
  ospf_lsdb_init (&new->reserve);

  new->reserve.new_lsa_hook = ospf_apiserver_new_lsa_hook; /* debug */
  new->reserve.del_lsa_hook = ospf_apiserver_del_lsa_hook; /* debug */

  new->out_sync_fifo = msg_fifo_new ();
  new->out_async_fifo = msg_fifo_new ();
  new->t_sync_read = NULL;
#ifdef USE_ASYNC_READ
  new->t_async_read = NULL;
#endif /* USE_ASYNC_READ */
  new->t_sync_write = NULL;
  new->t_async_write = NULL;

  new->filter->typemask = 0;	/* filter all LSAs */
  new->filter->origin = ANY_ORIGIN;
  new->filter->num_areas = 0;

  return new;
}

void
ospf_apiserver_event (enum event event, int fd,
		      struct ospf_apiserver *apiserv)
{
  struct thread *apiserver_serv_thread;

  switch (event)
    {
    case OSPF_APISERVER_ACCEPT:
      apiserver_serv_thread =
	thread_add_read (master, ospf_apiserver_accept, apiserv, fd);
      break;
    case OSPF_APISERVER_SYNC_READ:
      apiserv->t_sync_read =
	thread_add_read (master, ospf_apiserver_read, apiserv, fd);
      break;
#ifdef USE_ASYNC_READ
    case OSPF_APISERVER_ASYNC_READ:
      apiserv->t_async_read =
	thread_add_read (master, ospf_apiserver_read, apiserv, fd);
      break;
#endif /* USE_ASYNC_READ */
    case OSPF_APISERVER_SYNC_WRITE:
      if (!apiserv->t_sync_write)
	{
	  apiserv->t_sync_write =
	    thread_add_write (master, ospf_apiserver_sync_write, apiserv, fd);
	}
      break;
    case OSPF_APISERVER_ASYNC_WRITE:
      if (!apiserv->t_async_write)
	{
	  apiserv->t_async_write =
	    thread_add_write (master, ospf_apiserver_async_write, apiserv, fd);
	}
      break;
    }
}

/* Free instance. First unregister all opaque types used by
   application, flush opaque LSAs injected by application 
   from network and close connection. */
void
ospf_apiserver_free (struct ospf_apiserver *apiserv)
{
  listnode node;

  /* Cancel read and write threads. */
  if (apiserv->t_sync_read)
    {
      thread_cancel (apiserv->t_sync_read);
    }
#ifdef USE_ASYNC_READ
  if (apiserv->t_async_read)
    {
      thread_cancel (apiserv->t_async_read);
    }
#endif /* USE_ASYNC_READ */
  if (apiserv->t_sync_write)
    {
      thread_cancel (apiserv->t_sync_write);
    }

  if (apiserv->t_async_write)
    {
      thread_cancel (apiserv->t_async_write);
    }

  /* Unregister all opaque types that application registered 
     and flush opaque LSAs if still in LSDB. */

  while ((node = listhead (apiserv->opaque_types)) != NULL)
    {

      struct registered_opaque_type *regtype = node->data;

      ospf_apiserver_unregister_opaque_type (apiserv, regtype->lsa_type,
					     regtype->opaque_type);

    }

  /* Close connections to OSPFd. */
  if (apiserv->fd_sync > 0)
    {
      close (apiserv->fd_sync);
    }

  if (apiserv->fd_async > 0)
    {
      close (apiserv->fd_async);
    }

  /* Free fifos */
  msg_fifo_free (apiserv->out_sync_fifo);
  msg_fifo_free (apiserv->out_async_fifo);

  /* Clear temporary strage for LSA instances to be refreshed. */
  ospf_lsdb_delete_all (&apiserv->reserve);
  ospf_lsdb_cleanup (&apiserv->reserve);

  /* Remove from the list of active clients. */
  listnode_delete (apiserver_list, apiserv);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: Delete apiserv(%p), total#(%d)", apiserv, apiserver_list->count);

  /* And free instance. */
  XFREE (MTYPE_OSPF_APISERVER, apiserv);
}

int
ospf_apiserver_read (struct thread *thread)
{
  struct ospf_apiserver *apiserv;
  struct msg *msg;
  int fd;
  int rc = -1;
  enum event event;

  apiserv = THREAD_ARG (thread);
  fd = THREAD_FD (thread);

  if (fd == apiserv->fd_sync)
    {
      event = OSPF_APISERVER_SYNC_READ;
      apiserv->t_sync_read = NULL;

      if (IS_DEBUG_OSPF_EVENT)
        zlog_info ("API: ospf_apiserver_read: Peer: %s/%u",
                    inet_ntoa (apiserv->peer_sync.sin_addr),
                    ntohs (apiserv->peer_sync.sin_port));
    }
#ifdef USE_ASYNC_READ
  else if (fd == apiserv->fd_async)
    {
      event = OSPF_APISERVER_ASYNC_READ;
      apiserv->t_async_read = NULL;

      if (IS_DEBUG_OSPF_EVENT)
        zlog_info ("API: ospf_apiserver_read: Peer: %s/%u",
                    inet_ntoa (apiserv->peer_async.sin_addr),
                    ntohs (apiserv->peer_async.sin_port));
    }
#endif /* USE_ASYNC_READ */
  else
    {
      zlog_warn ("ospf_apiserver_read: Unknown fd(%d)", fd);
      ospf_apiserver_free (apiserv);
      goto out;
    }

  /* Read message from fd. */
  msg = msg_read (fd);
  if (msg == NULL)
    {
      zlog_warn
	("ospf_apiserver_read: read failed on fd=%d, closing connection", fd);

      /* Perform cleanup. */
      ospf_apiserver_free (apiserv);
      goto out;
    }

  if (IS_DEBUG_OSPF_EVENT)
    msg_print (msg);

  /* Dispatch to corresponding message handler. */
  rc = ospf_apiserver_handle_msg (apiserv, msg);

  /* Prepare for next message, add read thread. */
  ospf_apiserver_event (event, fd, apiserv);

  msg_free (msg);

out:
  return rc;
}

int
ospf_apiserver_sync_write (struct thread *thread)
{
  struct ospf_apiserver *apiserv;
  struct msg *msg;
  int fd;
  int rc = -1;

  apiserv = THREAD_ARG (thread);
  assert (apiserv);
  fd = THREAD_FD (thread);

  apiserv->t_sync_write = NULL;

  /* Sanity check */
  if (fd != apiserv->fd_sync)
    {
      zlog_warn ("ospf_apiserver_sync_write: Unknown fd=%d", fd);
      goto out;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: ospf_apiserver_sync_write: Peer: %s/%u",
                inet_ntoa (apiserv->peer_sync.sin_addr),
                ntohs (apiserv->peer_sync.sin_port));

  /* Check whether there is really a message in the fifo. */
  msg = msg_fifo_pop (apiserv->out_sync_fifo);
  if (!msg)
    {
      zlog_warn ("API: ospf_apiserver_sync_write: No message in Sync-FIFO?");
      return 0;
    }

  if (IS_DEBUG_OSPF_EVENT)
    msg_print (msg);

  rc = msg_write (fd, msg);

  /* Once a message is dequeued, it should be freed anyway. */
  msg_free (msg);

  if (rc < 0)
    {
      zlog_warn
        ("ospf_apiserver_sync_write: write failed on fd=%d", fd);
      goto out;
    }


  /* If more messages are in sync message fifo, schedule write thread. */
  if (msg_fifo_head (apiserv->out_sync_fifo))
    {
      ospf_apiserver_event (OSPF_APISERVER_SYNC_WRITE, apiserv->fd_sync,
                            apiserv);
    }
  
 out:

  if (rc < 0)
  {
      /* Perform cleanup and disconnect with peer */
      ospf_apiserver_free (apiserv);
    }

  return rc;
}


int
ospf_apiserver_async_write (struct thread *thread)
{
  struct ospf_apiserver *apiserv;
  struct msg *msg;
  int fd;
  int rc = -1;

  apiserv = THREAD_ARG (thread);
  assert (apiserv);
  fd = THREAD_FD (thread);

  apiserv->t_async_write = NULL;

  /* Sanity check */
  if (fd != apiserv->fd_async)
    {
      zlog_warn ("ospf_apiserver_async_write: Unknown fd=%d", fd);
      goto out;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: ospf_apiserver_async_write: Peer: %s/%u",
                inet_ntoa (apiserv->peer_async.sin_addr),
                ntohs (apiserv->peer_async.sin_port));

  /* Check whether there is really a message in the fifo. */
  msg = msg_fifo_pop (apiserv->out_async_fifo);
  if (!msg)
    {
      zlog_warn ("API: ospf_apiserver_async_write: No message in Async-FIFO?");
      return 0;
    }

  if (IS_DEBUG_OSPF_EVENT)
    msg_print (msg);

  rc = msg_write (fd, msg);

  /* Once a message is dequeued, it should be freed anyway. */
  msg_free (msg);

  if (rc < 0)
    {
      zlog_warn
        ("ospf_apiserver_async_write: write failed on fd=%d", fd);
      goto out;
    }


  /* If more messages are in async message fifo, schedule write thread. */
  if (msg_fifo_head (apiserv->out_async_fifo))
    {
      ospf_apiserver_event (OSPF_APISERVER_ASYNC_WRITE, apiserv->fd_async,
                            apiserv);
    }

 out:

  if (rc < 0)
    {
      /* Perform cleanup and disconnect with peer */
      ospf_apiserver_free (apiserv);
    }

  return rc;
}


int
ospf_apiserver_serv_sock_family (unsigned short port, int family)
{
  union sockunion su;
  int accept_sock;
  int rc;

  memset (&su, 0, sizeof (union sockunion));
  su.sa.sa_family = family;

  /* Make new socket */
  accept_sock = sockunion_stream_socket (&su);
  if (accept_sock < 0)
    return accept_sock;

  /* This is a server, so reuse address and port */
  sockopt_reuseaddr (accept_sock);
  sockopt_reuseport (accept_sock);

  /* Bind socket to address and given port. */
  rc = sockunion_bind (accept_sock, &su, port, NULL);
  if (rc < 0)
    {
      close (accept_sock);	/* Close socket */
      return rc;
    }

  /* Listen socket under queue length 3. */
  rc = listen (accept_sock, 3);
  if (rc < 0)
    {
      zlog_warn ("ospf_apiserver_serv_sock_family: listen: %s",
                 strerror (errno));
      close (accept_sock);	/* Close socket */
      return rc;
    }
  return accept_sock;
}


/* Accept connection request from external applications. For each
   accepted connection allocate own connection instance. */
int
ospf_apiserver_accept (struct thread *thread)
{
  int accept_sock;
  int new_sync_sock;
  int new_async_sock;
  union sockunion su;
  struct ospf_apiserver *apiserv;
  struct sockaddr_in peer_async;
  struct sockaddr_in peer_sync;
  int peerlen;
  int ret;

  /* THREAD_ARG (thread) is NULL */
  accept_sock = THREAD_FD (thread);

  /* Keep hearing on socket for further connections. */
  ospf_apiserver_event (OSPF_APISERVER_ACCEPT, accept_sock, NULL);

  memset (&su, 0, sizeof (union sockunion));
  /* Accept connection for synchronous messages */
  new_sync_sock = sockunion_accept (accept_sock, &su);
  if (new_sync_sock < 0)
    {
      zlog_warn ("ospf_apiserver_accept: accept: %s", strerror (errno));
      return -1;
    }

  /* Get port address and port number of peer to make reverse connection.
     The reverse channel uses the port number of the peer port+1. */

  memset(&peer_sync, 0, sizeof(struct sockaddr_in));
  peerlen = sizeof (struct sockaddr_in);

  ret = getpeername (new_sync_sock, (struct sockaddr *)&peer_sync, &peerlen);
  if (ret < 0)
    {
      zlog_warn ("ospf_apiserver_accept: getpeername: %s", strerror (errno));
      close (new_sync_sock);
      return -1;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: ospf_apiserver_accept: New peer: %s/%u",
               inet_ntoa (peer_sync.sin_addr), ntohs (peer_sync.sin_port));

  /* Create new socket for asynchronous messages. */
  peer_async = peer_sync;
  peer_async.sin_port = htons(ntohs(peer_sync.sin_port) + 1);

  /* Check if remote port number to make reverse connection is valid one. */
  if (ntohs (peer_async.sin_port) == ospf_apiserver_getport ())
    {
      zlog_warn ("API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?",
               inet_ntoa (peer_async.sin_addr), ntohs (peer_async.sin_port));
      close (new_sync_sock);
      return -1;
    }

  new_async_sock = socket (AF_INET, SOCK_STREAM, 0);
  if (new_async_sock < 0)
    {
      zlog_warn ("ospf_apiserver_accept: socket: %s", strerror (errno));
      close (new_sync_sock);
      return -1;
    }

  ret = connect (new_async_sock, (struct sockaddr *) &peer_async,
		 sizeof (struct sockaddr_in));

  if (ret < 0)
    {
      zlog_warn ("ospf_apiserver_accept: connect: %s", strerror (errno));
      close (new_sync_sock);
      close (new_async_sock);
      return -1;
    }

#ifdef USE_ASYNC_READ
#else /* USE_ASYNC_READ */
  /* Make the asynchronous channel write-only. */
  ret = shutdown (new_async_sock, SHUT_RD);
  if (ret < 0)
    {
      zlog_warn ("ospf_apiserver_accept: shutdown: %s", strerror (errno));
      close (new_sync_sock);
      close (new_async_sock);
      return -1;
    }
#endif /* USE_ASYNC_READ */

  /* Allocate new server-side connection structure */
  apiserv = ospf_apiserver_new (new_sync_sock, new_async_sock);

  /* Add to active connection list */
  listnode_add (apiserver_list, apiserv);
  apiserv->peer_sync = peer_sync;
  apiserv->peer_async = peer_async;

  /* And add read threads for new connection */
  ospf_apiserver_event (OSPF_APISERVER_SYNC_READ, new_sync_sock, apiserv);
#ifdef USE_ASYNC_READ
  ospf_apiserver_event (OSPF_APISERVER_ASYNC_READ, new_async_sock, apiserv);
#endif /* USE_ASYNC_READ */

  if (IS_DEBUG_OSPF_EVENT)
    zlog_warn ("API: New apiserv(%p), total#(%d)", apiserv, apiserver_list->count);

  return 0;
}


/* -----------------------------------------------------------
 * Send reply with return code to client application
 * -----------------------------------------------------------
 */

int
ospf_apiserver_send_msg (struct ospf_apiserver *apiserv, struct msg *msg)
{
  struct msg_fifo *fifo;
  struct msg *msg2;
  enum event event;
  int fd;

  switch (msg->hdr.msgtype)
    {
    case MSG_REPLY:
      fifo = apiserv->out_sync_fifo;
      fd = apiserv->fd_sync;
      event = OSPF_APISERVER_SYNC_WRITE;
      break;
    case MSG_READY_NOTIFY:
    case MSG_LSA_UPDATE_NOTIFY:
    case MSG_LSA_DELETE_NOTIFY:
    case MSG_NEW_IF:
    case MSG_DEL_IF:
    case MSG_ISM_CHANGE:
    case MSG_NSM_CHANGE:
      fifo = apiserv->out_async_fifo;
      fd = apiserv->fd_async;
      event = OSPF_APISERVER_ASYNC_WRITE;
      break;
    default:
      zlog_warn ("ospf_apiserver_send_msg: Unknown message type %d",
		 msg->hdr.msgtype);
      return -1;
    }

  /* Make a copy of the message and put in the fifo. Once the fifo
     gets drained by the write thread, the message will be freed. */
  /* NB: Given "msg" is untouched in this function. */
  msg2 = msg_dup (msg);

  /* Enqueue message into corresponding fifo queue */
  msg_fifo_push (fifo, msg2);

  /* Schedule write thread */
  ospf_apiserver_event (event, fd, apiserv);
  return 0;
}

int
ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr,
			   u_char rc)
{
  struct msg *msg = new_msg_reply (seqnr, rc);
  int ret;

  if (!msg)
    {
      zlog_warn ("ospf_apiserver_send_reply: msg_new failed");
#ifdef NOTYET
      /* Cannot allocate new message. What should we do? */
      ospf_apiserver_free (apiserv);
#endif
      return -1;
    }

  ret = ospf_apiserver_send_msg (apiserv, msg);
  msg_free (msg);
  return ret;
}


/* -----------------------------------------------------------
 * Generic message dispatching handler function
 * -----------------------------------------------------------
 */

int
ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg)
{
  int rc;

  /* Call corresponding message handler function. */
  switch (msg->hdr.msgtype)
    {
    case MSG_REGISTER_OPAQUETYPE:
      rc = ospf_apiserver_handle_register_opaque_type (apiserv, msg);
      break;
    case MSG_UNREGISTER_OPAQUETYPE:
      rc = ospf_apiserver_handle_unregister_opaque_type (apiserv, msg);
      break;
    case MSG_REGISTER_EVENT:
      rc = ospf_apiserver_handle_register_event (apiserv, msg);
      break;
    case MSG_SYNC_LSDB:
      rc = ospf_apiserver_handle_sync_lsdb (apiserv, msg);
      break;
    case MSG_ORIGINATE_REQUEST:
      rc = ospf_apiserver_handle_originate_request (apiserv, msg);
      break;
    case MSG_DELETE_REQUEST:
      rc = ospf_apiserver_handle_delete_request (apiserv, msg);
      break;
    default:
      zlog_warn ("ospf_apiserver_handle_msg: Unknown message type: %d",
		 msg->hdr.msgtype);
      rc = -1;
    }
  return rc;
}


/* -----------------------------------------------------------
 * Following are functions for opaque type registration
 * -----------------------------------------------------------
 */

int
ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserv,
				     u_char lsa_type, u_char opaque_type)
{
  struct registered_opaque_type *regtype;
  int (*originator_func) (void *arg);
  int rc;

  switch (lsa_type)
    {
    case OSPF_OPAQUE_LINK_LSA:
      originator_func = ospf_apiserver_lsa9_originator;
      break;
    case OSPF_OPAQUE_AREA_LSA:
      originator_func = ospf_apiserver_lsa10_originator;
      break;
    case OSPF_OPAQUE_AS_LSA:
      originator_func = ospf_apiserver_lsa11_originator;
      break;
    default:
      zlog_warn ("ospf_apiserver_register_opaque_type: lsa_type(%d)",
		 lsa_type);
      return OSPF_API_ILLEGALLSATYPE;
    }
  

  /* Register opaque function table */
  /* NB: Duplicated registration will be detected inside the function. */
  rc =
    ospf_register_opaque_functab (lsa_type, opaque_type,
				  NULL, /* ospf_apiserver_new_if */
				  NULL, /* ospf_apiserver_del_if */
				  NULL, /* ospf_apiserver_ism_change */
				  NULL, /* ospf_apiserver_nsm_change */
				  NULL,
				  NULL,
				  NULL,
				  ospf_apiserver_show_info,
				  originator_func,
				  ospf_apiserver_lsa_refresher,
				  NULL, /* ospf_apiserver_lsa_update */
				  NULL /* ospf_apiserver_lsa_delete */);

  if (rc != 0)
    {
      zlog_warn ("Failed to register opaque type [%d/%d]",
		 lsa_type, opaque_type);
      return OSPF_API_OPAQUETYPEINUSE;
    }

  /* Remember the opaque type that application registers so when
     connection shuts down, we can flush all LSAs of this opaque
     type. */

  regtype =
    XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct registered_opaque_type));
  memset (regtype, 0, sizeof (struct registered_opaque_type));
  regtype->lsa_type = lsa_type;
  regtype->opaque_type = opaque_type;

  /* Add to list of registered opaque types */
  listnode_add (apiserv->opaque_types, regtype);

  if (IS_DEBUG_OSPF_EVENT)
    zlog_info ("API: Add LSA-type(%d)/Opaque-type(%d) into apiserv(%p), total#(%d)", lsa_type, opaque_type, apiserv, listcount (apiserv->opaque_types));

  return 0;
}

int
ospf_apiserver_unregister_opaque_type (struct ospf_apiserver *apiserv,
				       u_char lsa_type, u_char opaque_type)
{
  listnode node;

  for (node = listhead (apiserv->opaque_types); node; nextnode (node))
    {
      struct registered_opaque_type *regtype = node->data;

      /* Check if we really registered this opaque type */
      if (regtype->lsa_type == lsa_type &&
	  regtype->opaque_type == opaque_type)
	{

	  /* Yes, we registered this opaque type. Flush
	     all existing opaque LSAs of this type */

	  ospf_apiserver_flush_opaque_lsa (apiserv, lsa_type, opaque_type);
	  ospf_delete_opaque_functab (lsa_type, opaque_type);

	  /* Remove from list of registered opaque types */
	  listnode_delete (apiserv->opaque_types, regtype);

          if (IS_DEBUG_OSPF_EVENT)
            zlog_info ("API: Del LSA-type(%d)/Opaque-type(%d) from apiserv(%p), total#(%d)", lsa_type, opaque_type, apiserv, listcount (apiserv->opaque_types));

	  return 0;
	}
    }

  /* Opaque type is not registered */
  zlog_warn ("Failed to unregister opaque type [%d/%d]",
	     lsa_type, opaque_type);
  return OSPF_API_OPAQUETYPENOTREGISTERED;
}


int
apiserver_is_opaque_type_registered (struct ospf_apiserver *apiserv,
				     u_char lsa_type, u_char opaque_type)
{
  listnode node;

  for (node = listhead (apiserv->opaque_types); node; nextnode (node))
    {
      struct registered_opaque_type *regtype = node->data;

      /* Check if we really registered this opaque type */
      if (regtype->lsa_type == lsa_type &&
	  regtype->opaque_type == opaque_type)
	{
	  /* Yes registered */
	  return 1;
	}
    }
  /* Not registered */
  return 0;
}

int
ospf_apiserver_handle_register_opaque_type (struct ospf_apiserver *apiserv,
					    struct msg *msg)
{
  struct msg_register_opaque_type *rmsg;
  u_char lsa_type;
  u_char opaque_type;
  int rc = 0;

  /* Extract parameters from register opaque type message */
  rmsg = (struct msg_register_opaque_type *) STREAM_DATA (msg->s);

  lsa_type = rmsg->lsatype;
  opaque_type = rmsg->opaquetype;

  rc = ospf_apiserver_register_opaque_type (apiserv, lsa_type, opaque_type);

  /* Send a reply back to client including return code */
  rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
  if (rc < 0)
    goto out;

  /* Now inform application about opaque types that are ready */
  switch (lsa_type)
    {
    case OSPF_OPAQUE_LINK_LSA:
      ospf_apiserver_notify_ready_type9 (apiserv);
      break;
    case OSPF_OPAQUE_AREA_LSA:
      ospf_apiserver_notify_ready_type10 (apiserv);
      break;
    case OSPF_OPAQUE_AS_LSA:
      ospf_apiserver_notify_ready_type11 (apiserv);
      break;
    }
out:
  return rc;
}


/* Notify specific client about all opaque types 9 that are ready. */
void
ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv)
{
  listnode node;
  listnode n2;
  struct ospf *ospf;

  ospf = ospf_lookup ();

  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      struct ospf_interface *oi = (struct ospf_interface *) getdata (node);

      /* Check if this interface is indeed ready for type 9 */
      if (!ospf_apiserver_is_ready_type9 (oi))
	continue;

      /* Check for registered opaque type 9 types */
      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  struct registered_opaque_type *r =
	    (struct registered_opaque_type *) getdata (n2);
	  struct msg *msg;

	  if (r->lsa_type == OSPF_OPAQUE_LINK_LSA)
	    {

	      /* Yes, this opaque type is ready */
	      msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA,
					  r->opaque_type,
					  oi->address->u.prefix4);
	      if (!msg)
		{
		  zlog_warn ("apiserver_notify_ready_type9: msg_new failed");
#ifdef NOTYET
		  /* Cannot allocate new message. What should we do? */
		  ospf_apiserver_free (apiserv);
#endif
		  goto out;
		}
	      ospf_apiserver_send_msg (apiserv, msg);
	      msg_free (msg);
	    }
	}
    }

out:
  return;
}


/* Notify specific client about all opaque types 10 that are ready. */
void
ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv)
{
  listnode node;
  listnode n2;
  struct ospf *ospf;

  ospf = ospf_lookup ();

  for (node = listhead (ospf->areas); node; nextnode (node))
    {
      struct ospf_area *area = getdata (node);

      if (!ospf_apiserver_is_ready_type10 (area))
	{
	  continue;
	}

      /* Check for registered opaque type 10 types */
      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  struct registered_opaque_type *r =
	    (struct registered_opaque_type *) getdata (n2);
	  struct msg *msg;

	  if (r->lsa_type == OSPF_OPAQUE_AREA_LSA)
	    {
	      /* Yes, this opaque type is ready */
	      msg =
		new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA,
				      r->opaque_type, area->area_id);
	      if (!msg)
		{
		  zlog_warn ("apiserver_notify_ready_type10: msg_new failed");
#ifdef NOTYET
		  /* Cannot allocate new message. What should we do? */
		  ospf_apiserver_free (apiserv);
#endif
		  goto out;
		}
	      ospf_apiserver_send_msg (apiserv, msg);
	      msg_free (msg);
	    }
	}
    }

out:
  return;
}

/* Notify specific client about all opaque types 11 that are ready */
void
ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv)
{
  listnode n2;
  struct ospf *ospf;

  ospf = ospf_lookup ();

  /* Can type 11 be originated? */
  if (!ospf_apiserver_is_ready_type11 (ospf))
    goto out;;

  /* Check for registered opaque type 11 types */
  for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
    {
      struct registered_opaque_type *r =
	(struct registered_opaque_type *) getdata (n2);
      struct msg *msg;
      struct in_addr noarea_id = { 0L };

      if (r->lsa_type == OSPF_OPAQUE_AS_LSA)
	{
	  /* Yes, this opaque type is ready */
	  msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA,
				      r->opaque_type, noarea_id);

	  if (!msg)
	    {
	      zlog_warn ("apiserver_notify_ready_type11: msg_new failed");
#ifdef NOTYET
	      /* Cannot allocate new message. What should we do? */
	      ospf_apiserver_free (apiserv);
#endif
	      goto out;
	    }
	  ospf_apiserver_send_msg (apiserv, msg);
	  msg_free (msg);
	}
    }

out:
  return;
}

int
ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv,
					      struct msg *msg)
{
  struct msg_unregister_opaque_type *umsg;
  u_char ltype;
  u_char otype;
  int rc = 0;

  /* Extract parameters from unregister opaque type message */
  umsg = (struct msg_unregister_opaque_type *) STREAM_DATA (msg->s);

  ltype = umsg->lsatype;
  otype = umsg->opaquetype;

  rc = ospf_apiserver_unregister_opaque_type (apiserv, ltype, otype);

  /* Send a reply back to client including return code */
  rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);

  return rc;
}


/* -----------------------------------------------------------
 * Following are functions for event (filter) registration.
 * -----------------------------------------------------------
 */
int
ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv,
				      struct msg *msg)
{
  struct msg_register_event *rmsg;
  int rc;
  u_int32_t seqnum;

  rmsg = (struct msg_register_event *) STREAM_DATA (msg->s);

  /* Get request sequence number */
  seqnum = msg_get_seq (msg);

  /* Free existing filter in apiserv. */
  XFREE (MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter);
  /* Alloc new space for filter. */

  apiserv->filter = XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER,
			     ntohs (msg->hdr.msglen));
  if (apiserv->filter)
    {
      /* copy it over. */
      memcpy (apiserv->filter, &rmsg->filter, ntohs (msg->hdr.msglen));
      rc = OSPF_API_OK;
    }
  else
    {
      rc = OSPF_API_NOMEMORY;
    }
  /* Send a reply back to client with return code */
  rc = ospf_apiserver_send_reply (apiserv, seqnum, rc);
  return rc;
}


/* -----------------------------------------------------------
 * Followings are functions for LSDB synchronization.
 * -----------------------------------------------------------
 */

int
apiserver_sync_callback (struct ospf_lsa *lsa, void *p_arg, int int_arg)
{
  struct ospf_apiserver *apiserv;
  int seqnum;
  struct msg *msg;
  struct param_t
  {
    struct ospf_apiserver *apiserv;
    struct lsa_filter_type *filter;
  }
   *param;
  int rc = -1;

  /* Sanity check */
  assert (lsa->data);
  assert (p_arg);

  param = (struct param_t *) p_arg;
  apiserv = param->apiserv;
  seqnum = (u_int32_t) int_arg;

  /* Check origin in filter. */
  if ((param->filter->origin == ANY_ORIGIN) ||
      (param->filter->origin == (lsa->flags & OSPF_LSA_SELF)))
    {

      /* Default area for AS-External and Opaque11 LSAs */
      struct in_addr area_id = { 0L };

      /* Default interface for non Opaque9 LSAs */
      struct in_addr ifaddr = { 0L };

      if (lsa->area)
	{
	  area_id = lsa->area->area_id;
	}
      if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
	{
	  ifaddr = lsa->oi->address->u.prefix4;
	}

      msg = new_msg_lsa_change_notify (MSG_LSA_UPDATE_NOTIFY,
				       seqnum,
				       ifaddr, area_id,
				       lsa->flags & OSPF_LSA_SELF, lsa->data);
      if (!msg)
	{
	  zlog_warn ("apiserver_sync_callback: new_msg_update failed");
#ifdef NOTYET
	  /* Cannot allocate new message. What should we do? */
/*        ospf_apiserver_free (apiserv);*//* Do nothing here XXX */
#endif
	  goto out;
	}

      /* Send LSA */
      ospf_apiserver_send_msg (apiserv, msg);
      msg_free (msg);
    }
  rc = 0;

out:
  return rc;
}

int
ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv,
				 struct msg *msg)
{
  listnode node;
  u_int32_t seqnum;
  int rc = 0;
  struct msg_sync_lsdb *smsg;
  struct param_t
  {
    struct ospf_apiserver *apiserv;
    struct lsa_filter_type *filter;
  }
  param;
  u_int16_t mask;
  struct route_node *rn;
  struct ospf_lsa *lsa;
  struct ospf *ospf;

  ospf = ospf_lookup ();

  /* Get request sequence number */
  seqnum = msg_get_seq (msg);
  /* Set sync msg. */
  smsg = (struct msg_sync_lsdb *) STREAM_DATA (msg->s);

  /* Set parameter struct. */
  param.apiserv = apiserv;
  param.filter = &smsg->filter;

  /* Remember mask. */
  mask = ntohs (smsg->filter.typemask);

  /* Iterate over all areas. */
  for (node = listhead (ospf->areas); node; nextnode (node))
    {
      struct ospf_area *area = node->data;
      int i;
      u_int32_t *area_id = NULL;
      /* Compare area_id with area_ids in sync request. */
      if ((i = smsg->filter.num_areas) > 0)
	{
	  /* Let area_id point to the list of area IDs,
	   * which is at the end of smsg->filter. */
	  area_id = (u_int32_t *) (&smsg->filter + 1);
	  while (i)
	    {
	      if (*area_id == area->area_id.s_addr)
		{
		  break;
		}
	      i--;
	      area_id++;
	    }
	}
      else
	{
	  i = 1;
	}

      /* If area was found, then i>0 here. */
      if (i)
	{
	  /* Check msg type. */
	  if (mask & Power2[OSPF_ROUTER_LSA])
	    LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
	      apiserver_sync_callback(lsa, (void *) &param, seqnum);
	  if (mask & Power2[OSPF_NETWORK_LSA])
            LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
              apiserver_sync_callback(lsa, (void *) &param, seqnum);
	  if (mask & Power2[OSPF_SUMMARY_LSA])
            LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
              apiserver_sync_callback(lsa, (void *) &param, seqnum);
	  if (mask & Power2[OSPF_ASBR_SUMMARY_LSA])
            LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
              apiserver_sync_callback(lsa, (void *) &param, seqnum);
	  if (mask & Power2[OSPF_OPAQUE_LINK_LSA])
            LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
              apiserver_sync_callback(lsa, (void *) &param, seqnum);
	  if (mask & Power2[OSPF_OPAQUE_AREA_LSA])
            LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
              apiserver_sync_callback(lsa, (void *) &param, seqnum);
	}
    }

  /* For AS-external LSAs */
  if (ospf->lsdb)
    {
      if (mask & Power2[OSPF_AS_EXTERNAL_LSA])
	LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
	  apiserver_sync_callback(lsa, (void *) &param, seqnum);
    }

  /* For AS-external opaque LSAs */
  if (ospf->lsdb)
    {
      if (mask & Power2[OSPF_OPAQUE_AS_LSA])
	LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
	  apiserver_sync_callback(lsa, (void *) &param, seqnum);
    }

  /* Send a reply back to client with return code */
  rc = ospf_apiserver_send_reply (apiserv, seqnum, rc);
  return rc;
}


/* -----------------------------------------------------------
 * Followings are functions to originate or update LSA
 * from an application.
 * -----------------------------------------------------------
 */

/* Create a new internal opaque LSA by taking prototype and filling in
   missing fields such as age, sequence number, advertising router,
   checksum and so on. The interface parameter is used for type 9
   LSAs, area parameter for type 10. Type 11 LSAs do neither need area
   nor interface. */

struct ospf_lsa *
ospf_apiserver_opaque_lsa_new (struct ospf_area *area,
			       struct ospf_interface *oi,
			       struct lsa_header *protolsa)
{
  struct stream *s;
  struct lsa_header *newlsa;
  struct ospf_lsa *new = NULL;
  u_char options = 0x0;
  u_int16_t length;

  struct ospf *ospf;

  ospf = ospf_lookup();
  assert(ospf);

  /* Create a stream for internal opaque LSA */
  if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL)
    {
      zlog_warn ("ospf_apiserver_opaque_lsa_new: stream_new failed");
      return NULL;
    }

  newlsa = (struct lsa_header *) STREAM_DATA (s);

  /* XXX If this is a link-local LSA or an AS-external LSA, how do we
     have to set options? */

  if (area)
    {
      options = LSA_OPTIONS_GET (area);
      options |= LSA_OPTIONS_NSSA_GET (area);
    }

  options |= OSPF_OPTION_O;	/* Don't forget to set option bit */

  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_info ("LSA[Type%d:%s]: Creating an Opaque-LSA instance",
		 protolsa->type, inet_ntoa (protolsa->id));
    }

  /* Set opaque-LSA header fields. */
  lsa_header_set (s, options, protolsa->type, protolsa->id, 
                  ospf->router_id);

  /* Set opaque-LSA body fields. */
  stream_put (s, ((u_char *) protolsa) + sizeof (struct lsa_header),
	      ntohs (protolsa->length) - sizeof (struct lsa_header));

  /* Determine length of LSA. */
  length = stream_get_endp (s);
  newlsa->length = htons (length);

  /* Create OSPF LSA. */
  if ((new = ospf_lsa_new ()) == NULL)
    {
      zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_new() ?");
      stream_free (s);
      return NULL;
    }

  if ((new->data = ospf_lsa_data_new (length)) == NULL)
    {
      zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_data_new() ?");
      ospf_lsa_free (new);
      new = NULL;
      stream_free (s);
      return NULL;
    }

  new->area = area;
  new->oi = oi;

  SET_FLAG (new->flags, OSPF_LSA_SELF);
  memcpy (new->data, newlsa, length);
  stream_free (s);

  return new;
}


int
ospf_apiserver_is_ready_type9 (struct ospf_interface *oi)
{
  /* Type 9 opaque LSA can be originated if there is at least one
     active opaque-capable neighbor attached to the outgoing
     interface. */

  return (ospf_nbr_count_opaque_capable (oi) > 0);
}

int
ospf_apiserver_is_ready_type10 (struct ospf_area *area)
{
  /* Type 10 opaque LSA can be originated if there is at least one
     interface belonging to the area that has an active opaque-capable
     neighbor. */
  listnode node;

  for (node = listhead (area->oiflist); node; nextnode (node))
    {
      struct ospf_interface *oi = getdata (node);

      /* Is there an active neighbor attached to this interface? */
      if (ospf_apiserver_is_ready_type9 (oi))
	{
	  return 1;
	}
    }
  /* No active neighbor in area */
  return 0;
}

int
ospf_apiserver_is_ready_type11 (struct ospf *ospf)
{
  /* Type 11 opaque LSA can be originated if there is at least one interface
     that has an active opaque-capable neighbor. */
  listnode node;

  for (node = listhead (ospf->oiflist); node; nextnode (node))
    {
      struct ospf_interface *oi = getdata (node);

      /* Is there an active neighbor attached to this interface? */
      if (ospf_apiserver_is_ready_type9 (oi))
	return 1;
    }
  /* No active neighbor at all */
  return 0;
}


int
ospf_apiserver_handle_originate_request (struct ospf_apiserver *apiserv,
					 struct msg *msg)
{
  struct msg_originate_request *omsg;
  struct lsa_header *data;
  struct ospf_lsa *new;
  struct ospf_lsa *old;
  struct ospf_area *area = NULL;
  struct ospf_interface *oi = NULL;
  struct ospf_lsdb *lsdb = NULL;
  struct ospf *ospf;
  int lsa_type, opaque_type;
  int ready = 0;
  int rc = 0;
  
  ospf = ospf_lookup();

  /* Extract opaque LSA data from message */
  omsg = (struct msg_originate_request *) STREAM_DATA (msg->s);
  data = &omsg->data;

  /* Determine interface for type9 or area for type10 LSAs. */
  switch (data->type)
    {
    case OSPF_OPAQUE_LINK_LSA:
      oi = ospf_apiserver_if_lookup_by_addr (omsg->ifaddr);
      if (!oi)
	{
	  zlog_warn ("apiserver_originate: unknown interface %s",
		     inet_ntoa (omsg->ifaddr));
	  rc = OSPF_API_NOSUCHINTERFACE;
	  goto out;
	}
      area = oi->area;
      lsdb = area->lsdb;
      break;
    case OSPF_OPAQUE_AREA_LSA:
      area = ospf_area_lookup_by_area_id (ospf, omsg->area_id);
      if (!area)
	{
	  zlog_warn ("apiserver_originate: unknown area %s",
		     inet_ntoa (omsg->area_id));
	  rc = OSPF_API_NOSUCHAREA;
	  goto out;
	}
      lsdb = area->lsdb;
      break;
    case OSPF_OPAQUE_AS_LSA:
      lsdb = ospf->lsdb;
      break;
    default:
      /* We can only handle opaque types here */
      zlog_warn ("apiserver_originate: Cannot originate non-opaque LSA type %d",
		 data->type);
      rc = OSPF_API_ILLEGALLSATYPE;
      goto out;
    }

  /* Check if we registered this opaque type */
  lsa_type = data->type;
  opaque_type = GET_OPAQUE_TYPE (ntohl (data->id.s_addr));

  if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type))
    {
      zlog_warn ("apiserver_originate: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type);
      rc = OSPF_API_OPAQUETYPENOTREGISTERED;
      goto out;
    }

  /* Make sure that the neighbors are ready before we can originate */
  switch (data->type)
    {
    case OSPF_OPAQUE_LINK_LSA:
      ready = ospf_apiserver_is_ready_type9 (oi);
      break;
    case OSPF_OPAQUE_AREA_LSA:
      ready = ospf_apiserver_is_ready_type10 (area);
      break;
    case OSPF_OPAQUE_AS_LSA:
      ready = ospf_apiserver_is_ready_type11 (ospf);
      break;
    default:
      break;
    }

  if (!ready)
    {
      zlog_warn ("Neighbors not ready to originate type %d", data->type);
      rc = OSPF_API_NOTREADY;
      goto out;
    }

  /* Create OSPF's internal opaque LSA representation */
  new = ospf_apiserver_opaque_lsa_new (area, oi, data);
  if (!new)
    {
      rc = OSPF_API_NOMEMORY;	/* XXX */
      goto out;
    }

  /* Determine if LSA is new or an update for an existing one. */
  old = ospf_lsdb_lookup (lsdb, new);

  if (!old)
    {
      /* New LSA install in LSDB. */
      rc = ospf_apiserver_originate1 (new);
    }
  else
    {
      /*
       * Keep the new LSA instance in the "waiting place" until the next
       * refresh timing. If several LSA update requests for the same LSID
       * have issued by peer, the last one takes effect.
       */
      new->lsdb = &apiserv->reserve;
      ospf_lsdb_add (&apiserv->reserve, new);

      /* Kick the scheduler function. */
      ospf_opaque_lsa_refresh_schedule (old);
    }

out:

  /* Send a reply back to client with return code */
  rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
  return rc;
}


/* -----------------------------------------------------------
 * Flood an LSA within its flooding scope. 
 * -----------------------------------------------------------
 */

/* XXX We can probably use ospf_flood_through instead of this function
   but then we need the neighbor parameter. If we set nbr to 
   NULL then ospf_flood_through crashes due to dereferencing NULL. */

void
ospf_apiserver_flood_opaque_lsa (struct ospf_lsa *lsa)
{
  assert (lsa);

  switch (lsa->data->type)
    {
    case OSPF_OPAQUE_LINK_LSA:
      /* Increment counters? XXX */

      /* Flood LSA through local network. */
      ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa);
      break;
    case OSPF_OPAQUE_AREA_LSA:
      /* Update LSA origination count. */
      assert (lsa->area);
      lsa->area->ospf->lsa_originate_count++;

      /* Flood LSA through area. */
      ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa);
      break;
    case OSPF_OPAQUE_AS_LSA:
      {
	struct ospf *ospf;

	ospf = ospf_lookup();
	assert(ospf);

	/* Increment counters? XXX */

	/* Flood LSA through AS. */
	ospf_flood_through_as (ospf, NULL /*nbr */ , lsa);
	break;
      }
    }
}

int
ospf_apiserver_originate1 (struct ospf_lsa *lsa)
{
  struct ospf *ospf;

  ospf = ospf_lookup();
  assert(ospf);

  /* Install this LSA into LSDB. */
  if (ospf_lsa_install (ospf, lsa->oi, lsa) == NULL)
    {
      zlog_warn ("ospf_apiserver_originate1: ospf_lsa_install failed");
      return -1;
    }

  /* Flood LSA within scope */

#ifdef NOTYET
  /*
   * NB: Modified version of "ospf_flood_though ()" accepts NULL "inbr"
   *     parameter, and thus it does not cause SIGSEGV error.
   */
  ospf_flood_through (NULL /*nbr */ , lsa);
#else /* NOTYET */

  ospf_apiserver_flood_opaque_lsa (lsa);
#endif /* NOTYET */

  return 0;
}


/* Opaque LSAs of type 9 on a specific interface can now be
   originated. Tell clients that registered type 9. */
int
ospf_apiserver_lsa9_originator (void *arg)
{
  struct ospf_interface *oi;

  oi = (struct ospf_interface *) arg;
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_ready_type9 (oi);
  }
  return 0;
}

int
ospf_apiserver_lsa10_originator (void *arg)
{
  struct ospf_area *area;

  area = (struct ospf_area *) arg;
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_ready_type10 (area);
  }
  return 0;
}

int
ospf_apiserver_lsa11_originator (void *arg)
{
  struct ospf *ospf;

  ospf = (struct ospf *) arg;
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_ready_type11 (ospf);
  }
  return 0;
}


/* Periodically refresh opaque LSAs so that they do not expire in
   other routers. */
void
ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)
{
  struct ospf_apiserver *apiserv;
  struct ospf_lsa *new = NULL;
  struct ospf * ospf;

  ospf = ospf_lookup();
  assert(ospf);

  apiserv = lookup_apiserver_by_lsa (lsa);
  if (!apiserv)
    {
      zlog_warn ("ospf_apiserver_lsa_refresher: LSA[%s]: No apiserver?", dump_lsa_key (lsa));
      lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */
    }

  if (IS_LSA_MAXAGE (lsa))
    {
      ospf_opaque_lsa_flush_schedule (lsa);
      goto out;
    }

  /* Check if updated version of LSA instance has already prepared. */
  new = ospf_lsdb_lookup (&apiserv->reserve, lsa);
  if (!new)
    {
      /* This is a periodic refresh, driven by core OSPF mechanism. */
      new = ospf_apiserver_opaque_lsa_new (lsa->area, lsa->oi, lsa->data);
      if (!new)
        {
          zlog_warn ("ospf_apiserver_lsa_refresher: Cannot create a new LSA?");
          goto out;
        }
    }
  else
    {
      /* This is a forcible refresh, requested by OSPF-API client. */
      ospf_lsdb_delete (&apiserv->reserve, new);
      new->lsdb = NULL;
    }

  /* Increment sequence number */
  new->data->ls_seqnum = lsa_seqnum_increment (lsa);

  /* New LSA is in same area. */
  new->area = lsa->area;
  SET_FLAG (new->flags, OSPF_LSA_SELF);

  /* Install LSA into LSDB. */
  if (ospf_lsa_install (ospf, new->oi, new) == NULL)
    {
      zlog_warn ("ospf_apiserver_lsa_refresher: ospf_lsa_install failed");
      ospf_lsa_free (new);
      goto out;
    }

  /* Flood updated LSA through interface, area or AS */

#ifdef NOTYET
  ospf_flood_through (NULL /*nbr */ , new);
#endif /* NOTYET */
  ospf_apiserver_flood_opaque_lsa (new);

  /* Debug logging. */
  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
    {
      zlog_info ("LSA[Type%d:%s]: Refresh Opaque LSA",
		 new->data->type, inet_ntoa (new->data->id));
      ospf_lsa_header_dump (new->data);
    }

out:
  return;
}


/* -----------------------------------------------------------
 * Followings are functions to delete LSAs
 * -----------------------------------------------------------
 */

int
ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv,
				      struct msg *msg)
{
  struct msg_delete_request *dmsg;
  struct ospf_lsa *old;
  struct ospf_area *area = NULL;
  struct in_addr id;
  int lsa_type, opaque_type;
  int rc = 0;
  struct ospf * ospf;

  ospf = ospf_lookup();
  assert(ospf);

  /* Extract opaque LSA from message */
  dmsg = (struct msg_delete_request *) STREAM_DATA (msg->s);

  /* Lookup area for link-local and area-local opaque LSAs */
  switch (dmsg->lsa_type)
    {
    case OSPF_OPAQUE_LINK_LSA:
    case OSPF_OPAQUE_AREA_LSA:
      area = ospf_area_lookup_by_area_id (ospf, dmsg->area_id);
      if (!area)
	{
	  zlog_warn ("ospf_apiserver_lsa_delete: unknown area %s",
		     inet_ntoa (dmsg->area_id));
	  rc = OSPF_API_NOSUCHAREA;
	  goto out;
	}
      break;
    case OSPF_OPAQUE_AS_LSA:
      /* AS-external opaque LSAs have no designated area */
      area = NULL;
      break;
    default:
      zlog_warn
	("ospf_apiserver_lsa_delete: Cannot delete non-opaque LSA type %d",
	 dmsg->lsa_type);
      rc = OSPF_API_ILLEGALLSATYPE;
      goto out;
    }

  /* Check if we registered this opaque type */
  lsa_type = dmsg->lsa_type;
  opaque_type = dmsg->opaque_type;

  if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type))
    {
      zlog_warn ("ospf_apiserver_lsa_delete: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type);
      rc = OSPF_API_OPAQUETYPENOTREGISTERED;
      goto out;
    }

  /* opaque_id is in network byte order */
  id.s_addr = htonl (SET_OPAQUE_LSID (dmsg->opaque_type,
				      ntohl (dmsg->opaque_id)));

  /*
   * Even if the target LSA has once scheduled to flush, it remains in
   * the LSDB until it is finally handled by the maxage remover thread.
   * Therefore, the lookup function below may return non-NULL result.
   */
  old = ospf_lsa_lookup (area, dmsg->lsa_type, id, ospf->router_id);
  if (!old)
    {
      zlog_warn ("ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
		 dmsg->lsa_type, inet_ntoa (id));
      rc = OSPF_API_NOSUCHLSA;
      goto out;
    }

  /* Schedule flushing of LSA from LSDB */
  /* NB: Multiple scheduling will produce a warning message, but harmless. */
  ospf_opaque_lsa_flush_schedule (old);

out:

  /* Send reply back to client including return code */
  rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
  return rc;
}

/* Flush self-originated opaque LSA */
int
apiserver_flush_opaque_type_callback (struct ospf_lsa *lsa,
				      void *p_arg, int int_arg)
{
  struct param_t
  {
    struct ospf_apiserver *apiserv;
    u_char lsa_type;
    u_char opaque_type;
  }
   *param;

  /* Sanity check */
  assert (lsa->data);
  assert (p_arg);
  param = (struct param_t *) p_arg;

  /* If LSA matches type and opaque type then delete it */
  if (IS_LSA_SELF (lsa) && lsa->data->type == param->lsa_type
      && GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)) == param->opaque_type)
    {
      ospf_opaque_lsa_flush_schedule (lsa);
    }
  return 0;
}

/* Delete self-originated opaque LSAs of a given opaque type. This
   function is called when an application unregisters a given opaque
   type or a connection to an application closes and all those opaque
   LSAs need to be flushed the LSDB. */
void
ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv,
				 u_char lsa_type, u_char opaque_type)
{
  struct param_t
  {
    struct ospf_apiserver *apiserv;
    u_char lsa_type;
    u_char opaque_type;
  }
  param;
  listnode node;
  struct ospf * ospf;

  ospf = ospf_lookup();
  assert(ospf);

  /* Set parameter struct. */
  param.apiserv = apiserv;
  param.lsa_type = lsa_type;
  param.opaque_type = opaque_type;

#ifdef ORIGINAL_CODING
  /* Iterate over all areas */
  for (node = listhead (ospf_top->areas); node; nextnode (node))
    {
      struct ospf_area *area = node->data;

      foreach_lsa (OPAQUE_LINK_LSDB (area), (void *) &param, 0,
		   apiserver_flush_opaque_type_callback);
      foreach_lsa (OPAQUE_AREA_LSDB (area), (void *) &param, 0,
		   apiserver_flush_opaque_type_callback);
    }

  /* For AS-external opaque LSAs */
  if (ospf->lsdb)
    {
      foreach_lsa (OPAQUE_AS_LSDB (ospf_top), (void *) &param, 0,
		   apiserver_flush_opaque_type_callback);
    }
#else /* ORIGINAL_CODING */
  switch (lsa_type)
    {
      struct route_node *rn;
      struct ospf_lsa *lsa;

    case OSPF_OPAQUE_LINK_LSA:
      for (node = listhead (ospf->areas); node; nextnode (node))
        {
          struct ospf_area *area = node->data;
	  LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
	    apiserver_flush_opaque_type_callback(lsa, (void *) &param, 0);
        }
      break;
    case OSPF_OPAQUE_AREA_LSA:
      for (node = listhead (ospf->areas); node; nextnode (node))
        {
          struct ospf_area *area = node->data;
	  LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
	    apiserver_flush_opaque_type_callback(lsa, (void *) &param, 0);
        }
      break;
    case OSPF_OPAQUE_AS_LSA:
      LSDB_LOOP (OPAQUE_LINK_LSDB (ospf), rn, lsa)
	apiserver_flush_opaque_type_callback(lsa, (void *) &param, 0);
      break;
    default:
      break;
    }
  return;
#endif /* ORIGINAL_CODING */
}


/* -----------------------------------------------------------
 * Followings are callback functions to handle opaque types 
 * -----------------------------------------------------------
 */

int
ospf_apiserver_new_if (struct interface *ifp)
{
  struct ospf_interface *oi;

  /* For some strange reason it seems possible that we are invoked
     with an interface that has no name. This seems to happen during
     initialization. Return if this happens */

  if (ifp->name[0] == '\0') {
    /* interface has empty name */
    zlog_warn ("ospf_apiserver_new_if: interface has no name?");
    return 0;
  }

  /* zlog_warn for debugging */
  zlog_warn ("ospf_apiserver_new_if");
  zlog_warn ("ifp name=%s status=%d index=%d", ifp->name, ifp->status,
	     ifp->ifindex);

  if (ifp->name[0] == '\0') {
    /* interface has empty name */
    zlog_warn ("ospf_apiserver_new_if: interface has no name?");
    return 0;
  }

  oi = ospf_apiserver_if_lookup_by_ifp (ifp);
  
  if (!oi) {
    /* This interface is known to Zebra but not to OSPF daemon yet. */
    zlog_warn ("ospf_apiserver_new_if: interface %s not known to OSPFd?", 
	       ifp->name);
    return 0;
  }

  assert (oi);

  /* New interface added to OSPF, tell clients about it */
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_new_if (oi);
  }
  return 0;
}

int
ospf_apiserver_del_if (struct interface *ifp)
{
  struct ospf_interface *oi;

  /* zlog_warn for debugging */
  zlog_warn ("ospf_apiserver_del_if");
  zlog_warn ("ifp name=%s status=%d index=%d\n", ifp->name, ifp->status,
	     ifp->ifindex);

  oi = ospf_apiserver_if_lookup_by_ifp (ifp);

  if (!oi) {
    /* This interface is known to Zebra but not to OSPF daemon
       anymore. No need to tell clients about it */
    return 0;
  }

  /* Interface deleted, tell clients about it */
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_del_if (oi);
  }
  return 0;
}

void
ospf_apiserver_ism_change (struct ospf_interface *oi, int old_state)
{
  /* Tell clients about interface change */

  /* zlog_warn for debugging */
  zlog_warn ("ospf_apiserver_ism_change");
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_ism_change (oi);
  }

  zlog_warn ("oi->ifp->name=%s", oi->ifp->name);
  zlog_warn ("old_state=%d", old_state);
  zlog_warn ("oi->state=%d", oi->state);
}

void
ospf_apiserver_nsm_change (struct ospf_neighbor *nbr, int old_status)
{
  /* Neighbor status changed, tell clients about it */
  zlog_warn ("ospf_apiserver_nsm_change");
  if (listcount (apiserver_list) > 0) {
    ospf_apiserver_clients_notify_nsm_change (nbr);
  }
}

void
ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa)
{
  struct opaque_lsa
  {
    struct lsa_header header;
    u_char data[1]; /* opaque data have variable length. This is start
                       address */
  };
  struct opaque_lsa *olsa;
  int opaquelen;

  olsa = (struct opaque_lsa *) lsa->data;

  if (VALID_OPAQUE_INFO_LEN (lsa->data))
    {
      opaquelen = ntohs (lsa->data->length) - OSPF_LSA_HEADER_SIZE;
    }
  else
    {
      opaquelen = 0;
    }

  /* Output information about opaque LSAs */
  if (vty != NULL)
    {
      int i;
      vty_out (vty, "  Added using OSPF API: %u octets of opaque data %s%s",
	       opaquelen,
	       VALID_OPAQUE_INFO_LEN (lsa->data) ? "" : "(Invalid length?)",
	       VTY_NEWLINE);
      vty_out (vty, "  Opaque data: ");

      for (i = 0; i < opaquelen; i++)
	{
	  vty_out (vty, "0x%x ", olsa->data[i]);
	}
      vty_out (vty, "%s", VTY_NEWLINE);
    }
  else
    {
      int i;
      zlog_info ("    Added using OSPF API: %u octets of opaque data %s",
		 opaquelen,
		 VALID_OPAQUE_INFO_LEN (lsa->
					data) ? "" : "(Invalid length?)");
      zlog_info ("    Opaque data: ");

      for (i = 0; i < opaquelen; i++)
	{
	  zlog_info ("0x%x ", olsa->data[i]);
	}
      zlog_info ("\n");
    }
  return;
}

/* -----------------------------------------------------------
 * Followings are functions to notify clients about events
 * -----------------------------------------------------------
 */

/* Send a message to all clients. This is useful for messages
   that need to be notified to all clients (such as interface
   changes) */

void
ospf_apiserver_clients_notify_all (struct msg *msg)
{
  listnode node;

  /* Send message to all clients */
  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv =
	(struct ospf_apiserver *) getdata (node);

      ospf_apiserver_send_msg (apiserv, msg);
    }
}

/* An interface is now ready to accept opaque LSAs. Notify all
   clients that registered to use this opaque type */
void
ospf_apiserver_clients_notify_ready_type9 (struct ospf_interface *oi)
{
  listnode node;
  struct msg *msg;

  assert (oi);
  if (!oi->address)
    {
      zlog_warn ("Interface has no address?");
      return;
    }

  if (!ospf_apiserver_is_ready_type9 (oi))
    {
      zlog_warn ("Interface not ready for type 9?");
      return;
    }

  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv =
	(struct ospf_apiserver *) getdata (node);
      listnode n2;

      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  struct registered_opaque_type *r =
	    (struct registered_opaque_type *) getdata (n2);
	  if (r->lsa_type == OSPF_OPAQUE_LINK_LSA)
	    {
	      msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA,
					  r->opaque_type,
					  oi->address->u.prefix4);
	      if (!msg)
		{
		  zlog_warn
		    ("ospf_apiserver_clients_notify_ready_type9: new_msg_ready_notify failed");
#ifdef NOTYET
		  /* Cannot allocate new message. What should we do? */
		  ospf_apiserver_free (apiserv);
#endif
		  goto out;
		}

	      ospf_apiserver_send_msg (apiserv, msg);
	      msg_free (msg);
	    }
	}
    }

out:
  return;
}

void
ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area)
{
  listnode node;
  struct msg *msg;

  assert (area);

  if (!ospf_apiserver_is_ready_type10 (area))
    {
      zlog_warn ("Area not ready for type 10?");
      return;
    }

  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv =
	(struct ospf_apiserver *) getdata (node);
      listnode n2;

      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  struct registered_opaque_type *r =
	    (struct registered_opaque_type *) getdata (n2);
	  if (r->lsa_type == OSPF_OPAQUE_AREA_LSA)
	    {
	      msg = new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA,
					  r->opaque_type, area->area_id);
	      if (!msg)
		{
		  zlog_warn
		    ("ospf_apiserver_clients_notify_ready_type10: new_msg_ready_nofity failed");
#ifdef NOTYET
		  /* Cannot allocate new message. What should we do? */
		  ospf_apiserver_free (apiserv);
#endif
		  goto out;
		}

	      ospf_apiserver_send_msg (apiserv, msg);
	      msg_free (msg);
	    }
	}
    }

out:
  return;
}


void
ospf_apiserver_clients_notify_ready_type11 (struct ospf *top)
{
  listnode node;
  struct msg *msg;
  struct in_addr id_null = { 0L };

  assert (top);

  if (!ospf_apiserver_is_ready_type11 (top))
    {
      zlog_warn ("AS not ready for type 11?");
      return;
    }

  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv =
	(struct ospf_apiserver *) getdata (node);
      listnode n2;

      for (n2 = listhead (apiserv->opaque_types); n2; nextnode (n2))
	{
	  struct registered_opaque_type *r =
	    (struct registered_opaque_type *) getdata (n2);
	  if (r->lsa_type == OSPF_OPAQUE_AS_LSA)
	    {
	      msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA,
					  r->opaque_type, id_null);
	      if (!msg)
		{
		  zlog_warn
		    ("ospf_apiserver_clients_notify_ready_type11: new_msg_ready_notify failed");
#ifdef NOTYET
		  /* Cannot allocate new message. What should we do? */
		  ospf_apiserver_free (apiserv);
#endif
		  goto out;
		}

	      ospf_apiserver_send_msg (apiserv, msg);
	      msg_free (msg);
	    }
	}
    }

out:
  return;
}

void
ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi)
{
  struct msg *msg;

  msg = new_msg_new_if (0, oi->address->u.prefix4, oi->area->area_id);
  if (msg != NULL)
    {
      ospf_apiserver_clients_notify_all (msg);
      msg_free (msg);
    }
}

void
ospf_apiserver_clients_notify_del_if (struct ospf_interface *oi)
{
  struct msg *msg;

  msg = new_msg_del_if (0, oi->address->u.prefix4);
  if (msg != NULL)
    {
      ospf_apiserver_clients_notify_all (msg);
      msg_free (msg);
    }
}

void
ospf_apiserver_clients_notify_ism_change (struct ospf_interface *oi)
{
  struct msg *msg;
  struct in_addr ifaddr = { 0L };
  struct in_addr area_id = { 0L };

  assert (oi);
  assert (oi->ifp);

  if (oi->address)
    {
      ifaddr = oi->address->u.prefix4;
    }
  if (oi->area)
    {
      area_id = oi->area->area_id;
    }

  msg = new_msg_ism_change (0, ifaddr, area_id, oi->ifp->status);
  if (!msg)
    {
      zlog_warn ("apiserver_clients_notify_ism_change: msg_new failed");
      return;
    }

  ospf_apiserver_clients_notify_all (msg);
  msg_free (msg);
}

void
ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr)
{
  struct msg *msg;
  struct in_addr ifaddr = { 0L };
  struct in_addr nbraddr = { 0L };

  assert (nbr);

  if (nbr->oi)
    {
      ifaddr = nbr->oi->address->u.prefix4;
    }

  nbraddr = nbr->address.u.prefix4;

  msg = new_msg_nsm_change (0, ifaddr, nbraddr, nbr->router_id, nbr->state);
  if (!msg)
    {
      zlog_warn ("apiserver_clients_notify_nsm_change: msg_new failed");
      return;
    }

  ospf_apiserver_clients_notify_all (msg);
  msg_free (msg);
}

void
apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa)
{
  struct msg *msg;
  listnode node;

  /* Default area for AS-External and Opaque11 LSAs */
  struct in_addr area_id = { 0L };

  /* Default interface for non Opaque9 LSAs */
  struct in_addr ifaddr = { 0L };

  if (lsa->area)
    {
      area_id = lsa->area->area_id;
    }
  if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
    {
      assert (lsa->oi);
      ifaddr = lsa->oi->address->u.prefix4;
    }

  /* Prepare message that can be sent to clients that have a matching
     filter */
  msg = new_msg_lsa_change_notify (msgtype, 0L,	/* no sequence number */
				   ifaddr, area_id,
				   lsa->flags & OSPF_LSA_SELF, lsa->data);
  if (!msg)
    {
      zlog_warn ("apiserver_clients_lsa_change_notify: msg_new failed");
      return;
    }

  /* Now send message to all clients with a matching filter */
  for (node = listhead (apiserver_list); node; nextnode (node))
    {
      struct ospf_apiserver *apiserv = (struct ospf_apiserver *) node->data;
      struct lsa_filter_type *filter;
      u_int16_t mask;
      u_int32_t *area;
      int i;

      /* Check filter for this client. */
      filter = apiserv->filter;

      /* Check area IDs in case of non AS-E LSAs.
       * If filter has areas (num_areas > 0),
       * then one of the areas must match the area ID of this LSA. */

      i = filter->num_areas;
      if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) ||
	  (lsa->data->type == OSPF_OPAQUE_AS_LSA))
	{
	  i = 0;
	}

      if (i > 0)
	{
	  area = (u_int32_t *) (filter + 1);
	  while (i)
	    {
	      if (*area == area_id.s_addr)
		{
		  break;
		}
	      i--;
	      area++;
	    }
	}
      else
	{
	  i = 1;
	}

      if (i > 0)
	{
	  /* Area match. Check LSA type. */
	  mask = ntohs (filter->typemask);

	  if (mask & Power2[lsa->data->type])
	    {
	      /* Type also matches. Check origin. */
	      if ((filter->origin == ANY_ORIGIN) ||
		  (filter->origin == IS_LSA_SELF (lsa)))
		{
		  ospf_apiserver_send_msg (apiserv, msg);
		}
	    }
	}
    }
  /* Free message since it is not used anymore */
  msg_free (msg);
}


/* -------------------------------------------------------------
 * Followings are hooks invoked when LSAs are updated or deleted
 * -------------------------------------------------------------
 */


int
apiserver_notify_clients_lsa (u_char msgtype, struct ospf_lsa *lsa)
{
  struct msg *msg;
  /* default area for AS-External and Opaque11 LSAs */
  struct in_addr area_id = { 0L };

  /* default interface for non Opaque9 LSAs */
  struct in_addr ifaddr = { 0L };

  /* Only notify this update if the LSA's age is smaller than
     MAXAGE. Otherwise clients would see LSA updates with max age just
     before they are deleted from the LSDB. LSA delete messages have
     MAXAGE too but should not be filtered. */
  if (IS_LSA_MAXAGE(lsa) && (msgtype == MSG_LSA_UPDATE_NOTIFY)) {
    return 0;
  }

  if (lsa->area)
    {
      area_id = lsa->area->area_id;
    }
  if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
    {
      ifaddr = lsa->oi->address->u.prefix4;
    }
  msg = new_msg_lsa_change_notify (msgtype, 0L,	/* no sequence number */
				   ifaddr, area_id,
				   lsa->flags & OSPF_LSA_SELF, lsa->data);
  if (!msg)
    {
      zlog_warn ("notify_clients_lsa: msg_new failed");
      return -1;
    }
  /* Notify all clients that new LSA is added/updated */
  apiserver_clients_lsa_change_notify (msgtype, lsa);

  /* Clients made their own copies of msg so we can free msg here */
  msg_free (msg);

  return 0;
}

int
ospf_apiserver_lsa_update (struct ospf_lsa *lsa)
{
  return apiserver_notify_clients_lsa (MSG_LSA_UPDATE_NOTIFY, lsa);
}

int
ospf_apiserver_lsa_delete (struct ospf_lsa *lsa)
{
  return apiserver_notify_clients_lsa (MSG_LSA_DELETE_NOTIFY, lsa);
}

#endif /* SUPPORT_OSPF_API */

