1: /*
2: * Server side of OSPF API.
3: * Copyright (C) 2001, 2002 Ralph Keller
4: *
5: * This file is part of GNU Zebra.
6: *
7: * GNU Zebra is free software; you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as published
9: * by the Free Software Foundation; either version 2, or (at your
10: * option) any later version.
11: *
12: * GNU Zebra is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with GNU Zebra; see the file COPYING. If not, write to the
19: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20: * Boston, MA 02111-1307, USA.
21: */
22:
23: #include <zebra.h>
24:
25: #ifdef SUPPORT_OSPF_API
26: #ifndef HAVE_OPAQUE_LSA
27: #error "Core Opaque-LSA module must be configured."
28: #endif /* HAVE_OPAQUE_LSA */
29:
30: #include "linklist.h"
31: #include "prefix.h"
32: #include "if.h"
33: #include "table.h"
34: #include "memory.h"
35: #include "command.h"
36: #include "vty.h"
37: #include "stream.h"
38: #include "log.h"
39: #include "thread.h"
40: #include "hash.h"
41: #include "sockunion.h" /* for inet_aton() */
42: #include "buffer.h"
43:
44: #include <sys/types.h>
45:
46: #include "ospfd/ospfd.h" /* for "struct thread_master" */
47: #include "ospfd/ospf_interface.h"
48: #include "ospfd/ospf_ism.h"
49: #include "ospfd/ospf_asbr.h"
50: #include "ospfd/ospf_lsa.h"
51: #include "ospfd/ospf_lsdb.h"
52: #include "ospfd/ospf_neighbor.h"
53: #include "ospfd/ospf_nsm.h"
54: #include "ospfd/ospf_flood.h"
55: #include "ospfd/ospf_packet.h"
56: #include "ospfd/ospf_spf.h"
57: #include "ospfd/ospf_dump.h"
58: #include "ospfd/ospf_route.h"
59: #include "ospfd/ospf_ase.h"
60: #include "ospfd/ospf_zebra.h"
61:
62: #include "ospfd/ospf_api.h"
63: #include "ospfd/ospf_apiserver.h"
64:
65: /* This is an implementation of an API to the OSPF daemon that allows
66: * external applications to access the OSPF daemon through socket
67: * connections. The application can use this API to inject its own
68: * opaque LSAs and flood them to other OSPF daemons. Other OSPF
69: * daemons then receive these LSAs and inform applications through the
70: * API by sending a corresponding message. The application can also
71: * register to receive all LSA types (in addition to opaque types) and
72: * use this information to reconstruct the OSPF's LSDB. The OSPF
73: * daemon supports multiple applications concurrently. */
74:
75: /* List of all active connections. */
76: struct list *apiserver_list;
77:
78: /* -----------------------------------------------------------
79: * Functions to lookup interfaces
80: * -----------------------------------------------------------
81: */
82:
83: struct ospf_interface *
84: ospf_apiserver_if_lookup_by_addr (struct in_addr address)
85: {
86: struct listnode *node, *nnode;
87: struct ospf_interface *oi;
88: struct ospf *ospf;
89:
90: if (!(ospf = ospf_lookup ()))
91: return NULL;
92:
93: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
94: if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
95: if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
96: return oi;
97:
98: return NULL;
99: }
100:
101: struct ospf_interface *
102: ospf_apiserver_if_lookup_by_ifp (struct interface *ifp)
103: {
104: struct listnode *node, *nnode;
105: struct ospf_interface *oi;
106: struct ospf *ospf;
107:
108: if (!(ospf = ospf_lookup ()));
109: return NULL;
110:
111: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
112: if (oi->ifp == ifp)
113: return oi;
114:
115: return NULL;
116: }
117:
118: /* -----------------------------------------------------------
119: * Initialization
120: * -----------------------------------------------------------
121: */
122:
123: unsigned short
124: ospf_apiserver_getport (void)
125: {
126: struct servent *sp = getservbyname ("ospfapi", "tcp");
127:
128: return sp ? ntohs (sp->s_port) : OSPF_API_SYNC_PORT;
129: }
130:
131: /* Initialize OSPF API module. Invoked from ospf_opaque_init() */
132: int
133: ospf_apiserver_init (void)
134: {
135: int fd;
136: int rc = -1;
137:
138: /* Create new socket for synchronous messages. */
139: fd = ospf_apiserver_serv_sock_family (ospf_apiserver_getport (), AF_INET);
140:
141: if (fd < 0)
142: goto out;
143:
144: /* Schedule new thread that handles accepted connections. */
145: ospf_apiserver_event (OSPF_APISERVER_ACCEPT, fd, NULL);
146:
147: /* Initialize list that keeps track of all connections. */
148: apiserver_list = list_new ();
149:
150: /* Register opaque-independent call back functions. These functions
151: are invoked on ISM, NSM changes and LSA update and LSA deletes */
152: rc =
153: ospf_register_opaque_functab (0 /* all LSAs */,
154: 0 /* all opaque types */,
155: ospf_apiserver_new_if,
156: ospf_apiserver_del_if,
157: ospf_apiserver_ism_change,
158: ospf_apiserver_nsm_change,
159: NULL,
160: NULL,
161: NULL,
162: NULL, /* ospf_apiserver_show_info */
163: NULL, /* originator_func */
164: NULL, /* ospf_apiserver_lsa_refresher */
165: ospf_apiserver_lsa_update,
166: ospf_apiserver_lsa_delete);
167: if (rc != 0)
168: {
169: zlog_warn ("ospf_apiserver_init: Failed to register opaque type [0/0]");
170: }
171:
172: rc = 0;
173:
174: out:
175: return rc;
176: }
177:
178: /* Terminate OSPF API module. */
179: void
180: ospf_apiserver_term (void)
181: {
182: struct ospf_apiserver *apiserv;
183:
184: /* Unregister wildcard [0/0] type */
185: ospf_delete_opaque_functab (0 /* all LSAs */,
186: 0 /* all opaque types */);
187:
188: /*
189: * Free all client instances. ospf_apiserver_free removes the node
190: * from the list, so we examine the head of the list anew each time.
191: */
192: while ( apiserver_list &&
193: (apiserv = listgetdata (listhead (apiserver_list))) != NULL)
194: ospf_apiserver_free (apiserv);
195:
196: /* Free client list itself */
197: if (apiserver_list)
198: list_delete (apiserver_list);
199:
200: /* Free wildcard list */
201: /* XXX */
202: }
203:
204: static struct ospf_apiserver *
205: lookup_apiserver (u_char lsa_type, u_char opaque_type)
206: {
207: struct listnode *n1, *n2;
208: struct registered_opaque_type *r;
209: struct ospf_apiserver *apiserv, *found = NULL;
210:
211: /* XXX: this approaches O(n**2) */
212: for (ALL_LIST_ELEMENTS_RO (apiserver_list, n1, apiserv))
213: {
214: for (ALL_LIST_ELEMENTS_RO (apiserv->opaque_types, n2, r))
215: if (r->lsa_type == lsa_type && r->opaque_type == opaque_type)
216: {
217: found = apiserv;
218: goto out;
219: }
220: }
221: out:
222: return found;
223: }
224:
225: static struct ospf_apiserver *
226: lookup_apiserver_by_lsa (struct ospf_lsa *lsa)
227: {
228: struct lsa_header *lsah = lsa->data;
229: struct ospf_apiserver *found = NULL;
230:
231: if (IS_OPAQUE_LSA (lsah->type))
232: {
233: found = lookup_apiserver (lsah->type,
234: GET_OPAQUE_TYPE (ntohl (lsah->id.s_addr)));
235: }
236: return found;
237: }
238:
239: /* -----------------------------------------------------------
240: * Followings are functions to manage client connections.
241: * -----------------------------------------------------------
242: */
243: static int
244: ospf_apiserver_new_lsa_hook (struct ospf_lsa *lsa)
245: {
246: if (IS_DEBUG_OSPF_EVENT)
247: zlog_debug ("API: Put LSA(%p)[%s] into reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total);
248: return 0;
249: }
250:
251: static int
252: ospf_apiserver_del_lsa_hook (struct ospf_lsa *lsa)
253: {
254: if (IS_DEBUG_OSPF_EVENT)
255: zlog_debug ("API: Get LSA(%p)[%s] from reserve, total=%ld", lsa, dump_lsa_key (lsa), lsa->lsdb->total);
256: return 0;
257: }
258:
259: /* Allocate new connection structure. */
260: struct ospf_apiserver *
261: ospf_apiserver_new (int fd_sync, int fd_async)
262: {
263: struct ospf_apiserver *new =
264: XMALLOC (MTYPE_OSPF_APISERVER, sizeof (struct ospf_apiserver));
265:
266: new->filter =
267: XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER, sizeof (struct lsa_filter_type));
268:
269: new->fd_sync = fd_sync;
270: new->fd_async = fd_async;
271:
272: /* list of registered opaque types that application uses */
273: new->opaque_types = list_new ();
274:
275: /* Initialize temporary strage for LSA instances to be refreshed. */
276: memset (&new->reserve, 0, sizeof (struct ospf_lsdb));
277: ospf_lsdb_init (&new->reserve);
278:
279: new->reserve.new_lsa_hook = ospf_apiserver_new_lsa_hook; /* debug */
280: new->reserve.del_lsa_hook = ospf_apiserver_del_lsa_hook; /* debug */
281:
282: new->out_sync_fifo = msg_fifo_new ();
283: new->out_async_fifo = msg_fifo_new ();
284: new->t_sync_read = NULL;
285: #ifdef USE_ASYNC_READ
286: new->t_async_read = NULL;
287: #endif /* USE_ASYNC_READ */
288: new->t_sync_write = NULL;
289: new->t_async_write = NULL;
290:
291: new->filter->typemask = 0; /* filter all LSAs */
292: new->filter->origin = ANY_ORIGIN;
293: new->filter->num_areas = 0;
294:
295: return new;
296: }
297:
298: void
299: ospf_apiserver_event (enum event event, int fd,
300: struct ospf_apiserver *apiserv)
301: {
302: struct thread *apiserver_serv_thread;
303:
304: switch (event)
305: {
306: case OSPF_APISERVER_ACCEPT:
307: apiserver_serv_thread =
308: thread_add_read (master, ospf_apiserver_accept, apiserv, fd);
309: break;
310: case OSPF_APISERVER_SYNC_READ:
311: apiserv->t_sync_read =
312: thread_add_read (master, ospf_apiserver_read, apiserv, fd);
313: break;
314: #ifdef USE_ASYNC_READ
315: case OSPF_APISERVER_ASYNC_READ:
316: apiserv->t_async_read =
317: thread_add_read (master, ospf_apiserver_read, apiserv, fd);
318: break;
319: #endif /* USE_ASYNC_READ */
320: case OSPF_APISERVER_SYNC_WRITE:
321: if (!apiserv->t_sync_write)
322: {
323: apiserv->t_sync_write =
324: thread_add_write (master, ospf_apiserver_sync_write, apiserv, fd);
325: }
326: break;
327: case OSPF_APISERVER_ASYNC_WRITE:
328: if (!apiserv->t_async_write)
329: {
330: apiserv->t_async_write =
331: thread_add_write (master, ospf_apiserver_async_write, apiserv, fd);
332: }
333: break;
334: }
335: }
336:
337: /* Free instance. First unregister all opaque types used by
338: application, flush opaque LSAs injected by application
339: from network and close connection. */
340: void
341: ospf_apiserver_free (struct ospf_apiserver *apiserv)
342: {
343: struct listnode *node;
344:
345: /* Cancel read and write threads. */
346: if (apiserv->t_sync_read)
347: {
348: thread_cancel (apiserv->t_sync_read);
349: }
350: #ifdef USE_ASYNC_READ
351: if (apiserv->t_async_read)
352: {
353: thread_cancel (apiserv->t_async_read);
354: }
355: #endif /* USE_ASYNC_READ */
356: if (apiserv->t_sync_write)
357: {
358: thread_cancel (apiserv->t_sync_write);
359: }
360:
361: if (apiserv->t_async_write)
362: {
363: thread_cancel (apiserv->t_async_write);
364: }
365:
366: /* Unregister all opaque types that application registered
367: and flush opaque LSAs if still in LSDB. */
368:
369: while ((node = listhead (apiserv->opaque_types)) != NULL)
370: {
371: struct registered_opaque_type *regtype = listgetdata(node);
372:
373: ospf_apiserver_unregister_opaque_type (apiserv, regtype->lsa_type,
374: regtype->opaque_type);
375:
376: }
377:
378: /* Close connections to OSPFd. */
379: if (apiserv->fd_sync > 0)
380: {
381: close (apiserv->fd_sync);
382: }
383:
384: if (apiserv->fd_async > 0)
385: {
386: close (apiserv->fd_async);
387: }
388:
389: /* Free fifos */
390: msg_fifo_free (apiserv->out_sync_fifo);
391: msg_fifo_free (apiserv->out_async_fifo);
392:
393: /* Clear temporary strage for LSA instances to be refreshed. */
394: ospf_lsdb_delete_all (&apiserv->reserve);
395: ospf_lsdb_cleanup (&apiserv->reserve);
396:
397: /* Remove from the list of active clients. */
398: listnode_delete (apiserver_list, apiserv);
399:
400: if (IS_DEBUG_OSPF_EVENT)
401: zlog_debug ("API: Delete apiserv(%p), total#(%d)", apiserv, apiserver_list->count);
402:
403: /* And free instance. */
404: XFREE (MTYPE_OSPF_APISERVER, apiserv);
405: }
406:
407: int
408: ospf_apiserver_read (struct thread *thread)
409: {
410: struct ospf_apiserver *apiserv;
411: struct msg *msg;
412: int fd;
413: int rc = -1;
414: enum event event;
415:
416: apiserv = THREAD_ARG (thread);
417: fd = THREAD_FD (thread);
418:
419: if (fd == apiserv->fd_sync)
420: {
421: event = OSPF_APISERVER_SYNC_READ;
422: apiserv->t_sync_read = NULL;
423:
424: if (IS_DEBUG_OSPF_EVENT)
425: zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u",
426: inet_ntoa (apiserv->peer_sync.sin_addr),
427: ntohs (apiserv->peer_sync.sin_port));
428: }
429: #ifdef USE_ASYNC_READ
430: else if (fd == apiserv->fd_async)
431: {
432: event = OSPF_APISERVER_ASYNC_READ;
433: apiserv->t_async_read = NULL;
434:
435: if (IS_DEBUG_OSPF_EVENT)
436: zlog_debug ("API: ospf_apiserver_read: Peer: %s/%u",
437: inet_ntoa (apiserv->peer_async.sin_addr),
438: ntohs (apiserv->peer_async.sin_port));
439: }
440: #endif /* USE_ASYNC_READ */
441: else
442: {
443: zlog_warn ("ospf_apiserver_read: Unknown fd(%d)", fd);
444: ospf_apiserver_free (apiserv);
445: goto out;
446: }
447:
448: /* Read message from fd. */
449: msg = msg_read (fd);
450: if (msg == NULL)
451: {
452: zlog_warn
453: ("ospf_apiserver_read: read failed on fd=%d, closing connection", fd);
454:
455: /* Perform cleanup. */
456: ospf_apiserver_free (apiserv);
457: goto out;
458: }
459:
460: if (IS_DEBUG_OSPF_EVENT)
461: msg_print (msg);
462:
463: /* Dispatch to corresponding message handler. */
464: rc = ospf_apiserver_handle_msg (apiserv, msg);
465:
466: /* Prepare for next message, add read thread. */
467: ospf_apiserver_event (event, fd, apiserv);
468:
469: msg_free (msg);
470:
471: out:
472: return rc;
473: }
474:
475: int
476: ospf_apiserver_sync_write (struct thread *thread)
477: {
478: struct ospf_apiserver *apiserv;
479: struct msg *msg;
480: int fd;
481: int rc = -1;
482:
483: apiserv = THREAD_ARG (thread);
484: assert (apiserv);
485: fd = THREAD_FD (thread);
486:
487: apiserv->t_sync_write = NULL;
488:
489: /* Sanity check */
490: if (fd != apiserv->fd_sync)
491: {
492: zlog_warn ("ospf_apiserver_sync_write: Unknown fd=%d", fd);
493: goto out;
494: }
495:
496: if (IS_DEBUG_OSPF_EVENT)
497: zlog_debug ("API: ospf_apiserver_sync_write: Peer: %s/%u",
498: inet_ntoa (apiserv->peer_sync.sin_addr),
499: ntohs (apiserv->peer_sync.sin_port));
500:
501: /* Check whether there is really a message in the fifo. */
502: msg = msg_fifo_pop (apiserv->out_sync_fifo);
503: if (!msg)
504: {
505: zlog_warn ("API: ospf_apiserver_sync_write: No message in Sync-FIFO?");
506: return 0;
507: }
508:
509: if (IS_DEBUG_OSPF_EVENT)
510: msg_print (msg);
511:
512: rc = msg_write (fd, msg);
513:
514: /* Once a message is dequeued, it should be freed anyway. */
515: msg_free (msg);
516:
517: if (rc < 0)
518: {
519: zlog_warn
520: ("ospf_apiserver_sync_write: write failed on fd=%d", fd);
521: goto out;
522: }
523:
524:
525: /* If more messages are in sync message fifo, schedule write thread. */
526: if (msg_fifo_head (apiserv->out_sync_fifo))
527: {
528: ospf_apiserver_event (OSPF_APISERVER_SYNC_WRITE, apiserv->fd_sync,
529: apiserv);
530: }
531:
532: out:
533:
534: if (rc < 0)
535: {
536: /* Perform cleanup and disconnect with peer */
537: ospf_apiserver_free (apiserv);
538: }
539:
540: return rc;
541: }
542:
543:
544: int
545: ospf_apiserver_async_write (struct thread *thread)
546: {
547: struct ospf_apiserver *apiserv;
548: struct msg *msg;
549: int fd;
550: int rc = -1;
551:
552: apiserv = THREAD_ARG (thread);
553: assert (apiserv);
554: fd = THREAD_FD (thread);
555:
556: apiserv->t_async_write = NULL;
557:
558: /* Sanity check */
559: if (fd != apiserv->fd_async)
560: {
561: zlog_warn ("ospf_apiserver_async_write: Unknown fd=%d", fd);
562: goto out;
563: }
564:
565: if (IS_DEBUG_OSPF_EVENT)
566: zlog_debug ("API: ospf_apiserver_async_write: Peer: %s/%u",
567: inet_ntoa (apiserv->peer_async.sin_addr),
568: ntohs (apiserv->peer_async.sin_port));
569:
570: /* Check whether there is really a message in the fifo. */
571: msg = msg_fifo_pop (apiserv->out_async_fifo);
572: if (!msg)
573: {
574: zlog_warn ("API: ospf_apiserver_async_write: No message in Async-FIFO?");
575: return 0;
576: }
577:
578: if (IS_DEBUG_OSPF_EVENT)
579: msg_print (msg);
580:
581: rc = msg_write (fd, msg);
582:
583: /* Once a message is dequeued, it should be freed anyway. */
584: msg_free (msg);
585:
586: if (rc < 0)
587: {
588: zlog_warn
589: ("ospf_apiserver_async_write: write failed on fd=%d", fd);
590: goto out;
591: }
592:
593:
594: /* If more messages are in async message fifo, schedule write thread. */
595: if (msg_fifo_head (apiserv->out_async_fifo))
596: {
597: ospf_apiserver_event (OSPF_APISERVER_ASYNC_WRITE, apiserv->fd_async,
598: apiserv);
599: }
600:
601: out:
602:
603: if (rc < 0)
604: {
605: /* Perform cleanup and disconnect with peer */
606: ospf_apiserver_free (apiserv);
607: }
608:
609: return rc;
610: }
611:
612:
613: int
614: ospf_apiserver_serv_sock_family (unsigned short port, int family)
615: {
616: union sockunion su;
617: int accept_sock;
618: int rc;
619:
620: memset (&su, 0, sizeof (union sockunion));
621: su.sa.sa_family = family;
622:
623: /* Make new socket */
624: accept_sock = sockunion_stream_socket (&su);
625: if (accept_sock < 0)
626: return accept_sock;
627:
628: /* This is a server, so reuse address and port */
629: sockopt_reuseaddr (accept_sock);
630: sockopt_reuseport (accept_sock);
631:
632: /* Bind socket to address and given port. */
633: rc = sockunion_bind (accept_sock, &su, port, NULL);
634: if (rc < 0)
635: {
636: close (accept_sock); /* Close socket */
637: return rc;
638: }
639:
640: /* Listen socket under queue length 3. */
641: rc = listen (accept_sock, 3);
642: if (rc < 0)
643: {
644: zlog_warn ("ospf_apiserver_serv_sock_family: listen: %s",
645: safe_strerror (errno));
646: close (accept_sock); /* Close socket */
647: return rc;
648: }
649: return accept_sock;
650: }
651:
652:
653: /* Accept connection request from external applications. For each
654: accepted connection allocate own connection instance. */
655: int
656: ospf_apiserver_accept (struct thread *thread)
657: {
658: int accept_sock;
659: int new_sync_sock;
660: int new_async_sock;
661: union sockunion su;
662: struct ospf_apiserver *apiserv;
663: struct sockaddr_in peer_async;
664: struct sockaddr_in peer_sync;
665: unsigned int peerlen;
666: int ret;
667:
668: /* THREAD_ARG (thread) is NULL */
669: accept_sock = THREAD_FD (thread);
670:
671: /* Keep hearing on socket for further connections. */
672: ospf_apiserver_event (OSPF_APISERVER_ACCEPT, accept_sock, NULL);
673:
674: memset (&su, 0, sizeof (union sockunion));
675: /* Accept connection for synchronous messages */
676: new_sync_sock = sockunion_accept (accept_sock, &su);
677: if (new_sync_sock < 0)
678: {
679: zlog_warn ("ospf_apiserver_accept: accept: %s", safe_strerror (errno));
680: return -1;
681: }
682:
683: /* Get port address and port number of peer to make reverse connection.
684: The reverse channel uses the port number of the peer port+1. */
685:
686: memset(&peer_sync, 0, sizeof(struct sockaddr_in));
687: peerlen = sizeof (struct sockaddr_in);
688:
689: ret = getpeername (new_sync_sock, (struct sockaddr *)&peer_sync, &peerlen);
690: if (ret < 0)
691: {
692: zlog_warn ("ospf_apiserver_accept: getpeername: %s", safe_strerror (errno));
693: close (new_sync_sock);
694: return -1;
695: }
696:
697: if (IS_DEBUG_OSPF_EVENT)
698: zlog_debug ("API: ospf_apiserver_accept: New peer: %s/%u",
699: inet_ntoa (peer_sync.sin_addr), ntohs (peer_sync.sin_port));
700:
701: /* Create new socket for asynchronous messages. */
702: peer_async = peer_sync;
703: peer_async.sin_port = htons(ntohs(peer_sync.sin_port) + 1);
704:
705: /* Check if remote port number to make reverse connection is valid one. */
706: if (ntohs (peer_async.sin_port) == ospf_apiserver_getport ())
707: {
708: zlog_warn ("API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?",
709: inet_ntoa (peer_async.sin_addr), ntohs (peer_async.sin_port));
710: close (new_sync_sock);
711: return -1;
712: }
713:
714: new_async_sock = socket (AF_INET, SOCK_STREAM, 0);
715: if (new_async_sock < 0)
716: {
717: zlog_warn ("ospf_apiserver_accept: socket: %s", safe_strerror (errno));
718: close (new_sync_sock);
719: return -1;
720: }
721:
722: ret = connect (new_async_sock, (struct sockaddr *) &peer_async,
723: sizeof (struct sockaddr_in));
724:
725: if (ret < 0)
726: {
727: zlog_warn ("ospf_apiserver_accept: connect: %s", safe_strerror (errno));
728: close (new_sync_sock);
729: close (new_async_sock);
730: return -1;
731: }
732:
733: #ifdef USE_ASYNC_READ
734: #else /* USE_ASYNC_READ */
735: /* Make the asynchronous channel write-only. */
736: ret = shutdown (new_async_sock, SHUT_RD);
737: if (ret < 0)
738: {
739: zlog_warn ("ospf_apiserver_accept: shutdown: %s", safe_strerror (errno));
740: close (new_sync_sock);
741: close (new_async_sock);
742: return -1;
743: }
744: #endif /* USE_ASYNC_READ */
745:
746: /* Allocate new server-side connection structure */
747: apiserv = ospf_apiserver_new (new_sync_sock, new_async_sock);
748:
749: /* Add to active connection list */
750: listnode_add (apiserver_list, apiserv);
751: apiserv->peer_sync = peer_sync;
752: apiserv->peer_async = peer_async;
753:
754: /* And add read threads for new connection */
755: ospf_apiserver_event (OSPF_APISERVER_SYNC_READ, new_sync_sock, apiserv);
756: #ifdef USE_ASYNC_READ
757: ospf_apiserver_event (OSPF_APISERVER_ASYNC_READ, new_async_sock, apiserv);
758: #endif /* USE_ASYNC_READ */
759:
760: if (IS_DEBUG_OSPF_EVENT)
761: zlog_debug ("API: New apiserv(%p), total#(%d)", apiserv, apiserver_list->count);
762:
763: return 0;
764: }
765:
766:
767: /* -----------------------------------------------------------
768: * Send reply with return code to client application
769: * -----------------------------------------------------------
770: */
771:
772: static int
773: ospf_apiserver_send_msg (struct ospf_apiserver *apiserv, struct msg *msg)
774: {
775: struct msg_fifo *fifo;
776: struct msg *msg2;
777: enum event event;
778: int fd;
779:
780: switch (msg->hdr.msgtype)
781: {
782: case MSG_REPLY:
783: fifo = apiserv->out_sync_fifo;
784: fd = apiserv->fd_sync;
785: event = OSPF_APISERVER_SYNC_WRITE;
786: break;
787: case MSG_READY_NOTIFY:
788: case MSG_LSA_UPDATE_NOTIFY:
789: case MSG_LSA_DELETE_NOTIFY:
790: case MSG_NEW_IF:
791: case MSG_DEL_IF:
792: case MSG_ISM_CHANGE:
793: case MSG_NSM_CHANGE:
794: fifo = apiserv->out_async_fifo;
795: fd = apiserv->fd_async;
796: event = OSPF_APISERVER_ASYNC_WRITE;
797: break;
798: default:
799: zlog_warn ("ospf_apiserver_send_msg: Unknown message type %d",
800: msg->hdr.msgtype);
801: return -1;
802: }
803:
804: /* Make a copy of the message and put in the fifo. Once the fifo
805: gets drained by the write thread, the message will be freed. */
806: /* NB: Given "msg" is untouched in this function. */
807: msg2 = msg_dup (msg);
808:
809: /* Enqueue message into corresponding fifo queue */
810: msg_fifo_push (fifo, msg2);
811:
812: /* Schedule write thread */
813: ospf_apiserver_event (event, fd, apiserv);
814: return 0;
815: }
816:
817: int
818: ospf_apiserver_send_reply (struct ospf_apiserver *apiserv, u_int32_t seqnr,
819: u_char rc)
820: {
821: struct msg *msg = new_msg_reply (seqnr, rc);
822: int ret;
823:
824: if (!msg)
825: {
826: zlog_warn ("ospf_apiserver_send_reply: msg_new failed");
827: #ifdef NOTYET
828: /* Cannot allocate new message. What should we do? */
829: ospf_apiserver_free (apiserv);
830: #endif
831: return -1;
832: }
833:
834: ret = ospf_apiserver_send_msg (apiserv, msg);
835: msg_free (msg);
836: return ret;
837: }
838:
839:
840: /* -----------------------------------------------------------
841: * Generic message dispatching handler function
842: * -----------------------------------------------------------
843: */
844:
845: int
846: ospf_apiserver_handle_msg (struct ospf_apiserver *apiserv, struct msg *msg)
847: {
848: int rc;
849:
850: /* Call corresponding message handler function. */
851: switch (msg->hdr.msgtype)
852: {
853: case MSG_REGISTER_OPAQUETYPE:
854: rc = ospf_apiserver_handle_register_opaque_type (apiserv, msg);
855: break;
856: case MSG_UNREGISTER_OPAQUETYPE:
857: rc = ospf_apiserver_handle_unregister_opaque_type (apiserv, msg);
858: break;
859: case MSG_REGISTER_EVENT:
860: rc = ospf_apiserver_handle_register_event (apiserv, msg);
861: break;
862: case MSG_SYNC_LSDB:
863: rc = ospf_apiserver_handle_sync_lsdb (apiserv, msg);
864: break;
865: case MSG_ORIGINATE_REQUEST:
866: rc = ospf_apiserver_handle_originate_request (apiserv, msg);
867: break;
868: case MSG_DELETE_REQUEST:
869: rc = ospf_apiserver_handle_delete_request (apiserv, msg);
870: break;
871: default:
872: zlog_warn ("ospf_apiserver_handle_msg: Unknown message type: %d",
873: msg->hdr.msgtype);
874: rc = -1;
875: }
876: return rc;
877: }
878:
879:
880: /* -----------------------------------------------------------
881: * Following are functions for opaque type registration
882: * -----------------------------------------------------------
883: */
884:
885: int
886: ospf_apiserver_register_opaque_type (struct ospf_apiserver *apiserv,
887: u_char lsa_type, u_char opaque_type)
888: {
889: struct registered_opaque_type *regtype;
890: int (*originator_func) (void *arg);
891: int rc;
892:
893: switch (lsa_type)
894: {
895: case OSPF_OPAQUE_LINK_LSA:
896: originator_func = ospf_apiserver_lsa9_originator;
897: break;
898: case OSPF_OPAQUE_AREA_LSA:
899: originator_func = ospf_apiserver_lsa10_originator;
900: break;
901: case OSPF_OPAQUE_AS_LSA:
902: originator_func = ospf_apiserver_lsa11_originator;
903: break;
904: default:
905: zlog_warn ("ospf_apiserver_register_opaque_type: lsa_type(%d)",
906: lsa_type);
907: return OSPF_API_ILLEGALLSATYPE;
908: }
909:
910:
911: /* Register opaque function table */
912: /* NB: Duplicated registration will be detected inside the function. */
913: rc =
914: ospf_register_opaque_functab (lsa_type, opaque_type,
915: NULL, /* ospf_apiserver_new_if */
916: NULL, /* ospf_apiserver_del_if */
917: NULL, /* ospf_apiserver_ism_change */
918: NULL, /* ospf_apiserver_nsm_change */
919: NULL,
920: NULL,
921: NULL,
922: ospf_apiserver_show_info,
923: originator_func,
924: ospf_apiserver_lsa_refresher,
925: NULL, /* ospf_apiserver_lsa_update */
926: NULL /* ospf_apiserver_lsa_delete */);
927:
928: if (rc != 0)
929: {
930: zlog_warn ("Failed to register opaque type [%d/%d]",
931: lsa_type, opaque_type);
932: return OSPF_API_OPAQUETYPEINUSE;
933: }
934:
935: /* Remember the opaque type that application registers so when
936: connection shuts down, we can flush all LSAs of this opaque
937: type. */
938:
939: regtype =
940: XCALLOC (MTYPE_OSPF_APISERVER, sizeof (struct registered_opaque_type));
941: regtype->lsa_type = lsa_type;
942: regtype->opaque_type = opaque_type;
943:
944: /* Add to list of registered opaque types */
945: listnode_add (apiserv->opaque_types, regtype);
946:
947: if (IS_DEBUG_OSPF_EVENT)
948: zlog_debug ("API: Add LSA-type(%d)/Opaque-type(%d) into"
949: " apiserv(%p), total#(%d)",
950: lsa_type, opaque_type, apiserv,
951: listcount (apiserv->opaque_types));
952:
953: return 0;
954: }
955:
956: int
957: ospf_apiserver_unregister_opaque_type (struct ospf_apiserver *apiserv,
958: u_char lsa_type, u_char opaque_type)
959: {
960: struct listnode *node, *nnode;
961: struct registered_opaque_type *regtype;
962:
963: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype))
964: {
965: /* Check if we really registered this opaque type */
966: if (regtype->lsa_type == lsa_type &&
967: regtype->opaque_type == opaque_type)
968: {
969:
970: /* Yes, we registered this opaque type. Flush
971: all existing opaque LSAs of this type */
972:
973: ospf_apiserver_flush_opaque_lsa (apiserv, lsa_type, opaque_type);
974: ospf_delete_opaque_functab (lsa_type, opaque_type);
975:
976: /* Remove from list of registered opaque types */
977: listnode_delete (apiserv->opaque_types, regtype);
978:
979: if (IS_DEBUG_OSPF_EVENT)
980: zlog_debug ("API: Del LSA-type(%d)/Opaque-type(%d)"
981: " from apiserv(%p), total#(%d)",
982: lsa_type, opaque_type, apiserv,
983: listcount (apiserv->opaque_types));
984:
985: return 0;
986: }
987: }
988:
989: /* Opaque type is not registered */
990: zlog_warn ("Failed to unregister opaque type [%d/%d]",
991: lsa_type, opaque_type);
992: return OSPF_API_OPAQUETYPENOTREGISTERED;
993: }
994:
995:
996: static int
997: apiserver_is_opaque_type_registered (struct ospf_apiserver *apiserv,
998: u_char lsa_type, u_char opaque_type)
999: {
1000: struct listnode *node, *nnode;
1001: struct registered_opaque_type *regtype;
1002:
1003: /* XXX: how many types are there? if few, why not just a bitmap? */
1004: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, regtype))
1005: {
1006: /* Check if we really registered this opaque type */
1007: if (regtype->lsa_type == lsa_type &&
1008: regtype->opaque_type == opaque_type)
1009: {
1010: /* Yes registered */
1011: return 1;
1012: }
1013: }
1014: /* Not registered */
1015: return 0;
1016: }
1017:
1018: int
1019: ospf_apiserver_handle_register_opaque_type (struct ospf_apiserver *apiserv,
1020: struct msg *msg)
1021: {
1022: struct msg_register_opaque_type *rmsg;
1023: u_char lsa_type;
1024: u_char opaque_type;
1025: int rc = 0;
1026:
1027: /* Extract parameters from register opaque type message */
1028: rmsg = (struct msg_register_opaque_type *) STREAM_DATA (msg->s);
1029:
1030: lsa_type = rmsg->lsatype;
1031: opaque_type = rmsg->opaquetype;
1032:
1033: rc = ospf_apiserver_register_opaque_type (apiserv, lsa_type, opaque_type);
1034:
1035: /* Send a reply back to client including return code */
1036: rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
1037: if (rc < 0)
1038: goto out;
1039:
1040: /* Now inform application about opaque types that are ready */
1041: switch (lsa_type)
1042: {
1043: case OSPF_OPAQUE_LINK_LSA:
1044: ospf_apiserver_notify_ready_type9 (apiserv);
1045: break;
1046: case OSPF_OPAQUE_AREA_LSA:
1047: ospf_apiserver_notify_ready_type10 (apiserv);
1048: break;
1049: case OSPF_OPAQUE_AS_LSA:
1050: ospf_apiserver_notify_ready_type11 (apiserv);
1051: break;
1052: }
1053: out:
1054: return rc;
1055: }
1056:
1057:
1058: /* Notify specific client about all opaque types 9 that are ready. */
1059: void
1060: ospf_apiserver_notify_ready_type9 (struct ospf_apiserver *apiserv)
1061: {
1062: struct listnode *node, *nnode;
1063: struct listnode *node2, *nnode2;
1064: struct ospf *ospf;
1065: struct ospf_interface *oi;
1066: struct registered_opaque_type *r;
1067:
1068: ospf = ospf_lookup ();
1069:
1070: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
1071: {
1072: /* Check if this interface is indeed ready for type 9 */
1073: if (!ospf_apiserver_is_ready_type9 (oi))
1074: continue;
1075:
1076: /* Check for registered opaque type 9 types */
1077: /* XXX: loop-de-loop - optimise me */
1078: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r))
1079: {
1080: struct msg *msg;
1081:
1082: if (r->lsa_type == OSPF_OPAQUE_LINK_LSA)
1083: {
1084:
1085: /* Yes, this opaque type is ready */
1086: msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA,
1087: r->opaque_type,
1088: oi->address->u.prefix4);
1089: if (!msg)
1090: {
1091: zlog_warn ("apiserver_notify_ready_type9: msg_new failed");
1092: #ifdef NOTYET
1093: /* Cannot allocate new message. What should we do? */
1094: ospf_apiserver_free (apiserv);
1095: #endif
1096: goto out;
1097: }
1098: ospf_apiserver_send_msg (apiserv, msg);
1099: msg_free (msg);
1100: }
1101: }
1102: }
1103:
1104: out:
1105: return;
1106: }
1107:
1108:
1109: /* Notify specific client about all opaque types 10 that are ready. */
1110: void
1111: ospf_apiserver_notify_ready_type10 (struct ospf_apiserver *apiserv)
1112: {
1113: struct listnode *node, *nnode;
1114: struct listnode *node2, *nnode2;
1115: struct ospf *ospf;
1116: struct ospf_area *area;
1117:
1118: ospf = ospf_lookup ();
1119:
1120: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
1121: {
1122: struct registered_opaque_type *r;
1123:
1124: if (!ospf_apiserver_is_ready_type10 (area))
1125: {
1126: continue;
1127: }
1128:
1129: /* Check for registered opaque type 10 types */
1130: /* XXX: loop in loop - optimise me */
1131: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r))
1132: {
1133: struct msg *msg;
1134:
1135: if (r->lsa_type == OSPF_OPAQUE_AREA_LSA)
1136: {
1137: /* Yes, this opaque type is ready */
1138: msg =
1139: new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA,
1140: r->opaque_type, area->area_id);
1141: if (!msg)
1142: {
1143: zlog_warn ("apiserver_notify_ready_type10: msg_new failed");
1144: #ifdef NOTYET
1145: /* Cannot allocate new message. What should we do? */
1146: ospf_apiserver_free (apiserv);
1147: #endif
1148: goto out;
1149: }
1150: ospf_apiserver_send_msg (apiserv, msg);
1151: msg_free (msg);
1152: }
1153: }
1154: }
1155:
1156: out:
1157: return;
1158: }
1159:
1160: /* Notify specific client about all opaque types 11 that are ready */
1161: void
1162: ospf_apiserver_notify_ready_type11 (struct ospf_apiserver *apiserv)
1163: {
1164: struct listnode *node, *nnode;
1165: struct ospf *ospf;
1166: struct registered_opaque_type *r;
1167:
1168: ospf = ospf_lookup ();
1169:
1170: /* Can type 11 be originated? */
1171: if (!ospf_apiserver_is_ready_type11 (ospf))
1172: goto out;
1173:
1174: /* Check for registered opaque type 11 types */
1175: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node, nnode, r))
1176: {
1177: struct msg *msg;
1178: struct in_addr noarea_id = { .s_addr = 0L };
1179:
1180: if (r->lsa_type == OSPF_OPAQUE_AS_LSA)
1181: {
1182: /* Yes, this opaque type is ready */
1183: msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA,
1184: r->opaque_type, noarea_id);
1185:
1186: if (!msg)
1187: {
1188: zlog_warn ("apiserver_notify_ready_type11: msg_new failed");
1189: #ifdef NOTYET
1190: /* Cannot allocate new message. What should we do? */
1191: ospf_apiserver_free (apiserv);
1192: #endif
1193: goto out;
1194: }
1195: ospf_apiserver_send_msg (apiserv, msg);
1196: msg_free (msg);
1197: }
1198: }
1199:
1200: out:
1201: return;
1202: }
1203:
1204: int
1205: ospf_apiserver_handle_unregister_opaque_type (struct ospf_apiserver *apiserv,
1206: struct msg *msg)
1207: {
1208: struct msg_unregister_opaque_type *umsg;
1209: u_char ltype;
1210: u_char otype;
1211: int rc = 0;
1212:
1213: /* Extract parameters from unregister opaque type message */
1214: umsg = (struct msg_unregister_opaque_type *) STREAM_DATA (msg->s);
1215:
1216: ltype = umsg->lsatype;
1217: otype = umsg->opaquetype;
1218:
1219: rc = ospf_apiserver_unregister_opaque_type (apiserv, ltype, otype);
1220:
1221: /* Send a reply back to client including return code */
1222: rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
1223:
1224: return rc;
1225: }
1226:
1227:
1228: /* -----------------------------------------------------------
1229: * Following are functions for event (filter) registration.
1230: * -----------------------------------------------------------
1231: */
1232: int
1233: ospf_apiserver_handle_register_event (struct ospf_apiserver *apiserv,
1234: struct msg *msg)
1235: {
1236: struct msg_register_event *rmsg;
1237: int rc;
1238: u_int32_t seqnum;
1239:
1240: rmsg = (struct msg_register_event *) STREAM_DATA (msg->s);
1241:
1242: /* Get request sequence number */
1243: seqnum = msg_get_seq (msg);
1244:
1245: /* Free existing filter in apiserv. */
1246: XFREE (MTYPE_OSPF_APISERVER_MSGFILTER, apiserv->filter);
1247: /* Alloc new space for filter. */
1248:
1249: apiserv->filter = XMALLOC (MTYPE_OSPF_APISERVER_MSGFILTER,
1250: ntohs (msg->hdr.msglen));
1251: if (apiserv->filter)
1252: {
1253: /* copy it over. */
1254: memcpy (apiserv->filter, &rmsg->filter, ntohs (msg->hdr.msglen));
1255: rc = OSPF_API_OK;
1256: }
1257: else
1258: {
1259: rc = OSPF_API_NOMEMORY;
1260: }
1261: /* Send a reply back to client with return code */
1262: rc = ospf_apiserver_send_reply (apiserv, seqnum, rc);
1263: return rc;
1264: }
1265:
1266:
1267: /* -----------------------------------------------------------
1268: * Followings are functions for LSDB synchronization.
1269: * -----------------------------------------------------------
1270: */
1271:
1272: static int
1273: apiserver_sync_callback (struct ospf_lsa *lsa, void *p_arg, int int_arg)
1274: {
1275: struct ospf_apiserver *apiserv;
1276: int seqnum;
1277: struct msg *msg;
1278: struct param_t
1279: {
1280: struct ospf_apiserver *apiserv;
1281: struct lsa_filter_type *filter;
1282: }
1283: *param;
1284: int rc = -1;
1285:
1286: /* Sanity check */
1287: assert (lsa->data);
1288: assert (p_arg);
1289:
1290: param = (struct param_t *) p_arg;
1291: apiserv = param->apiserv;
1292: seqnum = (u_int32_t) int_arg;
1293:
1294: /* Check origin in filter. */
1295: if ((param->filter->origin == ANY_ORIGIN) ||
1296: (param->filter->origin == (lsa->flags & OSPF_LSA_SELF)))
1297: {
1298:
1299: /* Default area for AS-External and Opaque11 LSAs */
1300: struct in_addr area_id = { .s_addr = 0L };
1301:
1302: /* Default interface for non Opaque9 LSAs */
1303: struct in_addr ifaddr = { .s_addr = 0L };
1304:
1305: if (lsa->area)
1306: {
1307: area_id = lsa->area->area_id;
1308: }
1309: if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
1310: {
1311: ifaddr = lsa->oi->address->u.prefix4;
1312: }
1313:
1314: msg = new_msg_lsa_change_notify (MSG_LSA_UPDATE_NOTIFY,
1315: seqnum,
1316: ifaddr, area_id,
1317: lsa->flags & OSPF_LSA_SELF, lsa->data);
1318: if (!msg)
1319: {
1320: zlog_warn ("apiserver_sync_callback: new_msg_update failed");
1321: #ifdef NOTYET
1322: /* Cannot allocate new message. What should we do? */
1323: /* ospf_apiserver_free (apiserv);*//* Do nothing here XXX */
1324: #endif
1325: goto out;
1326: }
1327:
1328: /* Send LSA */
1329: ospf_apiserver_send_msg (apiserv, msg);
1330: msg_free (msg);
1331: }
1332: rc = 0;
1333:
1334: out:
1335: return rc;
1336: }
1337:
1338: int
1339: ospf_apiserver_handle_sync_lsdb (struct ospf_apiserver *apiserv,
1340: struct msg *msg)
1341: {
1342: struct listnode *node, *nnode;
1343: u_int32_t seqnum;
1344: int rc = 0;
1345: struct msg_sync_lsdb *smsg;
1346: struct ospf_apiserver_param_t
1347: {
1348: struct ospf_apiserver *apiserv;
1349: struct lsa_filter_type *filter;
1350: } param;
1351: u_int16_t mask;
1352: struct route_node *rn;
1353: struct ospf_lsa *lsa;
1354: struct ospf *ospf;
1355: struct ospf_area *area;
1356:
1357: ospf = ospf_lookup ();
1358:
1359: /* Get request sequence number */
1360: seqnum = msg_get_seq (msg);
1361: /* Set sync msg. */
1362: smsg = (struct msg_sync_lsdb *) STREAM_DATA (msg->s);
1363:
1364: /* Set parameter struct. */
1365: param.apiserv = apiserv;
1366: param.filter = &smsg->filter;
1367:
1368: /* Remember mask. */
1369: mask = ntohs (smsg->filter.typemask);
1370:
1371: /* Iterate over all areas. */
1372: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
1373: {
1374: int i;
1375: u_int32_t *area_id = NULL;
1376:
1377: /* Compare area_id with area_ids in sync request. */
1378: if ((i = smsg->filter.num_areas) > 0)
1379: {
1380: /* Let area_id point to the list of area IDs,
1381: * which is at the end of smsg->filter. */
1382: area_id = (u_int32_t *) (&smsg->filter + 1);
1383: while (i)
1384: {
1385: if (*area_id == area->area_id.s_addr)
1386: {
1387: break;
1388: }
1389: i--;
1390: area_id++;
1391: }
1392: }
1393: else
1394: {
1395: i = 1;
1396: }
1397:
1398: /* If area was found, then i>0 here. */
1399: if (i)
1400: {
1401: /* Check msg type. */
1402: if (mask & Power2[OSPF_ROUTER_LSA])
1403: LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
1404: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1405: if (mask & Power2[OSPF_NETWORK_LSA])
1406: LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
1407: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1408: if (mask & Power2[OSPF_SUMMARY_LSA])
1409: LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
1410: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1411: if (mask & Power2[OSPF_ASBR_SUMMARY_LSA])
1412: LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
1413: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1414: if (mask & Power2[OSPF_OPAQUE_LINK_LSA])
1415: LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
1416: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1417: if (mask & Power2[OSPF_OPAQUE_AREA_LSA])
1418: LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
1419: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1420: }
1421: }
1422:
1423: /* For AS-external LSAs */
1424: if (ospf->lsdb)
1425: {
1426: if (mask & Power2[OSPF_AS_EXTERNAL_LSA])
1427: LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
1428: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1429: }
1430:
1431: /* For AS-external opaque LSAs */
1432: if (ospf->lsdb)
1433: {
1434: if (mask & Power2[OSPF_OPAQUE_AS_LSA])
1435: LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
1436: apiserver_sync_callback(lsa, (void *) ¶m, seqnum);
1437: }
1438:
1439: /* Send a reply back to client with return code */
1440: rc = ospf_apiserver_send_reply (apiserv, seqnum, rc);
1441: return rc;
1442: }
1443:
1444:
1445: /* -----------------------------------------------------------
1446: * Followings are functions to originate or update LSA
1447: * from an application.
1448: * -----------------------------------------------------------
1449: */
1450:
1451: /* Create a new internal opaque LSA by taking prototype and filling in
1452: missing fields such as age, sequence number, advertising router,
1453: checksum and so on. The interface parameter is used for type 9
1454: LSAs, area parameter for type 10. Type 11 LSAs do neither need area
1455: nor interface. */
1456:
1457: struct ospf_lsa *
1458: ospf_apiserver_opaque_lsa_new (struct ospf_area *area,
1459: struct ospf_interface *oi,
1460: struct lsa_header *protolsa)
1461: {
1462: struct stream *s;
1463: struct lsa_header *newlsa;
1464: struct ospf_lsa *new = NULL;
1465: u_char options = 0x0;
1466: u_int16_t length;
1467:
1468: struct ospf *ospf;
1469:
1470: ospf = ospf_lookup();
1471: assert(ospf);
1472:
1473: /* Create a stream for internal opaque LSA */
1474: if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL)
1475: {
1476: zlog_warn ("ospf_apiserver_opaque_lsa_new: stream_new failed");
1477: return NULL;
1478: }
1479:
1480: newlsa = (struct lsa_header *) STREAM_DATA (s);
1481:
1482: /* XXX If this is a link-local LSA or an AS-external LSA, how do we
1483: have to set options? */
1484:
1485: if (area)
1486: {
1487: options = LSA_OPTIONS_GET (area);
1488: options |= LSA_OPTIONS_NSSA_GET (area);
1489: }
1490:
1491: options |= OSPF_OPTION_O; /* Don't forget to set option bit */
1492:
1493: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1494: {
1495: zlog_debug ("LSA[Type%d:%s]: Creating an Opaque-LSA instance",
1496: protolsa->type, inet_ntoa (protolsa->id));
1497: }
1498:
1499: /* Set opaque-LSA header fields. */
1500: lsa_header_set (s, options, protolsa->type, protolsa->id,
1501: ospf->router_id);
1502:
1503: /* Set opaque-LSA body fields. */
1504: stream_put (s, ((u_char *) protolsa) + sizeof (struct lsa_header),
1505: ntohs (protolsa->length) - sizeof (struct lsa_header));
1506:
1507: /* Determine length of LSA. */
1508: length = stream_get_endp (s);
1509: newlsa->length = htons (length);
1510:
1511: /* Create OSPF LSA. */
1512: if ((new = ospf_lsa_new ()) == NULL)
1513: {
1514: zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_new() ?");
1515: stream_free (s);
1516: return NULL;
1517: }
1518:
1519: if ((new->data = ospf_lsa_data_new (length)) == NULL)
1520: {
1521: zlog_warn ("ospf_apiserver_opaque_lsa_new: ospf_lsa_data_new() ?");
1522: ospf_lsa_unlock (&new);
1523: stream_free (s);
1524: return NULL;
1525: }
1526:
1527: new->area = area;
1528: new->oi = oi;
1529:
1530: SET_FLAG (new->flags, OSPF_LSA_SELF);
1531: memcpy (new->data, newlsa, length);
1532: stream_free (s);
1533:
1534: return new;
1535: }
1536:
1537:
1538: int
1539: ospf_apiserver_is_ready_type9 (struct ospf_interface *oi)
1540: {
1541: /* Type 9 opaque LSA can be originated if there is at least one
1542: active opaque-capable neighbor attached to the outgoing
1543: interface. */
1544:
1545: return (ospf_nbr_count_opaque_capable (oi) > 0);
1546: }
1547:
1548: int
1549: ospf_apiserver_is_ready_type10 (struct ospf_area *area)
1550: {
1551: /* Type 10 opaque LSA can be originated if there is at least one
1552: interface belonging to the area that has an active opaque-capable
1553: neighbor. */
1554: struct listnode *node, *nnode;
1555: struct ospf_interface *oi;
1556:
1557: for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
1558: /* Is there an active neighbor attached to this interface? */
1559: if (ospf_apiserver_is_ready_type9 (oi))
1560: return 1;
1561:
1562: /* No active neighbor in area */
1563: return 0;
1564: }
1565:
1566: int
1567: ospf_apiserver_is_ready_type11 (struct ospf *ospf)
1568: {
1569: /* Type 11 opaque LSA can be originated if there is at least one interface
1570: that has an active opaque-capable neighbor. */
1571: struct listnode *node, *nnode;
1572: struct ospf_interface *oi;
1573:
1574: for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
1575: /* Is there an active neighbor attached to this interface? */
1576: if (ospf_apiserver_is_ready_type9 (oi))
1577: return 1;
1578:
1579: /* No active neighbor at all */
1580: return 0;
1581: }
1582:
1583:
1584: int
1585: ospf_apiserver_handle_originate_request (struct ospf_apiserver *apiserv,
1586: struct msg *msg)
1587: {
1588: struct msg_originate_request *omsg;
1589: struct lsa_header *data;
1590: struct ospf_lsa *new;
1591: struct ospf_lsa *old;
1592: struct ospf_area *area = NULL;
1593: struct ospf_interface *oi = NULL;
1594: struct ospf_lsdb *lsdb = NULL;
1595: struct ospf *ospf;
1596: int lsa_type, opaque_type;
1597: int ready = 0;
1598: int rc = 0;
1599:
1600: ospf = ospf_lookup();
1601:
1602: /* Extract opaque LSA data from message */
1603: omsg = (struct msg_originate_request *) STREAM_DATA (msg->s);
1604: data = &omsg->data;
1605:
1606: /* Determine interface for type9 or area for type10 LSAs. */
1607: switch (data->type)
1608: {
1609: case OSPF_OPAQUE_LINK_LSA:
1610: oi = ospf_apiserver_if_lookup_by_addr (omsg->ifaddr);
1611: if (!oi)
1612: {
1613: zlog_warn ("apiserver_originate: unknown interface %s",
1614: inet_ntoa (omsg->ifaddr));
1615: rc = OSPF_API_NOSUCHINTERFACE;
1616: goto out;
1617: }
1618: area = oi->area;
1619: lsdb = area->lsdb;
1620: break;
1621: case OSPF_OPAQUE_AREA_LSA:
1622: area = ospf_area_lookup_by_area_id (ospf, omsg->area_id);
1623: if (!area)
1624: {
1625: zlog_warn ("apiserver_originate: unknown area %s",
1626: inet_ntoa (omsg->area_id));
1627: rc = OSPF_API_NOSUCHAREA;
1628: goto out;
1629: }
1630: lsdb = area->lsdb;
1631: break;
1632: case OSPF_OPAQUE_AS_LSA:
1633: lsdb = ospf->lsdb;
1634: break;
1635: default:
1636: /* We can only handle opaque types here */
1637: zlog_warn ("apiserver_originate: Cannot originate non-opaque LSA type %d",
1638: data->type);
1639: rc = OSPF_API_ILLEGALLSATYPE;
1640: goto out;
1641: }
1642:
1643: /* Check if we registered this opaque type */
1644: lsa_type = data->type;
1645: opaque_type = GET_OPAQUE_TYPE (ntohl (data->id.s_addr));
1646:
1647: if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type))
1648: {
1649: zlog_warn ("apiserver_originate: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type);
1650: rc = OSPF_API_OPAQUETYPENOTREGISTERED;
1651: goto out;
1652: }
1653:
1654: /* Make sure that the neighbors are ready before we can originate */
1655: switch (data->type)
1656: {
1657: case OSPF_OPAQUE_LINK_LSA:
1658: ready = ospf_apiserver_is_ready_type9 (oi);
1659: break;
1660: case OSPF_OPAQUE_AREA_LSA:
1661: ready = ospf_apiserver_is_ready_type10 (area);
1662: break;
1663: case OSPF_OPAQUE_AS_LSA:
1664: ready = ospf_apiserver_is_ready_type11 (ospf);
1665: break;
1666: default:
1667: break;
1668: }
1669:
1670: if (!ready)
1671: {
1672: zlog_warn ("Neighbors not ready to originate type %d", data->type);
1673: rc = OSPF_API_NOTREADY;
1674: goto out;
1675: }
1676:
1677: /* Create OSPF's internal opaque LSA representation */
1678: new = ospf_apiserver_opaque_lsa_new (area, oi, data);
1679: if (!new)
1680: {
1681: rc = OSPF_API_NOMEMORY; /* XXX */
1682: goto out;
1683: }
1684:
1685: /* Determine if LSA is new or an update for an existing one. */
1686: old = ospf_lsdb_lookup (lsdb, new);
1687:
1688: if (!old)
1689: {
1690: /* New LSA install in LSDB. */
1691: rc = ospf_apiserver_originate1 (new);
1692: }
1693: else
1694: {
1695: /*
1696: * Keep the new LSA instance in the "waiting place" until the next
1697: * refresh timing. If several LSA update requests for the same LSID
1698: * have issued by peer, the last one takes effect.
1699: */
1700: new->lsdb = &apiserv->reserve;
1701: ospf_lsdb_add (&apiserv->reserve, new);
1702:
1703: /* Kick the scheduler function. */
1704: ospf_opaque_lsa_refresh_schedule (old);
1705: }
1706:
1707: out:
1708:
1709: /* Send a reply back to client with return code */
1710: rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
1711: return rc;
1712: }
1713:
1714:
1715: /* -----------------------------------------------------------
1716: * Flood an LSA within its flooding scope.
1717: * -----------------------------------------------------------
1718: */
1719:
1720: /* XXX We can probably use ospf_flood_through instead of this function
1721: but then we need the neighbor parameter. If we set nbr to
1722: NULL then ospf_flood_through crashes due to dereferencing NULL. */
1723:
1724: void
1725: ospf_apiserver_flood_opaque_lsa (struct ospf_lsa *lsa)
1726: {
1727: assert (lsa);
1728:
1729: switch (lsa->data->type)
1730: {
1731: case OSPF_OPAQUE_LINK_LSA:
1732: /* Increment counters? XXX */
1733:
1734: /* Flood LSA through local network. */
1735: ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa);
1736: break;
1737: case OSPF_OPAQUE_AREA_LSA:
1738: /* Update LSA origination count. */
1739: assert (lsa->area);
1740: lsa->area->ospf->lsa_originate_count++;
1741:
1742: /* Flood LSA through area. */
1743: ospf_flood_through_area (lsa->area, NULL /*nbr */ , lsa);
1744: break;
1745: case OSPF_OPAQUE_AS_LSA:
1746: {
1747: struct ospf *ospf;
1748:
1749: ospf = ospf_lookup();
1750: assert(ospf);
1751:
1752: /* Increment counters? XXX */
1753:
1754: /* Flood LSA through AS. */
1755: ospf_flood_through_as (ospf, NULL /*nbr */ , lsa);
1756: break;
1757: }
1758: }
1759: }
1760:
1761: int
1762: ospf_apiserver_originate1 (struct ospf_lsa *lsa)
1763: {
1764: struct ospf *ospf;
1765:
1766: ospf = ospf_lookup();
1767: assert(ospf);
1768:
1769: /* Install this LSA into LSDB. */
1770: if (ospf_lsa_install (ospf, lsa->oi, lsa) == NULL)
1771: {
1772: zlog_warn ("ospf_apiserver_originate1: ospf_lsa_install failed");
1773: return -1;
1774: }
1775:
1776: /* Flood LSA within scope */
1777:
1778: #ifdef NOTYET
1779: /*
1780: * NB: Modified version of "ospf_flood_though ()" accepts NULL "inbr"
1781: * parameter, and thus it does not cause SIGSEGV error.
1782: */
1783: ospf_flood_through (NULL /*nbr */ , lsa);
1784: #else /* NOTYET */
1785:
1786: ospf_apiserver_flood_opaque_lsa (lsa);
1787: #endif /* NOTYET */
1788:
1789: return 0;
1790: }
1791:
1792:
1793: /* Opaque LSAs of type 9 on a specific interface can now be
1794: originated. Tell clients that registered type 9. */
1795: int
1796: ospf_apiserver_lsa9_originator (void *arg)
1797: {
1798: struct ospf_interface *oi;
1799:
1800: oi = (struct ospf_interface *) arg;
1801: if (listcount (apiserver_list) > 0) {
1802: ospf_apiserver_clients_notify_ready_type9 (oi);
1803: }
1804: return 0;
1805: }
1806:
1807: int
1808: ospf_apiserver_lsa10_originator (void *arg)
1809: {
1810: struct ospf_area *area;
1811:
1812: area = (struct ospf_area *) arg;
1813: if (listcount (apiserver_list) > 0) {
1814: ospf_apiserver_clients_notify_ready_type10 (area);
1815: }
1816: return 0;
1817: }
1818:
1819: int
1820: ospf_apiserver_lsa11_originator (void *arg)
1821: {
1822: struct ospf *ospf;
1823:
1824: ospf = (struct ospf *) arg;
1825: if (listcount (apiserver_list) > 0) {
1826: ospf_apiserver_clients_notify_ready_type11 (ospf);
1827: }
1828: return 0;
1829: }
1830:
1831:
1832: /* Periodically refresh opaque LSAs so that they do not expire in
1833: other routers. */
1834: struct ospf_lsa *
1835: ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)
1836: {
1837: struct ospf_apiserver *apiserv;
1838: struct ospf_lsa *new = NULL;
1839: struct ospf * ospf;
1840:
1841: ospf = ospf_lookup();
1842: assert(ospf);
1843:
1844: apiserv = lookup_apiserver_by_lsa (lsa);
1845: if (!apiserv)
1846: {
1847: zlog_warn ("ospf_apiserver_lsa_refresher: LSA[%s]: No apiserver?", dump_lsa_key (lsa));
1848: lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */
1849: }
1850:
1851: if (IS_LSA_MAXAGE (lsa))
1852: {
1853: ospf_opaque_lsa_flush_schedule (lsa);
1854: goto out;
1855: }
1856:
1857: /* Check if updated version of LSA instance has already prepared. */
1858: new = ospf_lsdb_lookup (&apiserv->reserve, lsa);
1859: if (!new)
1860: {
1861: /* This is a periodic refresh, driven by core OSPF mechanism. */
1862: new = ospf_apiserver_opaque_lsa_new (lsa->area, lsa->oi, lsa->data);
1863: if (!new)
1864: {
1865: zlog_warn ("ospf_apiserver_lsa_refresher: Cannot create a new LSA?");
1866: goto out;
1867: }
1868: }
1869: else
1870: {
1871: /* This is a forcible refresh, requested by OSPF-API client. */
1872: ospf_lsdb_delete (&apiserv->reserve, new);
1873: new->lsdb = NULL;
1874: }
1875:
1876: /* Increment sequence number */
1877: new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1878:
1879: /* New LSA is in same area. */
1880: new->area = lsa->area;
1881: SET_FLAG (new->flags, OSPF_LSA_SELF);
1882:
1883: /* Install LSA into LSDB. */
1884: if (ospf_lsa_install (ospf, new->oi, new) == NULL)
1885: {
1886: zlog_warn ("ospf_apiserver_lsa_refresher: ospf_lsa_install failed");
1887: ospf_lsa_unlock (&new);
1888: goto out;
1889: }
1890:
1891: /* Flood updated LSA through interface, area or AS */
1892:
1893: #ifdef NOTYET
1894: ospf_flood_through (NULL /*nbr */ , new);
1895: #endif /* NOTYET */
1896: ospf_apiserver_flood_opaque_lsa (new);
1897:
1898: /* Debug logging. */
1899: if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1900: {
1901: zlog_debug ("LSA[Type%d:%s]: Refresh Opaque LSA",
1902: new->data->type, inet_ntoa (new->data->id));
1903: ospf_lsa_header_dump (new->data);
1904: }
1905:
1906: out:
1907: return new;
1908: }
1909:
1910:
1911: /* -----------------------------------------------------------
1912: * Followings are functions to delete LSAs
1913: * -----------------------------------------------------------
1914: */
1915:
1916: int
1917: ospf_apiserver_handle_delete_request (struct ospf_apiserver *apiserv,
1918: struct msg *msg)
1919: {
1920: struct msg_delete_request *dmsg;
1921: struct ospf_lsa *old;
1922: struct ospf_area *area = NULL;
1923: struct in_addr id;
1924: int lsa_type, opaque_type;
1925: int rc = 0;
1926: struct ospf * ospf;
1927:
1928: ospf = ospf_lookup();
1929: assert(ospf);
1930:
1931: /* Extract opaque LSA from message */
1932: dmsg = (struct msg_delete_request *) STREAM_DATA (msg->s);
1933:
1934: /* Lookup area for link-local and area-local opaque LSAs */
1935: switch (dmsg->lsa_type)
1936: {
1937: case OSPF_OPAQUE_LINK_LSA:
1938: case OSPF_OPAQUE_AREA_LSA:
1939: area = ospf_area_lookup_by_area_id (ospf, dmsg->area_id);
1940: if (!area)
1941: {
1942: zlog_warn ("ospf_apiserver_lsa_delete: unknown area %s",
1943: inet_ntoa (dmsg->area_id));
1944: rc = OSPF_API_NOSUCHAREA;
1945: goto out;
1946: }
1947: break;
1948: case OSPF_OPAQUE_AS_LSA:
1949: /* AS-external opaque LSAs have no designated area */
1950: area = NULL;
1951: break;
1952: default:
1953: zlog_warn
1954: ("ospf_apiserver_lsa_delete: Cannot delete non-opaque LSA type %d",
1955: dmsg->lsa_type);
1956: rc = OSPF_API_ILLEGALLSATYPE;
1957: goto out;
1958: }
1959:
1960: /* Check if we registered this opaque type */
1961: lsa_type = dmsg->lsa_type;
1962: opaque_type = dmsg->opaque_type;
1963:
1964: if (!apiserver_is_opaque_type_registered (apiserv, lsa_type, opaque_type))
1965: {
1966: zlog_warn ("ospf_apiserver_lsa_delete: LSA-type(%d)/Opaque-type(%d): Not registered", lsa_type, opaque_type);
1967: rc = OSPF_API_OPAQUETYPENOTREGISTERED;
1968: goto out;
1969: }
1970:
1971: /* opaque_id is in network byte order */
1972: id.s_addr = htonl (SET_OPAQUE_LSID (dmsg->opaque_type,
1973: ntohl (dmsg->opaque_id)));
1974:
1975: /*
1976: * Even if the target LSA has once scheduled to flush, it remains in
1977: * the LSDB until it is finally handled by the maxage remover thread.
1978: * Therefore, the lookup function below may return non-NULL result.
1979: */
1980: old = ospf_lsa_lookup (area, dmsg->lsa_type, id, ospf->router_id);
1981: if (!old)
1982: {
1983: zlog_warn ("ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
1984: dmsg->lsa_type, inet_ntoa (id));
1985: rc = OSPF_API_NOSUCHLSA;
1986: goto out;
1987: }
1988:
1989: /* Schedule flushing of LSA from LSDB */
1990: /* NB: Multiple scheduling will produce a warning message, but harmless. */
1991: ospf_opaque_lsa_flush_schedule (old);
1992:
1993: out:
1994:
1995: /* Send reply back to client including return code */
1996: rc = ospf_apiserver_send_reply (apiserv, ntohl (msg->hdr.msgseq), rc);
1997: return rc;
1998: }
1999:
2000: /* Flush self-originated opaque LSA */
2001: static int
2002: apiserver_flush_opaque_type_callback (struct ospf_lsa *lsa,
2003: void *p_arg, int int_arg)
2004: {
2005: struct param_t
2006: {
2007: struct ospf_apiserver *apiserv;
2008: u_char lsa_type;
2009: u_char opaque_type;
2010: }
2011: *param;
2012:
2013: /* Sanity check */
2014: assert (lsa->data);
2015: assert (p_arg);
2016: param = (struct param_t *) p_arg;
2017:
2018: /* If LSA matches type and opaque type then delete it */
2019: if (IS_LSA_SELF (lsa) && lsa->data->type == param->lsa_type
2020: && GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)) == param->opaque_type)
2021: {
2022: ospf_opaque_lsa_flush_schedule (lsa);
2023: }
2024: return 0;
2025: }
2026:
2027: /* Delete self-originated opaque LSAs of a given opaque type. This
2028: function is called when an application unregisters a given opaque
2029: type or a connection to an application closes and all those opaque
2030: LSAs need to be flushed the LSDB. */
2031: void
2032: ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv,
2033: u_char lsa_type, u_char opaque_type)
2034: {
2035: struct param_t
2036: {
2037: struct ospf_apiserver *apiserv;
2038: u_char lsa_type;
2039: u_char opaque_type;
2040: } param;
2041: struct listnode *node, *nnode;
2042: struct ospf * ospf;
2043: struct ospf_area *area;
2044:
2045: ospf = ospf_lookup();
2046: assert(ospf);
2047:
2048: /* Set parameter struct. */
2049: param.apiserv = apiserv;
2050: param.lsa_type = lsa_type;
2051: param.opaque_type = opaque_type;
2052:
2053: switch (lsa_type)
2054: {
2055: struct route_node *rn;
2056: struct ospf_lsa *lsa;
2057:
2058: case OSPF_OPAQUE_LINK_LSA:
2059: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
2060: LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2061: apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0);
2062: break;
2063: case OSPF_OPAQUE_AREA_LSA:
2064: for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
2065: LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2066: apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0);
2067: break;
2068: case OSPF_OPAQUE_AS_LSA:
2069: LSDB_LOOP (OPAQUE_LINK_LSDB (ospf), rn, lsa)
2070: apiserver_flush_opaque_type_callback(lsa, (void *) ¶m, 0);
2071: break;
2072: default:
2073: break;
2074: }
2075: return;
2076: }
2077:
2078:
2079: /* -----------------------------------------------------------
2080: * Followings are callback functions to handle opaque types
2081: * -----------------------------------------------------------
2082: */
2083:
2084: int
2085: ospf_apiserver_new_if (struct interface *ifp)
2086: {
2087: struct ospf_interface *oi;
2088:
2089: /* For some strange reason it seems possible that we are invoked
2090: with an interface that has no name. This seems to happen during
2091: initialization. Return if this happens */
2092:
2093: if (ifp->name[0] == '\0') {
2094: /* interface has empty name */
2095: zlog_warn ("ospf_apiserver_new_if: interface has no name?");
2096: return 0;
2097: }
2098:
2099: /* zlog_warn for debugging */
2100: zlog_warn ("ospf_apiserver_new_if");
2101: zlog_warn ("ifp name=%s status=%d index=%d", ifp->name, ifp->status,
2102: ifp->ifindex);
2103:
2104: if (ifp->name[0] == '\0') {
2105: /* interface has empty name */
2106: zlog_warn ("ospf_apiserver_new_if: interface has no name?");
2107: return 0;
2108: }
2109:
2110: oi = ospf_apiserver_if_lookup_by_ifp (ifp);
2111:
2112: if (!oi) {
2113: /* This interface is known to Zebra but not to OSPF daemon yet. */
2114: zlog_warn ("ospf_apiserver_new_if: interface %s not known to OSPFd?",
2115: ifp->name);
2116: return 0;
2117: }
2118:
2119: assert (oi);
2120:
2121: /* New interface added to OSPF, tell clients about it */
2122: if (listcount (apiserver_list) > 0) {
2123: ospf_apiserver_clients_notify_new_if (oi);
2124: }
2125: return 0;
2126: }
2127:
2128: int
2129: ospf_apiserver_del_if (struct interface *ifp)
2130: {
2131: struct ospf_interface *oi;
2132:
2133: /* zlog_warn for debugging */
2134: zlog_warn ("ospf_apiserver_del_if");
2135: zlog_warn ("ifp name=%s status=%d index=%d\n", ifp->name, ifp->status,
2136: ifp->ifindex);
2137:
2138: oi = ospf_apiserver_if_lookup_by_ifp (ifp);
2139:
2140: if (!oi) {
2141: /* This interface is known to Zebra but not to OSPF daemon
2142: anymore. No need to tell clients about it */
2143: return 0;
2144: }
2145:
2146: /* Interface deleted, tell clients about it */
2147: if (listcount (apiserver_list) > 0) {
2148: ospf_apiserver_clients_notify_del_if (oi);
2149: }
2150: return 0;
2151: }
2152:
2153: void
2154: ospf_apiserver_ism_change (struct ospf_interface *oi, int old_state)
2155: {
2156: /* Tell clients about interface change */
2157:
2158: /* zlog_warn for debugging */
2159: zlog_warn ("ospf_apiserver_ism_change");
2160: if (listcount (apiserver_list) > 0) {
2161: ospf_apiserver_clients_notify_ism_change (oi);
2162: }
2163:
2164: zlog_warn ("oi->ifp->name=%s", oi->ifp->name);
2165: zlog_warn ("old_state=%d", old_state);
2166: zlog_warn ("oi->state=%d", oi->state);
2167: }
2168:
2169: void
2170: ospf_apiserver_nsm_change (struct ospf_neighbor *nbr, int old_status)
2171: {
2172: /* Neighbor status changed, tell clients about it */
2173: zlog_warn ("ospf_apiserver_nsm_change");
2174: if (listcount (apiserver_list) > 0) {
2175: ospf_apiserver_clients_notify_nsm_change (nbr);
2176: }
2177: }
2178:
2179: void
2180: ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa)
2181: {
2182: struct opaque_lsa
2183: {
2184: struct lsa_header header;
2185: u_char data[1]; /* opaque data have variable length. This is start
2186: address */
2187: };
2188: struct opaque_lsa *olsa;
2189: int opaquelen;
2190:
2191: olsa = (struct opaque_lsa *) lsa->data;
2192:
2193: if (VALID_OPAQUE_INFO_LEN (lsa->data))
2194: opaquelen = ntohs (lsa->data->length) - OSPF_LSA_HEADER_SIZE;
2195: else
2196: opaquelen = 0;
2197:
2198: /* Output information about opaque LSAs */
2199: if (vty != NULL)
2200: {
2201: int i;
2202: vty_out (vty, " Added using OSPF API: %u octets of opaque data %s%s",
2203: opaquelen,
2204: VALID_OPAQUE_INFO_LEN (lsa->data) ? "" : "(Invalid length?)",
2205: VTY_NEWLINE);
2206: vty_out (vty, " Opaque data: ");
2207:
2208: for (i = 0; i < opaquelen; i++)
2209: {
2210: vty_out (vty, "0x%x ", olsa->data[i]);
2211: }
2212: vty_out (vty, "%s", VTY_NEWLINE);
2213: }
2214: else
2215: {
2216: int i;
2217: zlog_debug (" Added using OSPF API: %u octets of opaque data %s",
2218: opaquelen,
2219: VALID_OPAQUE_INFO_LEN (lsa->
2220: data) ? "" : "(Invalid length?)");
2221: zlog_debug (" Opaque data: ");
2222:
2223: for (i = 0; i < opaquelen; i++)
2224: {
2225: zlog_debug ("0x%x ", olsa->data[i]);
2226: }
2227: zlog_debug ("\n");
2228: }
2229: return;
2230: }
2231:
2232: /* -----------------------------------------------------------
2233: * Followings are functions to notify clients about events
2234: * -----------------------------------------------------------
2235: */
2236:
2237: /* Send a message to all clients. This is useful for messages
2238: that need to be notified to all clients (such as interface
2239: changes) */
2240:
2241: void
2242: ospf_apiserver_clients_notify_all (struct msg *msg)
2243: {
2244: struct listnode *node, *nnode;
2245: struct ospf_apiserver *apiserv;
2246:
2247: /* Send message to all clients */
2248: for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv))
2249: ospf_apiserver_send_msg (apiserv, msg);
2250: }
2251:
2252: /* An interface is now ready to accept opaque LSAs. Notify all
2253: clients that registered to use this opaque type */
2254: void
2255: ospf_apiserver_clients_notify_ready_type9 (struct ospf_interface *oi)
2256: {
2257: struct listnode *node, *nnode;
2258: struct msg *msg;
2259: struct ospf_apiserver *apiserv;
2260:
2261: assert (oi);
2262: if (!oi->address)
2263: {
2264: zlog_warn ("Interface has no address?");
2265: return;
2266: }
2267:
2268: if (!ospf_apiserver_is_ready_type9 (oi))
2269: {
2270: zlog_warn ("Interface not ready for type 9?");
2271: return;
2272: }
2273:
2274: for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv))
2275: {
2276: struct listnode *node2, *nnode2;
2277: struct registered_opaque_type *r;
2278:
2279: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r))
2280: {
2281: if (r->lsa_type == OSPF_OPAQUE_LINK_LSA)
2282: {
2283: msg = new_msg_ready_notify (0, OSPF_OPAQUE_LINK_LSA,
2284: r->opaque_type,
2285: oi->address->u.prefix4);
2286: if (!msg)
2287: {
2288: zlog_warn
2289: ("ospf_apiserver_clients_notify_ready_type9: new_msg_ready_notify failed");
2290: #ifdef NOTYET
2291: /* Cannot allocate new message. What should we do? */
2292: ospf_apiserver_free (apiserv);
2293: #endif
2294: goto out;
2295: }
2296:
2297: ospf_apiserver_send_msg (apiserv, msg);
2298: msg_free (msg);
2299: }
2300: }
2301: }
2302:
2303: out:
2304: return;
2305: }
2306:
2307: void
2308: ospf_apiserver_clients_notify_ready_type10 (struct ospf_area *area)
2309: {
2310: struct listnode *node, *nnode;
2311: struct msg *msg;
2312: struct ospf_apiserver *apiserv;
2313:
2314: assert (area);
2315:
2316: if (!ospf_apiserver_is_ready_type10 (area))
2317: {
2318: zlog_warn ("Area not ready for type 10?");
2319: return;
2320: }
2321:
2322: for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv))
2323: {
2324: struct listnode *node2, *nnode2;
2325: struct registered_opaque_type *r;
2326:
2327: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r))
2328: {
2329: if (r->lsa_type == OSPF_OPAQUE_AREA_LSA)
2330: {
2331: msg = new_msg_ready_notify (0, OSPF_OPAQUE_AREA_LSA,
2332: r->opaque_type, area->area_id);
2333: if (!msg)
2334: {
2335: zlog_warn
2336: ("ospf_apiserver_clients_notify_ready_type10: new_msg_ready_nofity failed");
2337: #ifdef NOTYET
2338: /* Cannot allocate new message. What should we do? */
2339: ospf_apiserver_free (apiserv);
2340: #endif
2341: goto out;
2342: }
2343:
2344: ospf_apiserver_send_msg (apiserv, msg);
2345: msg_free (msg);
2346: }
2347: }
2348: }
2349:
2350: out:
2351: return;
2352: }
2353:
2354:
2355: void
2356: ospf_apiserver_clients_notify_ready_type11 (struct ospf *top)
2357: {
2358: struct listnode *node, *nnode;
2359: struct msg *msg;
2360: struct in_addr id_null = { .s_addr = 0L };
2361: struct ospf_apiserver *apiserv;
2362:
2363: assert (top);
2364:
2365: if (!ospf_apiserver_is_ready_type11 (top))
2366: {
2367: zlog_warn ("AS not ready for type 11?");
2368: return;
2369: }
2370:
2371: for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv))
2372: {
2373: struct listnode *node2, *nnode2;
2374: struct registered_opaque_type *r;
2375:
2376: for (ALL_LIST_ELEMENTS (apiserv->opaque_types, node2, nnode2, r))
2377: {
2378: if (r->lsa_type == OSPF_OPAQUE_AS_LSA)
2379: {
2380: msg = new_msg_ready_notify (0, OSPF_OPAQUE_AS_LSA,
2381: r->opaque_type, id_null);
2382: if (!msg)
2383: {
2384: zlog_warn
2385: ("ospf_apiserver_clients_notify_ready_type11: new_msg_ready_notify failed");
2386: #ifdef NOTYET
2387: /* Cannot allocate new message. What should we do? */
2388: ospf_apiserver_free (apiserv);
2389: #endif
2390: goto out;
2391: }
2392:
2393: ospf_apiserver_send_msg (apiserv, msg);
2394: msg_free (msg);
2395: }
2396: }
2397: }
2398:
2399: out:
2400: return;
2401: }
2402:
2403: void
2404: ospf_apiserver_clients_notify_new_if (struct ospf_interface *oi)
2405: {
2406: struct msg *msg;
2407:
2408: msg = new_msg_new_if (0, oi->address->u.prefix4, oi->area->area_id);
2409: if (msg != NULL)
2410: {
2411: ospf_apiserver_clients_notify_all (msg);
2412: msg_free (msg);
2413: }
2414: }
2415:
2416: void
2417: ospf_apiserver_clients_notify_del_if (struct ospf_interface *oi)
2418: {
2419: struct msg *msg;
2420:
2421: msg = new_msg_del_if (0, oi->address->u.prefix4);
2422: if (msg != NULL)
2423: {
2424: ospf_apiserver_clients_notify_all (msg);
2425: msg_free (msg);
2426: }
2427: }
2428:
2429: void
2430: ospf_apiserver_clients_notify_ism_change (struct ospf_interface *oi)
2431: {
2432: struct msg *msg;
2433: struct in_addr ifaddr = { .s_addr = 0L };
2434: struct in_addr area_id = { .s_addr = 0L };
2435:
2436: assert (oi);
2437: assert (oi->ifp);
2438:
2439: if (oi->address)
2440: {
2441: ifaddr = oi->address->u.prefix4;
2442: }
2443: if (oi->area)
2444: {
2445: area_id = oi->area->area_id;
2446: }
2447:
2448: msg = new_msg_ism_change (0, ifaddr, area_id, oi->state);
2449: if (!msg)
2450: {
2451: zlog_warn ("apiserver_clients_notify_ism_change: msg_new failed");
2452: return;
2453: }
2454:
2455: ospf_apiserver_clients_notify_all (msg);
2456: msg_free (msg);
2457: }
2458:
2459: void
2460: ospf_apiserver_clients_notify_nsm_change (struct ospf_neighbor *nbr)
2461: {
2462: struct msg *msg;
2463: struct in_addr ifaddr = { .s_addr = 0L };
2464: struct in_addr nbraddr = { .s_addr = 0L };
2465:
2466: assert (nbr);
2467:
2468: if (nbr->oi)
2469: {
2470: ifaddr = nbr->oi->address->u.prefix4;
2471: }
2472:
2473: nbraddr = nbr->address.u.prefix4;
2474:
2475: msg = new_msg_nsm_change (0, ifaddr, nbraddr, nbr->router_id, nbr->state);
2476: if (!msg)
2477: {
2478: zlog_warn ("apiserver_clients_notify_nsm_change: msg_new failed");
2479: return;
2480: }
2481:
2482: ospf_apiserver_clients_notify_all (msg);
2483: msg_free (msg);
2484: }
2485:
2486: static void
2487: apiserver_clients_lsa_change_notify (u_char msgtype, struct ospf_lsa *lsa)
2488: {
2489: struct msg *msg;
2490: struct listnode *node, *nnode;
2491: struct ospf_apiserver *apiserv;
2492:
2493: /* Default area for AS-External and Opaque11 LSAs */
2494: struct in_addr area_id = { .s_addr = 0L };
2495:
2496: /* Default interface for non Opaque9 LSAs */
2497: struct in_addr ifaddr = { .s_addr = 0L };
2498:
2499: if (lsa->area)
2500: {
2501: area_id = lsa->area->area_id;
2502: }
2503: if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
2504: {
2505: assert (lsa->oi);
2506: ifaddr = lsa->oi->address->u.prefix4;
2507: }
2508:
2509: /* Prepare message that can be sent to clients that have a matching
2510: filter */
2511: msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */
2512: ifaddr, area_id,
2513: lsa->flags & OSPF_LSA_SELF, lsa->data);
2514: if (!msg)
2515: {
2516: zlog_warn ("apiserver_clients_lsa_change_notify: msg_new failed");
2517: return;
2518: }
2519:
2520: /* Now send message to all clients with a matching filter */
2521: for (ALL_LIST_ELEMENTS (apiserver_list, node, nnode, apiserv))
2522: {
2523: struct lsa_filter_type *filter;
2524: u_int16_t mask;
2525: u_int32_t *area;
2526: int i;
2527:
2528: /* Check filter for this client. */
2529: filter = apiserv->filter;
2530:
2531: /* Check area IDs in case of non AS-E LSAs.
2532: * If filter has areas (num_areas > 0),
2533: * then one of the areas must match the area ID of this LSA. */
2534:
2535: i = filter->num_areas;
2536: if ((lsa->data->type == OSPF_AS_EXTERNAL_LSA) ||
2537: (lsa->data->type == OSPF_OPAQUE_AS_LSA))
2538: {
2539: i = 0;
2540: }
2541:
2542: if (i > 0)
2543: {
2544: area = (u_int32_t *) (filter + 1);
2545: while (i)
2546: {
2547: if (*area == area_id.s_addr)
2548: {
2549: break;
2550: }
2551: i--;
2552: area++;
2553: }
2554: }
2555: else
2556: {
2557: i = 1;
2558: }
2559:
2560: if (i > 0)
2561: {
2562: /* Area match. Check LSA type. */
2563: mask = ntohs (filter->typemask);
2564:
2565: if (mask & Power2[lsa->data->type])
2566: {
2567: /* Type also matches. Check origin. */
2568: if ((filter->origin == ANY_ORIGIN) ||
2569: (filter->origin == IS_LSA_SELF (lsa)))
2570: {
2571: ospf_apiserver_send_msg (apiserv, msg);
2572: }
2573: }
2574: }
2575: }
2576: /* Free message since it is not used anymore */
2577: msg_free (msg);
2578: }
2579:
2580:
2581: /* -------------------------------------------------------------
2582: * Followings are hooks invoked when LSAs are updated or deleted
2583: * -------------------------------------------------------------
2584: */
2585:
2586:
2587: static int
2588: apiserver_notify_clients_lsa (u_char msgtype, struct ospf_lsa *lsa)
2589: {
2590: struct msg *msg;
2591: /* default area for AS-External and Opaque11 LSAs */
2592: struct in_addr area_id = { .s_addr = 0L };
2593:
2594: /* default interface for non Opaque9 LSAs */
2595: struct in_addr ifaddr = { .s_addr = 0L };
2596:
2597: /* Only notify this update if the LSA's age is smaller than
2598: MAXAGE. Otherwise clients would see LSA updates with max age just
2599: before they are deleted from the LSDB. LSA delete messages have
2600: MAXAGE too but should not be filtered. */
2601: if (IS_LSA_MAXAGE(lsa) && (msgtype == MSG_LSA_UPDATE_NOTIFY)) {
2602: return 0;
2603: }
2604:
2605: if (lsa->area)
2606: {
2607: area_id = lsa->area->area_id;
2608: }
2609: if (lsa->data->type == OSPF_OPAQUE_LINK_LSA)
2610: {
2611: ifaddr = lsa->oi->address->u.prefix4;
2612: }
2613: msg = new_msg_lsa_change_notify (msgtype, 0L, /* no sequence number */
2614: ifaddr, area_id,
2615: lsa->flags & OSPF_LSA_SELF, lsa->data);
2616: if (!msg)
2617: {
2618: zlog_warn ("notify_clients_lsa: msg_new failed");
2619: return -1;
2620: }
2621: /* Notify all clients that new LSA is added/updated */
2622: apiserver_clients_lsa_change_notify (msgtype, lsa);
2623:
2624: /* Clients made their own copies of msg so we can free msg here */
2625: msg_free (msg);
2626:
2627: return 0;
2628: }
2629:
2630: int
2631: ospf_apiserver_lsa_update (struct ospf_lsa *lsa)
2632: {
2633: return apiserver_notify_clients_lsa (MSG_LSA_UPDATE_NOTIFY, lsa);
2634: }
2635:
2636: int
2637: ospf_apiserver_lsa_delete (struct ospf_lsa *lsa)
2638: {
2639: return apiserver_notify_clients_lsa (MSG_LSA_DELETE_NOTIFY, lsa);
2640: }
2641:
2642: #endif /* SUPPORT_OSPF_API */
2643:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>