Re: [EVL] Client UDP not receiving data

Hannes Diethelm <[email protected]>
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
Am 22.05.26 um 17:40 schrieb Philippe Gerum:
> Hannes Diethelm <[email protected]> writes:
> 
>>
>> Thanks for the detailed answer. I might have been not precise enough.
>>
>> The -S and the -R mode work as designed. To show the issue with connect() in evl, I changed
>> the -S mode to:
>> connect()
>> while{
>>    oob_sendmsg()
>>    oob_recvmsg()
>> }
>>
>> This is the classical UDP client pattern. It works with vanilla linux (net-udp.c)
>> but not with evl (oob-net-udp.c), I do not receive any data.
>>
>> By just sending the modified code, it is easy to explain and hopefully for you to
>> reproduce. This is also why I attached the files instead of sending a patch.
>> Be aware that this is just to demonstrate what is not working, not intended as a patch.
>>
>> I run Xenomai4 in a VM and communicate with the host for debugging
>> but I have also a real PC as the final target where I have the same issues.
>>
>> First start on the host:
>> echo Hello | nc -u -l 5201
>>
>> Then in the VM:
>> sudo evl net -ei enp7s0
>> sudo oob-net-udp -d -i enp7s0 -a 192.168.122.1 -p 5201 -S
>>
>> On the host:
>> Mellow sword!
>>
>> In the VM:
>> == bound to enp7s0
>> == sender mode (=> 192.168.122.1:5201)
>> --------tx--------
>> IP-Adresse: 192.168.122.1
>> Port:       5201
>> Family:     512
>> --------rx--------
>> IP-Adresse: 192.168.122.155
>> Port:       58422
>> Family:     512
>>
>> The package is visible in wireshark but oob_recvmsg does not return:
>> No "= 6 bytes received: Hello" and no second transmit.
> 
> Ok, I totally misinterpreted your previous post, sorry for
> that. Brain received -ENOCOFFEE.
> 
>>
>> It looks like the auto assigned and bound port from connect() is not forwarded
>> to the oob stage, so no data is received in oob_recvmsg().
>>
> 
> This is exactly the point, indeed. Could you please try this branch [1]?
> The two commits on top improve the situation with your test code here.
Thanks for the very fast fix. Connect works now as expected. And I was able to remove the workaround.

I switched to libevl r58, r57 did not work any more. Is there any visible link libevl->kernel? I just
got an operation not permitted in oob_sleep_until.

But there are two new issues:

-oob_sendmsg returns "Invalid argument" errno 22 exactly every second. The last number is the
system time in ns.
ERROR: oob_sendmsg Invalid argument 22 806999652287
ERROR: oob_sendmsg Invalid argument 22 807999655503
ERROR: oob_sendmsg Invalid argument 22 808999650416

I have this with the exact same code as before using bind() and also with the now working connect().
There are 3000 tx / 1000 rx packages/s.

I tried do{oob_sendmsg}while(errno == 22) but that resulted in a full freeze of the PC.

-The last commit a4cc7967 on the next branch doesn't compile. Just FYI, I took one commit before, so I was able to test it.

Error:
In file included from ./include/evl/sched.h:14,
                  from ./include/evl/lock.h:9,
                  from ./include/asm-generic/evl/net.h:8,
                  from ./arch/x86/include/dovetail/net.h:6,
                  from ./include/net/net_namespace.h:41,
                  from ./include/linux/netdevice.h:38,
                  from ./include/net/sock.h:46,
                  from mm/memcontrol.c:67:
./include/evl/thread.h: In function ‘evl_unblock_kthread’:
./include/evl/thread.h:415:9: error: implicit declaration of function ‘evl_schedule’; did you mean ‘io_schedule’? [-Wimplicit-function-declaration]
   415 |         evl_schedule();
       |         ^~~~~~~~~~~~
       |         io_schedule
./include/evl/sched.h: At top level:
./include/evl/sched.h:290:20: warning: conflicting types for ‘evl_schedule’; have ‘void(void)’
   290 | static inline void evl_schedule(void)
       |                    ^~~~~~~~~~~~
./include/evl/sched.h:290:20: error: static declaration of ‘evl_schedule’ follows non-static declaration
./include/evl/thread.h:415:9: note: previous implicit declaration of ‘evl_schedule’ with type ‘void(void)’
   415 |         evl_schedule();
       |         ^~~~~~~~~~~~

> 
>>
>> But might be evl was never intended to work using connect() in classical UDP client style?
>>
> 
> IMO, the evl netstack (and evl in general) should follow the POLA
> principle as closely as possible, and any UDP user can reasonably expect
> auto-binding to be handled. So this needs fixing.
> 
>>
>> If you think this this example is useful, I can finalize it (for now with the bind() workaround) and also add a server mode.
>> So there would be 4 modes in total. With a server mode, you can run the server on one host, the client on the other and continuously
>> send data forward / backward and measure delays. I would use:
>> -T send (previously it was -S but then I have nothing for server)
>> -R receive
>> -S server: Waits for data and sends a response for each received package.
>> -C client: Sends data and measures how long it takes for the server to response.
>>
>> As an alternative, I could just create a second example oob-net-udp-server-client.c. This would result in a bit of duplicated code but not to much.
>>
>> What do you prefer?
> 
> It is definitely useful. I would go for option #1, i.e. integrated
> send/recv/server/client example. First because all the boilerplate and
> ancillary support for parsing options and setting up connections is
> already there and the code running the client scenario to be added is
> likely small enough.
> 
> Next because the I'd rather have a 'client' mode measuring round-trip
> times explicitly in the context of some example code, rather than
> letting people think that we would actually provide a 'ping' command
> that way. Reason is about performance: the standard in-band ICMP server
> is operated from kernel context; although the latency would bite
> compared to any oob-based server under high load, on average the figures
> obtained on an idle system would be somewhat misleading compared to the
> oob server in application space, because reinstating a userland context
> for handling ICMP requests may be more time-consuming than handling it
> directly as close as possible from the packet delivery point in kernel
> space, i.e. without entailing any context switching to userland (even to
> an oob thread).
> 
Ok, I will finalize this and send a patch.

>>
>> I also created oob-net-ping in the same style as oob-net-icmp but this sends out a ping, receives the response
>> and measures the delay, similar as the ping command:
>> ./oob-net-ping -i enp7s0 -a 192.168.122.1
>> [0] count=98, proto=0x800, ifindex=3, type=0, halen=6, mac=52:54:00:6b:05:f1 rtt=317.1us
>> [1] count=98, proto=0x800, ifindex=3, type=0, halen=6, mac=52:54:00:6b:05:f1 rtt=218.5us
>> [2] count=98, proto=0x800, ifindex=3, type=0, halen=6, mac=52:54:00:6b:05:f1 rtt=252.5us
>> [3] count=98, proto=0x800, ifindex=3, type=0, halen=6, mac=52:54:00:6b:05:f1 rtt=320.1us
>> It has to be cleaned it up a bit and integrated it into the libevl repo but then I will also send a patch.
>>
> 
> I think we need a simple agent somewhere in the evl netstack in kernel
> space answering ICMP_ECHO requests flowing in oob channels directly,
> just like the in-band stack does for in-band traffic. I can look into
> this.
The oob-net-ping sends out pings, so basically the inverse of the existing oob-net-icmp. Now you can run
oob-net-ping on one machine and oob-net-icmp on the other to ping between. For my application, I use it to ping an FPGA
board to see if the connection basically works.

ICMP_ECHO would help in some cases, but ^ works also.

> 
> PS: thanks for the test code you provided, it saved a lot of time on my
> end.
You are welcome, I had to create it anyway to understand what was going wrong. Thanks for the easy to understand example
code, helped me a lot to create the test code.

> 
> [1] https://gitlab.com/Xenomai/xenomai4/linux-evl/-/tree/next/v6.12.y-cip-evl-rebase?ref_type=heads
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.