diff options
Diffstat (limited to 'ospfd/ospf_apiserver.c')
| -rw-r--r-- | ospfd/ospf_apiserver.c | 4053 |
1 files changed, 1948 insertions, 2105 deletions
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 2b72abcd75..a5f5971ac0 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -34,12 +34,12 @@ #include "log.h" #include "thread.h" #include "hash.h" -#include "sockunion.h" /* for inet_aton() */ +#include "sockunion.h" /* for inet_aton() */ #include "buffer.h" #include <sys/types.h> -#include "ospfd/ospfd.h" /* for "struct thread_master" */ +#include "ospfd/ospfd.h" /* for "struct thread_master" */ #include "ospfd/ospf_interface.h" #include "ospfd/ospf_ism.h" #include "ospfd/ospf_asbr.h" @@ -76,39 +76,37 @@ struct list *apiserver_list; * ----------------------------------------------------------- */ -struct ospf_interface * -ospf_apiserver_if_lookup_by_addr (struct in_addr address) +struct ospf_interface *ospf_apiserver_if_lookup_by_addr(struct in_addr address) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - struct ospf *ospf; + struct listnode *node, *nnode; + struct ospf_interface *oi; + struct ospf *ospf; - if (!(ospf = ospf_lookup ())) - return NULL; + if (!(ospf = ospf_lookup())) + return NULL; - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - if (oi->type != OSPF_IFTYPE_VIRTUALLINK) - if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4)) - return oi; + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + if (oi->type != OSPF_IFTYPE_VIRTUALLINK) + if (IPV4_ADDR_SAME(&address, &oi->address->u.prefix4)) + return oi; - return NULL; + return NULL; } -struct ospf_interface * -ospf_apiserver_if_lookup_by_ifp (struct interface *ifp) +struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp) { - struct listnode *node, *nnode; - struct ospf_interface *oi; - struct ospf *ospf; + struct listnode *node, *nnode; + struct ospf_interface *oi; + struct ospf *ospf; - if (!(ospf = ospf_lookup ())) - return NULL; + if (!(ospf = ospf_lookup())) + return NULL; - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - if (oi->ifp == ifp) - return oi; + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + if (oi->ifp == ifp) + return oi; - return NULL; + return NULL; } /* ----------------------------------------------------------- @@ -116,644 +114,604 @@ ospf_apiserver_if_lookup_by_ifp (struct interface *ifp) * ----------------------------------------------------------- */ -unsigned short -ospf_apiserver_getport (void) +unsigned short ospf_apiserver_getport(void) { - struct servent *sp = getservbyname ("ospfapi", "tcp"); + struct servent *sp = getservbyname("ospfapi", "tcp"); - return sp ? ntohs (sp->s_port) : OSPF_API_SYNC_PORT; + 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 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; + 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; + return rc; } /* Terminate OSPF API module. */ -void -ospf_apiserver_term (void) +void ospf_apiserver_term(void) { - struct ospf_apiserver *apiserv; - - /* Unregister wildcard [0/0] type */ - ospf_delete_opaque_functab (0 /* all LSAs */, - 0 /* all opaque types */); - - /* - * Free all client instances. ospf_apiserver_free removes the node - * from the list, so we examine the head of the list anew each time. - */ - while ( apiserver_list && - (apiserv = listgetdata (listhead (apiserver_list))) != NULL) - ospf_apiserver_free (apiserv); - - /* Free client list itself */ - if (apiserver_list) - list_delete (apiserver_list); - - /* Free wildcard list */ - /* XXX */ + struct ospf_apiserver *apiserv; + + /* Unregister wildcard [0/0] type */ + ospf_delete_opaque_functab(0 /* all LSAs */, 0 /* all opaque types */); + + /* + * Free all client instances. ospf_apiserver_free removes the node + * from the list, so we examine the head of the list anew each time. + */ + while (apiserver_list + && (apiserv = listgetdata(listhead(apiserver_list))) != NULL) + ospf_apiserver_free(apiserv); + + /* Free client list itself */ + if (apiserver_list) + list_delete(apiserver_list); + + /* Free wildcard list */ + /* XXX */ } -static struct ospf_apiserver * -lookup_apiserver (u_char lsa_type, u_char opaque_type) +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 (ALL_LIST_ELEMENTS_RO (apiserver_list, n1, apiserv)) - { - for (ALL_LIST_ELEMENTS_RO (apiserv->opaque_types, n2, r)) - if (r->lsa_type == lsa_type && r->opaque_type == opaque_type) - { - found = apiserv; - goto out; - } - } + struct listnode *n1, *n2; + struct registered_opaque_type *r; + struct ospf_apiserver *apiserv, *found = NULL; + + /* XXX: this approaches O(n**2) */ + for (ALL_LIST_ELEMENTS_RO(apiserver_list, n1, apiserv)) { + for (ALL_LIST_ELEMENTS_RO(apiserv->opaque_types, n2, r)) + if (r->lsa_type == lsa_type + && r->opaque_type == opaque_type) { + found = apiserv; + goto out; + } + } out: - return found; + return found; } -static struct ospf_apiserver * -lookup_apiserver_by_lsa (struct ospf_lsa *lsa) +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; + 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) +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", (void *)lsa, - dump_lsa_key (lsa), lsa->lsdb->total); - return 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Put LSA(%p)[%s] into reserve, total=%ld", + (void *)lsa, dump_lsa_key(lsa), lsa->lsdb->total); + return 0; } -static int -ospf_apiserver_del_lsa_hook (struct ospf_lsa *lsa) +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", (void *)lsa, - dump_lsa_key (lsa), lsa->lsdb->total); - return 0; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Get LSA(%p)[%s] from reserve, total=%ld", + (void *)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 *ospf_apiserver_new(int fd_sync, int fd_async) { - struct ospf_apiserver *new = - XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct ospf_apiserver)); + 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->filter = XMALLOC(MTYPE_OSPF_APISERVER_MSGFILTER, + sizeof(struct lsa_filter_type)); - new->fd_sync = fd_sync; - new->fd_async = fd_async; + new->fd_sync = fd_sync; + new->fd_async = fd_async; - /* list of registered opaque types that application uses */ - new->opaque_types = list_new (); + /* 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); + /* 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->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; + 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; + new->t_async_read = NULL; #endif /* USE_ASYNC_READ */ - new->t_sync_write = NULL; - new->t_async_write = NULL; + 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; + new->filter->typemask = 0; /* filter all LSAs */ + new->filter->origin = ANY_ORIGIN; + new->filter->num_areas = 0; - return new; + return new; } -void -ospf_apiserver_event (enum event event, int fd, - struct ospf_apiserver *apiserv) +void ospf_apiserver_event(enum event event, int fd, + struct ospf_apiserver *apiserv) { - switch (event) - { - case OSPF_APISERVER_ACCEPT: - (void) thread_add_read(master, ospf_apiserver_accept, apiserv, fd, NULL); - break; - case OSPF_APISERVER_SYNC_READ: - apiserv->t_sync_read = NULL; - thread_add_read(master, ospf_apiserver_read, apiserv, fd, - &apiserv->t_sync_read); - break; + switch (event) { + case OSPF_APISERVER_ACCEPT: + (void)thread_add_read(master, ospf_apiserver_accept, apiserv, + fd, NULL); + break; + case OSPF_APISERVER_SYNC_READ: + apiserv->t_sync_read = NULL; + thread_add_read(master, ospf_apiserver_read, apiserv, fd, + &apiserv->t_sync_read); + break; #ifdef USE_ASYNC_READ - case OSPF_APISERVER_ASYNC_READ: - apiserv->t_async_read = NULL; - thread_add_read(master, ospf_apiserver_read, apiserv, fd, - &apiserv->t_async_read); - break; + case OSPF_APISERVER_ASYNC_READ: + apiserv->t_async_read = NULL; + thread_add_read(master, ospf_apiserver_read, apiserv, fd, + &apiserv->t_async_read); + break; #endif /* USE_ASYNC_READ */ - case OSPF_APISERVER_SYNC_WRITE: - thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd, - &apiserv->t_sync_write); - break; - case OSPF_APISERVER_ASYNC_WRITE: - thread_add_write(master, ospf_apiserver_async_write, apiserv, fd, - &apiserv->t_async_write); - break; - } + case OSPF_APISERVER_SYNC_WRITE: + thread_add_write(master, ospf_apiserver_sync_write, apiserv, fd, + &apiserv->t_sync_write); + break; + case OSPF_APISERVER_ASYNC_WRITE: + thread_add_write(master, ospf_apiserver_async_write, apiserv, + fd, &apiserv->t_async_write); + break; + } } /* Free instance. First unregister all opaque types used by - application, flush opaque LSAs injected by application + application, flush opaque LSAs injected by application from network and close connection. */ -void -ospf_apiserver_free (struct ospf_apiserver *apiserv) +void ospf_apiserver_free(struct ospf_apiserver *apiserv) { - struct listnode *node; + struct listnode *node; - /* Cancel read and write threads. */ - if (apiserv->t_sync_read) - { - thread_cancel (apiserv->t_sync_read); - } + /* 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); - } + 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); - } + if (apiserv->t_sync_write) { + thread_cancel(apiserv->t_sync_write); + } - /* Unregister all opaque types that application registered - and flush opaque LSAs if still in LSDB. */ + if (apiserv->t_async_write) { + thread_cancel(apiserv->t_async_write); + } - while ((node = listhead (apiserv->opaque_types)) != NULL) - { - struct registered_opaque_type *regtype = listgetdata(node); + /* Unregister all opaque types that application registered + and flush opaque LSAs if still in LSDB. */ - ospf_apiserver_unregister_opaque_type (apiserv, regtype->lsa_type, - regtype->opaque_type); + while ((node = listhead(apiserv->opaque_types)) != NULL) { + struct registered_opaque_type *regtype = listgetdata(node); - } + 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); - } + /* Close connections to OSPFd. */ + if (apiserv->fd_sync > 0) { + close(apiserv->fd_sync); + } - if (apiserv->fd_async > 0) - { - close (apiserv->fd_async); - } + 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); + /* 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); + /* 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); + /* 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)", - (void *)apiserv, apiserver_list->count); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: Delete apiserv(%p), total#(%d)", + (void *)apiserv, apiserver_list->count); - /* And free instance. */ - XFREE (MTYPE_OSPF_APISERVER, apiserv); + /* And free instance. */ + XFREE(MTYPE_OSPF_APISERVER, apiserv); } -int -ospf_apiserver_read (struct thread *thread) +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)); - } + 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)); - } + 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; - } + 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); + /* 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; - } + /* Perform cleanup. */ + ospf_apiserver_free(apiserv); + goto out; + } - if (IS_DEBUG_OSPF_EVENT) - msg_print (msg); + if (IS_DEBUG_OSPF_EVENT) + msg_print(msg); - /* Dispatch to corresponding message handler. */ - rc = ospf_apiserver_handle_msg (apiserv, 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); + /* Prepare for next message, add read thread. */ + ospf_apiserver_event(event, fd, apiserv); - msg_free (msg); + msg_free(msg); out: - return rc; + return rc; } -int -ospf_apiserver_sync_write (struct thread *thread) +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; + 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) +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; + 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) +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; + 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 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; - unsigned 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; - } + 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; + unsigned 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; - } +#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); + /* 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; + /* 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); + /* 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); + 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)", - (void *)apiserv, apiserver_list->count); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("API: New apiserv(%p), total#(%d)", (void *)apiserv, + apiserver_list->count); - return 0; + return 0; } @@ -762,71 +720,68 @@ ospf_apiserver_accept (struct thread *thread) * ----------------------------------------------------------- */ -static int -ospf_apiserver_send_msg (struct ospf_apiserver *apiserv, struct msg *msg) +static 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; + 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) +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; + struct msg *msg = new_msg_reply(seqnr, rc); + int ret; - if (!msg) - { - zlog_warn ("ospf_apiserver_send_reply: msg_new failed"); + 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); + /* Cannot allocate new message. What should we do? */ + ospf_apiserver_free(apiserv); #endif - return -1; - } + return -1; + } - ret = ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - return ret; + ret = ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + return ret; } @@ -835,38 +790,36 @@ ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr, * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg) +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; + 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; } @@ -875,346 +828,327 @@ ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg) * ----------------------------------------------------------- */ -int -ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +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 = - XCALLOC (MTYPE_OSPF_APISERVER, 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, (void *)apiserv, - listcount (apiserv->opaque_types)); - - return 0; + 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 = XCALLOC(MTYPE_OSPF_APISERVER, + 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, (void *)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) +int ospf_apiserver_unregister_opaque_type(struct ospf_apiserver *apiserv, + u_char lsa_type, u_char opaque_type) { - struct listnode *node, *nnode; - struct registered_opaque_type *regtype; + struct listnode *node, *nnode; + struct registered_opaque_type *regtype; - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) - { - /* Check if we really registered this opaque type */ - if (regtype->lsa_type == lsa_type && - regtype->opaque_type == opaque_type) - { + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, regtype)) { + /* 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 */ + /* 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); + 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); + /* 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, (void *)apiserv, - listcount (apiserv->opaque_types)); + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "API: Del LSA-type(%d)/Opaque-type(%d)" + " from apiserv(%p), total#(%d)", + lsa_type, opaque_type, (void *)apiserv, + listcount(apiserv->opaque_types)); - return 0; + return 0; + } } - } - /* Opaque type is not registered */ - zlog_warn ("Failed to unregister opaque type [%d/%d]", - lsa_type, opaque_type); - return OSPF_API_OPAQUETYPENOTREGISTERED; + /* Opaque type is not registered */ + zlog_warn("Failed to unregister opaque type [%d/%d]", lsa_type, + opaque_type); + return OSPF_API_OPAQUETYPENOTREGISTERED; } -static int -apiserver_is_opaque_type_registered (struct ospf_apiserver *apiserv, - u_char lsa_type, u_char opaque_type) +static int apiserver_is_opaque_type_registered(struct ospf_apiserver *apiserv, + u_char lsa_type, + u_char opaque_type) { - struct listnode *node, *nnode; - struct registered_opaque_type *regtype; - - /* XXX: how many types are there? if few, why not just a bitmap? */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype)) - { - /* 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; + struct listnode *node, *nnode; + struct registered_opaque_type *regtype; + + /* XXX: how many types are there? if few, why not just a bitmap? */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, regtype)) { + /* 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) +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; - } + 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; + return rc; } /* Notify specific client about all opaque types 9 that are ready. */ -void -ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type9(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct ospf *ospf; - struct ospf_interface *oi; - struct registered_opaque_type *r; - - ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - /* 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 */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - 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"); + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct ospf *ospf; + struct ospf_interface *oi; + struct registered_opaque_type *r; + + ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) { + /* 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 */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + 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); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } } - } out: - return; + return; } /* Notify specific client about all opaque types 10 that are ready. */ -void -ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type10(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - struct listnode *node2, *nnode2; - struct ospf *ospf; - struct ospf_area *area; - - ospf = ospf_lookup (); - - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - 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 */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - 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"); + struct listnode *node, *nnode; + struct listnode *node2, *nnode2; + struct ospf *ospf; + struct ospf_area *area; + + ospf = ospf_lookup(); + + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + 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 */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + 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); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } } - } out: - return; + return; } /* Notify specific client about all opaque types 11 that are ready */ -void -ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv) +void ospf_apiserver_notify_ready_type11(struct ospf_apiserver *apiserv) { - struct listnode *node, *nnode; - 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 */ - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, r)) - { - struct msg *msg; - struct in_addr noarea_id = { .s_addr = 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"); + struct listnode *node, *nnode; + 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 */ + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node, nnode, r)) { + struct msg *msg; + struct in_addr noarea_id = {.s_addr = 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); + /* Cannot allocate new message. What should we + * do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); + goto out; + } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } } - } out: - return; + return; } -int -ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv, - struct msg *msg) +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; + 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); + /* Extract parameters from unregister opaque type message */ + umsg = (struct msg_unregister_opaque_type *)STREAM_DATA(msg->s); - ltype = umsg->lsatype; - otype = umsg->opaquetype; + ltype = umsg->lsatype; + otype = umsg->opaquetype; - rc = ospf_apiserver_unregister_opaque_type (apiserv, ltype, otype); + 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); + /* Send a reply back to client including return code */ + rc = ospf_apiserver_send_reply(apiserv, ntohl(msg->hdr.msgseq), rc); - return rc; + return rc; } @@ -1222,38 +1156,34 @@ ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv, * Following are functions for event (filter) registration. * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, - struct msg *msg) +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; + 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; } @@ -1262,176 +1192,161 @@ ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv, * ----------------------------------------------------------- */ -static int -apiserver_sync_callback (struct ospf_lsa *lsa, void *p_arg, int int_arg) +static 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 = { .s_addr = 0L }; - - /* Default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 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"); + 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 = {.s_addr = 0L}; + + /* Default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 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 */ + /* Cannot allocate new message. What should we do? */ + /* ospf_apiserver_free (apiserv);*/ /* Do nothing + here XXX + */ #endif - goto out; - } + goto out; + } - /* Send LSA */ - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } - rc = 0; + /* Send LSA */ + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + rc = 0; out: - return rc; + return rc; } -int -ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, - struct msg *msg) +int ospf_apiserver_handle_sync_lsdb(struct ospf_apiserver *apiserv, + struct msg *msg) { - struct listnode *node, *nnode; - u_int32_t seqnum; - int rc = 0; - struct msg_sync_lsdb *smsg; - struct ospf_apiserver_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. */ - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - { - 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; + struct listnode *node, *nnode; + u_int32_t seqnum; + int rc = 0; + struct msg_sync_lsdb *smsg; + struct ospf_apiserver_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. */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) { + 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 *)¶m, seqnum); + if (mask & Power2[OSPF_NETWORK_LSA]) + LSDB_LOOP(NETWORK_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_SUMMARY_LSA]) + LSDB_LOOP(SUMMARY_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_ASBR_SUMMARY_LSA]) + LSDB_LOOP(ASBR_SUMMARY_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_OPAQUE_LINK_LSA]) + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); + if (mask & Power2[OSPF_OPAQUE_AREA_LSA]) + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + apiserver_sync_callback(lsa, (void *)¶m, seqnum); } - 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 *) ¶m, seqnum); - if (mask & Power2[OSPF_NETWORK_LSA]) - LSDB_LOOP (NETWORK_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_SUMMARY_LSA]) - LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_ASBR_SUMMARY_LSA]) - LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_OPAQUE_LINK_LSA]) - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, seqnum); - if (mask & Power2[OSPF_OPAQUE_AREA_LSA]) - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - apiserver_sync_callback(lsa, (void *) ¶m, 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 *) ¶m, 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 *) ¶m, seqnum); - } - - /* Send a reply back to client with return code */ - rc = ospf_apiserver_send_reply (apiserv, seqnum, rc); - return rc; + } + + /* 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 *)¶m, 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 *)¶m, seqnum); + } + + /* Send a reply back to client with return code */ + rc = ospf_apiserver_send_reply(apiserv, seqnum, rc); + return rc; } @@ -1447,457 +1362,435 @@ ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv, 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 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; + 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) +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. */ + /* 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); + return (ospf_nbr_count_opaque_capable(oi) > 0); } -int -ospf_apiserver_is_ready_type10 (struct ospf_area *area) +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, *nnode; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi)) - /* 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; + /* 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, *nnode; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS(area->oiflist, node, nnode, oi)) + /* 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) +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, *nnode; - struct ospf_interface *oi; - - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - /* 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; + /* Type 11 opaque LSA can be originated if there is at least one + interface + that has an active opaque-capable neighbor. */ + struct listnode *node, *nnode; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) + /* 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) +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); - } + 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; + /* 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. + * 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 + 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) +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; - } - } + 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) +int ospf_apiserver_originate1(struct ospf_lsa *lsa) { - struct ospf *ospf; + struct ospf *ospf; - ospf = ospf_lookup(); - assert(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; - } + /* 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 */ +/* 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); + /* + * 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; + 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) +int ospf_apiserver_lsa9_originator(void *arg) { - struct ospf_interface *oi; + struct ospf_interface *oi; - oi = (struct ospf_interface *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type9 (oi); - } - return 0; + 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) +int ospf_apiserver_lsa10_originator(void *arg) { - struct ospf_area *area; + struct ospf_area *area; - area = (struct ospf_area *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type10 (area); - } - return 0; + 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) +int ospf_apiserver_lsa11_originator(void *arg) { - struct ospf *ospf; + struct ospf *ospf; - ospf = (struct ospf *) arg; - if (listcount (apiserver_list) > 0) { - ospf_apiserver_clients_notify_ready_type11 (ospf); - } - return 0; + 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. */ -struct ospf_lsa * -ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa) +struct ospf_lsa *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 */ + 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); + ospf_flood_through(NULL /*nbr */, new); #endif /* NOTYET */ - ospf_apiserver_flood_opaque_lsa (new); + 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); - } + /* 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 new; + return new; } @@ -1906,319 +1799,308 @@ out: * ----------------------------------------------------------- */ -int -ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv, - struct msg *msg) +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); + 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; + /* 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 */ -static int -apiserver_flush_opaque_type_callback (struct ospf_lsa *lsa, - void *p_arg, int int_arg) +static 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; + 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) +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, *nnode; - 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: - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - case OSPF_OPAQUE_AREA_LSA: - for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area)) - LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - case OSPF_OPAQUE_AS_LSA: - LSDB_LOOP (OPAQUE_LINK_LSDB (ospf), rn, lsa) - apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0); - break; - default: - break; - } - return; + struct param_t { + struct ospf_apiserver *apiserv; + u_char lsa_type; + u_char opaque_type; + } param; + struct listnode *node, *nnode; + 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: + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + LSDB_LOOP(OPAQUE_LINK_LSDB(area), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + case OSPF_OPAQUE_AREA_LSA: + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + LSDB_LOOP(OPAQUE_AREA_LSDB(area), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + case OSPF_OPAQUE_AS_LSA: + LSDB_LOOP(OPAQUE_LINK_LSDB(ospf), rn, lsa) + apiserver_flush_opaque_type_callback(lsa, (void *)¶m, 0); + break; + default: + break; + } + return; } /* ----------------------------------------------------------- - * Followings are callback functions to handle opaque types + * Followings are callback functions to handle opaque types * ----------------------------------------------------------- */ -int -ospf_apiserver_new_if (struct interface *ifp) +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; + 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) +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; + 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) +void ospf_apiserver_ism_change(struct ospf_interface *oi, int old_state) { - /* Tell clients about interface change */ + /* 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 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); + 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) +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); - } + /* 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) +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\n", - opaquelen, - VALID_OPAQUE_INFO_LEN(lsa->data) ? "" : "(Invalid length?)"); - vty_out (vty, " Opaque data: "); - - for (i = 0; i < opaquelen; i++) - { - vty_out (vty, "0x%x ", olsa->data[i]); - } - vty_out (vty, "\n"); - } - 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; + 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\n", + opaquelen, + VALID_OPAQUE_INFO_LEN(lsa->data) ? "" + : "(Invalid length?)"); + vty_out(vty, " Opaque data: "); + + for (i = 0; i < opaquelen; i++) { + vty_out(vty, "0x%x ", olsa->data[i]); + } + vty_out(vty, "\n"); + } 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; } /* ----------------------------------------------------------- @@ -2230,343 +2112,311 @@ ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa) that need to be notified to all clients (such as interface changes) */ -void -ospf_apiserver_clients_notify_all (struct msg *msg) +void ospf_apiserver_clients_notify_all(struct msg *msg) { - struct listnode *node, *nnode; - struct ospf_apiserver *apiserv; + struct listnode *node, *nnode; + struct ospf_apiserver *apiserv; - /* Send message to all clients */ - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - ospf_apiserver_send_msg (apiserv, msg); + /* Send message to all clients */ + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) + 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) +void ospf_apiserver_clients_notify_ready_type9(struct ospf_interface *oi) { - struct listnode *node, *nnode; - 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; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - 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"); + struct listnode *node, *nnode; + 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; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + 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); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area) +void ospf_apiserver_clients_notify_ready_type10(struct ospf_area *area) { - struct listnode *node, *nnode; - 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; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - 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"); + struct listnode *node, *nnode; + 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; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + 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); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_ready_type11 (struct ospf *top) +void ospf_apiserver_clients_notify_ready_type11(struct ospf *top) { - struct listnode *node, *nnode; - struct msg *msg; - struct in_addr id_null = { .s_addr = 0L }; - struct ospf_apiserver *apiserv; - - assert (top); - - if (!ospf_apiserver_is_ready_type11 (top)) - { - zlog_warn ("AS not ready for type 11?"); - return; - } - - for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - struct listnode *node2, *nnode2; - struct registered_opaque_type *r; - - for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r)) - { - 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"); + struct listnode *node, *nnode; + struct msg *msg; + struct in_addr id_null = {.s_addr = 0L}; + struct ospf_apiserver *apiserv; + + assert(top); + + if (!ospf_apiserver_is_ready_type11(top)) { + zlog_warn("AS not ready for type 11?"); + return; + } + + for (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + struct listnode *node2, *nnode2; + struct registered_opaque_type *r; + + for (ALL_LIST_ELEMENTS(apiserv->opaque_types, node2, nnode2, + r)) { + 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); + /* Cannot allocate new message. What + * should we do? */ + ospf_apiserver_free(apiserv); #endif - goto out; - } + goto out; + } - ospf_apiserver_send_msg (apiserv, msg); - msg_free (msg); - } + ospf_apiserver_send_msg(apiserv, msg); + msg_free(msg); + } + } } - } out: - return; + return; } -void -ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi) +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); - } + 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) +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); - } + 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) +void ospf_apiserver_clients_notify_ism_change(struct ospf_interface *oi) { - struct msg *msg; - struct in_addr ifaddr = { .s_addr = 0L }; - struct in_addr area_id = { .s_addr = 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->state); - if (!msg) - { - zlog_warn ("apiserver_clients_notify_ism_change: msg_new failed"); - return; - } - - ospf_apiserver_clients_notify_all (msg); - msg_free (msg); + struct msg *msg; + struct in_addr ifaddr = {.s_addr = 0L}; + struct in_addr area_id = {.s_addr = 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->state); + 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) +void ospf_apiserver_clients_notify_nsm_change(struct ospf_neighbor *nbr) { - struct msg *msg; - struct in_addr ifaddr = { .s_addr = 0L }; - struct in_addr nbraddr = { .s_addr = 0L }; + struct msg *msg; + struct in_addr ifaddr = {.s_addr = 0L}; + struct in_addr nbraddr = {.s_addr = 0L}; - assert (nbr); + assert(nbr); - if (nbr->oi) - { - ifaddr = nbr->oi->address->u.prefix4; - } + if (nbr->oi) { + ifaddr = nbr->oi->address->u.prefix4; + } - nbraddr = nbr->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; - } + 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); + ospf_apiserver_clients_notify_all(msg); + msg_free(msg); } -static void -apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa) +static void apiserver_clients_lsa_change_notify(u_char msgtype, + struct ospf_lsa *lsa) { - struct msg *msg; - struct listnode *node, *nnode; - struct ospf_apiserver *apiserv; - - /* Default area for AS-External and Opaque11 LSAs */ - struct in_addr area_id = { .s_addr = 0L }; - - /* Default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 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 (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv)) - { - 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; + struct msg *msg; + struct listnode *node, *nnode; + struct ospf_apiserver *apiserv; + + /* Default area for AS-External and Opaque11 LSAs */ + struct in_addr area_id = {.s_addr = 0L}; + + /* Default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 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 (ALL_LIST_ELEMENTS(apiserver_list, node, nnode, apiserv)) { + 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; } - 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); + + 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); + /* Free message since it is not used anymore */ + msg_free(msg); } @@ -2576,60 +2426,53 @@ apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa) */ -static int -apiserver_notify_clients_lsa (u_char msgtype, struct ospf_lsa *lsa) +static 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 = { .s_addr = 0L }; - - /* default interface for non Opaque9 LSAs */ - struct in_addr ifaddr = { .s_addr = 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; + struct msg *msg; + /* default area for AS-External and Opaque11 LSAs */ + struct in_addr area_id = {.s_addr = 0L}; + + /* default interface for non Opaque9 LSAs */ + struct in_addr ifaddr = {.s_addr = 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) +int ospf_apiserver_lsa_update(struct ospf_lsa *lsa) { - return apiserver_notify_clients_lsa (MSG_LSA_UPDATE_NOTIFY, lsa); + return apiserver_notify_clients_lsa(MSG_LSA_UPDATE_NOTIFY, lsa); } -int -ospf_apiserver_lsa_delete (struct ospf_lsa *lsa) +int ospf_apiserver_lsa_delete(struct ospf_lsa *lsa) { - return apiserver_notify_clients_lsa (MSG_LSA_DELETE_NOTIFY, lsa); + return apiserver_notify_clients_lsa(MSG_LSA_DELETE_NOTIFY, lsa); } #endif /* SUPPORT_OSPF_API */ - |
