Пример #1
0
/* 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);
	}
}
Пример #2
0
/**
 * 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);
}
Пример #3
0
/* 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);
	}
}