Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 31 Mar 2021 11:38:35 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: e243367b6445 - main - mbuf: add a way to mark flowid as calculated from the internal headers
Message-ID:  <202103311138.12VBcZKp018609@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=e243367b644562c9410b39f8d78dafdb7e785d85

commit e243367b644562c9410b39f8d78dafdb7e785d85
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-02-12 13:38:07 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-03-31 11:38:26 +0000

    mbuf: add a way to mark flowid as calculated from the internal headers
    
    In some settings offload might calculate hash from decapsulated packet.
    Reserve a bit in packet header rsstype to indicate that.
    
    Add m_adj_decap() that acts similarly to m_adj, but also either clear
    flowid if it is not marked as inner, or transfer it to the decapsulated
    header, clearing inner indicator. It depends on the internals of m_adj()
    that reuses the argument packet header for the result.
    
    Use m_adj_decap() for decapsulating vxlan(4) and gif(4) input packets.
    
    Reviewed by:    ae, hselasky, np
    Sponsored by:   Nvidia Networking / Mellanox Technologies
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D28773
---
 sys/kern/uipc_mbuf.c | 23 +++++++++++++++++++++++
 sys/net/if_gif.c     |  3 ++-
 sys/net/if_vxlan.c   |  3 ++-
 sys/sys/mbuf.h       | 12 +++++++++---
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 5296aac0edc4..f7852bc7dd7f 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -855,6 +855,29 @@ m_adj(struct mbuf *mp, int req_len)
 	}
 }
 
+void
+m_adj_decap(struct mbuf *mp, int len)
+{
+	uint8_t rsstype;
+
+	m_adj(mp, len);
+	if ((mp->m_flags & M_PKTHDR) != 0) {
+		/*
+		 * If flowid was calculated by card from the inner
+		 * headers, move flowid to the decapsulated mbuf
+		 * chain, otherwise clear.  This depends on the
+		 * internals of m_adj, which keeps pkthdr as is, in
+		 * particular not changing rsstype and flowid.
+		 */
+		rsstype = mp->m_pkthdr.rsstype;
+		if ((rsstype & M_HASHTYPE_INNER) != 0) {
+			M_HASHTYPE_SET(mp, rsstype & ~M_HASHTYPE_INNER);
+		} else {
+			M_HASHTYPE_CLEAR(mp);
+		}
+	}
+}
+
 /*
  * Rearange an mbuf chain so that len bytes are contiguous
  * and in the data area of an mbuf (so that mtod will work
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 1784d034ac2d..113bcb5c916e 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -540,7 +540,8 @@ gif_input(struct mbuf *m, struct ifnet *ifp, int proto, uint8_t ecn)
 			m_freem(m);
 			goto drop;
 		}
-		m_adj(m, sizeof(struct etherip_header));
+
+		m_adj_decap(m, sizeof(struct etherip_header));
 
 		m->m_flags &= ~(M_BCAST|M_MCAST);
 		m->m_pkthdr.rcvif = ifp;
diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index d0d335dba9ed..0d69244ce64b 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -2780,8 +2780,9 @@ vxlan_rcv_udp_packet(struct mbuf *m, int offset, struct inpcb *inpcb,
 		goto out;
 
 	vni = ntohl(vxh->vxlh_vni) >> VXLAN_HDR_VNI_SHIFT;
+
 	/* Adjust to the start of the inner Ethernet frame. */
-	m_adj(m, offset + sizeof(struct vxlan_header));
+	m_adj_decap(m, offset + sizeof(struct vxlan_header));
 
 	error = vxlan_input(vso, vni, &m, srcsa);
 	MPASS(error != 0 || m == NULL);
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 6aad1e36e710..371ae8feae46 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -532,6 +532,7 @@ m_epg_pagelen(const struct mbuf *m, int pidx, int pgoff)
  * https://docs.microsoft.com/en-us/windows-hardware/drivers/network/rss-hashing-types#ndishashipv6ex
  */
 #define	M_HASHTYPE_HASHPROP		0x80	/* has hash properties */
+#define	M_HASHTYPE_INNER		0x40	/* calculated from inner headers */
 #define	M_HASHTYPE_HASH(t)		(M_HASHTYPE_HASHPROP | (t))
 /* Microsoft RSS standard hash types */
 #define	M_HASHTYPE_NONE			0
@@ -548,15 +549,19 @@ m_epg_pagelen(const struct mbuf *m, int pidx, int pgoff)
 #define	M_HASHTYPE_RSS_UDP_IPV6_EX	M_HASHTYPE_HASH(10)/* IPv6 UDP 4-tuple +
 							    * ext hdrs */
 
-#define	M_HASHTYPE_OPAQUE		63	/* ordering, not affinity */
+#define	M_HASHTYPE_OPAQUE		0x3f	/* ordering, not affinity */
 #define	M_HASHTYPE_OPAQUE_HASH		M_HASHTYPE_HASH(M_HASHTYPE_OPAQUE)
 						/* ordering+hash, not affinity*/
 
 #define	M_HASHTYPE_CLEAR(m)	((m)->m_pkthdr.rsstype = 0)
-#define	M_HASHTYPE_GET(m)	((m)->m_pkthdr.rsstype)
+#define	M_HASHTYPE_GET(m)	((m)->m_pkthdr.rsstype & ~M_HASHTYPE_INNER)
 #define	M_HASHTYPE_SET(m, v)	((m)->m_pkthdr.rsstype = (v))
 #define	M_HASHTYPE_TEST(m, v)	(M_HASHTYPE_GET(m) == (v))
-#define	M_HASHTYPE_ISHASH(m)	(M_HASHTYPE_GET(m) & M_HASHTYPE_HASHPROP)
+#define	M_HASHTYPE_ISHASH(m)	\
+    (((m)->m_pkthdr.rsstype & M_HASHTYPE_HASHPROP) != 0)
+#define	M_HASHTYPE_SETINNER(m)	do {			\
+	(m)->m_pkthdr.rsstype |= M_HASHTYPE_INNER;	\
+    } while (0)
 
 /*
  * External mbuf storage buffer types.
@@ -792,6 +797,7 @@ int		 mb_unmapped_compress(struct mbuf *m);
 struct mbuf 	*mb_unmapped_to_ext(struct mbuf *m);
 void		 mb_free_notready(struct mbuf *m, int count);
 void		 m_adj(struct mbuf *, int);
+void		 m_adj_decap(struct mbuf *, int);
 int		 m_apply(struct mbuf *, int, int,
 		    int (*)(void *, void *, u_int), void *);
 int		 m_append(struct mbuf *, int, c_caddr_t);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103311138.12VBcZKp018609>