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); }
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); }