@@ -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
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 <tom@quantonium.net> --- include/uapi/linux/seg6.h | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-)