示例#1
0
/* netmap_pipe_krings_delete.
 *
 * There are two cases:
 *
 * 1) state is
 *
 *        usr1 --> e1 --> e2
 *
 *    and we are e1. We have to create both sets
 *    of krings.
 *
 * 2) state is
 *
 *        usr1 --> e1 --> e2
 *
 *    and we are e2. e1 is certainly registered and our
 *    krings already exist. Nothing to do.
 */
static int
netmap_pipe_krings_create(struct netmap_adapter *na)
{
	struct netmap_pipe_adapter *pna =
		(struct netmap_pipe_adapter *)na;
	struct netmap_adapter *ona = &pna->peer->up;
	int error = 0;
	enum txrx t;

	if (pna->peer_ref) {
		int i;

		/* case 1) above */
		D("%p: case 1, create both ends", na);
		error = netmap_krings_create(na, 0);
		if (error)
			goto err;

		/* create the krings of the other end */
		error = netmap_krings_create(ona, 0);
		if (error)
			goto del_krings1;

		/* cross link the krings */
		for_rx_tx(t) {
			enum txrx r = nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */
			for (i = 0; i < nma_get_nrings(na, t); i++) {
				NMR(na, t)[i].pipe = NMR(&pna->peer->up, r) + i;
				NMR(&pna->peer->up, r)[i].pipe = NMR(na, t) + i;
			}
		}

	}
示例#2
0
/* common functions for the nm_register() callbacks of both kind of
 * monitors.
 */
static int
netmap_monitor_reg_common(struct netmap_adapter *na, int onoff, int zmon)
{
	struct netmap_monitor_adapter *mna =
		(struct netmap_monitor_adapter *)na;
	struct netmap_priv_d *priv = &mna->priv;
	struct netmap_adapter *pna = priv->np_na;
	struct netmap_kring *kring, *mkring;
	int i;
	enum txrx t, s;

	ND("%p: onoff %d", na, onoff);
	if (onoff) {
		if (pna == NULL) {
			/* parent left netmap mode, fatal */
			D("%s: internal error", na->name);
			return ENXIO;
		}
		for_rx_tx(t) {
			for (i = 0; i < nma_get_nrings(na, t) + 1; i++) {
				mkring = &NMR(na, t)[i];
				if (!nm_kring_pending_on(mkring))
					continue;
				mkring->nr_mode = NKR_NETMAP_ON;
				if (t == NR_TX)
					continue;
				for_rx_tx(s) {
					if (i > nma_get_nrings(pna, s))
						continue;
					if (mna->flags & nm_txrx2flag(s)) {
						kring = &NMR(pna, s)[i];
						netmap_monitor_add(mkring, kring, zmon);
					}
				}
			}
		}
		na->na_flags |= NAF_NETMAP_ON;
	} else {
		if (na->active_fds == 0)
示例#3
0
/* This is called when the monitored adapter leaves netmap mode
 * (see netmap_do_unregif).
 * We need to notify the monitors that the monitored rings are gone.
 * We do this by setting their mna->priv.np_na to NULL.
 * Note that the rings are already stopped when this happens, so
 * no monitor ring callback can be active.
 */
void
netmap_monitor_stop(struct netmap_adapter *na)
{
	enum txrx t;

	for_rx_tx(t) {
		u_int i;

		for (i = 0; i < nma_get_nrings(na, t) + 1; i++) {
			struct netmap_kring *kring = &NMR(na, t)[i];
			struct netmap_kring *zkring;
			u_int j;

			for (j = 0; j < kring->n_monitors; j++) {
				struct netmap_kring *mkring =
					kring->monitors[j];
				struct netmap_monitor_adapter *mna =
					(struct netmap_monitor_adapter *)mkring->na;
				/* forget about this adapter */
				if (mna->priv.np_na != NULL) {
					netmap_adapter_put(mna->priv.np_na);
					mna->priv.np_na = NULL;
				}
			}

			zkring = kring->zmon_list[kring->tx].next;
			if (zkring != NULL) {
				struct netmap_monitor_adapter *next =
					(struct netmap_monitor_adapter *)zkring->na;
				struct netmap_monitor_adapter *this =
						(struct netmap_monitor_adapter *)na;
				struct netmap_adapter *pna = this->priv.np_na;
				/* let the next monitor forget about us */
				if (next->priv.np_na != NULL) {
					netmap_adapter_put(next->priv.np_na);
				}
				if (pna != NULL && nm_is_zmon(na)) {
					/* we are a monitor ourselves and we may
					 * need to pass down the reference to
					 * the previous adapter in the chain
					 */
					netmap_adapter_get(pna);
					next->priv.np_na = pna;
					continue;
				}
				next->priv.np_na = NULL;
			}
		}
	}
}
示例#4
0
/* This is called when the monitored adapter leaves netmap mode
 * (see netmap_do_unregif).
 * We need to notify the monitors that the monitored rings are gone.
 * We do this by setting their mna->priv.np_na to NULL.
 * Note that the rings are already stopped when this happens, so
 * no monitor ring callback can be active.
 */
void
netmap_monitor_stop(struct netmap_adapter *na)
{
    enum txrx t;

    for_rx_tx(t) {
        u_int i;

        for (i = 0; i < nma_get_nrings(na, t); i++) {
            struct netmap_kring *kring = &NMR(na, t)[i];
            u_int j;

            for (j = 0; j < kring->n_monitors; j++) {
                struct netmap_kring *mkring =
                        kring->monitors[j];
                struct netmap_monitor_adapter *mna =
                    (struct netmap_monitor_adapter *)mkring->na;
                /* forget about this adapter */
                mna->priv.np_na = NULL;
            }
        }
    }
}