All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathis Marion <Mathis.Marion@silabs.com>
To: "David S. Miller" <davem@davemloft.net>,
	David Ahern <dsahern@kernel.org>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Jérôme Pouiller" <jerome.pouiller@silabs.com>,
	"Kylian Balan" <kylian.balan@silabs.com>,
	"Alexander Aring" <alex.aring@gmail.com>,
	"Mathis Marion" <mathis.marion@silabs.com>
Subject: [PATCH v1 1/2] ipv6: introduce ipv6_rthdr_rcv_last()
Date: Mon, 24 Jun 2024 16:15:32 +0200	[thread overview]
Message-ID: <20240624141602.206398-2-Mathis.Marion@silabs.com> (raw)
In-Reply-To: <20240624141602.206398-1-Mathis.Marion@silabs.com>

From: Mathis Marion <mathis.marion@silabs.com>

This factorizes some code between ipv6_srh_rcv(), ipv6_rpl_srh_rcv()
and ipv6_rthdr_rcv().

Note that:
  - IPv4-in-IPv6 was previously only supported by ipv6_srh_rcv().
  - IPv6-in-IPv6 was previously not supported in ipv6_rthdr_rcv().

Signed-off-by: Mathis Marion <mathis.marion@silabs.com>
---
 net/ipv6/exthdrs.c | 107 ++++++++++++++++++---------------------------
 1 file changed, 42 insertions(+), 65 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 6789623b2b0d..083dbbafb166 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -366,9 +366,45 @@ static void seg6_update_csum(struct sk_buff *skb)
 			   (__be32 *)addr);
 }
 
-static int ipv6_srh_rcv(struct sk_buff *skb)
+static int ipv6_rthdr_rcv_last(struct sk_buff *skb)
 {
 	struct inet6_skb_parm *opt = IP6CB(skb);
+	struct net *net = dev_net(skb->dev);
+	const struct ipv6_rt_hdr *hdr;
+
+	hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
+
+	if (hdr->nexthdr == NEXTHDR_IPV6 || hdr->nexthdr == NEXTHDR_IPV4) {
+		int offset = (hdr->hdrlen + 1) << 3;
+
+		skb_postpull_rcsum(skb, skb_network_header(skb),
+				   skb_network_header_len(skb));
+		skb_pull(skb, offset);
+		skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
+
+		skb_reset_network_header(skb);
+		skb_reset_transport_header(skb);
+		skb->encapsulation = 0;
+		if (hdr->nexthdr == NEXTHDR_IPV4)
+			skb->protocol = htons(ETH_P_IP);
+		__skb_tunnel_rx(skb, skb->dev, net);
+
+		netif_rx(skb);
+		return -1;
+	}
+
+	opt->srcrt = skb_network_header_len(skb);
+	opt->lastopt = opt->srcrt;
+	skb->transport_header += (hdr->hdrlen + 1) << 3;
+	opt->dst0 = opt->dst1;
+	opt->dst1 = 0;
+	opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
+
+	return 1;
+}
+
+static int ipv6_srh_rcv(struct sk_buff *skb)
+{
 	struct net *net = dev_net(skb->dev);
 	struct ipv6_sr_hdr *hdr;
 	struct inet6_dev *idev;
@@ -395,34 +431,8 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
 #endif
 
 looped_back:
-	if (hdr->segments_left == 0) {
-		if (hdr->nexthdr == NEXTHDR_IPV6 || hdr->nexthdr == NEXTHDR_IPV4) {
-			int offset = (hdr->hdrlen + 1) << 3;
-
-			skb_postpull_rcsum(skb, skb_network_header(skb),
-					   skb_network_header_len(skb));
-			skb_pull(skb, offset);
-			skb_postpull_rcsum(skb, skb_transport_header(skb),
-					   offset);
-
-			skb_reset_network_header(skb);
-			skb_reset_transport_header(skb);
-			skb->encapsulation = 0;
-			if (hdr->nexthdr == NEXTHDR_IPV4)
-				skb->protocol = htons(ETH_P_IP);
-			__skb_tunnel_rx(skb, skb->dev, net);
-
-			netif_rx(skb);
-			return -1;
-		}
-
-		opt->srcrt = skb_network_header_len(skb);
-		opt->lastopt = opt->srcrt;
-		skb->transport_header += (hdr->hdrlen + 1) << 3;
-		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
-
-		return 1;
-	}
+	if (hdr->segments_left == 0)
+		return ipv6_rthdr_rcv_last(skb);
 
 	if (hdr->segments_left >= (hdr->hdrlen >> 1)) {
 		__IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
@@ -482,7 +492,6 @@ static int ipv6_srh_rcv(struct sk_buff *skb)
 static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
 {
 	struct ipv6_rpl_sr_hdr *hdr, *ohdr, *chdr;
-	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct net *net = dev_net(skb->dev);
 	struct inet6_dev *idev;
 	struct ipv6hdr *oldhdr;
@@ -506,33 +515,8 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
 looped_back:
 	hdr = (struct ipv6_rpl_sr_hdr *)skb_transport_header(skb);
 
-	if (hdr->segments_left == 0) {
-		if (hdr->nexthdr == NEXTHDR_IPV6) {
-			int offset = (hdr->hdrlen + 1) << 3;
-
-			skb_postpull_rcsum(skb, skb_network_header(skb),
-					   skb_network_header_len(skb));
-			skb_pull(skb, offset);
-			skb_postpull_rcsum(skb, skb_transport_header(skb),
-					   offset);
-
-			skb_reset_network_header(skb);
-			skb_reset_transport_header(skb);
-			skb->encapsulation = 0;
-
-			__skb_tunnel_rx(skb, skb->dev, net);
-
-			netif_rx(skb);
-			return -1;
-		}
-
-		opt->srcrt = skb_network_header_len(skb);
-		opt->lastopt = opt->srcrt;
-		skb->transport_header += (hdr->hdrlen + 1) << 3;
-		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
-
-		return 1;
-	}
+	if (hdr->segments_left == 0)
+		return ipv6_rthdr_rcv_last(skb);
 
 	n = (hdr->hdrlen << 3) - hdr->pad - (16 - hdr->cmpre);
 	r = do_div(n, (16 - hdr->cmpri));
@@ -648,7 +632,6 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
 static int ipv6_rthdr_rcv(struct sk_buff *skb)
 {
 	struct inet6_dev *idev = __in6_dev_get(skb->dev);
-	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct in6_addr *addr = NULL;
 	int n, i;
 	struct ipv6_rt_hdr *hdr;
@@ -709,13 +692,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
 		default:
 			break;
 		}
-
-		opt->lastopt = opt->srcrt = skb_network_header_len(skb);
-		skb->transport_header += (hdr->hdrlen + 1) << 3;
-		opt->dst0 = opt->dst1;
-		opt->dst1 = 0;
-		opt->nhoff = (&hdr->nexthdr) - skb_network_header(skb);
-		return 1;
+		return ipv6_rthdr_rcv_last(skb);
 	}
 
 	switch (hdr->type) {
-- 
2.43.0


  reply	other threads:[~2024-06-24 14:32 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-24 14:15 [PATCH v1 0/2] ipv6: always accept routing headers with 0 segments left Mathis Marion
2024-06-24 14:15 ` Mathis Marion [this message]
2024-06-24 14:15 ` [PATCH v1 2/2] " Mathis Marion
2024-06-25 21:38   ` Kuniyuki Iwashima
2024-06-26  1:45     ` Alexander Aring
2024-06-26 10:10       ` Mathis Marion
2024-06-26 13:48         ` Alexander Aring
2024-07-16 21:27         ` Alexander Aring

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=20240624141602.206398-2-Mathis.Marion@silabs.com \
    --to=mathis.marion@silabs.com \
    --cc=alex.aring@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=jerome.pouiller@silabs.com \
    --cc=kuba@kernel.org \
    --cc=kylian.balan@silabs.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /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.