This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Ethernet stack sends empty fragment


Am 01.03.2010 13:50, schrieb Gary Thomas:
Please keep your replies on the mailing list so that all benefit.

On 03/01/2010 05:31 AM, Timo Gerber wrote:
Am 01.03.2010 13:19, schrieb Gary Thomas:
On 03/01/2010 03:27 AM, Timo Gerber wrote:
Hi guys,
I'm working on an ethernet driver with scather gather support and I am
wondering:
When sending UDP packets from the application with a higher
payload-size (e.g. 2500Bytesand more), the ethernet stack calls my
DRV_eth_send() function with a weird sg_list.
For instance, some packets are fragmented like this:
sg_list[1].len => 42
sg_list[1].buf => points to the hdr.

sg_list[2].len => 1472
sg_list[2].buf => points to the payload.

sg_list[3].len => 0
sg_list[3].buf => points to an empty buffer.

As you can see the last sg fragment is kinda weird, but this scheme
appears all the time, not only now an then.

What's the MTU on that interface?


Its a standard ethernet interface with an MTU of 1514

Which matches the request (42+1472==1514). The upper layer which creates the SG list must be messing up when this happens.

Which stack (BSD, LWIP) are you using? I don't see how this
is possible with the BSD layer as it only counts segments which
have a non-zero length.

This is exactly I am wondering about. I'm using the FreeBSD stack, TCP runs just fine. But when the application tries to send an UDP packet larger it looses a fragment. At the moment my driver discards the whole ethernet-frame when it discovers a sg_list.len with size 0.


I just found out the the limit is 2048 Bytes. That means, udp packest with size <= 2048 are fine.

This is my small application code to test the udp interface:

static int udptest(void)
{
#define DEST_IP "192.168.222.100"
#define PORT 5555
#define NPACK 4
#define BUFLEN (2049)
	const int nBytes = BUFLEN * NPACK;
	struct sockaddr_in dest_host;
	int s, i;
	int slen = sizeof(dest_host);
	char buf[BUFLEN];

cyg_tick_count_t tv1, tv2;

	if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1){
		TST_PRINTF("socket error\n");
	}

memset(buf, 0, BUFLEN);

memset((char *) &dest_host, 0, sizeof(dest_host));
dest_host.sin_len = sizeof(struct sockaddr_in);
dest_host.sin_family = AF_INET;
dest_host.sin_port = htons(PORT);
if (inet_aton(DEST_IP, &dest_host.sin_addr) == 0) {
TST_PRINTF("inet_aton() failed\n");
return -1;
}
TST_PRINTF("Sending %d packets (%d kBytes)\n", NPACK, nBytes/1000);
tv1 = cyg_current_time();
for (i = 0; i < NPACK; i++)
{
//TST_PRINTF("Sending packet %d\n", i);
snprintf(buf, BUFLEN, "This is packet %d\n", i);
int ret = sendto(s, buf, BUFLEN, 0, (struct sockaddr *) &dest_host, slen );
if( ret == -1)
{
TST_PRINTF("sendto() error(%d)", errno);
TST_PRINTF("%s)", strerror(errno));
}
}
tv2 = cyg_current_time();
TST_PRINTF("Dauer: %llu ms\n", (tv2-tv1)*1000UL/TICKS_PER_SECOND);
TST_PRINTF("Durchsatz: %llu kByte/s\n", (((nBytes)) / ((tv2-tv1)*1000UL/TICKS_PER_SECOND)));
close(s);


	return 0;
}



--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]