Esempio n. 1
0
/*
 * Allocate mbuf for flow stat (and latency) info sending
 * m - Original mbuf (can be complicated mbuf data structure)
 * fsp_head - return pointer in which the flow stat info should be filled
 * is_const - is the given mbuf const
 * return new mbuf structure in which the fsp_head can be written. If needed, orginal mbuf is freed.
 */
rte_mbuf_t * CGenNodeStateless::alloc_flow_stat_mbuf(rte_mbuf_t *m, struct flow_stat_payload_header *&fsp_head
                                                     , bool is_const) {
    rte_mbuf_t *m_ret = NULL, *m_lat = NULL;
    uint16_t fsp_head_size = sizeof(struct flow_stat_payload_header);

    if (is_const) {
        // const mbuf case
        if (rte_pktmbuf_data_len(m) > 128) {
            m_ret = CGlobalInfo::pktmbuf_alloc_small(get_socket_id());
            assert(m_ret);
            // alloc mbuf just for the latency header
            m_lat = CGlobalInfo::pktmbuf_alloc( get_socket_id(), fsp_head_size);
            assert(m_lat);
            fsp_head = (struct flow_stat_payload_header *)rte_pktmbuf_append(m_lat, fsp_head_size);
            rte_pktmbuf_attach(m_ret, m);
            rte_pktmbuf_trim(m_ret, sizeof(struct flow_stat_payload_header));
            utl_rte_pktmbuf_add_after2(m_ret, m_lat);
            // ref count was updated when we took the (const) mbuf, and again in rte_pktmbuf_attach
            // so need do decrease now, to avoid leak.
            rte_pktmbuf_refcnt_update(m, -1);
            return m_ret;
        } else {
            // Short packet. Just copy all bytes.
            m_ret = CGlobalInfo::pktmbuf_alloc( get_socket_id(), rte_pktmbuf_data_len(m) );
            assert(m_ret);
            char *p = rte_pktmbuf_mtod(m, char*);
            char *p_new = rte_pktmbuf_append(m_ret, rte_pktmbuf_data_len(m));
            memcpy(p_new , p, rte_pktmbuf_data_len(m));
            fsp_head = (struct flow_stat_payload_header *)(p_new + rte_pktmbuf_data_len(m) - fsp_head_size);
            rte_pktmbuf_free(m);
            return m_ret;
        }
    } else {
        // Field engine (vm)
        if (rte_pktmbuf_is_contiguous(m)) {
Esempio n. 2
0
/**
 * @brief           Send packet from specified device
 *
 * @param devId     uint8_t, ID of DPDK device
 * @param mBuf      MBuf_t*, memory buffer
 *
 * @return          int, count of transmitted packets
 */
int DPDKAdapter::sendMbufBurstWithoutFree(uint8_t devId, MBuf_t** burst, uint8_t size)
{
    if (devId > RTE_MAX_ETHPORTS)
    {
        qCritical("Device ID is out of range");
        return -1;
    }

    if (size > DPDK_TX_MAX_PKT_BURST)
    {
        qCritical("Maximum packet burst value is exceeded");
        return -2;
    }

    // Nothing to do
    if (!burst)
    {
        qWarning("There is nothing to send");
        return 0;
    }

    for (uint8_t i = 0; i < size; i++)
    {
        rte_pktmbuf_refcnt_update(burst[i], 1);
    }

    return rte_eth_tx_burst(devId, 0, burst, size);
}
Esempio n. 3
0
int dpdpcap_transmit_in_loop(pcap_t *p, const u_char *buf, int size, int number)
{
    int transmitLcoreId = 0;
    int i = 0;

    if (p == NULL || buf == NULL ||
        p->deviceId < 0 || p->deviceId > RTE_MAX_ETHPORTS)
    {
        snprintf (errbuf_g, PCAP_ERRBUF_SIZE, "Invalid parameter");
        return DPDKPCAP_FAILURE;
    }

    for (i = 0; i < DEF_PKT_BURST; i++)
    {
        mbuf_g[i] = rte_pktmbuf_alloc(txPool);
        if (mbuf_g[i] == NULL)
        {
            snprintf (errbuf_g, PCAP_ERRBUF_SIZE, "Could not allocate buffer on port %d\n", p->deviceId);
            return DPDKPCAP_FAILURE;
        }

        struct rte_mbuf* mbuf = mbuf_g[i];

        if (mbuf->buf_len < size)
        {
            snprintf (errbuf_g, PCAP_ERRBUF_SIZE, "Can not copy packet data : packet size %d, mbuf length %d, port %d\n",
                   size, mbuf->buf_len, p->deviceId);
            return DPDKPCAP_FAILURE;
        }

        rte_memcpy(mbuf->pkt.data, buf, size);
        mbuf->pkt.data_len = size;
        mbuf->pkt.pkt_len = size;
        mbuf->pkt.nb_segs = 1;

        rte_pktmbuf_refcnt_update(mbuf, 1);
    }

    dpdkpcap_tx_args_t args;
    args.number = number;
    args.portId = p->deviceId;
    transmitLcoreId = p->deviceId + 1;

    debug("Transferring TX loop to the core %u\n", transmitLcoreId);

    if (rte_eal_remote_launch(txLoop, &args, transmitLcoreId) < 0)
    {
        snprintf (errbuf_g, PCAP_ERRBUF_SIZE, "Can not run TX on a slave core: transmitLcoreId %d\n",
                  transmitLcoreId);
        return DPDKPCAP_FAILURE;
    }

    rte_eal_wait_lcore(transmitLcoreId);

    return DPDKPCAP_OK;
}
Esempio n. 4
0
/* flood forward of the input packet */
static inline void
flood_forward(struct rte_mbuf *m, uint8_t rx_port, uint8_t nb_ports)
{
	uint8_t port;
	struct rte_mbuf *pkt;

	/* Mark all packet's segments as referenced port_num times */
	rte_pktmbuf_refcnt_update(m, (uint16_t)nb_ports);

	for (port = 0; port < nb_ports; port++) {
		/* skip for own port */
		if (unlikely (port == rx_port))
			continue; 

		pkt = m;		
		flood_send_pkt(pkt, port);
	}
	rte_pktmbuf_free(m);
}
Esempio n. 5
0
static int txLoop(void* arg)
{
    int ret = 0;
    dpdkpcap_tx_args_t* args_p = (dpdkpcap_tx_args_t*)arg;
    int number = args_p->number;
    int portId = args_p->portId;

    int lcoreId = rte_lcore_id();
    int packets = 0;
    int i = 0;

    debug("Starting transmit: core %u, port %u, packets num %d\n", lcoreId, portId, number);

    while (1)
    {
        ret = rte_eth_tx_burst(portId, 0, mbuf_g, DEF_PKT_BURST);
        if (ret < DEF_PKT_BURST)
        {
            debug("Transmitted %u packets\n", ret);
        }

        for (i = 0; i < ret; i++)
        {
             // rte_pktmbuf_free(mbuf_g[i]);
             rte_pktmbuf_refcnt_update(mbuf_g[i], 1);
        }

        packets += ret;

        if (args_p->number > 0)
        {
            if (number < 1)
                break;

            number -= ret;
        }
    }

    debug("Finished transmit on core %u\n", lcoreId);

    return DPDKPCAP_OK;
}