From: Florian Westphal <fw@strlen.de>
To: netdev@vger.kernel.org
Cc: steffen.klassert@secunet.com, herbert@gondor.apana.org.au,
Florian Westphal <fw@strlen.de>
Subject: [PATCH ipsec-next 5/5] xfrm: merge dstopt and routing hdroff functions
Date: Thu, 10 Jun 2021 14:06:29 +0200 [thread overview]
Message-ID: <20210610120629.23088-6-fw@strlen.de> (raw)
In-Reply-To: <20210610120629.23088-1-fw@strlen.de>
Both functions are very similar, so merge them into one.
The nexthdr is passed as argument to break the loop in the
ROUTING case, this is the only header type where slightly different
rules apply.
While at it, the merged function is realigned with
ip6_find_1stfragopt(). That function received bug fixes for
an infinite loop, but neither dstopt nor rh parsing functions
(copy-pasted from ip6_find_1stfragopt) were changed.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/xfrm/xfrm_output.c | 75 +++++++++++-------------------------------
1 file changed, 19 insertions(+), 56 deletions(-)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 10842d5cf6e1..9ad97cb16549 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -78,24 +78,29 @@ static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
}
#if IS_ENABLED(CONFIG_IPV6_MIP6)
-static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
- u8 **nexthdr)
+static int mip6_rthdr_offset(struct sk_buff *skb, u8 **nexthdr, int type)
{
- u16 offset = sizeof(struct ipv6hdr);
- struct ipv6_opt_hdr *exthdr =
- (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
- const unsigned char *nh = skb_network_header(skb);
+ unsigned int offset = sizeof(struct ipv6hdr);
unsigned int packet_len = skb_tail_pointer(skb) -
skb_network_header(skb);
int found_rhdr = 0;
*nexthdr = &ipv6_hdr(skb)->nexthdr;
- while (offset + 1 <= packet_len) {
+ while (offset <= packet_len) {
+ struct ipv6_opt_hdr *exthdr;
+
switch (**nexthdr) {
case NEXTHDR_HOP:
break;
case NEXTHDR_ROUTING:
+ if (type == IPPROTO_ROUTING && offset + 3 <= packet_len) {
+ struct ipv6_rt_hdr *rt;
+
+ rt = (struct ipv6_rt_hdr *)(nh + offset);
+ if (rt->type != 0)
+ return offset;
+ }
found_rhdr = 1;
break;
case NEXTHDR_DEST:
@@ -116,56 +121,15 @@ static int mip6_destopt_offset(struct xfrm_state *x, struct sk_buff *skb,
return offset;
}
- offset += ipv6_optlen(exthdr);
- *nexthdr = &exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr *)(nh + offset);
- }
-
- return offset;
-}
-
-static int mip6_rthdr_offset(struct xfrm_state *x, struct sk_buff *skb,
- u8 **nexthdr)
-{
- u16 offset = sizeof(struct ipv6hdr);
- struct ipv6_opt_hdr *exthdr =
- (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
- const unsigned char *nh = skb_network_header(skb);
- unsigned int packet_len = skb_tail_pointer(skb) -
- skb_network_header(skb);
- int found_rhdr = 0;
-
- *nexthdr = &ipv6_hdr(skb)->nexthdr;
-
- while (offset + 1 <= packet_len) {
- switch (**nexthdr) {
- case NEXTHDR_HOP:
- break;
- case NEXTHDR_ROUTING:
- if (offset + 3 <= packet_len) {
- struct ipv6_rt_hdr *rt;
-
- rt = (struct ipv6_rt_hdr *)(nh + offset);
- if (rt->type != 0)
- return offset;
- }
- found_rhdr = 1;
- break;
- case NEXTHDR_DEST:
- if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0)
- return offset;
-
- if (found_rhdr)
- return offset;
-
- break;
- default:
- return offset;
- }
+ if (offset + sizeof(struct ipv6_opt_hdr) > packet_len)
+ return -EINVAL;
+ exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
+ offset);
offset += ipv6_optlen(exthdr);
+ if (offset > IPV6_MAXPLEN)
+ return -EINVAL;
*nexthdr = &exthdr->nexthdr;
- exthdr = (struct ipv6_opt_hdr *)(nh + offset);
}
return offset;
@@ -177,9 +141,8 @@ static int xfrm6_hdr_offset(struct xfrm_state *x, struct sk_buff *skb, u8 **prev
switch (x->type->proto) {
#if IS_ENABLED(CONFIG_IPV6_MIP6)
case IPPROTO_DSTOPTS:
- return mip6_destopt_offset(x, skb, prevhdr);
case IPPROTO_ROUTING:
- return mip6_rthdr_offset(x, skb, prevhdr);
+ return mip6_rthdr_offset(skb, prevhdr, x->type->proto);
#endif
default:
break;
--
2.31.1
prev parent reply other threads:[~2021-06-10 12:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-10 12:06 [PATCH ipsec-next 0/5] xfrm: ipv6: remove hdr_off indirection Florian Westphal
2021-06-10 12:06 ` [PATCH ipsec-next 1/5] xfrm: ipv6: add xfrm6_hdr_offset helper Florian Westphal
2021-06-10 12:06 ` [PATCH ipsec-next 2/5] xfrm: ipv6: move mip6_destopt_offset into xfrm core Florian Westphal
2021-06-10 12:06 ` [PATCH ipsec-next 3/5] xfrm: ipv6: move mip6_rthdr_offset " Florian Westphal
2021-06-10 12:06 ` [PATCH ipsec-next 4/5] xfrm: remove hdr_offset indirection Florian Westphal
2021-06-10 12:06 ` Florian Westphal [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=20210610120629.23088-6-fw@strlen.de \
--to=fw@strlen.de \
--cc=herbert@gondor.apana.org.au \
--cc=netdev@vger.kernel.org \
--cc=steffen.klassert@secunet.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 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).