From: David Howells <dhowells@redhat.com> Date: 2014-02-14 14:36:51
Am I reading the ipv4 code right? If a UDP packet we send results in an
ICMP_FRAG_NEEDED packet being received, the cached routing information for the
peer will automatically be updated by __udp4_lib_err()?
And something similar in __udp6_lib_err()?
David
From: Hannes Frederic Sowa <hidden> Date: 2014-02-14 14:44:13
Hi!
On Fri, Feb 14, 2014 at 02:36:48PM +0000, David Howells wrote:
Am I reading the ipv4 code right? If a UDP packet we send results in an
ICMP_FRAG_NEEDED packet being received, the cached routing information for the
peer will automatically be updated by __udp4_lib_err()?
A next hop exception will be generated (or reused) which stores the path
mtu towards that target, yes (there is no more routing cache).
Prior to that a validation check happens if the socket really exists (this is
e.g. needed to identify the namespace or routing table the update should occur
on).
From: David Howells <dhowells@redhat.com> Date: 2014-02-14 15:00:48
Hannes Frederic Sowa [off-list ref] wrote:
On Fri, Feb 14, 2014 at 02:36:48PM +0000, David Howells wrote:
quoted
Am I reading the ipv4 code right? If a UDP packet we send results in an
ICMP_FRAG_NEEDED packet being received, the cached routing information for
the peer will automatically be updated by __udp4_lib_err()?
A next hop exception will be generated (or reused) which stores the path
mtu towards that target, yes (there is no more routing cache).
Prior to that a validation check happens if the socket really exists (this is
e.g. needed to identify the namespace or routing table the update should occur
on).
Sounds good. Does this work even if the socket is not connected (ie. the UDP
packets are being routed by the address fields in struct msghdr)?
David
From: Hannes Frederic Sowa <hidden> Date: 2014-02-14 15:03:29
On Fri, Feb 14, 2014 at 03:00:42PM +0000, David Howells wrote:
Hannes Frederic Sowa [off-list ref] wrote:
quoted
On Fri, Feb 14, 2014 at 02:36:48PM +0000, David Howells wrote:
quoted
Am I reading the ipv4 code right? If a UDP packet we send results in an
ICMP_FRAG_NEEDED packet being received, the cached routing information for
the peer will automatically be updated by __udp4_lib_err()?
A next hop exception will be generated (or reused) which stores the path
mtu towards that target, yes (there is no more routing cache).
Prior to that a validation check happens if the socket really exists (this is
e.g. needed to identify the namespace or routing table the update should occur
on).
Sounds good. Does this work even if the socket is not connected (ie. the UDP
packets are being routed by the address fields in struct msghdr)?
Yes, but connected sockets are checked prior to unconnected sockets, so the
most specific one wins.
For unconnected ones only the local ip/port is checked because kernel
does not know the past destination addresses.
Greetings,
Hannes
From: David Howells <dhowells@redhat.com> Date: 2014-02-14 15:42:57
Hannes Frederic Sowa [off-list ref] wrote:
Yes, but connected sockets are checked prior to unconnected sockets, so the
most specific one wins.
For unconnected ones only the local ip/port is checked because kernel
does not know the past destination addresses.
From: David Howells <dhowells@redhat.com> Date: 2014-02-14 15:49:21
One further question: If I want to get the MTU size of the NIC through which
packets will go to get to a particular peer, can I do:
struct rtable *rt;
struct flowi4 fl4;
unsigned if_mtu;
rt = ip_route_output_ports(&init_net, &fl4, NULL,
peer->srx.transport.sin.sin_addr.s_addr, 0,
htons(7000), htons(7001),
IPPROTO_UDP, 0, 0);
if_mtu = rt->dst->dev->mtu;
dst_release(&rt->dst);
Or might this go wrong if rt->dst->dev changes under me? Can it change
without replacing the dst record?
David
From: Hannes Frederic Sowa <hidden> Date: 2014-02-14 16:52:23
On Fri, Feb 14, 2014 at 03:49:17PM +0000, David Howells wrote:
One further question: If I want to get the MTU size of the NIC through which
packets will go to get to a particular peer, can I do:
struct rtable *rt;
struct flowi4 fl4;
unsigned if_mtu;
rt = ip_route_output_ports(&init_net, &fl4, NULL,
peer->srx.transport.sin.sin_addr.s_addr, 0,
htons(7000), htons(7001),
IPPROTO_UDP, 0, 0);
if_mtu = rt->dst->dev->mtu;
dst_release(&rt->dst);
Or might this go wrong if rt->dst->dev changes under me? Can it change
without replacing the dst record?
If it is a one-shot query this is fine. If you store the dst somewhere you need
to check dst->obsolete flags and redo the lookup if it is > 0. ->dev pointer
won't change for a created dst.
Bye,
Hannes
From: David Miller <davem@davemloft.net> Date: 2014-02-17 05:21:55
From: David Howells <dhowells@redhat.com>
Date: Fri, 14 Feb 2014 15:49:17 +0000
One further question: If I want to get the MTU size of the NIC through which
packets will go to get to a particular peer, can I do:
As has been suggested or at least hinted to by others, you have to use
the route dst's device pointer.
Practically speaking, this means you'll have to cache the route, just
like we do in ipv4 sockets. And on each packet send 1) validate the
route and relookup if it's become obsolute 2) dereference the dst->dev
to get the mtu.
This is because routes can change dynamically as can the physical
device's MTU setting, you'll therefore have to evaluate everything
on every packet send.
From: David Howells <dhowells@redhat.com> Date: 2014-02-20 18:07:34
David Miller [off-list ref] wrote:
quoted
One further question: If I want to get the MTU size of the NIC through
which packets will go to get to a particular peer, can I do:
As has been suggested or at least hinted to by others, you have to use
the route dst's device pointer.
So I gather. My query was intended to be about the safety of accessing the
dst->dev pointer. Can I just dereference it? Or do I need to take a lock or
use RCU?
David
From: Hannes Frederic Sowa <hidden> Date: 2014-02-20 18:12:53
On Thu, Feb 20, 2014 at 05:30:23PM +0000, David Howells wrote:
David Miller [off-list ref] wrote:
quoted
quoted
One further question: If I want to get the MTU size of the NIC through
which packets will go to get to a particular peer, can I do:
As has been suggested or at least hinted to by others, you have to use
the route dst's device pointer.
So I gather. My query was intended to be about the safety of accessing the
dst->dev pointer. Can I just dereference it? Or do I need to take a lock or
use RCU?
No, you can just dereference it. dst holds a reference on ->dev, so it
is safe without lock or rcu as long as dst is alive and referenced.
Greetings,
Hannes
From: David Miller <davem@davemloft.net> Date: 2014-02-20 18:45:06
From: David Howells <dhowells@redhat.com>
Date: Thu, 20 Feb 2014 17:30:23 +0000
David Miller [off-list ref] wrote:
quoted
quoted
One further question: If I want to get the MTU size of the NIC through
which packets will go to get to a particular peer, can I do:
As has been suggested or at least hinted to by others, you have to use
the route dst's device pointer.
So I gather. My query was intended to be about the safety of accessing the
dst->dev pointer. Can I just dereference it? Or do I need to take a lock or
use RCU?
If the dst is valid and you have a reference to it, dst->dev is good.