Currently no flags are defined for segment routing in
draft-ietf-6man-segment-routing-header-19. Mark them as being
obsolete.

The HMAC flag is the only one used by the stack. This needs
additional consideration. Rewrite sr_has_hmac in uapi/linux/seg6.h
to properly parse a segment routing header as opposed to relying
on the now obsolete flag.

Signed-off-by: Tom Herbert <t...@quantonium.net>
---
 include/uapi/linux/seg6.h | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/seg6.h b/include/uapi/linux/seg6.h
index 3a7d324..0d19a9c 100644
--- a/include/uapi/linux/seg6.h
+++ b/include/uapi/linux/seg6.h
@@ -33,11 +33,10 @@ struct ipv6_sr_hdr {
        struct in6_addr segments[0];
 };
 
-#define SR6_FLAG1_PROTECTED    (1 << 6)
-#define SR6_FLAG1_OAM          (1 << 5)
-#define SR6_FLAG1_ALERT                (1 << 4)
-#define SR6_FLAG1_HMAC         (1 << 3)
-
+#define SR6_FLAG1_PROTECTED    (1 << 6)        /* obsoleted */
+#define SR6_FLAG1_OAM          (1 << 5)        /* obsoleted */
+#define SR6_FLAG1_ALERT                (1 << 4)        /* obsoleted */
+#define SR6_FLAG1_HMAC         (1 << 3)        /* obsoleted */
 
 #define SR6_TLV_INGRESS                1       /* obsoleted */
 #define SR6_TLV_EGRESS         2       /* obsoleted */
@@ -47,12 +46,42 @@ struct ipv6_sr_hdr {
 #define SR6_TLV_PADN           1
 #define SR6_TLV_HMAC           5
 
-#define sr_has_hmac(srh) ((srh)->flags & SR6_FLAG1_HMAC)
-
 struct sr6_tlv {
        __u8 type;
        __u8 len;
        __u8 data[0];
 };
 
+static inline int sr_hmac_offset(struct ipv6_sr_hdr *srh)
+{
+       unsigned char *opt = (unsigned char *)srh;
+       unsigned int off = sizeof(*srh) + ((srh->first_segment + 1) << 4);
+       int len = ((srh->hdrlen + 1) << 8) - off;
+       unsigned int optlen;
+
+       while (len > 0) {
+               switch (opt[off]) {
+               case SR6_TLV_PAD1:
+                       optlen = 1;
+                       break;
+               case SR6_TLV_HMAC:
+                       return off;
+               default:
+                       if (len < sizeof(struct sr6_tlv))
+                               return 0;
+
+                       optlen = sizeof(struct sr6_tlv) +
+                                ((struct sr6_tlv *)&opt[off])->len;
+                       break;
+               }
+
+               off += optlen;
+               len -= optlen;
+       }
+
+       return 0;
+}
+
+#define sr_has_hmac(srh) (!!sr_hmac_offset(srh))
+
 #endif
-- 
2.7.4

Reply via email to