File:  [ELWIX - Embedded LightWeight unIX -] / fwsync / driver / Attic / fwsync_utils.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Fri Jul 15 10:46:17 2022 UTC (22 months, 2 weeks ago) by misho
Branches: MAIN
CVS tags: HEAD
import hash functions from ip_fw_dynamic.c

/*************************************************************************
* (C) 2022 CloudSigma AG - Sofia/Bulgaria
*  by Michael Pounov <misho@elwix.org>
**************************************************************************/
#include "fwsync.h"


#ifndef IPFIREWALL_JENKINSHASH
__inline uint32_t
fwsync_hash_packet(const struct ipfw_flow_id *id)
{
	uint32_t i;

#ifdef INET6
	if (IS_IP6_FLOW_ID(id))
		i = ntohl((id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
		    (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
		    (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
		    (id->src_ip6.__u6_addr.__u6_addr32[3]));
	else
#endif /* INET6 */
	i = (id->dst_ip) ^ (id->src_ip);
	i ^= (id->dst_port) ^ (id->src_port);
	return (i);
}

__inline uint32_t
fwsync_hash_parent(const struct ipfw_flow_id *id, const void *rule)
{

	return (fwsync_hash_packet(id) ^ ((uintptr_t)rule));
}

#else /* IPFIREWALL_JENKINSHASH */

VNET_DEFINE_STATIC(uint32_t, dyn_hashseed);
#define	V_dyn_hashseed		VNET(dyn_hashseed)

static __inline int
addrcmp4(const struct ipfw_flow_id *id)
{

	if (id->src_ip < id->dst_ip)
		return (0);
	if (id->src_ip > id->dst_ip)
		return (1);
	if (id->src_port <= id->dst_port)
		return (0);
	return (1);
}

#ifdef INET6
static __inline int
addrcmp6(const struct ipfw_flow_id *id)
{
	int ret;

	ret = memcmp(&id->src_ip6, &id->dst_ip6, sizeof(struct in6_addr));
	if (ret < 0)
		return (0);
	if (ret > 0)
		return (1);
	if (id->src_port <= id->dst_port)
		return (0);
	return (1);
}

__inline uint32_t
fwsync_hash_packet6(const struct ipfw_flow_id *id)
{
	struct tuple6 {
		struct in6_addr	addr[2];
		uint16_t	port[2];
	} t6;

	if (addrcmp6(id) == 0) {
		t6.addr[0] = id->src_ip6;
		t6.addr[1] = id->dst_ip6;
		t6.port[0] = id->src_port;
		t6.port[1] = id->dst_port;
	} else {
		t6.addr[0] = id->dst_ip6;
		t6.addr[1] = id->src_ip6;
		t6.port[0] = id->dst_port;
		t6.port[1] = id->src_port;
	}
	return (jenkins_hash32((const uint32_t *)&t6,
	    sizeof(t6) / sizeof(uint32_t), V_dyn_hashseed));
}
#endif

__inline uint32_t
fwsync_hash_packet(const struct ipfw_flow_id *id)
{
	struct tuple4 {
		in_addr_t	addr[2];
		uint16_t	port[2];
	} t4;

	if (IS_IP4_FLOW_ID(id)) {
		/* All fields are in host byte order */
		if (addrcmp4(id) == 0) {
			t4.addr[0] = id->src_ip;
			t4.addr[1] = id->dst_ip;
			t4.port[0] = id->src_port;
			t4.port[1] = id->dst_port;
		} else {
			t4.addr[0] = id->dst_ip;
			t4.addr[1] = id->src_ip;
			t4.port[0] = id->dst_port;
			t4.port[1] = id->src_port;
		}
		return (jenkins_hash32((const uint32_t *)&t4,
		    sizeof(t4) / sizeof(uint32_t), V_dyn_hashseed));
	} else
#ifdef INET6
	if (IS_IP6_FLOW_ID(id))
		return (fwsync_hash_packet6(id));
#endif
	return (0);
}

__inline uint32_t
fwsync_hash_parent(const struct ipfw_flow_id *id, const void *rule)
{

	return (jenkins_hash32((const uint32_t *)&rule,
	    sizeof(rule) / sizeof(uint32_t), fwsync_hash_packet(id)));
}
#endif /* IPFIREWALL_JENKINSHASH */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>