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
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to