All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] testpmd: handle UFO packets
@ 2018-02-24  9:35 Jianfeng Tan
  2018-02-28 14:10 ` Jason Wang
  0 siblings, 1 reply; 4+ messages in thread
From: Jianfeng Tan @ 2018-02-24  9:35 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan

Mostly likely, we will make UFO as a kind of GSO engine.

For short term, we can just call APIs in librte_ip_frag to fragment.

To test:

1. start testpmd with two vhost port.
 $ set fwd csum
 $ start

2. start vm0 connected to vhost0;
 $ ifconfig xxx 1.1.1.1/24 up
 $ ethtool -K xxx ufo on

3. start vm1 connected to vhost1;
 $ ifconfig xxx 1.1.1.2/24 up
 $ ethtool -K xxx ufo on
 $ (Fill a large file named 1.txt)
 $ cat 1.txt | socat - udp-sendto:1.1.1.1:5000

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 app/test-pmd/csumonly.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 5f5ab64..3e4c414 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -41,6 +41,7 @@
 #include <rte_flow.h>
 #include <rte_gro.h>
 #include <rte_gso.h>
+#include <rte_ip_frag.h>
 
 #include "testpmd.h"
 
@@ -574,6 +575,75 @@ pkt_copy_split(const struct rte_mbuf *pkt)
 	return md[0];
 }
 
+static inline void
+frag_v4_fixup(const struct rte_mbuf *ms, struct rte_mbuf *mf)
+{
+	struct ipv4_hdr *l3h;
+
+	mf->ol_flags = ms->ol_flags;
+	mf->tx_offload = ms->tx_offload;
+
+	if ((ms->ol_flags & PKT_TX_IP_CKSUM) == 0) {
+		l3h = rte_pktmbuf_mtod(mf, struct ipv4_hdr *);
+		l3h->hdr_checksum = rte_ipv4_cksum(l3h);
+	}
+}
+
+/*
+ * Returns negative for failure to fragment or actual number of fragments.
+ */
+static inline int
+fragment(struct rte_mbuf *m, struct rte_mbuf *frag[], uint32_t num)
+{
+	void *l2;
+	int l2_len;
+	int32_t frag_num, i;
+	uint16_t ether_type;
+	struct ether_hdr *eth_hdr;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); 
+	ether_type = eth_hdr->ether_type;
+	m->l2_len = sizeof(*eth_hdr);
+	if (ether_type == ETHER_TYPE_VLAN) {
+		struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1); 
+		ether_type = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+		m->l2_len += sizeof(struct vlan_hdr);
+	}
+	l2_len = m->l2_len;
+
+	/* store the l2 header */
+	uint8_t l2_hdr[l2_len];
+	rte_memcpy(l2_hdr, eth_hdr, l2_len);
+
+	/* Remove the l2 header from the input packet */
+	rte_pktmbuf_adj(m, l2_len);
+
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		frag_num = rte_ipv4_fragment_packet(m, frag, num,
+			m->tso_segsz, current_fwd_lcore()->mbp,
+			current_fwd_lcore()->mbp);
+	else
+		frag_num = rte_ipv6_fragment_packet(m, frag, num,
+			m->tso_segsz, current_fwd_lcore()->mbp,
+			current_fwd_lcore()->mbp);
+
+	if (frag_num > 0) {
+		for (i = 0; i != frag_num; i++) {
+
+			if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+				frag_v4_fixup(m, frag[i]);
+
+			/* Move data_off to include l2 header first */
+			l2 = rte_pktmbuf_prepend(frag[i], l2_len);
+
+			/* copy l2 header into fragmented packet */
+			rte_memcpy(l2, l2_hdr, l2_len);
+		}
+	}
+
+	return frag_num;
+}
+
 /*
  * Receive a burst of packets, and for each packet:
  *  - parse packet, and try to recognize a supported packet type (1)
@@ -603,6 +673,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 {
 	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
 	struct rte_mbuf *gso_segments[GSO_MAX_PKT_BURST];
+	struct rte_mbuf *ufo_segments[GSO_MAX_PKT_BURST];
 	struct rte_gso_ctx *gso_ctx;
 	struct rte_mbuf **tx_pkts_burst;
 	struct rte_port *txp;
@@ -656,6 +727,32 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 	if (gso_ports[fs->tx_port].enable)
 		info.gso_enable = 1;
 
+	nb_segments = 0;
+	for (i = 0; i < nb_rx; ++i) {
+		m = pkts_burst[i];
+		if (!(m->ol_flags & PKT_TX_UDP_SEG)) {
+			ufo_segments[nb_segments++] = m;
+			continue;
+		}
+
+		ret = fragment(m, &ufo_segments[nb_segments],
+				RTE_DIM(ufo_segments) - nb_segments);
+		if (ret <= 0) {
+			printf("ip frag failed %s\n", strerror(-ret));
+			rte_pktmbuf_free(m);
+			continue;
+		}
+		nb_segments += ret;
+		/* free the original packet */
+		rte_pktmbuf_free(m);
+	}
+
+	nb_rx = RTE_MIN(nb_segments, MAX_PKT_BURST);
+	for (i = 0; i < nb_rx; i++)
+		pkts_burst[i] = ufo_segments[i];
+	for (i = nb_rx; i < nb_segments; ++i)
+		rte_pktmbuf_free(ufo_segments[i]);
+
 	for (i = 0; i < nb_rx; i++) {
 		if (likely(i < nb_rx - 1))
 			rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
@@ -832,6 +929,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 		}
 	}
 
+	nb_segments = 0;
 	if (unlikely(gro_enable)) {
 		if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) {
 			nb_rx = rte_gro_reassemble_burst(pkts_burst, nb_rx,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC] testpmd: handle UFO packets
  2018-02-24  9:35 [RFC] testpmd: handle UFO packets Jianfeng Tan
@ 2018-02-28 14:10 ` Jason Wang
  2018-02-28 14:53   ` Tan, Jianfeng
  0 siblings, 1 reply; 4+ messages in thread
From: Jason Wang @ 2018-02-28 14:10 UTC (permalink / raw)
  To: Jianfeng Tan, dev



On 2018年02月24日 17:35, Jianfeng Tan wrote:
> Mostly likely, we will make UFO as a kind of GSO engine.
>
> For short term, we can just call APIs in librte_ip_frag to fragment.
>
> To test:
>
> 1. start testpmd with two vhost port.
>   $ set fwd csum
>   $ start
>
> 2. start vm0 connected to vhost0;
>   $ ifconfig xxx 1.1.1.1/24 up
>   $ ethtool -K xxx ufo on
>
> 3. start vm1 connected to vhost1;
>   $ ifconfig xxx 1.1.1.2/24 up
>   $ ethtool -K xxx ufo on
>   $ (Fill a large file named 1.txt)
>   $ cat 1.txt | socat - udp-sendto:1.1.1.1:5000

Just a reminder, UFO was completely removed upstream.

Thanks

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] testpmd: handle UFO packets
  2018-02-28 14:10 ` Jason Wang
@ 2018-02-28 14:53   ` Tan, Jianfeng
  2018-03-01  8:36     ` Jason Wang
  0 siblings, 1 reply; 4+ messages in thread
From: Tan, Jianfeng @ 2018-02-28 14:53 UTC (permalink / raw)
  To: Jason Wang, dev; +Cc: stephen, Bruce Richardson, Tiwei Bie

Hi Jason,


On 2/28/2018 10:10 PM, Jason Wang wrote:
>
>
> On 2018年02月24日 17:35, Jianfeng Tan wrote:
>> Mostly likely, we will make UFO as a kind of GSO engine.
>>
>> For short term, we can just call APIs in librte_ip_frag to fragment.
>>
>> To test:
>>
>> 1. start testpmd with two vhost port.
>>   $ set fwd csum
>>   $ start
>>
>> 2. start vm0 connected to vhost0;
>>   $ ifconfig xxx 1.1.1.1/24 up
>>   $ ethtool -K xxx ufo on
>>
>> 3. start vm1 connected to vhost1;
>>   $ ifconfig xxx 1.1.1.2/24 up
>>   $ ethtool -K xxx ufo on
>>   $ (Fill a large file named 1.txt)
>>   $ cat 1.txt | socat - udp-sendto:1.1.1.1:5000
>
> Just a reminder, UFO was completely removed upstream.
>

Thank you for the information.

Saw the deprecation patch at Linux v4.16-rc3, wonder what "version+" 
counts "merden kernels" in "modern kernels will no longer generate UFO 
skbs"? And this is mostly for stock VMs with old kernels to help the 
migration from kernel vswitch to user space vswitch.

Will other OSes generate UFO packets, FreeBSD, Windows? Anyone can 
provide such information?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC] testpmd: handle UFO packets
  2018-02-28 14:53   ` Tan, Jianfeng
@ 2018-03-01  8:36     ` Jason Wang
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Wang @ 2018-03-01  8:36 UTC (permalink / raw)
  To: Tan, Jianfeng, dev; +Cc: stephen, Bruce Richardson, Tiwei Bie



On 2018年02月28日 22:53, Tan, Jianfeng wrote:
> Hi Jason,
>
>
> On 2/28/2018 10:10 PM, Jason Wang wrote:
>>
>>
>> On 2018年02月24日 17:35, Jianfeng Tan wrote:
>>> Mostly likely, we will make UFO as a kind of GSO engine.
>>>
>>> For short term, we can just call APIs in librte_ip_frag to fragment.
>>>
>>> To test:
>>>
>>> 1. start testpmd with two vhost port.
>>>   $ set fwd csum
>>>   $ start
>>>
>>> 2. start vm0 connected to vhost0;
>>>   $ ifconfig xxx 1.1.1.1/24 up
>>>   $ ethtool -K xxx ufo on
>>>
>>> 3. start vm1 connected to vhost1;
>>>   $ ifconfig xxx 1.1.1.2/24 up
>>>   $ ethtool -K xxx ufo on
>>>   $ (Fill a large file named 1.txt)
>>>   $ cat 1.txt | socat - udp-sendto:1.1.1.1:5000
>>
>> Just a reminder, UFO was completely removed upstream.
>>
>
> Thank you for the information.
>
> Saw the deprecation patch at Linux v4.16-rc3, wonder what "version+" 
> counts "merden kernels" in "modern kernels will no longer generate UFO 
> skbs"? 

git describe d9d30adf56777c402c0027c0e6ae21f17cc0a365
v4.12-11055-gd9d30ad

So I think any Linux version beyond 4.12 won't generate any UFO packets.

> And this is mostly for stock VMs with old kernels to help the 
> migration from kernel vswitch to user space vswitch.
>

Yes, testpmd may still see UFO packets for old kernels. Just a reminder 
in case you miss it.

(Btw, we plan to support UDP tunnel offload for virtio-net.)

> Will other OSes generate UFO packets, FreeBSD, Windows? Anyone can 
> provide such information?

I don't know about them.

Thanks.

>
> Thanks,
> Jianfeng
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-03-01  8:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-24  9:35 [RFC] testpmd: handle UFO packets Jianfeng Tan
2018-02-28 14:10 ` Jason Wang
2018-02-28 14:53   ` Tan, Jianfeng
2018-03-01  8:36     ` Jason Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.