Exemplo n.º 1
0
static void
prepare_pkt(struct rte_mbuf *mbuf)
{
	struct ether_hdr *eth_hdr;
	struct vlan_hdr *vlan1, *vlan2;
	struct ipv4_hdr *ip_hdr;

	/* Simulate a classifier */
	eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
	vlan1 = (struct vlan_hdr *)(&eth_hdr->ether_type );
	vlan2 = (struct vlan_hdr *)((uintptr_t)&eth_hdr->ether_type + sizeof(struct vlan_hdr));
	eth_hdr = (struct ether_hdr *)((uintptr_t)&eth_hdr->ether_type + 2 *sizeof(struct vlan_hdr));
	ip_hdr = (struct ipv4_hdr *)((uintptr_t)eth_hdr +  sizeof(eth_hdr->ether_type));

	vlan1->vlan_tci = rte_cpu_to_be_16(SUBPORT);
	vlan2->vlan_tci = rte_cpu_to_be_16(PIPE);
	eth_hdr->ether_type =  rte_cpu_to_be_16(ETHER_TYPE_IPv4);
	ip_hdr->dst_addr = IPv4(0,0,TC,QUEUE);


	rte_sched_port_pkt_write(mbuf, SUBPORT, PIPE, TC, QUEUE, e_RTE_METER_YELLOW);

	/* 64 byte packet */
	mbuf->pkt.pkt_len  = 60;
	mbuf->pkt.data_len = 60;
}
Exemplo n.º 2
0
/* Encapsulate IPv6 packet in QinQ where the QinQ is derived from the IPv6 address */
static inline uint8_t handle_qinq_encap6(struct rte_mbuf *mbuf, struct task_qinq_encap6 *task)
{
	struct qinq_hdr *pqinq = (struct qinq_hdr *)rte_pktmbuf_prepend(mbuf, 2 * sizeof(struct vlan_hdr));

	PROX_RUNTIME_ASSERT(pqinq);
	struct ipv6_hdr *pip6 = (struct ipv6_hdr *)(pqinq + 1);

	if (pip6->hop_limits) {
		pip6->hop_limits--;
	}
	else {
		plog_info("TTL = 0 => Dropping\n");
		return NO_PORT_AVAIL;
	}

	// TODO: optimize to use bulk as intended with the rte_table_library
	uint64_t pkts_mask = RTE_LEN2MASK(1, uint64_t);
	uint64_t lookup_hit_mask;
	struct cpe_data* entries[64]; // TODO: use bulk size
	rte_table_hash_ext_dosig_ops.f_lookup(task->cpe_table, &mbuf, pkts_mask, &lookup_hit_mask, (void**)entries);

	if (lookup_hit_mask == 0x1) {
		/* will also overwrite part of the destination addr */
		(*(uint64_t *)pqinq) = entries[0]->mac_port_8bytes;
		pqinq->svlan.eth_proto = task->qinq_tag;
		pqinq->cvlan.eth_proto = ETYPE_VLAN;
		pqinq->svlan.vlan_tci = entries[0]->qinq_svlan;
		pqinq->cvlan.vlan_tci = entries[0]->qinq_cvlan;
		pqinq->ether_type = ETYPE_IPv6;

		/* classification can only be done from this point */
		if (task->runtime_flags & TASK_CLASSIFY) {
			rte_sched_port_pkt_write(mbuf, 0, entries[0]->user, 0, 0, 0);
		}
		return 0;
	}
	else {
		plogx_err("Unknown IP " IPv6_BYTES_FMT "\n", IPv6_BYTES(pip6->dst_addr));
		return NO_PORT_AVAIL;
	}
}
Exemplo n.º 3
0
/**
 * Dequeue mbufs from output queue and send to ethernet port.
 * This function is called from I/O (Output) thread.
 */
static inline void
app_lcore_io_tx(struct app_lcore_params_io *lp,
                uint32_t n_workers,
                uint32_t bsz_rd,
                uint32_t bsz_wr) {
  uint32_t worker;

  for (worker = 0; worker < n_workers; worker ++) {
    uint32_t i;

    for (i = 0; i < lp->tx.n_nic_ports; i ++) {
      uint8_t port = lp->tx.nic_ports[i];
      struct rte_ring *ring = lp->tx.rings[port][worker];
      struct interface *ifp;
      uint32_t n_mbufs, n_pkts;
      int ret;

      n_mbufs = lp->tx.mbuf_out[port].n_mbufs;
      ret = rte_ring_sc_dequeue_burst(ring,
                                      (void **) &lp->tx.mbuf_out[port].array[n_mbufs],
                                      bsz_rd - n_mbufs);

      if (unlikely(ret == 0)) {
        continue;
      }

      n_mbufs += (uint32_t)ret;

#if APP_IO_TX_DROP_ALL_PACKETS
      {
        uint32_t j;
        APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[0]);
        APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[1]);

        for (j = 0; j < n_mbufs; j ++) {
          if (likely(j < n_mbufs - 2)) {
            APP_IO_TX_PREFETCH0(lp->tx.mbuf_out[port].array[j + 2]);
          }
          rte_pktmbuf_free(lp->tx.mbuf_out[port].array[j]);
        }
        lp->tx.mbuf_out[port].n_mbufs = 0;
        continue;
      }
#endif
      if (unlikely(n_mbufs < bsz_wr)) {
        lp->tx.mbuf_out[port].n_mbufs = n_mbufs;
        lp->tx.mbuf_out_flush[port] = 1;
        continue;
      }
      ifp = dpdk_interface_lookup(port);
      if (ifp != NULL && ifp->sched_port != NULL) {
        struct lagopus_packet *pkt;
        struct rte_mbuf *m;
        int qidx, color;

        for (i = 0; i < n_mbufs; i++) {
          m = lp->tx.mbuf_out[port].array[i];
          pkt = (struct lagopus_packet *)
                (m->buf_addr + APP_DEFAULT_MBUF_LOCALDATA_OFFSET);
          if (unlikely(pkt->queue_id != 0)) {
            qidx = dpdk_interface_queue_id_to_index(ifp, pkt->queue_id);
            color = rte_meter_trtcm_color_blind_check(&ifp->ifqueue.meters[qidx],
                    rte_rdtsc(),
                    OS_M_PKTLEN(m));
            rte_sched_port_pkt_write(m, 0, 0, 0, qidx, color);
          }
        }
        n_mbufs = rte_sched_port_enqueue(ifp->sched_port,
                                         lp->tx.mbuf_out[port].array,
                                         n_mbufs);
        n_mbufs = rte_sched_port_dequeue(ifp->sched_port,
                                         lp->tx.mbuf_out[port].array,
                                         n_mbufs);
      }
      DPRINTF("send %d pkts\n", n_mbufs);
      n_pkts = rte_eth_tx_burst(port,
                                0,
                                lp->tx.mbuf_out[port].array,
                                (uint16_t) n_mbufs);
      DPRINTF("sent %d pkts\n", n_pkts);

#if APP_STATS
      lp->tx.nic_ports_iters[port] ++;
      lp->tx.nic_ports_count[port] += n_pkts;
      if (unlikely(lp->tx.nic_ports_iters[port] == APP_STATS)) {
        unsigned lcore = rte_lcore_id();

        printf("\t\t\tI/O TX %u out (port %u): avg burst size = %.2f\n",
               lcore,
               (unsigned) port,
               ((double) lp->tx.nic_ports_count[port]) / ((double)
                   lp->tx.nic_ports_iters[port]));
        lp->tx.nic_ports_iters[port] = 0;
        lp->tx.nic_ports_count[port] = 0;
      }
#endif

      if (unlikely(n_pkts < n_mbufs)) {
        uint32_t k;
        for (k = n_pkts; k < n_mbufs; k ++) {
          struct rte_mbuf *pkt_to_free = lp->tx.mbuf_out[port].array[k];
          rte_pktmbuf_free(pkt_to_free);
        }
      }
      lp->tx.mbuf_out[port].n_mbufs = 0;
      lp->tx.mbuf_out_flush[port] = 0;
    }
  }
}