On 2018-06-21 15:41, Jan Kiszka wrote:
> On 2018-06-21 13:55, Jan Kiszka wrote:
>> On 2018-06-21 13:20, Pintu Kumar wrote:
>>> Dear Jan, Greg,
>>>
>>> Is there any pointer about this issue?
>>> This is blocking my next work..
>>
>> Does this solve the issue AND still generate valid UDP checksums (please
>> check with wireshark or against a normal networking stack?
>>
>> diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c
>> b/kernel/drivers/net/stack/ipv4/udp/udp.c
>> index 8e80d3e0b..bb0b0fc12 100644
>> --- a/kernel/drivers/net/stack/ipv4/udp/udp.c
>> +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
>> @@ -556,18 +556,17 @@ static int rt_udp_getfrag(const void *p, unsigned char
>> *to,
>> if (offset)
>> return rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen, to,
>> fraglen);
>>
>> - /* Checksum of the complete data part of the UDP message: */
>> - for (i = 0; i < ufh->iovlen; i++) {
>> - ufh->wcheck = csum_partial(ufh->iov[i].iov_base,
>> ufh->iov[i].iov_len,
>> - ufh->wcheck);
>> - }
>> -
>> ret = rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen,
>> to + sizeof(struct udphdr),
>> fraglen - sizeof(struct udphdr));
>> if (ret)
>> return ret;
>>
>> + /* Checksum of the complete data part of the UDP message: */
>> + ufh->wcheck = csum_partial(to + sizeof(struct udphdr),
>> + fraglen - sizeof(struct udphdr),
>> + ufh->wcheck);
>> +
>> /* Checksum of the udp header: */
>> ufh->wcheck = csum_partial((unsigned char *)ufh,
>> sizeof(struct udphdr), ufh->wcheck);
>>
>
> This was definitely wrong. Here is another try:
>
> diff --git a/kernel/drivers/net/stack/ipv4/udp/udp.c
> b/kernel/drivers/net/stack/ipv4/udp/udp.c
> index 8e80d3e0b..6cf1d369e 100644
> --- a/kernel/drivers/net/stack/ipv4/udp/udp.c
> +++ b/kernel/drivers/net/stack/ipv4/udp/udp.c
> @@ -549,6 +549,7 @@ static int rt_udp_getfrag(const void *p, unsigned char
> *to,
> unsigned int offset, unsigned int fraglen)
> {
> struct udpfakehdr *ufh = (struct udpfakehdr *)p;
> + unsigned int datalen = 0;
> int i, ret;
>
>
> @@ -556,18 +557,18 @@ static int rt_udp_getfrag(const void *p, unsigned char
> *to,
> if (offset)
> return rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen, to,
> fraglen);
>
> - /* Checksum of the complete data part of the UDP message: */
> - for (i = 0; i < ufh->iovlen; i++) {
> - ufh->wcheck = csum_partial(ufh->iov[i].iov_base,
> ufh->iov[i].iov_len,
> - ufh->wcheck);
> - }
> -
> ret = rtnet_read_from_iov(ufh->fd, ufh->iov, ufh->iovlen,
> to + sizeof(struct udphdr),
> fraglen - sizeof(struct udphdr));
> if (ret)
> return ret;
>
> + /* Checksum of the complete data part of the UDP message: */
> + for (i = 0; i < ufh->iovlen; i++)
> + datalen += ufh->iov[i].iov_len;
> + ufh->wcheck = csum_partial(to + sizeof(struct udphdr), datalen,
> + ufh->wcheck);
> +
> /* Checksum of the udp header: */
> ufh->wcheck = csum_partial((unsigned char *)ufh,
> sizeof(struct udphdr), ufh->wcheck);
>
OK, this won't work either if fraglen < datalen. We have to rework this
more fundamentally.
As a workaround, run the kernel with nosmap.
Jan
_______________________________________________
Xenomai mailing list
[email protected]
https://xenomai.org/mailman/listinfo/xenomai