Bug Summary

File:src/usr.sbin/ospf6d/ospfe.c
Warning:line 1104, column 2
The left operand of '&' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ospfe.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/ospf6d/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/ospf6d -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ospf6d/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/ospf6d/ospfe.c
1/* $OpenBSD: ospfe.c,v 1.71 2023/12/13 15:34:43 claudio Exp $ */
2
3/*
4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
6 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/types.h>
22#include <sys/socket.h>
23#include <sys/queue.h>
24#include <netinet/in.h>
25#include <arpa/inet.h>
26#include <net/if_types.h>
27#include <stdlib.h>
28#include <signal.h>
29#include <string.h>
30#include <fcntl.h>
31#include <pwd.h>
32#include <unistd.h>
33#include <event.h>
34#include <err.h>
35#include <errno(*__errno()).h>
36#include <stdio.h>
37
38#include "ospf6.h"
39#include "ospf6d.h"
40#include "ospfe.h"
41#include "rde.h"
42#include "control.h"
43#include "log.h"
44
45void ospfe_sig_handler(int, short, void *);
46__dead__attribute__((__noreturn__)) void ospfe_shutdown(void);
47void orig_rtr_lsa_all(struct area *);
48struct iface *find_vlink(struct abr_rtr *);
49
50struct ospfd_conf *oeconf = NULL((void *)0), *noeconf;
51static struct imsgev *iev_main;
52static struct imsgev *iev_rde;
53int oe_nofib;
54
55void
56ospfe_sig_handler(int sig, short event, void *bula)
57{
58 switch (sig) {
59 case SIGINT2:
60 case SIGTERM15:
61 ospfe_shutdown();
62 /* NOTREACHED */
63 default:
64 fatalx("unexpected signal");
65 }
66}
67
68/* ospf engine */
69pid_t
70ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2],
71 int pipe_parent2rde[2])
72{
73 struct area *area;
74 struct iface *iface;
75 struct passwd *pw;
76 struct event ev_sigint, ev_sigterm;
77 pid_t pid;
78
79 switch (pid = fork()) {
80 case -1:
81 fatal("cannot fork");
82 case 0:
83 break;
84 default:
85 return (pid);
86 }
87
88 /* create the raw ip socket */
89 if ((xconf->ospf_socket = socket(AF_INET624,
90 SOCK_RAW3 | SOCK_CLOEXEC0x8000 | SOCK_NONBLOCK0x4000, IPPROTO_OSPF89)) == -1)
91 fatal("error creating raw socket");
92
93 /* set some defaults */
94 if (if_set_mcast_loop(xconf->ospf_socket) == -1)
95 fatal("if_set_mcast_loop");
96 if (if_set_ipv6_checksum(xconf->ospf_socket) == -1)
97 fatal("if_set_ipv6_checksum");
98 if (if_set_ipv6_pktinfo(xconf->ospf_socket, 1) == -1)
99 fatal("if_set_ipv6_pktinfo");
100 if_set_sockbuf(xconf->ospf_socket);
101
102 oeconf = xconf;
103 if (oeconf->flags & OSPFD_FLAG_NO_FIB_UPDATE0x0001)
104 oe_nofib = 1;
105
106 if ((pw = getpwnam(OSPF6D_USER"_ospf6d")) == NULL((void *)0))
107 fatal("getpwnam");
108
109 if (chroot(pw->pw_dir) == -1)
110 fatal("chroot");
111 if (chdir("/") == -1)
112 fatal("chdir(\"/\")");
113
114 setproctitle("ospf engine");
115 /*
116 * XXX needed with fork+exec
117 * log_init(debug, LOG_DAEMON);
118 * log_setverbose(verbose);
119 */
120
121 ospfd_process = PROC_OSPF_ENGINE;
122 log_procinit(log_procnames[ospfd_process]);
123
124 if (setgroups(1, &pw->pw_gid) ||
125 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
126 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
127 fatal("can't drop privileges");
128
129 if (pledge("stdio inet mcast recvfd", NULL((void *)0)) == -1)
130 fatal("pledge");
131
132 event_init();
133 nbr_init(NBR_HASHSIZE128);
134 lsa_cache_init(LSA_HASHSIZE512);
135
136 /* setup signal handler */
137 signal_set(&ev_sigint, SIGINT, ospfe_sig_handler, NULL)event_set(&ev_sigint, 2, 0x08|0x10, ospfe_sig_handler, ((
void *)0))
;
138 signal_set(&ev_sigterm, SIGTERM, ospfe_sig_handler, NULL)event_set(&ev_sigterm, 15, 0x08|0x10, ospfe_sig_handler, (
(void *)0))
;
139 signal_add(&ev_sigint, NULL)event_add(&ev_sigint, ((void *)0));
140 signal_add(&ev_sigterm, NULL)event_add(&ev_sigterm, ((void *)0));
141 signal(SIGPIPE13, SIG_IGN(void (*)(int))1);
142 signal(SIGHUP1, SIG_IGN(void (*)(int))1);
143
144 /* setup pipes */
145 close(pipe_parent2ospfe[0]);
146 close(pipe_ospfe2rde[1]);
147 close(pipe_parent2rde[0]);
148 close(pipe_parent2rde[1]);
149
150 if ((iev_rde = malloc(sizeof(struct imsgev))) == NULL((void *)0) ||
151 (iev_main = malloc(sizeof(struct imsgev))) == NULL((void *)0))
152 fatal(NULL((void *)0));
153 imsg_init(&iev_rde->ibuf, pipe_ospfe2rde[0]);
154 iev_rde->handler = ospfe_dispatch_rde;
155 imsg_init(&iev_main->ibuf, pipe_parent2ospfe[1]);
156 iev_main->handler = ospfe_dispatch_main;
157
158 /* setup event handler */
159 iev_rde->events = EV_READ0x02;
160 event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events,
161 iev_rde->handler, iev_rde);
162 event_add(&iev_rde->ev, NULL((void *)0));
163
164 iev_main->events = EV_READ0x02;
165 event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
166 iev_main->handler, iev_main);
167 event_add(&iev_main->ev, NULL((void *)0));
168
169 event_set(&oeconf->ev, oeconf->ospf_socket, EV_READ0x02|EV_PERSIST0x10,
170 recv_packet, oeconf);
171 event_add(&oeconf->ev, NULL((void *)0));
172
173 /* remove unneeded config stuff */
174 conf_clear_redist_list(&oeconf->redist_list);
175
176 /* start interfaces */
177 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
{
178 ospfe_demote_area(area, 0);
179 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
180 if_start(xconf, iface);
181 }
182
183 event_dispatch();
184
185 ospfe_shutdown();
186 /* NOTREACHED */
187 return (0);
188}
189
190__dead__attribute__((__noreturn__)) void
191ospfe_shutdown(void)
192{
193 struct area *area;
194 struct iface *iface;
195
196 /* close pipes */
197 msgbuf_write(&iev_rde->ibuf.w);
198 msgbuf_clear(&iev_rde->ibuf.w);
199 close(iev_rde->ibuf.fd);
200 msgbuf_write(&iev_main->ibuf.w);
201 msgbuf_clear(&iev_main->ibuf.w);
202 close(iev_main->ibuf.fd);
203
204 /* stop all interfaces and remove all areas */
205 while ((area = LIST_FIRST(&oeconf->area_list)((&oeconf->area_list)->lh_first)) != NULL((void *)0)) {
206 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
{
207 if (if_fsm(iface, IF_EVT_DOWN)) {
208 log_debug("error stopping interface %s",
209 iface->name);
210 }
211 }
212 LIST_REMOVE(area, entry)do { if ((area)->entry.le_next != ((void *)0)) (area)->
entry.le_next->entry.le_prev = (area)->entry.le_prev; *
(area)->entry.le_prev = (area)->entry.le_next; ; ; } while
(0)
;
213 area_del(area);
214 }
215
216 close(oeconf->ospf_socket);
217
218 /* clean up */
219 free(iev_rde);
220 free(iev_main);
221 free(oeconf);
222
223 log_info("ospf engine exiting");
224 _exit(0);
225}
226
227/* imesg */
228int
229ospfe_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen)
230{
231 return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
232}
233
234int
235ospfe_imsg_compose_rde(int type, u_int32_t peerid, pid_t pid,
236 void *data, u_int16_t datalen)
237{
238 return (imsg_compose_event(iev_rde, type, peerid, pid, -1,
239 data, datalen));
240}
241
242void
243ospfe_dispatch_main(int fd, short event, void *bula)
244{
245 static struct area *narea;
246 struct area *area;
247 struct iface *iface, *ifp, *i;
248 struct ifaddrchange *ifc;
249 struct iface_addr *ia, *nia;
250 struct imsg imsg;
251 struct imsgev *iev = bula;
252 struct imsgbuf *ibuf = &iev->ibuf;
253 int n, stub_changed, shut = 0, isvalid, wasvalid;
254
255 if (event & EV_READ0x02) {
1
Assuming the condition is false
2
Taking false branch
256 if ((n = imsg_read(ibuf)) == -1 && errno(*__errno()) != EAGAIN35)
257 fatal("imsg_read error");
258 if (n == 0) /* connection closed */
259 shut = 1;
260 }
261 if (event & EV_WRITE0x04) {
3
Assuming the condition is false
4
Taking false branch
262 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno(*__errno()) != EAGAIN35)
263 fatal("msgbuf_write");
264 if (n == 0) /* connection closed */
265 shut = 1;
266 }
267
268 for (;;) {
5
Loop condition is true. Entering loop body
269 if ((n = imsg_get(ibuf, &imsg)) == -1)
6
Assuming the condition is false
7
Taking false branch
270 fatal("ospfe_dispatch_main: imsg_get error");
271 if (n == 0)
8
Assuming 'n' is not equal to 0
9
Taking false branch
272 break;
273
274 switch (imsg.hdr.type) {
10
Control jumps to 'case IMSG_IFADDRDEL:' at line 343
275 case IMSG_IFINFO:
276 if (imsg.hdr.len != IMSG_HEADER_SIZEsizeof(struct imsg_hdr) +
277 sizeof(struct iface))
278 fatalx("IFINFO imsg with wrong len");
279 ifp = imsg.data;
280
281 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
{
282 LIST_FOREACH(i, &area->iface_list, entry)for((i) = ((&area->iface_list)->lh_first); (i)!= ((
void *)0); (i) = ((i)->entry.le_next))
{
283 if (strcmp(i->dependon,
284 ifp->name) == 0) {
285 log_warnx("interface %s"
286 " changed state, %s"
287 " depends on it",
288 ifp->name, i->name);
289 i->depend_ok =
290 ifstate_is_up(ifp);
291 if (ifstate_is_up(i))
292 orig_rtr_lsa(i->area);
293 }
294 }
295 }
296
297 if (!(ifp->cflags & F_IFACE_CONFIGURED0x02))
298 break;
299 iface = if_find(ifp->ifindex);
300 if (iface == NULL((void *)0))
301 fatalx("interface lost in ospfe");
302
303 wasvalid = (iface->flags & IFF_UP0x1) &&
304 LINK_STATE_IS_UP(iface->linkstate)((iface->linkstate) >= 4 || (iface->linkstate) == 0);
305
306 if_update(iface, ifp->mtu, ifp->flags, ifp->if_type,
307 ifp->linkstate, ifp->baudrate, ifp->rdomain);
308
309 isvalid = (iface->flags & IFF_UP0x1) &&
310 LINK_STATE_IS_UP(iface->linkstate)((iface->linkstate) >= 4 || (iface->linkstate) == 0);
311
312 if (wasvalid == isvalid)
313 break;
314
315 if (isvalid) {
316 if_fsm(iface, IF_EVT_UP);
317 log_warnx("interface %s up", iface->name);
318 } else {
319 if_fsm(iface, IF_EVT_DOWN);
320 log_warnx("interface %s down", iface->name);
321 }
322 break;
323 case IMSG_IFADDRNEW:
324 if (imsg.hdr.len != IMSG_HEADER_SIZEsizeof(struct imsg_hdr) +
325 sizeof(struct ifaddrchange))
326 fatalx("IFADDRNEW imsg with wrong len");
327 ifc = imsg.data;
328
329 iface = if_find(ifc->ifindex);
330 if (iface == NULL((void *)0))
331 fatalx("IFADDRNEW interface lost in ospfe");
332
333 if ((ia = calloc(1, sizeof(struct iface_addr))) ==
334 NULL((void *)0))
335 fatal("ospfe_dispatch_main IFADDRNEW");
336 ia->addr = ifc->addr;
337 ia->dstbrd = ifc->dstbrd;
338 ia->prefixlen = ifc->prefixlen;
339
340 TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry)do { (ia)->entry.tqe_next = ((void *)0); (ia)->entry.tqe_prev
= (&iface->ifa_list)->tqh_last; *(&iface->ifa_list
)->tqh_last = (ia); (&iface->ifa_list)->tqh_last
= &(ia)->entry.tqe_next; } while (0)
;
341 orig_link_lsa(iface);
342 break;
343 case IMSG_IFADDRDEL:
344 if (imsg.hdr.len != IMSG_HEADER_SIZEsizeof(struct imsg_hdr) +
11
Assuming the condition is false
12
Taking false branch
345 sizeof(struct ifaddrchange))
346 fatalx("IFADDRDEL imsg with wrong len");
347 ifc = imsg.data;
348
349 iface = if_find(ifc->ifindex);
350 if (iface == NULL((void *)0))
13
Assuming 'iface' is not equal to NULL
14
Taking false branch
351 fatalx("IFADDRDEL interface lost in ospfe");
352
353 for (ia = TAILQ_FIRST(&iface->ifa_list)((&iface->ifa_list)->tqh_first); ia != NULL((void *)0);
15
Assuming 'ia' is equal to NULL
16
Loop condition is false. Execution continues on line 365
354 ia = nia) {
355 nia = TAILQ_NEXT(ia, entry)((ia)->entry.tqe_next);
356
357 if (IN6_ARE_ADDR_EQUAL(&ia->addr,(memcmp(&(&ia->addr)->__u6_addr.__u6_addr8[0], &
(&ifc->addr)->__u6_addr.__u6_addr8[0], sizeof(struct
in6_addr)) == 0)
358 &ifc->addr)(memcmp(&(&ia->addr)->__u6_addr.__u6_addr8[0], &
(&ifc->addr)->__u6_addr.__u6_addr8[0], sizeof(struct
in6_addr)) == 0)
) {
359 TAILQ_REMOVE(&iface->ifa_list, ia,do { if (((ia)->entry.tqe_next) != ((void *)0)) (ia)->entry
.tqe_next->entry.tqe_prev = (ia)->entry.tqe_prev; else (
&iface->ifa_list)->tqh_last = (ia)->entry.tqe_prev
; *(ia)->entry.tqe_prev = (ia)->entry.tqe_next; ; ; } while
(0)
360 entry)do { if (((ia)->entry.tqe_next) != ((void *)0)) (ia)->entry
.tqe_next->entry.tqe_prev = (ia)->entry.tqe_prev; else (
&iface->ifa_list)->tqh_last = (ia)->entry.tqe_prev
; *(ia)->entry.tqe_prev = (ia)->entry.tqe_next; ; ; } while
(0)
;
361 free(ia);
362 break;
363 }
364 }
365 orig_link_lsa(iface);
17
Calling 'orig_link_lsa'
366 break;
367 case IMSG_RECONF_CONF:
368 if ((noeconf = malloc(sizeof(struct ospfd_conf))) ==
369 NULL((void *)0))
370 fatal(NULL((void *)0));
371 memcpy(noeconf, imsg.data, sizeof(struct ospfd_conf));
372
373 LIST_INIT(&noeconf->area_list)do { ((&noeconf->area_list)->lh_first) = ((void *)0
); } while (0)
;
374 LIST_INIT(&noeconf->cand_list)do { ((&noeconf->cand_list)->lh_first) = ((void *)0
); } while (0)
;
375 break;
376 case IMSG_RECONF_AREA:
377 if ((narea = area_new()) == NULL((void *)0))
378 fatal(NULL((void *)0));
379 memcpy(narea, imsg.data, sizeof(struct area));
380
381 LIST_INIT(&narea->iface_list)do { ((&narea->iface_list)->lh_first) = ((void *)0)
; } while (0)
;
382 LIST_INIT(&narea->nbr_list)do { ((&narea->nbr_list)->lh_first) = ((void *)0); }
while (0)
;
383 RB_INIT(&narea->lsa_tree)do { (&narea->lsa_tree)->rbh_root = ((void *)0); } while
(0)
;
384
385 LIST_INSERT_HEAD(&noeconf->area_list, narea, entry)do { if (((narea)->entry.le_next = (&noeconf->area_list
)->lh_first) != ((void *)0)) (&noeconf->area_list)->
lh_first->entry.le_prev = &(narea)->entry.le_next; (
&noeconf->area_list)->lh_first = (narea); (narea)->
entry.le_prev = &(&noeconf->area_list)->lh_first
; } while (0)
;
386 break;
387 case IMSG_RECONF_END:
388 if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER0x0002) !=
389 (noeconf->flags & OSPFD_FLAG_STUB_ROUTER0x0002))
390 stub_changed = 1;
391 else
392 stub_changed = 0;
393 merge_config(oeconf, noeconf);
394 noeconf = NULL((void *)0);
395 if (stub_changed)
396 orig_rtr_lsa_all(NULL((void *)0));
397 break;
398 case IMSG_CTL_KROUTE:
399 case IMSG_CTL_KROUTE_ADDR:
400 case IMSG_CTL_END:
401 control_imsg_relay(&imsg);
402 break;
403 case IMSG_CONTROLFD:
404 if ((fd = imsg_get_fd(&imsg)) == -1)
405 fatalx("%s: expected to receive imsg control"
406 "fd but didn't receive any", __func__);
407 /* Listen on control socket. */
408 control_listen(fd);
409 if (pledge("stdio inet mcast", NULL((void *)0)) == -1)
410 fatal("pledge");
411 break;
412 default:
413 log_debug("ospfe_dispatch_main: error handling imsg %d",
414 imsg.hdr.type);
415 break;
416 }
417 imsg_free(&imsg);
418 }
419 if (!shut)
420 imsg_event_add(iev);
421 else {
422 /* this pipe is dead, so remove the event handler */
423 event_del(&iev->ev);
424 event_loopexit(NULL((void *)0));
425 }
426}
427
428void
429ospfe_dispatch_rde(int fd, short event, void *bula)
430{
431 struct lsa_hdr lsa_hdr;
432 struct lsa_link lsa_link;
433 struct imsgev *iev = bula;
434 struct imsgbuf *ibuf = &iev->ibuf;
435 struct nbr *nbr;
436 struct lsa_hdr *lhp;
437 struct lsa_ref *ref;
438 struct area *area;
439 struct iface *iface;
440 struct lsa_entry *le;
441 struct imsg imsg;
442 struct abr_rtr ar;
443 int n, noack = 0, shut = 0;
444 u_int16_t l, age;
445
446 if (event & EV_READ0x02) {
447 if ((n = imsg_read(ibuf)) == -1 && errno(*__errno()) != EAGAIN35)
448 fatal("imsg_read error");
449 if (n == 0) /* connection closed */
450 shut = 1;
451 }
452 if (event & EV_WRITE0x04) {
453 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno(*__errno()) != EAGAIN35)
454 fatal("msgbuf_write");
455 if (n == 0) /* connection closed */
456 shut = 1;
457 }
458
459 for (;;) {
460 if ((n = imsg_get(ibuf, &imsg)) == -1)
461 fatal("ospfe_dispatch_rde: imsg_get error");
462 if (n == 0)
463 break;
464
465 switch (imsg.hdr.type) {
466 case IMSG_DD:
467 nbr = nbr_find_peerid(imsg.hdr.peerid);
468 if (nbr == NULL((void *)0))
469 break;
470
471 /* put these on my ls_req_list for retrieval */
472 lhp = lsa_hdr_new();
473 memcpy(lhp, imsg.data, sizeof(*lhp));
474 ls_req_list_add(nbr, lhp);
475 break;
476 case IMSG_DD_END:
477 nbr = nbr_find_peerid(imsg.hdr.peerid);
478 if (nbr == NULL((void *)0))
479 break;
480
481 nbr->dd_pending--;
482 if (nbr->dd_pending == 0 && nbr->state & NBR_STA_LOAD0x0080) {
483 if (ls_req_list_empty(nbr))
484 nbr_fsm(nbr, NBR_EVT_LOAD_DONE);
485 else
486 start_ls_req_tx_timer(nbr);
487 }
488 break;
489 case IMSG_DB_SNAPSHOT:
490 nbr = nbr_find_peerid(imsg.hdr.peerid);
491 if (nbr == NULL((void *)0))
492 break;
493 if (nbr->state != NBR_STA_SNAP0x0020) /* discard */
494 break;
495
496 /* add LSA header to the neighbor db_sum_list */
497 lhp = lsa_hdr_new();
498 memcpy(lhp, imsg.data, sizeof(*lhp));
499 db_sum_list_add(nbr, lhp);
500 break;
501 case IMSG_DB_END:
502 nbr = nbr_find_peerid(imsg.hdr.peerid);
503 if (nbr == NULL((void *)0))
504 break;
505
506 nbr->dd_snapshot = 0;
507 if (nbr->state != NBR_STA_SNAP0x0020)
508 break;
509
510 /* snapshot done, start tx of dd packets */
511 nbr_fsm(nbr, NBR_EVT_SNAP_DONE);
512 break;
513 case IMSG_LS_FLOOD:
514 nbr = nbr_find_peerid(imsg.hdr.peerid);
515 if (nbr == NULL((void *)0))
516 break;
517
518 l = imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr);
519 if (l < sizeof(lsa_hdr))
520 fatalx("ospfe_dispatch_rde: "
521 "bad imsg size");
522 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr));
523
524 ref = lsa_cache_add(imsg.data, l);
525
526 if (lsa_hdr.type == htons(LSA_TYPE_EXTERNAL)(__uint16_t)(__builtin_constant_p(0x4005) ? (__uint16_t)(((__uint16_t
)(0x4005) & 0xffU) << 8 | ((__uint16_t)(0x4005) &
0xff00U) >> 8) : __swap16md(0x4005))
) {
527 /*
528 * flood on all areas but stub areas and
529 * virtual links
530 */
531 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
{
532 if (area->stub)
533 continue;
534 LIST_FOREACH(iface, &area->iface_list,for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
535 entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
{
536 noack += lsa_flood(iface, nbr,
537 &lsa_hdr, imsg.data);
538 }
539 }
540 } else if (lsa_hdr.type == htons(LSA_TYPE_LINK)(__uint16_t)(__builtin_constant_p(0x0008) ? (__uint16_t)(((__uint16_t
)(0x0008) & 0xffU) << 8 | ((__uint16_t)(0x0008) &
0xff00U) >> 8) : __swap16md(0x0008))
) {
541 /*
542 * Save link-LSA options of neighbor.
543 * This is needed to originate network-LSA.
544 */
545 if (l - sizeof(lsa_hdr) < sizeof(lsa_link))
546 fatalx("ospfe_dispatch_rde: "
547 "bad imsg link size");
548 memcpy(&lsa_link, (char *)imsg.data +
549 sizeof(lsa_hdr), sizeof(lsa_link));
550 nbr->link_options = lsa_link.opts &
551 htonl(LSA_24_MASK)(__uint32_t)(__builtin_constant_p(0xffffff) ? (__uint32_t)(((
__uint32_t)(0xffffff) & 0xff) << 24 | ((__uint32_t)
(0xffffff) & 0xff00) << 8 | ((__uint32_t)(0xffffff)
& 0xff0000) >> 8 | ((__uint32_t)(0xffffff) & 0xff000000
) >> 24) : __swap32md(0xffffff))
;
552
553 /*
554 * flood on interface only
555 */
556 noack += lsa_flood(nbr->iface, nbr,
557 &lsa_hdr, imsg.data);
558 } else {
559 /*
560 * flood on all area interfaces on
561 * area 0.0.0.0 include also virtual links.
562 */
563 LIST_FOREACH(iface,for((iface) = ((&nbr->iface->area->iface_list)->
lh_first); (iface)!= ((void *)0); (iface) = ((iface)->entry
.le_next))
564 &nbr->iface->area->iface_list, entry)for((iface) = ((&nbr->iface->area->iface_list)->
lh_first); (iface)!= ((void *)0); (iface) = ((iface)->entry
.le_next))
{
565 noack += lsa_flood(iface, nbr,
566 &lsa_hdr, imsg.data);
567 }
568 /* XXX virtual links */
569 }
570
571 /* remove from ls_req_list */
572 le = ls_req_list_get(nbr, &lsa_hdr);
573 if (!(nbr->state & NBR_STA_FULL0x0100) && le != NULL((void *)0)) {
574 ls_req_list_free(nbr, le);
575 /*
576 * XXX no need to ack requested lsa
577 * the problem is that the RFC is very
578 * unclear about this.
579 */
580 noack = 1;
581 }
582
583 if (!noack && nbr->iface != NULL((void *)0) &&
584 nbr->iface->self != nbr) {
585 if (!(nbr->iface->state & IF_STA_BACKUP0x20) ||
586 nbr->iface->dr == nbr) {
587 /* delayed ack */
588 lhp = lsa_hdr_new();
589 memcpy(lhp, &lsa_hdr, sizeof(*lhp));
590 ls_ack_list_add(nbr->iface, lhp);
591 }
592 }
593
594 lsa_cache_put(ref, nbr);
595 break;
596 case IMSG_LS_UPD:
597 case IMSG_LS_SNAP:
598 /*
599 * IMSG_LS_UPD is used in two cases:
600 * 1. as response to ls requests
601 * 2. as response to ls updates where the DB
602 * is newer then the sent LSA
603 * IMSG_LS_SNAP is used in one case:
604 * in EXSTART when the LSA has age MaxAge
605 */
606 l = imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr);
607 if (l < sizeof(lsa_hdr))
608 fatalx("ospfe_dispatch_rde: "
609 "bad imsg size");
610
611 nbr = nbr_find_peerid(imsg.hdr.peerid);
612 if (nbr == NULL((void *)0))
613 break;
614
615 if (nbr->iface->self == nbr)
616 break;
617
618 if (imsg.hdr.type == IMSG_LS_SNAP &&
619 nbr->state != NBR_STA_SNAP0x0020)
620 break;
621
622 memcpy(&age, imsg.data, sizeof(age));
623 ref = lsa_cache_add(imsg.data, l);
624 if (ntohs(age)(__uint16_t)(__builtin_constant_p(age) ? (__uint16_t)(((__uint16_t
)(age) & 0xffU) << 8 | ((__uint16_t)(age) & 0xff00U
) >> 8) : __swap16md(age))
>= MAX_AGE3600)
625 /* add to retransmit list */
626 ls_retrans_list_add(nbr, imsg.data, 0, 0);
627 else
628 ls_retrans_list_add(nbr, imsg.data, 0, 1);
629
630 lsa_cache_put(ref, nbr);
631 break;
632 case IMSG_LS_ACK:
633 /*
634 * IMSG_LS_ACK is used in two cases:
635 * 1. LSA was a duplicate
636 * 2. LS age is MaxAge and there is no current
637 * instance in the DB plus no neighbor in state
638 * Exchange or Loading
639 */
640 nbr = nbr_find_peerid(imsg.hdr.peerid);
641 if (nbr == NULL((void *)0))
642 break;
643
644 if (nbr->iface->self == nbr)
645 break;
646
647 if (imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr) != sizeof(lsa_hdr))
648 fatalx("ospfe_dispatch_rde: bad imsg size");
649 memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr));
650
651 /* for case one check for implied acks */
652 if (nbr->iface->state & IF_STA_DROTHER0x10)
653 if (ls_retrans_list_del(nbr->iface->self,
654 &lsa_hdr) == 0)
655 break;
656 if (ls_retrans_list_del(nbr, &lsa_hdr) == 0)
657 break;
658
659 /* send a direct acknowledgement */
660 send_direct_ack(nbr->iface, nbr->addr, imsg.data,
661 imsg.hdr.len - IMSG_HEADER_SIZEsizeof(struct imsg_hdr));
662
663 break;
664 case IMSG_LS_BADREQ:
665 nbr = nbr_find_peerid(imsg.hdr.peerid);
666 if (nbr == NULL((void *)0))
667 break;
668
669 if (nbr->iface->self == nbr)
670 fatalx("ospfe_dispatch_rde: "
671 "dummy neighbor got BADREQ");
672
673 nbr_fsm(nbr, NBR_EVT_BAD_LS_REQ);
674 break;
675 case IMSG_ABR_UP:
676 memcpy(&ar, imsg.data, sizeof(ar));
677
678 if ((iface = find_vlink(&ar)) != NULL((void *)0) &&
679 iface->state == IF_STA_DOWN0x01)
680 if (if_fsm(iface, IF_EVT_UP)) {
681 log_debug("error starting interface %s",
682 iface->name);
683 }
684 break;
685 case IMSG_ABR_DOWN:
686 memcpy(&ar, imsg.data, sizeof(ar));
687
688 if ((iface = find_vlink(&ar)) != NULL((void *)0) &&
689 iface->state == IF_STA_POINTTOPOINT0x08)
690 if (if_fsm(iface, IF_EVT_DOWN)) {
691 log_debug("error stopping interface %s",
692 iface->name);
693 }
694 break;
695 case IMSG_CTL_AREA:
696 case IMSG_CTL_IFACE:
697 case IMSG_CTL_END:
698 case IMSG_CTL_SHOW_DATABASE:
699 case IMSG_CTL_SHOW_DB_EXT:
700 case IMSG_CTL_SHOW_DB_LINK:
701 case IMSG_CTL_SHOW_DB_NET:
702 case IMSG_CTL_SHOW_DB_RTR:
703 case IMSG_CTL_SHOW_DB_INTRA:
704 case IMSG_CTL_SHOW_DB_SELF:
705 case IMSG_CTL_SHOW_DB_SUM:
706 case IMSG_CTL_SHOW_DB_ASBR:
707 case IMSG_CTL_SHOW_RIB:
708 case IMSG_CTL_SHOW_SUM:
709 case IMSG_CTL_SHOW_SUM_AREA:
710 control_imsg_relay(&imsg);
711 break;
712 default:
713 log_debug("ospfe_dispatch_rde: error handling imsg %d",
714 imsg.hdr.type);
715 break;
716 }
717 imsg_free(&imsg);
718 }
719 if (!shut)
720 imsg_event_add(iev);
721 else {
722 /* this pipe is dead, so remove the event handler */
723 event_del(&iev->ev);
724 event_loopexit(NULL((void *)0));
725 }
726}
727
728struct iface *
729find_vlink(struct abr_rtr *ar)
730{
731 struct area *area;
732 struct iface *iface = NULL((void *)0);
733
734 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
735 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
736 if (iface->abr_id.s_addr == ar->abr_id.s_addr &&
737 iface->type == IF_TYPE_VIRTUALLINK &&
738 iface->area->id.s_addr == ar->area.s_addr) {
739 iface->dst = ar->dst_ip;
740 iface->addr = ar->addr;
741 iface->metric = ar->metric;
742
743 return (iface);
744 }
745
746 return (iface);
747}
748
749void
750orig_rtr_lsa_all(struct area *area)
751{
752 struct area *a;
753
754 /*
755 * update all router LSA in all areas except area itself,
756 * as this update is already running.
757 */
758 LIST_FOREACH(a, &oeconf->area_list, entry)for((a) = ((&oeconf->area_list)->lh_first); (a)!= (
(void *)0); (a) = ((a)->entry.le_next))
759 if (a != area)
760 orig_rtr_lsa(a);
761}
762
763void
764orig_rtr_lsa(struct area *area)
765{
766 struct lsa_hdr lsa_hdr;
767 struct lsa_rtr lsa_rtr;
768 struct lsa_rtr_link rtr_link;
769 struct iface *iface;
770 struct ibuf *buf;
771 struct nbr *nbr, *self = NULL((void *)0);
772 u_int32_t flags;
773 u_int16_t chksum;
774 u_int8_t border, virtual = 0;
775
776 log_debug("orig_rtr_lsa: area %s", inet_ntoa(area->id));
777
778 /* XXX IBUF_READ_SIZE */
779 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), IBUF_READ_SIZE65535)) == NULL((void *)0))
780 fatal("orig_rtr_lsa");
781
782 /* reserve space for LSA header and LSA Router header */
783 if (ibuf_add_zero(buf, sizeof(lsa_hdr)) == -1)
784 fatal("orig_rtr_lsa: ibuf_add_zero failed");
785
786 if (ibuf_add_zero(buf, sizeof(lsa_rtr)) == -1)
787 fatal("orig_rtr_lsa: ibuf_add_zero failed");
788
789 /* links */
790 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
{
791 if (self == NULL((void *)0) && iface->self != NULL((void *)0))
792 self = iface->self;
793
794 bzero(&rtr_link, sizeof(rtr_link));
795
796 switch (iface->type) {
797 case IF_TYPE_POINTOPOINT:
798 LIST_FOREACH(nbr, &iface->nbr_list, entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
799 if (nbr != iface->self &&
800 nbr->state & NBR_STA_FULL0x0100)
801 break;
802 if (nbr && iface->state & IF_STA_POINTTOPOINT0x08) {
803 log_debug("orig_rtr_lsa: point-to-point, "
804 "interface %s", iface->name);
805 rtr_link.type = LINK_TYPE_POINTTOPOINT1;
806 if (iface->dependon[0] != '\0' &&
807 iface->depend_ok == 0)
808 rtr_link.metric = MAX_METRIC65535;
809 else
810 rtr_link.metric = htons(iface->metric)(__uint16_t)(__builtin_constant_p(iface->metric) ? (__uint16_t
)(((__uint16_t)(iface->metric) & 0xffU) << 8 | (
(__uint16_t)(iface->metric) & 0xff00U) >> 8) : __swap16md
(iface->metric))
;
811 rtr_link.iface_id = htonl(iface->ifindex)(__uint32_t)(__builtin_constant_p(iface->ifindex) ? (__uint32_t
)(((__uint32_t)(iface->ifindex) & 0xff) << 24 | (
(__uint32_t)(iface->ifindex) & 0xff00) << 8 | ((
__uint32_t)(iface->ifindex) & 0xff0000) >> 8 | (
(__uint32_t)(iface->ifindex) & 0xff000000) >> 24
) : __swap32md(iface->ifindex))
;
812 rtr_link.nbr_iface_id = htonl(nbr->iface_id)(__uint32_t)(__builtin_constant_p(nbr->iface_id) ? (__uint32_t
)(((__uint32_t)(nbr->iface_id) & 0xff) << 24 | (
(__uint32_t)(nbr->iface_id) & 0xff00) << 8 | ((__uint32_t
)(nbr->iface_id) & 0xff0000) >> 8 | ((__uint32_t
)(nbr->iface_id) & 0xff000000) >> 24) : __swap32md
(nbr->iface_id))
;
813 rtr_link.nbr_rtr_id = nbr->id.s_addr;
814 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
815 fatalx("orig_rtr_lsa: ibuf_add failed");
816 }
817 continue;
818 case IF_TYPE_BROADCAST:
819 case IF_TYPE_NBMA:
820 if ((iface->state & IF_STA_MULTI(0x10 | 0x20 | 0x40))) {
821 if (iface->dr == iface->self) {
822 LIST_FOREACH(nbr, &iface->nbr_list,for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
823 entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
824 if (nbr != iface->self &&
825 nbr->state & NBR_STA_FULL0x0100)
826 break;
827 } else
828 nbr = iface->dr;
829
830 if (nbr && nbr->state & NBR_STA_FULL0x0100) {
831 log_debug("orig_rtr_lsa: transit net, "
832 "interface %s", iface->name);
833
834 rtr_link.type = LINK_TYPE_TRANSIT_NET2;
835 if (iface->dependon[0] != '\0' &&
836 iface->depend_ok == 0)
837 rtr_link.metric = MAX_METRIC65535;
838 else
839 rtr_link.metric =
840 htons(iface->metric)(__uint16_t)(__builtin_constant_p(iface->metric) ? (__uint16_t
)(((__uint16_t)(iface->metric) & 0xffU) << 8 | (
(__uint16_t)(iface->metric) & 0xff00U) >> 8) : __swap16md
(iface->metric))
;
841 rtr_link.iface_id = htonl(iface->ifindex)(__uint32_t)(__builtin_constant_p(iface->ifindex) ? (__uint32_t
)(((__uint32_t)(iface->ifindex) & 0xff) << 24 | (
(__uint32_t)(iface->ifindex) & 0xff00) << 8 | ((
__uint32_t)(iface->ifindex) & 0xff0000) >> 8 | (
(__uint32_t)(iface->ifindex) & 0xff000000) >> 24
) : __swap32md(iface->ifindex))
;
842 rtr_link.nbr_iface_id = htonl(iface->dr->iface_id)(__uint32_t)(__builtin_constant_p(iface->dr->iface_id) ?
(__uint32_t)(((__uint32_t)(iface->dr->iface_id) & 0xff
) << 24 | ((__uint32_t)(iface->dr->iface_id) &
0xff00) << 8 | ((__uint32_t)(iface->dr->iface_id
) & 0xff0000) >> 8 | ((__uint32_t)(iface->dr->
iface_id) & 0xff000000) >> 24) : __swap32md(iface->
dr->iface_id))
;
843 rtr_link.nbr_rtr_id = iface->dr->id.s_addr;
844 if (ibuf_add(buf, &rtr_link,
845 sizeof(rtr_link)))
846 fatalx("orig_rtr_lsa: "
847 "ibuf_add failed");
848 break;
849 }
850 }
851 break;
852#if 0 /* TODO virtualllink/pointtomulti */
853 case IF_TYPE_VIRTUALLINK:
854 LIST_FOREACH(nbr, &iface->nbr_list, entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
{
855 if (nbr != iface->self &&
856 nbr->state & NBR_STA_FULL0x0100)
857 break;
858 }
859 if (nbr) {
860 rtr_link.id = nbr->id.s_addr;
861//XXX rtr_link.data = iface->addr.s_addr;
862 rtr_link.type = LINK_TYPE_VIRTUAL4;
863 /* RFC 3137: stub router support */
864 if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER0x0002 ||
865 oe_nofib)
866 rtr_link.metric = 0xffff;
867 else
868 rtr_link.metric = htons(iface->metric)(__uint16_t)(__builtin_constant_p(iface->metric) ? (__uint16_t
)(((__uint16_t)(iface->metric) & 0xffU) << 8 | (
(__uint16_t)(iface->metric) & 0xff00U) >> 8) : __swap16md
(iface->metric))
;
869 virtual = 1;
870 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
871 fatalx("orig_rtr_lsa: ibuf_add failed");
872
873 log_debug("orig_rtr_lsa: virtual link, "
874 "interface %s", iface->name);
875 }
876 continue;
877 case IF_TYPE_POINTOMULTIPOINT:
878 log_debug("orig_rtr_lsa: stub net, "
879 "interface %s", iface->name);
880//XXX rtr_link.id = iface->addr.s_addr;
881 rtr_link.data = 0xffffffff;
882 rtr_link.type = LINK_TYPE_STUB_NET;
883 rtr_link.metric = htons(iface->metric)(__uint16_t)(__builtin_constant_p(iface->metric) ? (__uint16_t
)(((__uint16_t)(iface->metric) & 0xffU) << 8 | (
(__uint16_t)(iface->metric) & 0xff00U) >> 8) : __swap16md
(iface->metric))
;
884 if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
885 fatalx("orig_rtr_lsa: ibuf_add failed");
886
887 LIST_FOREACH(nbr, &iface->nbr_list, entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
{
888 if (nbr != iface->self &&
889 nbr->state & NBR_STA_FULL0x0100) {
890 bzero(&rtr_link, sizeof(rtr_link));
891 log_debug("orig_rtr_lsa: "
892 "point-to-multipoint, interface %s",
893 iface->name);
894//XXX rtr_link.id = nbr->addr.s_addr;
895//XXX rtr_link.data = iface->addr.s_addr;
896 rtr_link.type = LINK_TYPE_POINTTOPOINT1;
897 /* RFC 3137: stub router support */
898 if (oe_nofib || oeconf->flags &
899 OSPFD_FLAG_STUB_ROUTER0x0002)
900 rtr_link.metric = MAX_METRIC65535;
901 else if (iface->dependon[0] != '\0' &&
902 iface->dependon_ok == 0)
903 rtr_link.metric = MAX_METRIC65535;
904 else
905 rtr_link.metric =
906 htons(iface->metric)(__uint16_t)(__builtin_constant_p(iface->metric) ? (__uint16_t
)(((__uint16_t)(iface->metric) & 0xffU) << 8 | (
(__uint16_t)(iface->metric) & 0xff00U) >> 8) : __swap16md
(iface->metric))
;
907 if (ibuf_add(buf, &rtr_link,
908 sizeof(rtr_link)))
909 fatalx("orig_rtr_lsa: "
910 "ibuf_add failed");
911 }
912 }
913 continue;
914#endif /* TODO virtualllink/pointtomulti */
915 default:
916 fatalx("orig_rtr_lsa: unknown interface type");
917 }
918 }
919
920 /* LSA router header */
921 lsa_rtr.opts = 0;
922 flags = 0;
923
924 /*
925 * Set the E bit as soon as an as-ext lsa may be redistributed, only
926 * setting it in case we redistribute something is not worth the fuss.
927 */
928 if (oeconf->redistribute && !area->stub)
929 flags |= OSPF_RTR_E0x02;
930
931 border = (area_border_router(oeconf) != 0);
932 if (border != oeconf->border) {
933 oeconf->border = border;
934 orig_rtr_lsa_all(area);
935 }
936
937 if (oeconf->border)
938 flags |= OSPF_RTR_B0x01;
939 /* TODO set V flag if a active virtual link ends here and the
940 * area is the transit area for this link. */
941 if (virtual)
942 flags |= OSPF_RTR_V0x04;
943
944 LSA_24_SETLO(lsa_rtr.opts, area_ospf_options(area))((lsa_rtr.opts) = ((area_ospf_options(area)) & 0xffffff) |
((lsa_rtr.opts) & ~0xffffff))
;
945 LSA_24_SETHI(lsa_rtr.opts, flags)((lsa_rtr.opts) = ((lsa_rtr.opts) & 0xffffff) | (((flags)
& 0xff) << 24))
;
946 lsa_rtr.opts = htonl(lsa_rtr.opts)(__uint32_t)(__builtin_constant_p(lsa_rtr.opts) ? (__uint32_t
)(((__uint32_t)(lsa_rtr.opts) & 0xff) << 24 | ((__uint32_t
)(lsa_rtr.opts) & 0xff00) << 8 | ((__uint32_t)(lsa_rtr
.opts) & 0xff0000) >> 8 | ((__uint32_t)(lsa_rtr.opts
) & 0xff000000) >> 24) : __swap32md(lsa_rtr.opts))
;
947 if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_rtr, sizeof(lsa_rtr)) == -1)
948 fatal("orig_rtr_lsa: ibuf_set failed");
949
950 /* LSA header */
951 lsa_hdr.age = htons(DEFAULT_AGE)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
952 lsa_hdr.type = htons(LSA_TYPE_ROUTER)(__uint16_t)(__builtin_constant_p(0x2001) ? (__uint16_t)(((__uint16_t
)(0x2001) & 0xffU) << 8 | ((__uint16_t)(0x2001) &
0xff00U) >> 8) : __swap16md(0x2001))
;
953 /* XXX needs to be fixed if multiple router-lsa need to be announced */
954 lsa_hdr.ls_id = 0;
955 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;
956 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM)(__uint32_t)(__builtin_constant_p(0x80000001U) ? (__uint32_t)
(((__uint32_t)(0x80000001U) & 0xff) << 24 | ((__uint32_t
)(0x80000001U) & 0xff00) << 8 | ((__uint32_t)(0x80000001U
) & 0xff0000) >> 8 | ((__uint32_t)(0x80000001U) &
0xff000000) >> 24) : __swap32md(0x80000001U))
;
957 lsa_hdr.len = htons(ibuf_size(buf))(__uint16_t)(__builtin_constant_p(ibuf_size(buf)) ? (__uint16_t
)(((__uint16_t)(ibuf_size(buf)) & 0xffU) << 8 | ((__uint16_t
)(ibuf_size(buf)) & 0xff00U) >> 8) : __swap16md(ibuf_size
(buf)))
;
958 lsa_hdr.ls_chksum = 0; /* updated later */
959 if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1)
960 fatal("orig_rtr_lsa: ibuf_set failed");
961
962 chksum = iso_cksum(ibuf_data(buf), ibuf_size(buf), LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum));
963 if (ibuf_set_n16(buf, LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum), chksum) == -1)
964 fatal("orig_rtr_lsa: ibuf_set_n16 failed");
965
966 if (self)
967 imsg_compose_event(iev_rde, IMSG_LS_UPD, self->peerid, 0,
968 -1, ibuf_data(buf), ibuf_size(buf));
969 else
970 log_warnx("orig_rtr_lsa: empty area %s",
971 inet_ntoa(area->id));
972
973 ibuf_free(buf);
974}
975
976void
977orig_net_lsa(struct iface *iface)
978{
979 struct lsa_hdr lsa_hdr;
980 struct nbr *nbr;
981 struct ibuf *buf;
982 struct lsa_net lsa_net;
983 int num_rtr = 0;
984 u_int16_t chksum;
985
986 /* XXX IBUF_READ_SIZE */
987 if ((buf = ibuf_dynamic(sizeof(lsa_hdr), IBUF_READ_SIZE65535)) == NULL((void *)0))
988 fatal("orig_net_lsa");
989
990 /* reserve space for LSA header and options field */
991 if (ibuf_add_zero(buf, sizeof(lsa_hdr) + sizeof(lsa_net)) == -1)
992 fatal("orig_net_lsa: ibuf_add_zero failed");
993
994 lsa_net.opts = 0;
995 /* fully adjacent neighbors + self */
996 LIST_FOREACH(nbr, &iface->nbr_list, entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
997 if (nbr->state & NBR_STA_FULL0x0100) {
998 if (ibuf_add(buf, &nbr->id, sizeof(nbr->id)))
999 fatal("orig_net_lsa: ibuf_add failed");
1000 lsa_net.opts |= nbr->link_options;
1001 num_rtr++;
1002 }
1003
1004 if (num_rtr == 1) {
1005 /* non transit net therefore no need to generate a net lsa */
1006 ibuf_free(buf);
1007 return;
1008 }
1009
1010 /* LSA header */
1011 if (iface->state & IF_STA_DR0x40)
1012 lsa_hdr.age = htons(DEFAULT_AGE)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
1013 else
1014 lsa_hdr.age = htons(MAX_AGE)(__uint16_t)(__builtin_constant_p(3600) ? (__uint16_t)(((__uint16_t
)(3600) & 0xffU) << 8 | ((__uint16_t)(3600) & 0xff00U
) >> 8) : __swap16md(3600))
;
1015
1016 lsa_hdr.type = htons(LSA_TYPE_NETWORK)(__uint16_t)(__builtin_constant_p(0x2002) ? (__uint16_t)(((__uint16_t
)(0x2002) & 0xffU) << 8 | ((__uint16_t)(0x2002) &
0xff00U) >> 8) : __swap16md(0x2002))
;
1017 /* for network LSAs, the link state ID equals the interface ID */
1018 lsa_hdr.ls_id = htonl(iface->ifindex)(__uint32_t)(__builtin_constant_p(iface->ifindex) ? (__uint32_t
)(((__uint32_t)(iface->ifindex) & 0xff) << 24 | (
(__uint32_t)(iface->ifindex) & 0xff00) << 8 | ((
__uint32_t)(iface->ifindex) & 0xff0000) >> 8 | (
(__uint32_t)(iface->ifindex) & 0xff000000) >> 24
) : __swap32md(iface->ifindex))
;
1019 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;
1020 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM)(__uint32_t)(__builtin_constant_p(0x80000001U) ? (__uint32_t)
(((__uint32_t)(0x80000001U) & 0xff) << 24 | ((__uint32_t
)(0x80000001U) & 0xff00) << 8 | ((__uint32_t)(0x80000001U
) & 0xff0000) >> 8 | ((__uint32_t)(0x80000001U) &
0xff000000) >> 24) : __swap32md(0x80000001U))
;
1021 lsa_hdr.len = htons(ibuf_size(buf))(__uint16_t)(__builtin_constant_p(ibuf_size(buf)) ? (__uint16_t
)(((__uint16_t)(ibuf_size(buf)) & 0xffU) << 8 | ((__uint16_t
)(ibuf_size(buf)) & 0xff00U) >> 8) : __swap16md(ibuf_size
(buf)))
;
1022 lsa_hdr.ls_chksum = 0; /* updated later */
1023 if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1)
1024 fatal("orig_net_lsa: ibuf_set failed");
1025
1026 lsa_net.opts &= lsa_net.opts & htonl(LSA_24_MASK)(__uint32_t)(__builtin_constant_p(0xffffff) ? (__uint32_t)(((
__uint32_t)(0xffffff) & 0xff) << 24 | ((__uint32_t)
(0xffffff) & 0xff00) << 8 | ((__uint32_t)(0xffffff)
& 0xff0000) >> 8 | ((__uint32_t)(0xffffff) & 0xff000000
) >> 24) : __swap32md(0xffffff))
;
1027 if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_net, sizeof(lsa_net)) == -1)
1028 fatal("orig_net_lsa: ibuf_set failed");
1029
1030 chksum = iso_cksum(ibuf_data(buf), ibuf_size(buf), LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum));
1031 if (ibuf_set_n16(buf, LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum), chksum) == -1)
1032 fatal("orig_net_lsa: ibuf_set_n16 failed");
1033
1034 imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0,
1035 -1, ibuf_data(buf), ibuf_size(buf));
1036
1037 ibuf_free(buf);
1038}
1039
1040void
1041orig_link_lsa(struct iface *iface)
1042{
1043 struct lsa_hdr lsa_hdr;
1044 struct lsa_link lsa_link;
1045 struct lsa_prefix lsa_prefix;
1046 struct ibuf *buf;
1047 struct iface_addr *ia;
1048 struct in6_addr prefix;
1049 unsigned int num_prefix = 0;
1050 u_int16_t chksum;
1051 u_int32_t options;
1052
1053 log_debug("orig_link_lsa: interface %s", iface->name);
1054
1055 switch (iface->type) {
18
Control jumps to 'case IF_TYPE_POINTOMULTIPOINT:' at line 1064
1056 case IF_TYPE_VIRTUALLINK: /* forbidden by rfc5340 */
1057 return;
1058 case IF_TYPE_BROADCAST:
1059 case IF_TYPE_NBMA:
1060 if ((iface->state & IF_STA_MULTI(0x10 | 0x20 | 0x40)) == 0)
1061 return;
1062 break;
1063 case IF_TYPE_POINTOPOINT:
1064 case IF_TYPE_POINTOMULTIPOINT:
1065 if ((iface->state & IF_STA_POINTTOPOINT0x08) == 0)
19
Assuming the condition is false
20
Taking false branch
1066 return;
1067 break;
1068 default:
1069 fatalx("orig_link_lsa: unknown interface type");
1070 }
1071
1072 /* XXX IBUF_READ_SIZE */
1073 if ((buf = ibuf_dynamic(sizeof(lsa_hdr) + sizeof(lsa_link),
21
Execution continues on line 1073
22
Assuming the condition is false
23
Taking false branch
1074 IBUF_READ_SIZE65535)) == NULL((void *)0))
1075 fatal("orig_link_lsa");
1076
1077 /* reserve space for LSA header and LSA link header */
1078 if (ibuf_add_zero(buf, sizeof(lsa_hdr) + sizeof(lsa_link)) == -1)
24
Assuming the condition is false
25
Taking false branch
1079 fatal("orig_link_lsa: ibuf_add_zero failed");
1080
1081 /* link-local address, and all prefixes configured on interface */
1082 TAILQ_FOREACH(ia, &iface->ifa_list, entry)for((ia) = ((&iface->ifa_list)->tqh_first); (ia) !=
((void *)0); (ia) = ((ia)->entry.tqe_next))
{
26
Assuming 'ia' is equal to null
27
Loop condition is false. Execution continues on line 1104
1083 if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)(((&ia->addr)->__u6_addr.__u6_addr8[0] == 0xfe) &&
(((&ia->addr)->__u6_addr.__u6_addr8[1] & 0xc0)
== 0x80))
) {
1084 log_debug("orig_link_lsa: link local address %s",
1085 log_in6addr(&ia->addr));
1086 lsa_link.lladdr = ia->addr;
1087 continue;
1088 }
1089
1090 lsa_prefix.prefixlen = ia->prefixlen;
1091 lsa_prefix.options = 0;
1092 lsa_prefix.metric = 0;
1093 inet6applymask(&prefix, &ia->addr, ia->prefixlen);
1094 log_debug("orig_link_lsa: prefix %s", log_in6addr(&prefix));
1095 if (ibuf_add(buf, &lsa_prefix, sizeof(lsa_prefix)))
1096 fatal("orig_link_lsa: ibuf_add failed");
1097 if (ibuf_add(buf, &prefix.s6_addr__u6_addr.__u6_addr8[0],
1098 LSA_PREFIXSIZE(ia->prefixlen)(((ia->prefixlen) + 31)/32 * 4)))
1099 fatal("orig_link_lsa: ibuf_add failed");
1100 num_prefix++;
1101 }
1102
1103 /* LSA link header (lladdr has already been filled in above) */
1104 LSA_24_SETHI(lsa_link.opts, iface->priority)((lsa_link.opts) = ((lsa_link.opts) & 0xffffff) | (((iface
->priority) & 0xff) << 24))
;
28
The left operand of '&' is a garbage value
1105 options = area_ospf_options(iface->area);
1106 LSA_24_SETLO(lsa_link.opts, options)((lsa_link.opts) = ((options) & 0xffffff) | ((lsa_link.opts
) & ~0xffffff))
;
1107 lsa_link.opts = htonl(lsa_link.opts)(__uint32_t)(__builtin_constant_p(lsa_link.opts) ? (__uint32_t
)(((__uint32_t)(lsa_link.opts) & 0xff) << 24 | ((__uint32_t
)(lsa_link.opts) & 0xff00) << 8 | ((__uint32_t)(lsa_link
.opts) & 0xff0000) >> 8 | ((__uint32_t)(lsa_link.opts
) & 0xff000000) >> 24) : __swap32md(lsa_link.opts))
;
1108 lsa_link.numprefix = htonl(num_prefix)(__uint32_t)(__builtin_constant_p(num_prefix) ? (__uint32_t)(
((__uint32_t)(num_prefix) & 0xff) << 24 | ((__uint32_t
)(num_prefix) & 0xff00) << 8 | ((__uint32_t)(num_prefix
) & 0xff0000) >> 8 | ((__uint32_t)(num_prefix) &
0xff000000) >> 24) : __swap32md(num_prefix))
;
1109 if (ibuf_set(buf, sizeof(lsa_hdr), &lsa_link, sizeof(lsa_link)) == -1)
1110 fatal("orig_link_lsa: ibuf_set failed");
1111
1112 /* LSA header */
1113 lsa_hdr.age = htons(DEFAULT_AGE)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
1114 lsa_hdr.type = htons(LSA_TYPE_LINK)(__uint16_t)(__builtin_constant_p(0x0008) ? (__uint16_t)(((__uint16_t
)(0x0008) & 0xffU) << 8 | ((__uint16_t)(0x0008) &
0xff00U) >> 8) : __swap16md(0x0008))
;
1115 /* for link LSAs, the link state ID equals the interface ID */
1116 lsa_hdr.ls_id = htonl(iface->ifindex)(__uint32_t)(__builtin_constant_p(iface->ifindex) ? (__uint32_t
)(((__uint32_t)(iface->ifindex) & 0xff) << 24 | (
(__uint32_t)(iface->ifindex) & 0xff00) << 8 | ((
__uint32_t)(iface->ifindex) & 0xff0000) >> 8 | (
(__uint32_t)(iface->ifindex) & 0xff000000) >> 24
) : __swap32md(iface->ifindex))
;
1117 lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;
1118 lsa_hdr.seq_num = htonl(INIT_SEQ_NUM)(__uint32_t)(__builtin_constant_p(0x80000001U) ? (__uint32_t)
(((__uint32_t)(0x80000001U) & 0xff) << 24 | ((__uint32_t
)(0x80000001U) & 0xff00) << 8 | ((__uint32_t)(0x80000001U
) & 0xff0000) >> 8 | ((__uint32_t)(0x80000001U) &
0xff000000) >> 24) : __swap32md(0x80000001U))
;
1119 lsa_hdr.len = htons(ibuf_size(buf))(__uint16_t)(__builtin_constant_p(ibuf_size(buf)) ? (__uint16_t
)(((__uint16_t)(ibuf_size(buf)) & 0xffU) << 8 | ((__uint16_t
)(ibuf_size(buf)) & 0xff00U) >> 8) : __swap16md(ibuf_size
(buf)))
;
1120 lsa_hdr.ls_chksum = 0; /* updated later */
1121 if (ibuf_set(buf, 0, &lsa_hdr, sizeof(lsa_hdr)) == -1)
1122 fatal("orig_link_lsa: ibuf_set failed");
1123
1124 chksum = iso_cksum(ibuf_data(buf), ibuf_size(buf), LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum));
1125 if (ibuf_set_n16(buf, LS_CKSUM_OFFSET__builtin_offsetof(struct lsa_hdr, ls_chksum), chksum) == -1)
1126 fatal("orig_link_lsa: ibuf_set_n16 failed");
1127
1128 imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0,
1129 -1, ibuf_data(buf), ibuf_size(buf));
1130
1131 ibuf_free(buf);
1132}
1133
1134u_int32_t
1135ospfe_router_id(void)
1136{
1137 return (oeconf->rtr_id.s_addr);
1138}
1139
1140void
1141ospfe_fib_update(int type)
1142{
1143 int old = oe_nofib;
1144
1145 if (type == IMSG_CTL_FIB_COUPLE)
1146 oe_nofib = 0;
1147 if (type == IMSG_CTL_FIB_DECOUPLE)
1148 oe_nofib = 1;
1149 if (old != oe_nofib)
1150 orig_rtr_lsa_all(NULL((void *)0));
1151}
1152
1153void
1154ospfe_iface_ctl(struct ctl_conn *c, unsigned int idx)
1155{
1156 struct area *area;
1157 struct iface *iface;
1158 struct ctl_iface *ictl;
1159
1160 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
1161 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
1162 if (idx == 0 || idx == iface->ifindex) {
1163 ictl = if_to_ctl(iface);
1164 imsg_compose_event(&c->iev,
1165 IMSG_CTL_SHOW_INTERFACE, 0, 0, -1,
1166 ictl, sizeof(struct ctl_iface));
1167 }
1168}
1169
1170void
1171ospfe_nbr_ctl(struct ctl_conn *c)
1172{
1173 struct area *area;
1174 struct iface *iface;
1175 struct nbr *nbr;
1176 struct ctl_nbr *nctl;
1177
1178 LIST_FOREACH(area, &oeconf->area_list, entry)for((area) = ((&oeconf->area_list)->lh_first); (area
)!= ((void *)0); (area) = ((area)->entry.le_next))
1179 LIST_FOREACH(iface, &area->iface_list, entry)for((iface) = ((&area->iface_list)->lh_first); (iface
)!= ((void *)0); (iface) = ((iface)->entry.le_next))
1180 LIST_FOREACH(nbr, &iface->nbr_list, entry)for((nbr) = ((&iface->nbr_list)->lh_first); (nbr)!=
((void *)0); (nbr) = ((nbr)->entry.le_next))
{
1181 if (iface->self != nbr) {
1182 nctl = nbr_to_ctl(nbr);
1183 imsg_compose_event(&c->iev,
1184 IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
1185 sizeof(struct ctl_nbr));
1186 }
1187 }
1188
1189 imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL((void *)0), 0);
1190}
1191
1192void
1193ospfe_demote_area(struct area *area, int active)
1194{
1195 struct demote_msg dmsg;
1196
1197 if (ospfd_process != PROC_OSPF_ENGINE ||
1198 area->demote_group[0] == '\0')
1199 return;
1200
1201 bzero(&dmsg, sizeof(dmsg));
1202 strlcpy(dmsg.demote_group, area->demote_group,
1203 sizeof(dmsg.demote_group));
1204 dmsg.level = area->demote_level;
1205 if (active)
1206 dmsg.level = -dmsg.level;
1207
1208 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
1209}
1210
1211void
1212ospfe_demote_iface(struct iface *iface, int active)
1213{
1214 struct demote_msg dmsg;
1215
1216 if (ospfd_process != PROC_OSPF_ENGINE ||
1217 iface->demote_group[0] == '\0')
1218 return;
1219
1220 bzero(&dmsg, sizeof(dmsg));
1221 strlcpy(dmsg.demote_group, iface->demote_group,
1222 sizeof(dmsg.demote_group));
1223 if (active)
1224 dmsg.level = -1;
1225 else
1226 dmsg.level = 1;
1227
1228 log_warnx("ospfe_demote_iface: group %s level %d", dmsg.demote_group,
1229 dmsg.level);
1230
1231 ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
1232}