netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tom Herbert <tom@herbertland.com>
To: davem@davemloft.net, netdev@vger.kernel.org, dlebrun@google.com,
	ahabdels.dev@gmail.com
Cc: Tom Herbert <tom@quantonium.net>
Subject: [RFC PATCH 2/6] seg6: Implement a TLV parsing loop
Date: Fri, 31 May 2019 09:48:36 -0700	[thread overview]
Message-ID: <1559321320-9444-3-git-send-email-tom@quantonium.net> (raw)
In-Reply-To: <1559321320-9444-1-git-send-email-tom@quantonium.net>

Implement a TLV parsing loop for segment routing. The code is uniform
with other instances of TLV parsing loops in the stack (e.g. parsing of
Hop-by-Hop and Destination Options).

seg_validate_srh calls this function. Note, this fixes a bug in the
original parsing code that PAD1 was not supported.

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/net/seg6.h |  6 ++++++
 net/ipv6/seg6.c    | 60 +++++++++++++++++++++++++++++++-----------------------
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/include/net/seg6.h b/include/net/seg6.h
index 8b2dc68..563d4a6 100644
--- a/include/net/seg6.h
+++ b/include/net/seg6.h
@@ -38,6 +38,11 @@ static inline void update_csum_diff16(struct sk_buff *skb, __be32 *from,
 	skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum);
 }
 
+static inline unsigned int seg6_tlv_offset(struct ipv6_sr_hdr *srh)
+{
+	return sizeof(*srh) + ((srh->first_segment + 1) << 4);
+}
+
 struct seg6_pernet_data {
 	struct mutex lock;
 	struct in6_addr __rcu *tun_src;
@@ -62,6 +67,7 @@ extern void seg6_iptunnel_exit(void);
 extern int seg6_local_init(void);
 extern void seg6_local_exit(void);
 
+extern bool __seg6_parse_srh(struct ipv6_sr_hdr *srh);
 extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len);
 extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
 			     int proto);
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index 0c5479e..e461357 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -30,44 +30,52 @@
 #include <net/seg6_hmac.h>
 #endif
 
-bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
+bool __seg6_parse_srh(struct ipv6_sr_hdr *srh)
 {
-	int trailing;
-	unsigned int tlv_offset;
+	int len = ipv6_optlen((struct ipv6_opt_hdr *)srh);
+	unsigned char *opt = (unsigned char *)srh;
+	unsigned int off;
 
-	if (srh->type != IPV6_SRCRT_TYPE_4)
-		return false;
+	off = seg6_tlv_offset(srh);
+	len -= off;
 
-	if (((srh->hdrlen + 1) << 3) != len)
-		return false;
+	while (len > 0) {
+		struct sr6_tlv *tlv;
+		unsigned int optlen;
 
-	if (srh->segments_left > srh->first_segment)
-		return false;
+		switch (opt[off]) {
+		case SR6_TLV_PAD1:
+			optlen = 1;
+			break;
+		default:
+			if (len < sizeof(*tlv))
+				return false;
 
-	tlv_offset = sizeof(*srh) + ((srh->first_segment + 1) << 4);
+			tlv = (struct sr6_tlv *)&opt[off];
+			optlen = sizeof(*tlv) + tlv->len;
 
-	trailing = len - tlv_offset;
-	if (trailing < 0)
-		return false;
+			break;
+		}
 
-	while (trailing) {
-		struct sr6_tlv *tlv;
-		unsigned int tlv_len;
+		off += optlen;
+		len -= optlen;
+	}
 
-		if (trailing < sizeof(*tlv))
-			return false;
+	return !len;
+}
 
-		tlv = (struct sr6_tlv *)((unsigned char *)srh + tlv_offset);
-		tlv_len = sizeof(*tlv) + tlv->len;
+bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
+{
+	if (srh->type != IPV6_SRCRT_TYPE_4)
+		return false;
 
-		trailing -= tlv_len;
-		if (trailing < 0)
-			return false;
+	if (ipv6_optlen((struct ipv6_opt_hdr *)srh) != len)
+		return false;
 
-		tlv_offset += tlv_len;
-	}
+	if (srh->segments_left > srh->first_segment)
+		return false;
 
-	return true;
+	return __seg6_parse_srh(srh);
 }
 
 static struct genl_family seg6_genl_family;
-- 
2.7.4


  parent reply	other threads:[~2019-05-31 16:50 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-31 16:48 [RFC PATCH 0/6] seg6: Segment routing fixes Tom Herbert
2019-05-31 16:48 ` [RFC PATCH 1/6] seg6: Fix TLV definitions Tom Herbert
2019-05-31 16:48 ` Tom Herbert [this message]
2019-05-31 16:48 ` [RFC PATCH 3/6] seg6: Obsolete unused SRH flags Tom Herbert
2019-05-31 16:48 ` [RFC PATCH 4/6] ah6: Create function __zero_out_mutable_opts Tom Herbert
2019-05-31 16:48 ` [RFC PATCH 5/6] ah6: Be explicit about which routing types are processed Tom Herbert
2019-05-31 16:48 ` [RFC PATCH 6/6] seg6: Add support to rearrange SRH for AH ICV calculation Tom Herbert
2019-05-31 17:07   ` Ahmed Abdelsalam
2019-05-31 17:34     ` Tom Herbert
2019-06-02  9:54       ` Ahmed Abdelsalam
2019-06-02 15:48         ` Tom Herbert

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=1559321320-9444-3-git-send-email-tom@quantonium.net \
    --to=tom@herbertland.com \
    --cc=ahabdels.dev@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dlebrun@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=tom@quantonium.net \
    /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).