Module Name:    src
Committed By:   knakahara
Date:           Fri Sep 24 04:09:32 UTC 2021

Modified Files:
        src/sys/net: toeplitz.c toeplitz.h

Log Message:
Import asymmetric toeplitz hash without memcpy implemented by ryo@n.o.

This implementation has better performance than memcpy'ed one.
(30%-60% improvement in micro benchmark)

import from
    https://github.com/ryo/l2pkt/blob/master/l2pkt/toeplitz_hash.c


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/net/toeplitz.c src/sys/net/toeplitz.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/toeplitz.c
diff -u src/sys/net/toeplitz.c:1.2 src/sys/net/toeplitz.c:1.3
--- src/sys/net/toeplitz.c:1.2	Mon Apr  5 06:56:47 2021
+++ src/sys/net/toeplitz.c	Fri Sep 24 04:09:32 2021
@@ -202,3 +202,87 @@ stoeplitz_to_key(void *key, size_t klen)
 		k[i + 1] = skey;
 	}
 }
+
+/*
+ * e.g.)
+ *
+ * struct in_addr src, dst;
+ * uint16_t srcport, dstport;
+ * toeplitz_vhash(rsskey[], sizeof(rsskey),
+ *                    &src, sizeof(src),
+ *                    &dst, sizeof(dst),
+ *                    &srcport, sizeof(srcport),
+ *                    &dstport, sizeof(dstport),
+ *                    NULL);
+ *
+ * struct in6_addr src6, dst6;
+ * toeplitz_vhash(rsskey[], sizeof(rsskey),
+ *                    &src6, sizeof(src6),
+ *                    &dst6, sizeof(dst6),
+ *                    NULL);
+ *
+ * struct ip *ip;
+ * struct tcphdr *tcp;
+ * toeplitz_vhash(rsskey[], sizeof(rsskey),
+ *                    &ip->ip_src, sizeof(ip->ip_src),
+ *                    &ip->ip_dst, sizeof(ip->ip_dst),
+ *                    &tcp->th_sport, sizeof(tcp->th_sport),
+ *                    &tcp->th_dport, sizeof(tcp->th_dport),
+ *                    NULL);
+ *
+ */
+uint32_t
+toeplitz_vhash(const uint8_t *keyp, size_t keylen, ...)
+{
+	va_list ap;
+	uint32_t hash, v;
+	size_t datalen;
+	uint8_t *datap, key, data;
+	const uint8_t *keyend;
+
+	keyend = keyp + keylen;
+
+	/* first 32bit is initial vector */
+	v = *keyp++;
+	v <<= 8;
+	v |= *keyp++;
+	v <<= 8;
+	v |= *keyp++;
+	v <<= 8;
+	v |= *keyp++;
+
+	hash = 0;
+	va_start(ap, keylen);
+
+	while ((datap = va_arg(ap, uint8_t *)) != NULL) {
+		for (datalen = va_arg(ap, size_t); datalen > 0; datalen--) {
+			/* fetch key and input data by 8bit */
+			if (keyp < keyend)
+				key = *keyp++;
+			else
+				key = 0;
+			data = *datap++;
+
+#define XOR_AND_FETCH_BIT(x)			\
+			if (data & __BIT(x))		\
+				hash ^= v;		\
+			v <<= 1;			\
+			if (key & __BIT(x))		\
+				v |= 1;
+
+			XOR_AND_FETCH_BIT(7);
+			XOR_AND_FETCH_BIT(6);
+			XOR_AND_FETCH_BIT(5);
+			XOR_AND_FETCH_BIT(4);
+			XOR_AND_FETCH_BIT(3);
+			XOR_AND_FETCH_BIT(2);
+			XOR_AND_FETCH_BIT(1);
+			XOR_AND_FETCH_BIT(0);
+
+#undef XOR_AND_FETCH_BIT
+		}
+	}
+	va_end(ap);
+
+	return hash;
+}
Index: src/sys/net/toeplitz.h
diff -u src/sys/net/toeplitz.h:1.2 src/sys/net/toeplitz.h:1.3
--- src/sys/net/toeplitz.h:1.2	Mon Apr  5 06:53:45 2021
+++ src/sys/net/toeplitz.h	Fri Sep 24 04:09:32 2021
@@ -120,4 +120,10 @@ extern const struct stoeplitz_cache *con
 	stoeplitz_hash_ip6port(stoeplitz_cache, (_sa6), (_da6), (_sp), (_dp))
 #endif
 
+/*
+ * system also provided asymmetric toeplitz
+ */
+
+uint32_t	toeplitz_vhash(const uint8_t *, size_t, ...);
+
 #endif /* _SYS_NET_TOEPLITZ_H_ */

Reply via email to