public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH/RFC] net: defragment IP packets
@ 2009-07-24  8:04 Alessandro Rubini
  2009-07-25 22:09 ` Robin Getz
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Alessandro Rubini @ 2009-07-24  8:04 UTC (permalink / raw)
  To: u-boot

This patch add a quick and dirty defrag step in IP reception. This
allows to increase the TFTP block size and get more performance in
slow links (but at that point it should be made configurable).

The overhead is negligible, verified with an ARM9 CPU and 10MB data
file, changing the server MTU from 1500 to 800 and then 550.  However,
on a LAN connection, I didn't see advantes with using a 4k block
size with default MTU.

Signed-off-by: Alessandro Rubini <rubini@gnudd.com>
---

This patch is over mainline, without the (much appreciated) cleanup
patch that reached the list these days.

 net/net.c |   46 ++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/net/net.c b/net/net.c
index 641c37c..5034a2e 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1117,6 +1117,46 @@ static void CDPStart(void)
 }
 #endif
 
+/* This only reassembles fragments that come in proper order */
+static inline IP_t *NetDefragment(IP_t *ip, int *lenp)
+{
+	static uchar pkt_buff[16384]; /*temporary arbitrary limit */
+	static int next_fragment;
+	static ushort pkt_id;
+
+	#define IPSZ 20
+	uchar *pkt = (uchar *)ip;
+	ushort ip_off;
+	int offset, len = *lenp -2;
+
+	ip_off = ntohs(ip->ip_off);
+	if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
+		return ip;
+
+	offset = (ip_off & IP_OFFS) * 8;
+	if (!offset) { /* new packet begins, discard any we might have */
+		pkt_id = ip->ip_id;
+		memcpy(pkt_buff, ip, len);
+		next_fragment = len;
+		return NULL;
+	}
+
+	/* further fragment: discard IP header */
+	offset += IPSZ;	len -= IPSZ; pkt += IPSZ;
+
+	if (ip->ip_id != pkt_id || offset != next_fragment)
+		return NULL; /* out of order */
+
+	/* further fragment: skip ip header (we miss offset_of...) */
+	memcpy(pkt_buff + next_fragment, pkt, len);
+	next_fragment += len;
+
+	if (ip_off & IP_FLAGS_MFRAG)
+		return NULL; /* more expected */
+
+	*lenp = next_fragment;
+	return (IP_t *)pkt_buff;
+}
 
 void
 NetReceive(volatile uchar * inpkt, int len)
@@ -1360,6 +1400,8 @@ NetReceive(volatile uchar * inpkt, int len)
 		break;
 
 	case PROT_IP:
+		if (!(ip = NetDefragment(ip, &len)))
+			return;
 #ifdef ET_DEBUG
 		puts ("Got IP\n");
 #endif
@@ -1378,10 +1420,6 @@ NetReceive(volatile uchar * inpkt, int len)
 		if ((ip->ip_hl_v & 0xf0) != 0x40) {
 			return;
 		}
-		/* Can't deal with fragments */
-		if (ip->ip_off & htons(IP_OFFS | IP_FLAGS_MFRAG)) {
-			return;
-		}
 		/* can't deal with headers > 20 bytes */
 		if ((ip->ip_hl_v & 0x0f) > 0x05) {
 			return;
-- 
1.6.0.2

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

end of thread, other threads:[~2009-07-27 12:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-24  8:04 [U-Boot] [PATCH/RFC] net: defragment IP packets Alessandro Rubini
2009-07-25 22:09 ` Robin Getz
2009-07-26  2:02   ` Jerry Van Baren
2009-07-26  4:44     ` Robin Getz
2009-07-26 20:23       ` Alessandro Rubini
2009-07-27  0:19         ` Robin Getz
2009-07-27  5:08         ` Ben Warren
2009-07-27 11:46           ` Robin Getz
2009-07-27  0:59 ` Robin Getz
2009-07-27 12:13   ` Alessandro Rubini
2009-07-27 12:52     ` Robin Getz
2009-07-27 12:41   ` Wolfgang Denk
2009-07-27 12:50     ` Robin Getz
2009-07-27 11:41 ` Robin Getz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox