[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1559253021-16772-4-git-send-email-tom@quantonium.net>
Date: Thu, 30 May 2019 14:50:18 -0700
From: Tom Herbert <tom@...bertland.com>
To: davem@...emloft.net, netdev@...r.kernel.org, dlebrun@...gle.com
Cc: Tom Herbert <tom@...ntonium.net>
Subject: [PATCH net-next 3/6] seg6: Remove HMAC flag and implement seg6_find_hmac_tlv
The HMAC flag is no longer defined in the SRH specification. Remove
it and any uses of it.
This includes removal of sr_has_hmac. We replace this function with
seg6_find_hmac_tlv. That function parses (via __seg6_parse_srh) a
TLV list and returns the pointer to an HMAC TLV if one exists. The
parsing function also eliminates the assumption in seg6_get_tlv_hmac
that the HMAC TLV must be the first TLV.
Signed-off-by: Tom Herbert <tom@...ntonium.net>
---
include/net/seg6.h | 12 +++++++++++-
include/uapi/linux/seg6.h | 3 ---
net/ipv6/exthdrs.c | 2 +-
net/ipv6/seg6.c | 12 ++++++++++--
net/ipv6/seg6_hmac.c | 8 +++-----
net/ipv6/seg6_iptunnel.c | 4 ++--
6 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/include/net/seg6.h b/include/net/seg6.h
index 563d4a6..47e7c90 100644
--- a/include/net/seg6.h
+++ b/include/net/seg6.h
@@ -17,6 +17,7 @@
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/seg6.h>
+#include <linux/seg6_hmac.h>
#include <linux/rhashtable-types.h>
static inline void update_csum_diff4(struct sk_buff *skb, __be32 from,
@@ -67,11 +68,20 @@ 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_parse_srh(struct ipv6_sr_hdr *srh,
+ struct sr6_tlv_hmac **hmacp);
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);
extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh);
extern int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
u32 tbl_id);
+
+static inline struct sr6_tlv_hmac *seg6_find_hmac_tlv(struct ipv6_sr_hdr *srh)
+{
+ struct sr6_tlv_hmac *hmacp = NULL;
+
+ return __seg6_parse_srh(srh, &hmacp) ? hmacp : NULL;
+}
+
#endif
diff --git a/include/uapi/linux/seg6.h b/include/uapi/linux/seg6.h
index a69ce16..ca14df4 100644
--- a/include/uapi/linux/seg6.h
+++ b/include/uapi/linux/seg6.h
@@ -36,14 +36,11 @@ struct ipv6_sr_hdr {
#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_TLV_PAD1 0
#define SR6_TLV_PADDING 1
#define SR6_TLV_HMAC 5
-#define sr_has_hmac(srh) ((srh)->flags & SR6_FLAG1_HMAC)
-
struct sr6_tlv {
__u8 type;
__u8 len;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 20291c2..112e2fd 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -922,7 +922,7 @@ static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto,
}
#ifdef CONFIG_IPV6_SEG6_HMAC
- if (sr_has_hmac(sr_phdr)) {
+ if (seg6_find_hmac_tlv(sr_phdr)) {
struct net *net = NULL;
if (skb->dev)
diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
index e461357..1e782a6 100644
--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -30,7 +30,7 @@
#include <net/seg6_hmac.h>
#endif
-bool __seg6_parse_srh(struct ipv6_sr_hdr *srh)
+bool __seg6_parse_srh(struct ipv6_sr_hdr *srh, struct sr6_tlv_hmac **hmacp)
{
int len = ipv6_optlen((struct ipv6_opt_hdr *)srh);
unsigned char *opt = (unsigned char *)srh;
@@ -39,6 +39,8 @@ bool __seg6_parse_srh(struct ipv6_sr_hdr *srh)
off = seg6_tlv_offset(srh);
len -= off;
+ *hmacp = NULL;
+
while (len > 0) {
struct sr6_tlv *tlv;
unsigned int optlen;
@@ -47,6 +49,10 @@ bool __seg6_parse_srh(struct ipv6_sr_hdr *srh)
case SR6_TLV_PAD1:
optlen = 1;
break;
+ case SR6_TLV_HMAC:
+ if (!*hmacp)
+ *hmacp = (struct sr6_tlv_hmac *)&opt[off];
+ /* Fall through */
default:
if (len < sizeof(*tlv))
return false;
@@ -66,6 +72,8 @@ bool __seg6_parse_srh(struct ipv6_sr_hdr *srh)
bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
{
+ struct sr6_tlv_hmac *hmacp;
+
if (srh->type != IPV6_SRCRT_TYPE_4)
return false;
@@ -75,7 +83,7 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len)
if (srh->segments_left > srh->first_segment)
return false;
- return __seg6_parse_srh(srh);
+ return __seg6_parse_srh(srh, &hmacp);
}
static struct genl_family seg6_genl_family;
diff --git a/net/ipv6/seg6_hmac.c b/net/ipv6/seg6_hmac.c
index 8546f94..92b398c 100644
--- a/net/ipv6/seg6_hmac.c
+++ b/net/ipv6/seg6_hmac.c
@@ -95,13 +95,11 @@ static struct sr6_tlv_hmac *seg6_get_tlv_hmac(struct ipv6_sr_hdr *srh)
if (srh->hdrlen < (srh->first_segment + 1) * 2 + 5)
return NULL;
- if (!sr_has_hmac(srh))
+ tlv = seg6_find_hmac_tlv(srh);
+ if (!tlv)
return NULL;
- tlv = (struct sr6_tlv_hmac *)
- ((char *)srh + ((srh->hdrlen + 1) << 3) - 40);
-
- if (tlv->tlvhdr.type != SR6_TLV_HMAC || tlv->tlvhdr.len != 38)
+ if (tlv->tlvhdr.len != sizeof(*tlv) - 2)
return NULL;
return tlv;
diff --git a/net/ipv6/seg6_iptunnel.c b/net/ipv6/seg6_iptunnel.c
index 7a525fd..5344bee 100644
--- a/net/ipv6/seg6_iptunnel.c
+++ b/net/ipv6/seg6_iptunnel.c
@@ -161,7 +161,7 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
set_tun_src(net, dst->dev, &hdr->daddr, &hdr->saddr);
#ifdef CONFIG_IPV6_SEG6_HMAC
- if (sr_has_hmac(isrh)) {
+ if (seg6_find_hmac_tlv(isrh)) {
err = seg6_push_hmac(net, &hdr->saddr, isrh);
if (unlikely(err))
return err;
@@ -211,7 +211,7 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
hdr->daddr = isrh->segments[isrh->first_segment];
#ifdef CONFIG_IPV6_SEG6_HMAC
- if (sr_has_hmac(isrh)) {
+ if (seg6_find_hmac_tlv(isrh)) {
struct net *net = dev_net(skb_dst(skb)->dev);
err = seg6_push_hmac(net, &hdr->saddr, isrh);
--
2.7.4
Powered by blists - more mailing lists