version 1.1, 2022/07/05 21:58:48
|
version 1.2, 2022/07/15 10:46:17
|
Line 5
|
Line 5
|
#include "fwsync.h" |
#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 */ |