示例#1
0
int
if_netmap_attach(struct uinet_config_if *cfg)
{
	struct if_netmap_softc *sc = NULL;
	int fd = -1;
	int error = 0;
	uint32_t pool_size;
	uint32_t slotindex, curslotindex;
	uint32_t bufindex, unused;
	
	if (NULL == cfg->configstr) {
		error = EINVAL;
		goto fail;
	}

	printf("configstr is %s\n", cfg->configstr);

	snprintf(cfg->name, sizeof(cfg->name), "netmap%u", interface_count);
	interface_count++;

	sc = malloc(sizeof(struct if_netmap_softc), M_DEVBUF, M_WAITOK);
	if (NULL == sc) {
		printf("if_netmap_softc allocation failed\n");
		error = ENOMEM;
		goto fail;
	}
	memset(sc, 0, sizeof(struct if_netmap_softc));

	sc->cfg = cfg;

	error = if_netmap_process_configstr(sc);
	if (0 != error) {
		goto fail;
	}

	fd = uhi_open("/dev/netmap", UHI_O_RDWR);
	if (fd < 0) {
		printf("/dev/netmap open failed\n");
		error = ENXIO;
		goto fail;
	}

	sc->fd = fd;
	sc->stop_check_ticks = (IF_NETMAP_THREAD_STOP_CHECK_MS * hz) / 1000;
	if (sc->stop_check_ticks == 0)
		sc->stop_check_ticks = 1;

	if_netmap_stoppable_thread_init(&sc->tx_thread, "tx");
	if_netmap_stoppable_thread_init(&sc->rx_thread, "rx");

	sc->nm_host_ctx = if_netmap_register_if(sc->fd, sc->host_ifname, sc->isvale, sc->queue);
	if (NULL == sc->nm_host_ctx) {
		printf("Failed to register netmap interface\n");
		error = ENXIO;
		goto fail;
	}

	/*
	 * Limiting the size of the rxring zero-copy context pool to the
	 * given fraction of the rxring size limits the amount of rxring
	 * buffers that can be outstanding to the stack via zero-copy at any
	 * given time as a failure to allocate a zero-copy context in the
	 * receive loop causes the buffer to be copied to the stack.
	 */
	pool_size = (if_netmap_rxslots(sc->nm_host_ctx) * IF_NETMAP_RXRING_ZCOPY_FRAC_NUM) / IF_NETMAP_RXRING_ZCOPY_FRAC_DEN;
	error = if_netmap_bufinfo_pool_init(&sc->rx_bufinfo, pool_size);
	if (error != 0) {
		printf("bufinfo pool init failed\n");
		goto fail;
	}

	if (!sc->isvale) {
		if (0 != uhi_get_ifaddr(sc->host_ifname, sc->addr)) {
			printf("failed to find interface address\n");
			error = ENXIO;
			goto fail;
		}
	}

	sc->nm_buffer_indices = malloc(if_netmap_rxslots(sc->nm_host_ctx) *
				       sizeof(sc->nm_buffer_indices[0]),
				       M_DEVBUF, M_WAITOK);
	if (NULL == sc->nm_buffer_indices) {
		printf("Failed to alloc buffer index array\n");
		goto fail;
	}

	/*
	 * XXX This goes away when netmap implements buffer ownership tracking
	 * Record the set of netmap buffer indices in the rx ring so they
	 * can be restored on exit.
	 */
	slotindex = 0;
	do {
		curslotindex = slotindex;
		if_netmap_rxslot(sc->nm_host_ctx, &slotindex, &unused, &bufindex);		
		sc->nm_buffer_indices[curslotindex] = bufindex;
	} while (slotindex);

	if (0 != if_netmap_setup_interface(sc)) {
		error = ENXIO;
		goto fail;
	}

	cfg->ifindex = sc->ifp->if_index;
	cfg->ifdata = sc;
	cfg->ifp = sc->ifp;

	return (0);

fail:
	if (sc) {
		if (sc->nm_buffer_indices)
			free(sc->nm_buffer_indices, M_DEVBUF);

		if (sc->rx_bufinfo.initialized)
			if_netmap_bufinfo_pool_destroy(&sc->rx_bufinfo);

		if (sc->nm_host_ctx)
			if_netmap_deregister_if(sc->nm_host_ctx);

		if (sc->fd >= 0)
			uhi_close(sc->fd);

		free(sc, M_DEVBUF);
	}

	return (error);
}
示例#2
0
int
if_pcap_attach(struct uinet_if *uif)
{
	struct if_pcap_softc *sc = NULL;
	int error = 0;
	
	if (NULL == uif->configstr) {
		error = EINVAL;
		goto fail;
	}

	printf("configstr is %s\n", uif->configstr);

	snprintf(uif->name, sizeof(uif->name), "pcap%u", interface_count);
	interface_count++;

	sc = malloc(sizeof(struct if_pcap_softc), M_DEVBUF, M_WAITOK);
	if (NULL == sc) {
		printf("if_pcapap_softc allocation failed\n");
		error = ENOMEM;
		goto fail;
	}
	memset(sc, 0, sizeof(struct if_pcap_softc));

	sc->uif = uif;

	error = if_pcap_process_configstr(sc);
	if (0 != error) {
		goto fail;
	}

	sc->pcap_host_ctx = if_pcap_create_handle(sc->host_ifname, sc->isfile, if_pcap_receive_handler, sc);
	if (NULL == sc->pcap_host_ctx) {
		printf("Failed to create pcap handle for %s\n", sc->host_ifname);
		error = ENXIO;
		goto fail;
	}

	if (!sc->isfile) {
		if (0 != uhi_get_ifaddr(sc->host_ifname, sc->addr)) {
			printf("failed to find interface address\n");
			error = ENXIO;
			goto fail;
		}
	}

	if (0 != if_pcap_setup_interface(sc)) {
		error = ENXIO;
		goto fail;
	}

	uif->ifindex = sc->ifp->if_index;
	uif->ifdata = sc;
	uif->ifp = sc->ifp;

	return (0);

fail:
	if (sc) {
		if (sc->pcap_host_ctx)
			if_pcap_destroy_handle(sc->pcap_host_ctx);

		free(sc, M_DEVBUF);
	}

	return (error);
}