コード例 #1
0
ファイル: ofp_syscalls.c プロジェクト: bogdanPricope/ofp
void *ofp_udp_packet_parse(odp_packet_t pkt, int *length,
			       struct ofp_sockaddr *addr,
			       ofp_socklen_t *addrlen)
{
	struct ofp_sockaddr *src_addr = NULL;
	ofp_socklen_t src_len = 0;
	struct ofp_udphdr *uh =
		(struct ofp_udphdr *)odp_packet_l4_ptr(pkt, NULL);
	int udplen = odp_be_to_cpu_16(uh->uh_ulen) - sizeof(*uh);
	uint8_t *data = (uint8_t *)(uh + 1);
	uint8_t *start = odp_packet_data(pkt);

	if (addr && addrlen) {
		src_addr = (struct ofp_sockaddr *)odp_packet_l2_ptr(pkt,
				NULL);
		if (src_addr->sa_family == OFP_AF_INET)
			src_len = sizeof(struct ofp_sockaddr_in);
		else if (src_addr->sa_family == OFP_AF_INET6)
			src_len = sizeof(struct ofp_sockaddr_in6);
		else
			return NULL;

		memcpy(addr, src_addr, min(*addrlen, src_len));
		*addrlen = src_len;
	}
	if (data > start)
		odp_packet_pull_head(pkt, (uint32_t)(data - start));
	int pktlen = odp_packet_len(pkt);
	if (pktlen > udplen)
		odp_packet_pull_tail(pkt, (uint32_t)(pktlen - udplen));
	if (length)
		*length = udplen;

	return data;
}
コード例 #2
0
/*
 * Trim packet data beyond the end of L3 payload
 * (i.e. from the offset (L3 offset + l3_len) to the end of the packet).
 */
static inline void trim_tail(odp_packet_t pkt, uint32_t l3_len)
{
	uint32_t l3_offset = odp_packet_l3_offset(pkt);
	uint32_t len = odp_packet_len(pkt);

	if (len > l3_offset + l3_len)
		odp_packet_pull_tail(pkt, len - l3_offset - l3_len);
}
コード例 #3
0
ファイル: pktio.c プロジェクト: kalray/odp-mppa
void pktio_test_send_failure(void)
{
	odp_pktio_t pktio_tx, pktio_rx;
	odp_packet_t pkt_tbl[TX_BATCH_LEN];
	uint32_t pkt_seq[TX_BATCH_LEN];
	int ret, mtu, i, alloc_pkts;
	odp_pool_param_t pool_params;
	odp_pool_t pkt_pool;
	int long_pkt_idx = TX_BATCH_LEN / 2;
	pktio_info_t info_rx;

	pktio_tx = create_pktio(0, ODP_PKTIN_MODE_RECV,
				ODP_PKTOUT_MODE_SEND);
	if (pktio_tx == ODP_PKTIO_INVALID) {
		CU_FAIL("failed to open pktio");
		return;
	}

	/* read the MTU from the transmit interface */
	mtu = odp_pktio_mtu(pktio_tx);

	ret = odp_pktio_start(pktio_tx);
	CU_ASSERT_FATAL(ret == 0);

	/* configure the pool so that we can generate test packets larger
	 * than the interface MTU */
	memset(&pool_params, 0, sizeof(pool_params));
	pool_params.pkt.len     = mtu + 32;
	pool_params.pkt.seg_len = pool_params.pkt.len;
	pool_params.pkt.num     = TX_BATCH_LEN + 1;
	pool_params.type        = ODP_POOL_PACKET;
	pkt_pool = odp_pool_create("pkt_pool_oversize", &pool_params);
	CU_ASSERT_FATAL(pkt_pool != ODP_POOL_INVALID);

	if (num_ifaces > 1) {
		pktio_rx = create_pktio(1, ODP_PKTIN_MODE_RECV,
					ODP_PKTOUT_MODE_SEND);
		ret = odp_pktio_start(pktio_rx);
		CU_ASSERT_FATAL(ret == 0);
	} else {
		pktio_rx = pktio_tx;
	}

	/* generate a batch of packets with a single overly long packet
	 * in the middle */
	for (i = 0; i < TX_BATCH_LEN; ++i) {
		uint32_t pkt_len;

		if (i == long_pkt_idx)
			pkt_len = pool_params.pkt.len;
		else
			pkt_len = PKT_LEN_NORMAL;

		pkt_tbl[i] = odp_packet_alloc(pkt_pool, pkt_len);
		if (pkt_tbl[i] == ODP_PACKET_INVALID)
			break;

		pkt_seq[i] = pktio_init_packet(pkt_tbl[i]);

		pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx);
		if (pktio_fixup_checksums(pkt_tbl[i]) != 0) {
			odp_packet_free(pkt_tbl[i]);
			break;
		}

		if (pkt_seq[i] == TEST_SEQ_INVALID) {
			odp_packet_free(pkt_tbl[i]);
			break;
		}
	}
	alloc_pkts = i;

	if (alloc_pkts == TX_BATCH_LEN) {
		/* try to send the batch with the long packet in the middle,
		 * the initial short packets should be sent successfully */
		odp_errno_zero();
		ret = odp_pktio_send(pktio_tx, pkt_tbl, TX_BATCH_LEN);
		CU_ASSERT(ret == long_pkt_idx);
		CU_ASSERT(odp_errno() == 0);

		info_rx.id   = pktio_rx;
		info_rx.outq = ODP_QUEUE_INVALID;
		info_rx.inq  = ODP_QUEUE_INVALID;
		info_rx.in_mode = ODP_PKTIN_MODE_RECV;

		for (i = 0; i < ret; ++i) {
			pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i],
						     ODP_TIME_SEC_IN_NS);
			if (pkt_tbl[i] == ODP_PACKET_INVALID)
				break;
		}

		if (i == ret) {
			/* now try to send starting with the too-long packet
			 * and verify it fails */
			odp_errno_zero();
			ret = odp_pktio_send(pktio_tx,
					     &pkt_tbl[long_pkt_idx],
					     TX_BATCH_LEN - long_pkt_idx);
			CU_ASSERT(ret == -1);
			CU_ASSERT(odp_errno() != 0);
		} else {
			CU_FAIL("failed to receive transmitted packets\n");
		}

		/* now reduce the size of the long packet and attempt to send
		 * again - should work this time */
		i = long_pkt_idx;
		odp_packet_pull_tail(pkt_tbl[i],
				     odp_packet_len(pkt_tbl[i]) -
				     PKT_LEN_NORMAL);
		pkt_seq[i] = pktio_init_packet(pkt_tbl[i]);

		pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx);
		ret = pktio_fixup_checksums(pkt_tbl[i]);
		CU_ASSERT_FATAL(ret == 0);

		CU_ASSERT_FATAL(pkt_seq[i] != TEST_SEQ_INVALID);
		ret = odp_pktio_send(pktio_tx, &pkt_tbl[i], TX_BATCH_LEN - i);
		CU_ASSERT_FATAL(ret == (TX_BATCH_LEN - i));

		for (; i < TX_BATCH_LEN; ++i) {
			pkt_tbl[i] = wait_for_packet(&info_rx,
						     pkt_seq[i],
						     ODP_TIME_SEC_IN_NS);
			if (pkt_tbl[i] == ODP_PACKET_INVALID)
				break;
		}
		CU_ASSERT(i == TX_BATCH_LEN);
	} else {
		CU_FAIL("failed to generate test packets\n");
	}

	for (i = 0; i < alloc_pkts; ++i) {
		if (pkt_tbl[i] != ODP_PACKET_INVALID)
			odp_packet_free(pkt_tbl[i]);
	}

	if (pktio_rx != pktio_tx)
		CU_ASSERT(odp_pktio_close(pktio_rx) == 0);
	CU_ASSERT(odp_pktio_close(pktio_tx) == 0);
	CU_ASSERT(odp_pool_destroy(pkt_pool) == 0);
}