/* ARGSUSED */ void rde_dispatch_imsg(int fd, short event, void *bula) { struct imsgev *iev = bula; struct imsgbuf *ibuf = &iev->ibuf; struct rip_route rr; struct imsg imsg; ssize_t n; int shut = 0, verbose; if (event & EV_READ) { if ((n = imsg_read(ibuf)) == -1) fatal("imsg_read error"); if (n == 0) /* connection closed */ shut = 1; } if (event & EV_WRITE) { if (msgbuf_write(&ibuf->w) == -1 && errno != EAGAIN) fatal("msgbuf_write"); } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal("rde_dispatch_imsg: imsg_read error"); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_ROUTE_FEED: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(rr)) fatalx("invalid size of RDE request"); memcpy(&rr, imsg.data, sizeof(rr)); if (rde_check_route(&rr) == -1) log_debug("rde_dispatch_imsg: " "packet malformed\n"); break; case IMSG_FULL_REQUEST: bzero(&rr, sizeof(rr)); /* * AFI == 0 && metric == INFINITY request the * whole routing table */ rr.metric = INFINITY; rde_imsg_compose_ripe(IMSG_REQUEST_ADD, 0, 0, &rr, sizeof(rr)); rde_imsg_compose_ripe(IMSG_SEND_REQUEST, 0, 0, NULL, 0); break; case IMSG_FULL_RESPONSE: rt_snap(imsg.hdr.peerid); rde_imsg_compose_ripe(IMSG_SEND_RESPONSE, imsg.hdr.peerid, 0, NULL, 0); break; case IMSG_ROUTE_REQUEST: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(rr)) fatalx("invalid size of RDE request"); memcpy(&rr, imsg.data, sizeof(rr)); rt_complete(&rr); rde_imsg_compose_ripe(IMSG_RESPONSE_ADD, imsg.hdr.peerid, 0, &rr, sizeof(rr)); break; case IMSG_ROUTE_REQUEST_END: rde_imsg_compose_ripe(IMSG_SEND_RESPONSE, imsg.hdr.peerid, 0, NULL, 0); break; case IMSG_CTL_SHOW_RIB: rt_dump(imsg.hdr.pid); imsg_compose_event(iev_ripe, IMSG_CTL_END, 0, imsg.hdr.pid, -1, NULL, 0); break; case IMSG_CTL_LOG_VERBOSE: /* already checked by ripe */ memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); break; default: log_debug("rde_dispatch_msg: unexpected imsg %d", imsg.hdr.type); break; } imsg_free(&imsg); } if (!shut) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); } }
/** * Dump the node's routing table. */ void node_rt_dump(gds_stream_t * stream, net_node_t * node, ip_dest_t dest) { if (node->rt != NULL) rt_dump(stream, node->rt, dest); stream_flush(stream); }
/* ARGSUSED */ void lde_dispatch_imsg(int fd, short event, void *bula) { struct imsgev *iev = bula; struct imsgbuf *ibuf = &iev->ibuf; struct imsg imsg; struct lde_nbr rn, *nbr; struct map map; struct timespec tp; struct in_addr addr; ssize_t n; time_t now; int state, shut = 0, verbose; if (event & EV_READ) { if ((n = imsg_read(ibuf)) == -1) fatal("imsg_read error"); if (n == 0) /* connection closed */ shut = 1; } if (event & EV_WRITE) { if (msgbuf_write(&ibuf->w) == -1) fatal("msgbuf_write"); } clock_gettime(CLOCK_MONOTONIC, &tp); now = tp.tv_sec; for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal("lde_dispatch_imsg: imsg_read error"); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_LABEL_MAPPING_FULL: nbr = lde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) { log_debug("lde_dispatch_imsg: cannot find " "lde neighbor"); return; } rt_snap(nbr); lde_imsg_compose_ldpe(IMSG_MAPPING_ADD_END, imsg.hdr.peerid, 0, NULL, 0); break; case IMSG_LABEL_MAPPING: case IMSG_LABEL_REQUEST: case IMSG_LABEL_RELEASE: case IMSG_LABEL_WITHDRAW: case IMSG_LABEL_ABORT: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(map)) fatalx("invalid size of OE request"); memcpy(&map, imsg.data, sizeof(map)); nbr = lde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) { log_debug("lde_dispatch_imsg: cannot find " "lde neighbor"); return; } switch (imsg.hdr.type) { case IMSG_LABEL_MAPPING: lde_check_mapping(&map, nbr); break; case IMSG_LABEL_REQUEST: lde_check_request(&map, nbr); break; case IMSG_LABEL_RELEASE: lde_check_release(&map, nbr); break; case IMSG_LABEL_WITHDRAW: lde_check_withdraw(&map, nbr); break; default: log_warnx("type %d not yet handled. nbr %s", imsg.hdr.type, inet_ntoa(nbr->id)); } break; case IMSG_ADDRESS_ADD: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr)) fatalx("invalid size of OE request"); memcpy(&addr, imsg.data, sizeof(addr)); nbr = lde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) { log_debug("lde_dispatch_imsg: cannot find " "lde neighbor"); return; } if (lde_address_add(nbr, &addr) < 0) { log_debug("lde_dispatch_imsg: cannot add " "address %s, it already exists", inet_ntoa(addr)); } break; case IMSG_ADDRESS_DEL: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr)) fatalx("invalid size of OE request"); memcpy(&addr, imsg.data, sizeof(addr)); nbr = lde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) { log_debug("lde_dispatch_imsg: cannot find " "lde neighbor"); return; } if (lde_address_del(nbr, &addr) < 0) { log_debug("lde_dispatch_imsg: cannot delete " "address %s, it does not exists", inet_ntoa(addr)); } break; case IMSG_NEIGHBOR_UP: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(rn)) fatalx("invalid size of OE request"); memcpy(&rn, imsg.data, sizeof(rn)); if (lde_nbr_find(imsg.hdr.peerid)) fatalx("lde_dispatch_imsg: " "neighbor already exists"); lde_nbr_new(imsg.hdr.peerid, &rn); break; case IMSG_NEIGHBOR_DOWN: lde_nbr_del(lde_nbr_find(imsg.hdr.peerid)); break; case IMSG_NEIGHBOR_CHANGE: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(state)) fatalx("invalid size of OE request"); memcpy(&state, imsg.data, sizeof(state)); nbr = lde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) break; nbr->state = state; break; case IMSG_CTL_SHOW_LIB: rt_dump(imsg.hdr.pid); imsg_compose_event(iev_ldpe, IMSG_CTL_END, 0, imsg.hdr.pid, -1, NULL, 0); break; case IMSG_CTL_LOG_VERBOSE: /* already checked by ldpe */ memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); break; default: log_debug("lde_dispatch_imsg: unexpected imsg %d", imsg.hdr.type); break; } imsg_free(&imsg); } if (!shut) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); } }