* [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs
@ 2025-11-14 14:29 Jakub Głogowski
2025-11-14 14:29 ` [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction Jakub Głogowski
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Jakub Głogowski @ 2025-11-14 14:29 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: Jakub Głogowski, linux-man, LKML, Linux API, ej
I found the PKTINFO docs pretty confusing, so I tried clarifying them:
- being more specific about each field in the struct
(e.g. "local address of the packet" for a received packet could've
been interpreted in myriad ways),
- making the differences between sendmsg(2)'s and recvmsg(2)'s handling
of that struct more explicit,
- and some other slight rewording to make it (IMO) more readable - I cut
out most of a paragraph that wasn't really saying anything, etc.
I'm not sure if this should even be documented in ip(7) together with
the other sockopts, though? sendmsg(2)'s handling of in_pktinfo is
completely unrelated to the IP_PKTINFO sockopt. Documenting it in its
own manual page would also give us more room for subsection headings and
other formatting, examples, etc - instead of trying to cram it into
what's already an enormous manpage.
Same goes for some of the other more complex sockopts, I guess.
PS. sorry for not signing this email, but neomutt didn't want to
cooperate :/ I'll try to figure it out for any followup patches.
Jakub Głogowski (2):
man/man7/ip.7: Clarify PKTINFO's semantics depending on packet
direction
man/man7/ip.7: Reword IP_PKTINFO's description
man/man7/ip.7 | 57 +++++++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 27 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction
2025-11-14 14:29 [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Jakub Głogowski
@ 2025-11-14 14:29 ` Jakub Głogowski
2025-11-18 14:31 ` Alejandro Colomar
2025-11-14 14:29 ` [PATCH 2/2] man/man7/ip.7: Reword IP_PKTINFO's description Jakub Głogowski
2025-11-18 13:51 ` [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Alejandro Colomar
2 siblings, 1 reply; 5+ messages in thread
From: Jakub Głogowski @ 2025-11-14 14:29 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: Jakub Głogowski, linux-man, LKML, Linux API, ej
For recvmsg(2), ipi_spec_dst is set by ipv4_pktinfo_prepare() to the
result of fib_compute_sec_dst(). The latter was introduced in
linux.git 35ebf65e851c6d97 ("ipv4: Create and use fib_compute_spec_dst() helper.").
Quoting its commit message:
> The specific destination is the host we direct unicast replies to.
> Usually this is the original packet source address, but if we are
> responding to a multicast or broadcast packet we have to use something
> different.
>
> Specifically we must use the source address we would use if we were to
> send a packet to the unicast source of the original packet.
Experimentation seems to confirm that behavior.
As for the note about ipi_spec_dst being on a different interface:
- For unicast packets (for which ipi_spec_dst is the original
destination address), I believe this is trivially true because Linux
uses the weak host model (unless there's some interaction with
RTCF_LOCAL that I'm missing).
- For multicast/broadcast packets, fib_compute_sec_dst() only passes the
original interface to the lookup in the context of L3M. In
particular, the original implementation (cited above) set iif and oof
to 0. Also, citing
linux.git e7372197e15856ec ("net/ipv4: Set oif in fib_compute_spec_dst"),
> If the device is not enslaved, oif is still 0 so no affect.
It doesn't seem like using an address specifically from the interface
the packet was received on was ever the intention. I've also confirmed
this behavior (sending a multicast packet from another machine, whose IP
I've routed to a dummy interface).
I'm focusing on this because that's a misconception I've had before
digging into the code - the sendmsg behavior explained in the same
paragraph made me think ipi_spec_dst was the (primary?) address of
ipi_ifindex. I think this is worth clarifying.
I've made it explicit that ipi_addr isn't used by sendmsg because that's
another possible misconception.
The (first) extra comma in sendmsg's ipi_spec_dst's description is meant
to emphasize that it's used as the local source address _and_ for the
routing table lookup, as opposed to just affecting the routing table
lookup.
Stylistically it might be a bit weird but idk how to convey this better.
Apart from the cited commits I was referencing the linux-6.17.7 tarball.
__fib_validate_source (and the comment near it) might also be of
interest to people trying to figure out what "specific destinations"
are, exactly.
Signed-off-by: Jakub Głogowski <not@dzwdz.net>
---
man/man7/ip.7 | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/man/man7/ip.7 b/man/man7/ip.7
index a92939cd0..a7f118b42 100644
--- a/man/man7/ip.7
+++ b/man/man7/ip.7
@@ -809,12 +809,20 @@ .SS Socket options
.EE
.in
.IP
+When returned by
+.BR recvmsg (2) ,
.I ipi_ifindex
is the unique index of the interface the packet was received on.
.I ipi_spec_dst
-is the local address of the packet and
+is the preferred source address for replies to the given packet, and
.I ipi_addr
is the destination address in the packet header.
+These addresses are usually the same,
+but can differ for broadcast or multicast packets.
+Note that, depending on the configured routes,
+.I ipi_spec_dst
+might belong to a different interface from the one that received the packet.
+.IP
If
.B IP_PKTINFO
is passed to
@@ -822,14 +830,16 @@ .SS Socket options
and
.\" This field is grossly misnamed
.I ipi_spec_dst
-is not zero, then it is used as the local source address for the routing
-table lookup and for setting up IP source route options.
+is not zero, then it is used as the local source address, for the routing
+table lookup, and for setting up IP source route options.
When
.I ipi_ifindex
is not zero, the primary local address of the interface specified by the
index overwrites
.I ipi_spec_dst
for the routing table lookup.
+.I ipi_addr
+is ignored.
.IP
Not supported for
.B SOCK_STREAM
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] man/man7/ip.7: Reword IP_PKTINFO's description
2025-11-14 14:29 [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Jakub Głogowski
2025-11-14 14:29 ` [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction Jakub Głogowski
@ 2025-11-14 14:29 ` Jakub Głogowski
2025-11-18 13:51 ` [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Alejandro Colomar
2 siblings, 0 replies; 5+ messages in thread
From: Jakub Głogowski @ 2025-11-14 14:29 UTC (permalink / raw)
To: Alejandro Colomar; +Cc: Jakub Głogowski, linux-man, LKML, Linux API, ej
I've heavily cut down the first paragraph (which wasn't really saying
anything), and emphasized the difference between how recvmsg(2) and
sendmsg(2) treat this struct.
"This works only for datagram oriented sockets" is redundant with
"Not supported for SOCK_STREAM", and the mention of sendmsg(2) was moved
down.
I called it a boolean option because that's how these were introduced at
the start of the section.
I've tried rewording ipi_spec_dst's effect on sendmsg to be a bit more
clear.
The only piece of new information which this adds is that you can use
the structure returned by recvmsg with sendmsg, which directly follows
from the preceding text.
RFC 3542, Section 6, directly calls out this usecase for in6_pktinfo:
> Some UDP servers want to respond to client
> requests by sending their reply out the same interface on which the
> request was received and with the source IPv6 address of the reply
> equal to the destination IPv6 address of the request. To do this the
> application can enable just the IPV6_RECVPKTINFO socket option and
> then use the received control information from recvmsg() as the
> outgoing control information for sendmsg(). The application need not
> examine or modify the in6_pktinfo structure at all.
I'm not sure if this is the best place to document this, as the sendmsg
behavior is unrelated to the IP_PKTINFO sockopt at all. Maybe some of
the control messages should be broken out to another manpage?
Signed-off-by: Jakub Głogowski <not@dzwdz.net>
---
man/man7/ip.7 | 49 +++++++++++++++++++++----------------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/man/man7/ip.7 b/man/man7/ip.7
index a7f118b42..aa2508bc7 100644
--- a/man/man7/ip.7
+++ b/man/man7/ip.7
@@ -783,20 +783,13 @@ .SS Socket options
.TP
.BR IP_PKTINFO " (since Linux 2.2)"
.\" Precisely: since Linux 2.1.68
-Pass an
-.B IP_PKTINFO
-ancillary message that contains a
-.I pktinfo
-structure that supplies some information about the incoming packet.
-This works only for datagram oriented sockets.
-The argument is a flag that tells the socket whether the
-.B IP_PKTINFO
-message should be passed or not.
-The message itself can be sent/retrieved
-only as a control message with a packet using
+If this boolean option is enabled,
.BR recvmsg (2)
-or
-.BR sendmsg (2).
+outputs an
+.B IP_PKTINFO
+ancillary message containing an
+.I in_pktinfo
+structure.
.IP
.in +4n
.EX
@@ -809,37 +802,37 @@ .SS Socket options
.EE
.in
.IP
-When returned by
-.BR recvmsg (2) ,
+In this context,
.I ipi_ifindex
is the unique index of the interface the packet was received on.
.I ipi_spec_dst
is the preferred source address for replies to the given packet, and
.I ipi_addr
-is the destination address in the packet header.
+is the destination address from the packet header.
These addresses are usually the same,
but can differ for broadcast or multicast packets.
Note that, depending on the configured routes,
.I ipi_spec_dst
might belong to a different interface from the one that received the packet.
.IP
-If
-.B IP_PKTINFO
-is passed to
-.BR sendmsg (2)
-and
+This structure can also be passed as an ancillary message to
+.BR sendmsg (2) .
+In that case,
.\" This field is grossly misnamed
.I ipi_spec_dst
-is not zero, then it is used as the local source address, for the routing
-table lookup, and for setting up IP source route options.
-When
+is used as the local source address
+(if non-zero),
+including for the purposes of setting up IP source route options.
+It's also used for the routing table lookup, unless
.I ipi_ifindex
-is not zero, the primary local address of the interface specified by the
-index overwrites
-.I ipi_spec_dst
-for the routing table lookup.
+is non-zero \(en
+then the primary local address of that interface is used there instead.
.I ipi_addr
is ignored.
+The structure returned by
+.BR recvmsg (2)
+can be reused,
+which effectively sends a reply to the original packet.
.IP
Not supported for
.B SOCK_STREAM
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs
2025-11-14 14:29 [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Jakub Głogowski
2025-11-14 14:29 ` [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction Jakub Głogowski
2025-11-14 14:29 ` [PATCH 2/2] man/man7/ip.7: Reword IP_PKTINFO's description Jakub Głogowski
@ 2025-11-18 13:51 ` Alejandro Colomar
2 siblings, 0 replies; 5+ messages in thread
From: Alejandro Colomar @ 2025-11-18 13:51 UTC (permalink / raw)
To: Jakub Głogowski; +Cc: linux-man, LKML, Linux API, ej
[-- Attachment #1: Type: text/plain, Size: 1907 bytes --]
Hi Jakub,
On Fri, Nov 14, 2025 at 03:29:29PM +0100, Jakub Głogowski wrote:
> I found the PKTINFO docs pretty confusing, so I tried clarifying them:
> - being more specific about each field in the struct
> (e.g. "local address of the packet" for a received packet could've
> been interpreted in myriad ways),
> - making the differences between sendmsg(2)'s and recvmsg(2)'s handling
> of that struct more explicit,
> - and some other slight rewording to make it (IMO) more readable - I cut
> out most of a paragraph that wasn't really saying anything, etc.
>
> I'm not sure if this should even be documented in ip(7) together with
> the other sockopts, though? sendmsg(2)'s handling of in_pktinfo is
> completely unrelated to the IP_PKTINFO sockopt. Documenting it in its
> own manual page would also give us more room for subsection headings and
> other formatting, examples, etc - instead of trying to cram it into
> what's already an enormous manpage.
>
> Same goes for some of the other more complex sockopts, I guess.
Do you suggest moving each socket option to a manual page under
man2const/? I think I agree with that. There's precedent, and it makes
the pages more readable.
I'll try to do that soon. I'll ping you when I've finished, in case you
want to apply further changes.
> PS. sorry for not signing this email, but neomutt didn't want to
> cooperate :/ I'll try to figure it out for any followup patches.
Ok.
Have a lovely day!
Alex
> Jakub Głogowski (2):
> man/man7/ip.7: Clarify PKTINFO's semantics depending on packet
> direction
> man/man7/ip.7: Reword IP_PKTINFO's description
>
> man/man7/ip.7 | 57 +++++++++++++++++++++++++++------------------------
> 1 file changed, 30 insertions(+), 27 deletions(-)
>
> --
> 2.47.3
>
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction
2025-11-14 14:29 ` [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction Jakub Głogowski
@ 2025-11-18 14:31 ` Alejandro Colomar
0 siblings, 0 replies; 5+ messages in thread
From: Alejandro Colomar @ 2025-11-18 14:31 UTC (permalink / raw)
To: Jakub Głogowski; +Cc: linux-man, LKML, Linux API, ej
[-- Attachment #1: Type: text/plain, Size: 4944 bytes --]
Hi Jakub,
On Fri, Nov 14, 2025 at 03:29:30PM +0100, Jakub Głogowski wrote:
> For recvmsg(2), ipi_spec_dst is set by ipv4_pktinfo_prepare() to the
> result of fib_compute_sec_dst(). The latter was introduced in
> linux.git 35ebf65e851c6d97 ("ipv4: Create and use fib_compute_spec_dst() helper.").
>
> Quoting its commit message:
>
> > The specific destination is the host we direct unicast replies to.
> > Usually this is the original packet source address, but if we are
> > responding to a multicast or broadcast packet we have to use something
> > different.
> >
> > Specifically we must use the source address we would use if we were to
> > send a packet to the unicast source of the original packet.
>
> Experimentation seems to confirm that behavior.
>
> As for the note about ipi_spec_dst being on a different interface:
> - For unicast packets (for which ipi_spec_dst is the original
> destination address), I believe this is trivially true because Linux
> uses the weak host model (unless there's some interaction with
> RTCF_LOCAL that I'm missing).
> - For multicast/broadcast packets, fib_compute_sec_dst() only passes the
> original interface to the lookup in the context of L3M. In
> particular, the original implementation (cited above) set iif and oof
> to 0. Also, citing
> linux.git e7372197e15856ec ("net/ipv4: Set oif in fib_compute_spec_dst"),
> > If the device is not enslaved, oif is still 0 so no affect.
>
> It doesn't seem like using an address specifically from the interface
> the packet was received on was ever the intention. I've also confirmed
> this behavior (sending a multicast packet from another machine, whose IP
> I've routed to a dummy interface).
>
> I'm focusing on this because that's a misconception I've had before
> digging into the code - the sendmsg behavior explained in the same
> paragraph made me think ipi_spec_dst was the (primary?) address of
> ipi_ifindex. I think this is worth clarifying.
>
> I've made it explicit that ipi_addr isn't used by sendmsg because that's
> another possible misconception.
>
> The (first) extra comma in sendmsg's ipi_spec_dst's description is meant
> to emphasize that it's used as the local source address _and_ for the
> routing table lookup, as opposed to just affecting the routing table
> lookup.
> Stylistically it might be a bit weird but idk how to convey this better.
>
> Apart from the cited commits I was referencing the linux-6.17.7 tarball.
>
> __fib_validate_source (and the comment near it) might also be of
> interest to people trying to figure out what "specific destinations"
> are, exactly.
>
> Signed-off-by: Jakub Głogowski <not@dzwdz.net>
Thanks! I've applied the patch. I've added CC tags (please, copy those
yourself in future patches).
I've also s/PKTINFO/IP_PKTINFO/ in the subject.
And I've applied minor wording and source improvements.
I've pushed here:
<https://www.alejandro-colomar.es/src/alx/linux/man-pages/man-pages.git/commit/?h=contrib&id=b8f472450f6607e2d5bd68a1b60615a91ed3d111>
(use port 80).
> ---
> man/man7/ip.7 | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/man/man7/ip.7 b/man/man7/ip.7
> index a92939cd0..a7f118b42 100644
> --- a/man/man7/ip.7
> +++ b/man/man7/ip.7
> @@ -809,12 +809,20 @@ .SS Socket options
> .EE
> .in
> .IP
> +When returned by
> +.BR recvmsg (2) ,
> .I ipi_ifindex
> is the unique index of the interface the packet was received on.
> .I ipi_spec_dst
> -is the local address of the packet and
> +is the preferred source address for replies to the given packet, and
> .I ipi_addr
> is the destination address in the packet header.
> +These addresses are usually the same,
> +but can differ for broadcast or multicast packets.
> +Note that, depending on the configured routes,
I've removed 'Note that,'. It's redundant. Everything in a manual page
should be noteworthy.
Have a lovely day!
Alex
> +.I ipi_spec_dst
> +might belong to a different interface from the one that received the packet.
> +.IP
> If
> .B IP_PKTINFO
> is passed to
> @@ -822,14 +830,16 @@ .SS Socket options
> and
> .\" This field is grossly misnamed
> .I ipi_spec_dst
> -is not zero, then it is used as the local source address for the routing
> -table lookup and for setting up IP source route options.
> +is not zero, then it is used as the local source address, for the routing
> +table lookup, and for setting up IP source route options.
> When
> .I ipi_ifindex
> is not zero, the primary local address of the interface specified by the
> index overwrites
> .I ipi_spec_dst
> for the routing table lookup.
> +.I ipi_addr
> +is ignored.
> .IP
> Not supported for
> .B SOCK_STREAM
> --
> 2.47.3
>
--
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-11-18 14:31 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 14:29 [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Jakub Głogowski
2025-11-14 14:29 ` [PATCH 1/2] man/man7/ip.7: Clarify PKTINFO's semantics depending on packet direction Jakub Głogowski
2025-11-18 14:31 ` Alejandro Colomar
2025-11-14 14:29 ` [PATCH 2/2] man/man7/ip.7: Reword IP_PKTINFO's description Jakub Głogowski
2025-11-18 13:51 ` [PATCH 0/2] man7/ip.7: Clarify PKTINFO's docs Alejandro Colomar
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).