/************************************************************************* * (C) 2022 CloudSigma AG - Sofia/Bulgaria * by Michael Pounov **************************************************************************/ #include "fwsync.h" #if 0 #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 */ #endif