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 >