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