/*
 * 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);
#ifdef HAVE_NSSA
      options |= LSA_OPTIONS_NSSA_GET (area);
#endif /* HAVE_NSSA */
    }

  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 */

