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