Re: [PATCH 1/1] tidbits: net-udp: solicit new client for server mode

Philippe Gerum <[email protected]> Mon, 27 Jul 2026 10:36:55 +0200
Newsgroups dev.linux.lists.xenomai
Message-ID <[email protected]>
Hannes Diethelm <[email protected]> writes:

> Am 23.07.26 um 09:47 schrieb Philippe Gerum:
>> Hannes Diethelm <[email protected]> writes:
>>=20
>>> Am 22.07.26 um 20:36 schrieb Philippe Gerum:
>>>> Philippe Gerum <[email protected]> writes:
>>>>
>>>>> Hannes Diethelm <[email protected]> writes:
>>>>>
>>>>>> Am 22.07.26 um 00:36 schrieb Hannes Diethelm:
>>>>>>> Am 21.07.26 um 22:15 schrieb Philippe Gerum:
>>>>>>>> Hannes Diethelm <[email protected]> writes:
>>>>>>>>
>>>>>>>>> Am 20.07.26 um 16:27 schrieb Philippe Gerum:
>>>>>>>>>
>>>>>>>>> An option would be either to support of oob_ioctl() for
>>>>>>>>> SIOCGARP. Or create something like
>>>>>>>>> evl_net_routeinfo(s, addr) returning flags would make probing obs=
olete.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Not entirely. The issue with solely having SIOCGARP or any probe-o=
nly
>>>>>>>> explicit request is that you would have to pair two syscalls at ea=
ch
>>>>>>>> transmit at least, one to probe for the sender address before poss=
ibly
>>>>>>>> soliciting that peer if absent from the oob cache, another one for
>>>>>>>> sending the message eventually. i.e., for every packet:
>>>>>>>>
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0 ioctl(SIOCGARP)
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 !ATF_COM?=
 -> evl_net_solicit()
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0 oob_sendmsg(..., 0)
>>>>>>> You are right, that is an unneeded syscall as long as you don't keep
>>>>>>> a
>>>>>>> list of clients as before. This can remove the need from calling
>>>>>>> evl_net_solicit() in the case the client is already in ARP and
>>>>>>> permanent but
>>>>>>> this will be the only change and won't help that much.
>>>>>>>
>>>>>>>>
>>>>>>>> OTOH, with the latest attempt to address this issue, we can send a
>>>>>>>> probe-only request by passing MSG_PROBE (EHOSTUNREACH), or a reque=
st
>>>>>>>> that does not attempt to defer transmit to the inband stage on pro=
be
>>>>>>>> failure by passing MSG_DONTWAIT (EWOULDBLOCK). i.e., for every pac=
ket
>>>>>>>>
>>>>>>>> redo:
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0 oob_sendmsg(..., MSG_DONTWAIT)
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EWOULDBLO=
CK?
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 oob_sendmsg(..., MSG_PROBE)
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 EHOSTUNREACH?
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 evl_n=
et_solicit()
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 goto =
redo
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 otherwise assume ENOMEM
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 otherwise=
 all done
>>>>>>>>
>>>>>>>> IOW, using a proper combination of MSG_DONTWAIT and MSG_PROBE in t=
he
>>>>>>>> right sequence would either succeed to send the packet immediately=
 on
>>>>>>>> the first oob_sendmsg() call, otherwise fail on memory shortage or
>>>>>>>> missing route from the oob cache. In the latter case, which could =
only
>>>>>>>> happen once for each new peer under normal circumstances, we could
>>>>>>>> disambiguate the EWOULDBLOCK status using an explicit probe.
>>>>>>>>
>>>>>>>> A better way to do this in a single step unambiguously would requi=
re the
>>>>>>>> addition of another operation flag, like MSG_DONTDEFER, preventing=
 the
>>>>>>>> deferral to inband on failed probe and causing oob_sendmsg() to re=
turn
>>>>>>>> with a specific error code. e.g. something as simple as the follow=
ing
>>>>>>>> would cover all requirements:
>>>>>>>>
>>>>>>>>   =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 oob_sendmsg(..., MSG_DONTDEFER) -=
> EADDRNOTAVAIL on failed probe.
>>>>>>>>
>>>>>>>> Now, we might also piggyback off of MSG_OOB instead of defining yet
>>>>>>>> another operation flag, as a way to say "oob only, don't relay to
>>>>>>>> inband", but I'm still pondering whether this would be nicely witt=
y or
>>>>>>>> utterly confusing..
>>>>>>>>
>>>>>>> Yes, this is a variant. I was not aware that MSG_DONTWAIT ->
>>>>>>> EWOULDBLOCK
>>>>>>> can also mean ENOMEM.
>>>>>>> Now after considering all options, i start to prefer the variant
>>>>>>> before
>>>>>>> this patch, keeping a list of already solicit'ed clients. It is str=
aight
>>>>>>> forward, simple and fast. And you know exactly when to expect an in=
 band
>>>>>>> call. Might be we should just drop this patch instead of adding unn=
ecessary
>>>>>>> complexity for example code?
>>>>>>
>>>>>> BTW: With drop this patch I don't mean the one already in but this o=
ne:
>>>>>> [PATCH] tidbits: net-udp: use MSG_DONTWAIT for server mode
>>>>>> https://lore.kernel.org/xenomai/20260717192541.15829-1-hannes.diethe=
[email protected]/T/#u
>>>>>>
>>>>>
>>>>> Got it, it may be worth waiting for the dust to settle in the core
>>>>> regarding the probing issue before adapting this tidbit anyway. I'm
>>>>> going to consolidate the points we have discussed so far, in order to
>>>>> come up with an implementation that satisfies all the requirements.
>>>> Here is a new proposal that should cover all the cases we discussed
>>>> so
>>>> far (next/v6.12.y-cip-evl-rebase branch). A new flag is introduced,
>>>> namely MSG_STEADY, which tells the core to only accept cache lookups
>>>> that deliver permanent ARP records. This flag can be combined with
>>>> MSG_PROBE and MSG_DONTWAIT for extended semantics. Meanwhile, a
>>>> zero-sized message is still accepted in order to request a mere address
>>>> probe without having to pass any meaningful data. This goes like this:
>>>> Function: probe-only
>>>> 	      oob_sendmsg(s, &msghdr, NULL, MSG_PROBE)
>>>> 	          -> EADDRNOTAVAIL if no peer address found
>>>> Function: probe-only, permanent peer address required
>>>>     	      oob_sendmsg(s, &msghdr, NULL, MSG_PROBE|MSG_STEADY)
>>>> 	          -> EADDRNOTAVAIL if no permanent peer address found
>>>>                        (also upon match of aging ARP record)
>>>> Function: send, no deferral (to inband) allowed
>>>> 	      oob_sendmsg(s, &msghdr, NULL, MSG_DONTWAIT)
>>>> 	          -> EADDRNOTAVAIL if no peer address found
>>>> 	          -> EWOULDBLOCK on memory shortage
>>>> Function: send, no deferral (to inband) allowed, permanent peer
>>>> address required
>>>> 	      oob_sendmsg(s, &msghdr, NULL, MSG_DONTWAIT|MSG_STEADY)
>>>> 	          -> EADDRNOTAVAIL if no permanent peer address found
>>>>                        (also upon match of aging ARP record)
>>>> 	          -> EWOULDBLOCK on memory shortage
>>>> Function: send, permanent peer address required
>>>> 	      oob_sendmsg(s, &msghdr, NULL, MSG_STEADY)
>>>> 	          -> EADDRNOTAVAIL if no permanent peer address found
>>>>                        (also upon match of aging ARP record)
>>>>
>>>
>>> Looks promising. This also means after
>>> oob_sendmsg(..., MSG_DONTWAIT|MSG_STEADY)
>>> no second call oob_sendmsg(..., MSG_PROBE) is needed to handle
>>> -ENOMEM right?
>> Correct.
>>=20
>>>
>>> oob_sendmsg(s, &msghdr, NULL, 0) is the only case with deferral to inba=
nd
>>> as it looks in udp.c:421...423?
>>> if (ret !=3D -EADDRNOTAVAIL ||
>>> 	msg_flags & (MSG_PROBE|MSG_DONTWAIT|MSG_STEADY))
>>> 		return ret;
>>>
>>>
>> Open question: does it still make sense to have MSG_DONTWAIT prevent
>> the
>> deferral to the inband stage, now that MSG_STEADY can be used for this?
>> i.e.:
>>=20
>>>> Function: send, no deferral (to inband) allowed
>>>> 	      oob_sendmsg(s, &msghdr, NULL, MSG_DONTWAIT)
>>>> 	          -> EADDRNOTAVAIL if no peer address found
>>>> 	          -> EWOULDBLOCK on memory shortage
>> Not considering MSG_DONTWAIT (alone) anymore as a way to prevent
>> deferral would make MSG_STEADY the only option for this, tightening the
>> requirement from "any cached destination address" to "permanent
>> destination address". This being said:
>> - If $user wants a sure shot wrt to oob transmission, then a
>> permanent
>>    address is most likely desired, in which case MSG_STEADY should be
>>    given. Otherwise, what would be the point of sending to a peer using
>>    an aging ARP record _and_ being concerned about timeliness and
>>    deterministic behavior in general (therefore denying deferral)?
>> - As it is, the implementation somewhat abuses the dont-wait
>>    semantics. As a matter of fact, inband deferral won't make the caller
>>    wait at all, only the packet will be delayed until the regular
>>    netstack picks it. Meanwhile, EWOULDBLOCK is conventionally paired
>>    with MSG_DONTWAIT, not EADDRNOTAVAIL.
>>=20
>
> MSG_DONTWAIT denying inband was only introduced in 644d55e78e8e, right?
>

Yes, this can still be considered as a tentative, undocumented so far.

> In this case I agree. Either you'd like to stay out of band now and in
> the future -> MSG_STEADY or you don't care -> 0.
>
> Otherwise, it might break already existing applications.

--=20
Philippe.