From: Guillaume Nault <gnault@redhat.com>
To: Aleksey Shumnik <ashumnik9@gmail.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
Jakub Kicinski <kuba@kernel.org>,
waltje@uwalt.nl.mugnet.org, gw4pts@gw4pts.ampr.org, xeb@mail.ru,
kuznet@ms2.inr.ac.ru, rzsfl@rz.uni-sb.de
Subject: Re: [BUG] In af_packet.c::dev_parse_header() skb.network_header does not point to the network header
Date: Thu, 20 Apr 2023 18:53:42 +0200 [thread overview]
Message-ID: <ZEFuFqMjO19De/e/@debian> (raw)
In-Reply-To: <CAJGXZLgcH6bjmj7YR-hAWpEQW1CPjEcOdMN01hqsVk18E4ScZQ@mail.gmail.com>
On Tue, Apr 11, 2023 at 05:47:34PM +0300, Aleksey Shumnik wrote:
> Dear maintainers,
>
> I wrote the ip6gre_header_parser() function in ip6_gre.c, the
> implementation is similar to ipgre_header_parser() in ip_gre.c. (By
> the way, it is strange that this function is not implemented in
> ip6_gre.c)
> The implementation of the function is presented below.
> It should parse the ip6 header and take the source address and its
> length from there. To get a pointer to the ip header, it is logical to
> use skb_network_header(), but it does not work correctly and returns a
> pointer to payload (skb.data).
At this point, the tunnel device has already removed the outer headers.
So skb_network_header() points to the _inner_ network header.
> Also in ip_gre.c::ipgre_header_parser() skb_mac_header() returns a
> pointer to the ip header and everything works correctly (although it
> seems that this is also an error, because the pointer to the mac
> header should have been returned, and logically the
> skb_network_header() function should be applied),
Well, skb_mac_header() and skb_network_header() should point to the
inner mac and network headers respectively. However, because ip_gre
has no inner mac header, skb_mac_header() was repurposed to save the
position of the outer network header (so that ipgre_header_parse() can
find it).
> but in ip6_gre.c all
> skb_mac_header(), skb_network_header(), skb_tranport_header() returns
> a pointer to payload (skb.data).
The packet has already been decapsulated by the tunnel device: the
outer headers are gone. Therefore, the packet now starts right after
the gre header. So skb_mac_header() points there. And since ip6_gre
transports packets with no mac header, the mac header length is zero,
which means skb_network_header() equals skb_mac_header() and points to
the inner network header. Finally, as the inner network header hasn't
been parsed yet, we don't know where it ends, so skb_tranport_header()
isn't usable yet.
> This function is called when receiving a packet and parsing it in
> af_packet.c::packet_rcv() in dev_parse_header().
> The problem is that there is no way to accurately determine the
> beginning of the ip header.
>
> diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
> index 90565b8..0d0c37b 100644
> --- a/net/ipv6/ip6_gre.c
> +++ b/net/ipv6/ip6_gre.c
> @@ -1404,8 +1404,16 @@ static int ip6gre_header(struct sk_buff *skb,
> struct net_device *dev,
> return -t->hlen;
> }
>
> +static int ip6gre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
> +{
> + const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) skb_mac_header(skb);
> + memcpy(haddr, &ipv6h->saddr, 16);
> + return 16;
> +}
> +
> static const struct header_ops ip6gre_header_ops = {
> .create = ip6gre_header,
> + .parse = ip6gre_header_parse,
> };
>
> static const struct net_device_ops ip6gre_netdev_ops = {
>
> Would you answer whether this behavior is an error and why the
> behavior in ip_gre.c and ip6_gre.c differs?
For me, ip_gre should make the mac header point to the inner mac
header, which incidentally is also the inner network header.
The difference in behaviour between ip_gre and ip6_gre certainly comes
from the fact that both modules were implemented at different times, by
different people.
> Regards,
> Aleksey
>
prev parent reply other threads:[~2023-04-20 16:54 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-11 14:47 [BUG] In af_packet.c::dev_parse_header() skb.network_header does not point to the network header Aleksey Shumnik
2023-04-12 3:19 ` Willem de Bruijn
2023-04-20 16:19 ` Guillaume Nault
2023-04-20 16:53 ` Guillaume Nault [this message]
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=ZEFuFqMjO19De/e/@debian \
--to=gnault@redhat.com \
--cc=ashumnik9@gmail.com \
--cc=gw4pts@gw4pts.ampr.org \
--cc=kuba@kernel.org \
--cc=kuznet@ms2.inr.ac.ru \
--cc=netdev@vger.kernel.org \
--cc=rzsfl@rz.uni-sb.de \
--cc=waltje@uwalt.nl.mugnet.org \
--cc=xeb@mail.ru \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.