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