netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Ahern <dsahern@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>,
	Richard Gobert <richardbgobert@gmail.com>,
	davem@davemloft.net, yoshfuji@linux-ipv6.org, kuba@kernel.org,
	netdev@vger.kernel.org
Subject: Re: [PATCH] net: Fix IP_UNICAST_IF option behavior for connected sockets
Date: Wed, 6 Jul 2022 11:55:39 -0600	[thread overview]
Message-ID: <af40f817-e005-b7ee-9c10-c513fa36ac04@kernel.org> (raw)
In-Reply-To: <77c9a31ba08bcc472617c08c0542cd82f7959a58.camel@redhat.com>

On 7/6/22 10:21 AM, Paolo Abeni wrote:
> On Wed, 2022-07-06 at 09:14 -0600, David Ahern wrote:
>> On 6/27/22 2:52 AM, Richard Gobert wrote:
>>> The IP_UNICAST_IF socket option is used to set the outgoing interface for
>>> outbound packets.
>>> The IP_UNICAST_IF socket option was added as it was needed by the Wine
>>> project, since no other existing option (SO_BINDTODEVICE socket option,
>>> IP_PKTINFO socket option or the bind function) provided the needed
>>> characteristics needed by the IP_UNICAST_IF socket option. [1]
>>> The IP_UNICAST_IF socket option works well for unconnected sockets, that
>>> is, the interface specified by the IP_UNICAST_IF socket option is taken
>>> into consideration in the route lookup process when a packet is being
>>> sent.
>>> However, for connected sockets, the outbound interface is chosen when
>>> connecting the socket, and in the route lookup process which is done when
>>> a packet is being sent, the interface specified by the IP_UNICAST_IF
>>> socket option is being ignored.
>>>
>>> This inconsistent behavior was reported and discussed in an issue opened
>>> on systemd's GitHub project [2]. Also, a bug report was submitted in the
>>> kernel's bugzilla [3].
>>>
>>> To understand the problem in more detail, we can look at what happens
>>> for UDP packets over IPv4 (The same analysis was done separately in
>>> the referenced systemd issue).
>>> When a UDP packet is sent the udp_sendmsg function gets called and the
>>> following happens:
>>>
>>> 1. The oif member of the struct ipcm_cookie ipc (which stores the output
>>> interface of the packet) is initialized by the ipcm_init_sk function to
>>> inet->sk.sk_bound_dev_if (the device set by the SO_BINDTODEVICE socket
>>> option).
>>>
>>> 2. If the IP_PKTINFO socket option was set, the oif member gets overridden
>>> by the call to the ip_cmsg_send function.
>>>
>>> 3. If no output interface was selected yet, the interface specified by the
>>> IP_UNICAST_IF socket option is used.
>>>
>>> 4. If the socket is connected and no destination address is specified in
>>> the send function, the struct ipcm_cookie ipc is not taken into
>>> consideration and the cached route, that was calculated in the connect
>>> function is being used.
>>>
>>> Thus, for a connected socket, the IP_UNICAST_IF sockopt isn't taken into
>>> consideration.
>>>
>>> This patch corrects the behavior of the IP_UNICAST_IF socket option for
>>> connect()ed sockets by taking into consideration the IP_UNICAST_IF sockopt
>>> when connecting the socket.
>>>
>>> In order to avoid reconnecting the socket, this option is still ignored 
>>> when applied on an already connected socket until connect() is called
>>> again by the user.
>>>
>>> Change the __ip4_datagram_connect function, which is called during socket
>>> connection, to take into consideration the interface set by the
>>> IP_UNICAST_IF socket option, in a similar way to what is done in the
>>> udp_sendmsg function.
>>>
>>> [1] https://lore.kernel.org/netdev/1328685717.4736.4.camel@edumazet-laptop/T/
>>> [2] https://github.com/systemd/systemd/issues/11935#issuecomment-618691018
>>> [3] https://bugzilla.kernel.org/show_bug.cgi?id=210255
>>>
>>> Signed-off-by: Richard Gobert <richardbgobert@gmail.com>
>>> ---
>>>  net/ipv4/datagram.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>
>> Reviewed-by: David Ahern <dsahern@kernel.org>
>>
>> if the maintainers decide to pick it up.
> 
> I think your reasoning is correct, and I'm now ok with the patch. Jakub
> noted it does not apply cleanly, so a repost will be needed.
> Additionally it would be great to include some self-tests.

Agreed. nettest.c has '-S' option that sets IP_UNICAST_IF after the
socket() call and before connect() so it is already doing what is wanted
by this patch. Just need positive and negative test cases added to
tools/testing/selftests/net.


> 
> It looks like the feature (even the original one, I mean) is IPv4
> specific, don't you need an IPv6 counter-part?
> 
> Thanks!
> 
> Paolo
> 


  reply	other threads:[~2022-07-06 17:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-27  8:52 [PATCH] net: Fix IP_UNICAST_IF option behavior for connected sockets Richard Gobert
2022-06-28 13:08 ` Paolo Abeni
2022-07-05 15:50   ` Richard Gobert
2022-07-06 15:13     ` David Ahern
2022-07-06 15:14 ` David Ahern
2022-07-06 16:21   ` Paolo Abeni
2022-07-06 17:55     ` David Ahern [this message]
2022-07-13 12:45     ` Richard Gobert
2022-07-13 18:39       ` Jakub Kicinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=af40f817-e005-b7ee-9c10-c513fa36ac04@kernel.org \
    --to=dsahern@kernel.org \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=richardbgobert@gmail.com \
    --cc=yoshfuji@linux-ipv6.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).