/*
 * 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. */
struct list *apiserver_list;

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

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

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

  for (node = listhead (ospf->oiflist); node; nextnode (node))
  LIST_LOOP (ospf->oiflist, oi, node)
    if (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)
{
  struct listnode *node;
  struct ospf_interface *oi;
  struct ospf *ospf;

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

  LIST_LOOP (ospf->oiflist, oi, node)
    if (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)
{
  struct listnode *node;
  struct ospf_apiserver *apiserv;

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

  /* Free all client instances */
  while ( (node = listhead (apiserver_list)) != NULL)
    /*
     * XXX: this is just plain odd/wrong.  Is there a missing
     * apiserv = (struct ospf_apiserver *) 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)
{
  struct listnode *n1, *n2;
  struct registered_opaque_type *r;
  struct ospf_apiserver *apiserv, *found = NULL;

  /* XXX: this approaches O(n**2) */
  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_debug ("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_debug ("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)
{
  struct 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_debug ("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_debug ("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_debug ("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_debug ("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_debug ("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",
                 safe_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", safe_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", safe_strerror (errno));
      close (new_sync_sock);
      return -1;
    }

  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("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", safe_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", safe_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", safe_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_debug ("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_debug ("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)
{
  struct listnode *n1, *n1_next;
  struct registered_opaque_type *regtype;

  for (n1 = listhead (apiserv->opaque_types); n1; n1 = n1_next)
    {
      n1_next = n1->next;
      
      regtype = (struct registered_opaque_type *) getdata(n1);

      /* 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_debug ("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)
{
  struct listnode *node;
  struct registered_opaque_type *regtype;

  /* XXX: how many types are there? if few, why not just a bitmap? */
  LIST_LOOP (apiserv->opaque_types, regtype, node)
    {
      /* 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)
{
  struct listnode *node;
  struct listnode *n2;
  struct ospf *ospf;
  struct ospf_interface *oi;
  struct registered_opaque_type *r;

  ospf = ospf_lookup ();

  LIST_LOOP (ospf->oiflist, oi, 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 */
      /* XXX: loop-de-loop - optimise me */
      LIST_LOOP (apiserv->opaque_types, r, 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)
{
  struct listnode *node;
  struct listnode *n2;
  struct ospf *ospf;
  struct ospf_area *area;
  
  ospf = ospf_lookup ();

  LIST_LOOP (ospf->areas, area, node)
    {
      struct registered_opaque_type *r;
      
      if (!ospf_apiserver_is_ready_type10 (area))
	{
	  continue;
	}

      /* Check for registered opaque type 10 types */
      /* XXX: loop in loop - optimise me */
      LIST_LOOP (apiserv->opaque_types, r, 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)
{
  struct listnode *node;
  struct ospf *ospf;
  struct registered_opaque_type *r;

  ospf = ospf_lookup ();

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

  /* Check for registered opaque type 11 types */
  LIST_LOOP (apiserv->opaque_types, r, node)
    {
      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)
{
  struct 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;
  struct ospf_area *area;

  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. */
  LIST_LOOP (ospf->areas, area, node)
    {
      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_debug ("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_unlock (new);
      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. */
  struct listnode *node;
  struct ospf_interface *oi;

  LIST_LOOP (area->oiflist, oi, 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. */
  struct listnode *node;
  struct ospf_interface *oi;

  LIST_LOOP (ospf->oiflist, oi, 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_unlock (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_debug ("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;
  struct listnode *node;
  struct ospf * ospf;
  struct ospf_area *area;
  
  ospf = ospf_lookup();
  assert(ospf);

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

  switch (lsa_type)
    {
      struct route_node *rn;
      struct ospf_lsa *lsa;

    case OSPF_OPAQUE_LINK_LSA:
      LIST_LOOP (ospf->areas, area, node)
        LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
          apiserver_flush_opaque_type_callback(lsa, (void *) &param, 0);
      break;
    case OSPF_OPAQUE_AREA_LSA:
      LIST_LOOP (ospf->areas, area, node)
        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;
}


/* -----------------------------------------------------------
 * 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_debug ("    Added using OSPF API: %u octets of opaque data %s",
		 opaquelen,
		 VALID_OPAQUE_INFO_LEN (lsa->
					data) ? "" : "(Invalid length?)");
      zlog_debug ("    Opaque data: ");

      for (i = 0; i < opaquelen; i++)
	{
	  zlog_debug ("0x%x ", olsa->data[i]);
	}
      zlog_debug ("\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)
{
  struct listnode *node;
  struct ospf_apiserver *apiserv;

  /* Send message to all clients */
  LIST_LOOP (apiserver_list, apiserv, 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)
{
  struct listnode *node;
  struct msg *msg;
  struct ospf_apiserver *apiserv;

  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;
    }

  LIST_LOOP (apiserver_list, apiserv, node)
    {
      struct listnode *n2;
      struct registered_opaque_type *r;

      LIST_LOOP (apiserv->opaque_types, r, 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)
{
  struct listnode *node;
  struct msg *msg;
  struct ospf_apiserver *apiserv;

  assert (area);

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

  LIST_LOOP (apiserver_list, apiserv, node)
    {
      struct listnode *n2;
      struct registered_opaque_type *r;

      LIST_LOOP (apiserv->opaque_types, r, 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)
{
  struct listnode *node;
  struct msg *msg;
  struct in_addr id_null = { 0L };
  struct ospf_apiserver *apiserv;

  assert (top);

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

  LIST_LOOP (apiserver_list, apiserv, node)
    {
      struct listnode *n2;
      struct registered_opaque_type *r;

      LIST_LOOP (apiserv->opaque_types, r, 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;
  struct listnode *node;
  struct ospf_apiserver *apiserv;

  /* 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 */
  LIST_LOOP (apiserver_list, apiserv, node)
    {
      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 */

