From 511f60656b84bddfeafb3e545ec2b7bccdeaaf11 Mon Sep 17 00:00:00 2001 From: gogapp Date: Thu, 27 Sep 2018 13:48:48 +0530 Subject: [PATCH] Implement RHHH Algorithm. --- .vscode/settings.json | 6 + Makefile | 2 +- include/gatekeeper_rhhh.h | 107 ++++ lib/gatekeeper_rhhh.c | 1044 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1158 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json create mode 100644 include/gatekeeper_rhhh.h create mode 100644 lib/gatekeeper_rhhh.c diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..057e06a3d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "vector": "cpp", + "iostream": "cpp" + } +} \ No newline at end of file diff --git a/Makefile b/Makefile index 1686167b3..abd05a8cf 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ SRCS-y += sol/main.c # Libraries. SRCS-y += lib/mailbox.c lib/net.c lib/flow.c lib/ipip.c \ lib/luajit-ffi-cdata.c lib/launch.c lib/lpm.c lib/acl.c lib/varip.c \ - lib/l2.c lib/space_saving.c + lib/l2.c lib/space_saving.c lib/gatekeeper_rhhh.c LDLIBS += $(LDIR) -Bstatic -lluajit-5.1 -Bdynamic -lm -lmnl CFLAGS += $(WERROR_FLAGS) -I${GATEKEEPER}/include -I/usr/local/include/luajit-2.0/ diff --git a/include/gatekeeper_rhhh.h b/include/gatekeeper_rhhh.h new file mode 100644 index 000000000..ca4a6ca4e --- /dev/null +++ b/include/gatekeeper_rhhh.h @@ -0,0 +1,107 @@ +/* + * Gatekeeper - DoS protection system. + * Copyright (C) 2016 Digirati LTDA. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _GATEKEEPER_RHHH_H_ +#define _GATEKEEPER_RHHH_H_ + +#include "space_saving.h" + +#ifndef DIMENSION +#define DIMENSION 1 +#endif + +#ifndef NUM_V4_COUNTERS +#define NUM_V4_COUNTERS 5 +#endif + +#ifndef NUM_V6_COUNTERS +#define NUM_V6_COUNTERS 17 +#endif + +extern struct rte_hash *counter_ip4[NUM_V4_COUNTERS]; +extern struct rte_hash *counter_ip6[NUM_V6_COUNTERS]; + +typedef struct heavyhitter { + struct ip_key key; + + union { + /* Mask for IPv4 packets */ + struct { + uint32_t src_mask; + uint32_t dst_mask; + } v4; + + /* Mask for IPv6 packets */ + struct { + uint8_t src_mask[16]; + uint8_t dst_mask[16]; + } v6; + } msk; + + uint32_t upr_bnd; + uint32_t lwr_bnd; +} HeavyHitter; + +typedef struct descendant { + struct ip_key key; + union { + /* Mask for IPv4 packet. */ + struct { + uint32_t src_mask; + uint32_t dst_mask; + } v4; + + /* Mask for IPv6 packet. */ + struct { + uint8_t src_mask[16]; + uint8_t dst_mask[16]; + } v6; + } msk; +} Descendant; + +double dblmax(double a, double b); + +double two_to_the_k(int k); + +extern int +rhhh_init(unsigned int socket_id, uint16_t proto, double prob); + +void +rhhh_deinit(uint16_t proto); + +extern int +rhhh_update(unsigned int socket_id, struct ip_key *key); + +static +struct rte_hash * +create_dblcounter(unsigned int socket_id, uint16_t proto, int dblcounter_id, + int dblcounter_size); + +extern int +rhhh1D_v4_output(double threshold, unsigned int socket_id); + +extern int +calcPred2D_v4(struct ip_key *key, uint32_t src_mask, uint32_t dst_mask); + +extern int +rhhh2D_v4_output(double threshold, unsigned int socket_id); + +extern int +rhhh1D_v6_output(double threshold, unsigned int socket_id); + +#endif /* _GATEKEEPER_RHHH_H_ */ diff --git a/lib/gatekeeper_rhhh.c b/lib/gatekeeper_rhhh.c new file mode 100644 index 000000000..4033fbd13 --- /dev/null +++ b/lib/gatekeeper_rhhh.c @@ -0,0 +1,1044 @@ +/* + * Gatekeeper - DoS protection system. + * Copyright (C) 2016 Digirati LTDA. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* + * Implementation of RHHH algorithm in Gatekeeper. + * + * The script is based on reserch paper on Randomized Hierarchical Heavy Hitters + * algorithm by Ran Ben Basat, Gil Einziger, Roy Friedman, Marcelo C. Luizelli + * and Erez Waisbard. https://arxiv.org/pdf/1707.06778.pdf. + */ + +#include +#include +#include +#include + +#include + +#include "gatekeeper_rhhh.h" +#include "space_saving.h" + +#if NUM_V4_COUNTERS == 5 /* IPv4 byte heirarchies. */ +/* Masks for IPv4 byte heirarchies. */ +uint32_t mask_v4[NUM_V4_COUNTERS] = { + 0xFFFFFFFFu, 0xFFFFFF00u, 0xFFFF0000u, 0xFF000000u, 0x00000000u +}; + +uint8_t leveleps_v4[NUM_V4_COUNTERS] = { 32, 24, 16, 8, 0 }; + +#elif NUM_V4_COUNTERS == 33 /* IPv4 bit heirarchies. */ +/* Mask for IPv4 bit heirarchies. */ +uint32_t mask_v4[NUM_V4_COUNTERS] = { + 0xFFFFFFFFu << 0, 0xFFFFFFFFu << 1, 0xFFFFFFFFu << 2, + 0xFFFFFFFFu << 3, 0xFFFFFFFFu << 4, 0xFFFFFFFFu << 5, + 0xFFFFFFFFu << 6, 0xFFFFFFFFu << 7, 0xFFFFFFFFu << 8, + 0xFFFFFFFFu << 9, 0xFFFFFFFFu << 10, 0xFFFFFFFFu << 11, + 0xFFFFFFFFu << 12, 0xFFFFFFFFu << 13, 0xFFFFFFFFu << 14, + 0xFFFFFFFFu << 15, 0xFFFFFFFFu << 16, 0xFFFFFFFFu << 17, + 0xFFFFFFFFu << 18, 0xFFFFFFFFu << 19, 0xFFFFFFFFu << 20, + 0xFFFFFFFFu << 21, 0xFFFFFFFFu << 22, 0xFFFFFFFFu << 23, + 0xFFFFFFFFu << 24, 0xFFFFFFFFu << 25, 0xFFFFFFFFu << 26, + 0xFFFFFFFFu << 27, 0xFFFFFFFFu << 28, 0xFFFFFFFFu << 29, + 0xFFFFFFFFu << 30, 0xFFFFFFFFu << 31, 0x00000000u +}; + +uint8_t leveleps_v4[NUM_V4_COUNTERS] = { + 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +}; +#endif /* IPv4 heirarchies. */ + +#if NUM_V6_COUNTERS == 17 /* IPv6 byte heirarchies. */ +/* Mask for IPv6 byte heirarchies. */ +uint8_t mask_v6[NUM_V6_COUNTERS][16] = { + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u} +}; + +uint8_t leveleps_v6[NUM_V6_COUNTERS] = { 64, 56, 48, 40, 32, 24, 16, 8, 0 }; + +#elif NUM_V6_COUNTERS == 129 /* IPv6 bit heirarchies. */ +/* Mask for IPv6 bit heirarchies. */ +uint8_t mask_v6[NUM_V6_COUNTERS][16] = { + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFFu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFEu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xFCu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xF8u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xF0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xE0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0xC0u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0x80u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u}, + {0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, + 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u} +}; + +uint8_t leveleps_v6[NUM_V6_COUNTERS] = { + 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, + 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, + 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +}; +#endif /* IPv6 heirarchies. */ + +/* TODO: Test the code for correctness. */ + +#ifndef VMULT +#define VMULT 1 +#endif + +#if VMULT>1 +#define PROB +#endif + +struct rte_ring *ip4_hhh; +struct rte_ring *ip6_hhh; + +HeavyHitter *output_v4; +HeavyHitter *output_v6; +Descendant *Hp_table_v4; +Descendant *Hp_table_v6; + +int ss_epsilon = 512; +int opspace; +int hpspace; +int numhit; +int numdesc; + +#ifdef PROB +double ignoreProb; +double logIgnoreProb; +double minusQuantity; +int nrIgnore; +#endif + +double dblmax(double a, double b) +{ + return (a >= b ? a : b); +} + +double two_to_the_k(int k) +{ + k = k % 9; + double ans = 1; + while (k > 0) + { + ans *= 2; + k--; + } + return ans ; +} + +int +rhhh_init(unsigned int socket_id, uint16_t proto, double prob) +{ + int ret; + int i; + srand(time(0)); + + #ifdef PROB + ignoreProb = 1.0 - prob; + logIgnoreProb = log(ignoreProb); + minusQuantity = log(RAND_MAX) / logIgnoreProb; + nrIgnore = log((double)rand()) / logIgnoreProb - minusQuantity; + #endif + if (proto == ETHER_TYPE_IPv4) { + for(i = 0; i < NUM_V4_COUNTERS; i++) { + counter_ip4[i] = create_counter_table(socket_id, + proto, i, max(ss_epsilon, + two_to_the_k(leveleps_v4[i]))); + if (counter_ip4[i] == NULL) { + ret = -1; + goto out; + } + } + } else if (proto == ETHER_TYPE_IPv6) { + for(i = 0; i < NUM_V6_COUNTERS; i++) { + counter_ip6[i] = create_counter_table(socket_id, + proto, i, max(ss_epsilon, + two_to_the_k(leveleps_v6[i]))); + if (counter_ip6[i] == NULL) { + ret = -1; + goto out; + } + } + } else { + ret = -1; + goto out; + } + +out: + return ret; +} + +void +rhhh_deinit(uint16_t proto) +{ + int i; + if (proto == ETHER_TYPE_IPv4) { + for(i = 0; i < NUM_V4_COUNTERS; i++) + rte_hash_free(counter_ip4[i]); + } else if (proto == ETHER_TYPE_IPv6) { + for(i = 0; i < NUM_V6_COUNTERS; i++) + rte_hash_free(counter_ip6[i]); + } +} + +int +rhhh_update(unsigned int socket_id, struct ip_key *key) +{ + int ret; + + #ifdef PROB + if (nrIgnore--) return; + nrIgnore = log((double)rand()) / logIgnoreProb - minusQuantity; + #endif + if (key->proto == ETHER_TYPE_IPv4) { + short i = rand() % NUM_V4_COUNTERS; + //printf("MASK = %d\n", i); + #if DIMENSION == 1 + key->k.v4.src.s_addr = key->k.v4.src.s_addr & + mask_v4[i]; + #else + int src_ptr = 0, dst_ptr = 0; + src_ptr = i % NUM_V4_COUNTERS; + dst_ptr = i / NUM_V4_COUNTERS; + key->k.v4.src.s_addr = key->k.v4.src.s_addr & + mask_v4[src_ptr]; + key->k.v4.src.s_addr = key->k.v4.src.s_addr & + mask_v4[dst_ptr]; + #endif + ret = space_saving(socket_id, key->proto, + key, counter_ip4[i]); + //printf("Iterating\n"); + //SSiterate(counter_ip4[i], key->proto, 1); + + } else if (key->proto == ETHER_TYPE_IPv6) { + short i = rand() % NUM_V6_COUNTERS; + #if DIMENSION == 1 + int j; + for(j = 0; j < 16; j++) { + uint8_t src_bits = key->k.v6.src.s6_addr[j]; + src_bits = src_bits & mask_v6[i][j]; + key->k.v6.src.s6_addr[j] = src_bits; + } + #else + int src_ptr = 0, dst_ptr = 0, j; + src_ptr = i % NUM_V6_COUNTERS; + dst_ptr = i / NUM_V6_COUNTERS; + for(j = 0; j < 16; j++) { + uint8_t src_bits = key->k.v6.src.s6_addr[j]; + uint8_t dst_bits = key->k.v6.dst.s6_addr[j]; + src_bits = src_bits & mask_v6[src_ptr][j]; + dst_bits = dst_bits & mask_v6[dst_ptr][j]; + key->k.v6.src.s6_addr[j] = src_bits; + key->k.v6.dst.s6_addr[j] = dst_bits; + } + #endif + ret = space_saving(socket_id, key->proto, + key, counter_ip6[i]); + } else + ret = -1; + + return ret; +} + +static +struct rte_hash * +create_dblcounter(unsigned int socket_id, uint16_t proto, int dblcounter_id, + int dblcounter_size) +{ + int ret; + + int key_len = proto == ETHER_TYPE_IPv4 ? + 2 * sizeof(struct in_addr) : 2 * sizeof(struct in6_addr); + + char dblcounter_name[64]; + ret = snprintf(dblcounter_name, sizeof(dblcounter_name), + "Double_Counter_%d_%d", proto, dblcounter_id); + RTE_VERIFY(ret > 0 && ret < (int)sizeof(dblcounter_name)); + + struct rte_hash_parameters dblcounter_params = { + .name = dblcounter_name, + .entries = dblcounter_size, + .key_len = key_len, + .hash_func = DEFAULT_HASH_FUNC, + .hash_func_init_val = 0, + .reserved = 0, + .socket_id = socket_id, + }; + + if (proto == ETHER_TYPE_IPv4) { + struct rte_hash *dblcounter = rte_hash_create( + &dblcounter_params); + if (dblcounter == NULL) { + RTE_LOG(ERR, HASH, "Double_counter_%d_%d cannot " + "be created!\n", proto, dblcounter_id); + ret = -1; + } + return dblcounter; + } + + if (proto == ETHER_TYPE_IPv6) { + struct rte_hash *dblcounter = rte_hash_create( + &dblcounter_params); + if (dblcounter == NULL) { + RTE_LOG(ERR, HASH, "Double_Counter_%d_%d cannot " + "be created!\n", proto, dblcounter_id); + ret = -1; + } + return dblcounter; + } + + return NULL; +} + +extern int +rhhh1D_v4_output(double threshold, unsigned int socket_id) +{ + int iter_ret, ret; + struct ip_key *key; + struct ip_data *element; + uint32_t next = 0; + int src_ptr; + + int htsize = 2048; + struct rte_hash *dbl_counter = create_dblcounter(socket_id, + ETHER_TYPE_IPv4, 0, htsize); + +#ifdef PROB + double adjustedThreshold = + (1 - ignoreProb) * (threshold / ((double)NUM_V4_COUNTERS)); +#else + double adjustedThreshold = threshold / ((double) NUM_V4_COUNTERS); +#endif + + printf("Adjusted threshold = %f\n", adjustedThreshold); + numhit = 0; + int output_space = 2; + + int level, j; + unsigned long long * tmp; + + int dbl_cnt; + int z = 4; + + output_v4 = (HeavyHitter *) calloc(sizeof(HeavyHitter), output_space); + + //struct rte_hash *ct_table[NUM_V4_COUNTERS]; + for (level = 0; level < NUM_V4_COUNTERS; level++) { + printf("Iterating Counter #%d\n", level); + char ct_name[64]; + ret = snprintf(ct_name, sizeof(ct_name), "counter_hash_%d_%d", + ETHER_TYPE_IPv4, level); + RTE_VERIFY(ret > 0 && ret < (int)sizeof(ct_name)); + + //ct_table[level] = rte_hash_find_existing(ct_name); + iter_ret = rte_hash_iterate(counter_ip4[level], ( + const void **)&key, + (void **)&element, &next); + while (iter_ret >= 0) { + src_ptr = level; + printf("Src = %u Dst = %u\n", key->k.v4.src.s_addr, + key->k.v4.dst.s_addr); + int cnt = element->bkt_id; + if (cnt < adjustedThreshold) { + iter_ret = rte_hash_iterate(counter_ip4[level], + (const void **)&key, (void **)&element, + &next); + continue; + } + + uint64_t src = (key->k.v4.src.s_addr); + uint64_t src_key = (src << 32)|((uint64_t)level); + + ret = rte_hash_lookup_data(dbl_counter, + (const void *)&src_key, (void **)&dbl_cnt); + if (ret < 0) { + iter_ret = rte_hash_iterate(counter_ip4[level], + (const void **)&key, (void **)&element, + &next); + continue; + } + + ret = rte_hash_del_key(dbl_counter, &src_key); + if (ret < 0) { + RTE_LOG(ERR, HASH, "IP not found\n"); + continue; + } + + int freq; +#ifdef PROB + freq = (j-dbl_cnt)+(2*z*sqrt((1-ignoreProb)*2*j); +#else + freq = (j-dbl_cnt)+(2*z*sqrt(2*j)); +#endif + if (freq >= adjustedThreshold) { + while (output_space <= numhit) + output_space *= 2; + output_v4 = (HeavyHitter *) + realloc (output_v4, + output_space*sizeof(HeavyHitter)); + output_v4[numhit].key = *key; + output_v4[numhit].msk.v4.src_mask = level; + output_v4[numhit].upr_bnd = j; + output_v4[numhit].lwr_bnd = + j-element->err; + dbl_cnt = output_v4[numhit].lwr_bnd; + numhit++; + } + + if (dbl_cnt > 0 && level+1 < NUM_V4_COUNTERS) { + uint64_t pkey = ((src&mask_v4[level+1]) <<32)| + (level+1); + ret = rte_hash_add_key_data(dbl_counter, + &pkey, (void **)&dbl_cnt); + if (ret < 0) { + RTE_LOG(ERR, HASH, "IP not addeed\n"); + continue; + } + } + iter_ret = rte_hash_iterate(counter_ip4[level], + (const void **)&key, (void **)&element, &next); + } + //free(ct_table[level]); + } + + rte_hash_free(dbl_counter); + output_v4 = (HeavyHitter *)realloc(output_v4, + (numhit)*sizeof(HeavyHitter)); + + printf("\nNum of IPv4 heavy hitters = %d.\n", numhit); + + return ret; +out: + RTE_LOG(ERR, HASH, "Heavy Hitter output could not be generated!\n"); + ret = -1; + +} + +extern int +calcPred2D_v4(struct ip_key *key, uint32_t src_mask, uint32_t dst_mask) +{ + int ret; + int i, j, k, dblcount, src_msk_ptr, dst_msk_ptr, cntr; + numdesc = 0; + struct ip_key newIP; + + for(i = 0; i < numhit; i++) { + uint32_t src = key->k.v4.src.s_addr; + uint32_t dst = key->k.v4.dst.s_addr; + uint32_t hhh_src = output_v4[i].key.k.v4.src.s_addr; + uint32_t hhh_dst = output_v4[i].key.k.v4.dst.s_addr; + uint32_t hhh_src_mask = mask_v4[output_v4[i].msk.v4.src_mask]; + uint32_t hhh_dst_mask = mask_v4[output_v4[i].msk.v4.dst_mask]; + + if ( + (src_mask & hhh_src_mask) == src_mask && + (dst_mask & hhh_dst_mask) == dst_mask && + (src & src_mask) == (hhh_src & src_mask) && + (dst & dst_mask) == (hhh_dst & dst_mask) + ) { + j = 0; + for(k = 0; k < numdesc; k++) { + uint32_t Hp_src = + Hp_table_v4[k].key.k.v4.src.s_addr; + uint32_t Hp_dst = + Hp_table_v4[k].key.k.v4.dst.s_addr; + uint32_t Hp_src_mask = + mask_v4[Hp_table_v4[k].msk.v4.src_mask]; + uint32_t Hp_dst_mask = + mask_v4[Hp_table_v4[k].msk.v4.dst_mask]; + hhh_src = output_v4[k].key.k.v4.src.s_addr; + hhh_dst = output_v4[k].key.k.v4.dst.s_addr; + hhh_src_mask = + mask_v4[output_v4[k].msk.v4.src_mask]; + hhh_dst_mask = + mask_v4[output_v4[k].msk.v4.dst_mask]; + + Hp_table_v4[j] = Hp_table_v4[k]; + if ( + (src_mask&Hp_src_mask != src_mask) || + (dst_mask&Hp_dst_mask != dst_mask) || + (Hp_src&hhh_src_mask != + hhh_src&hhh_src_mask) || + (Hp_dst & hhh_dst_mask != + hhh_dst & hhh_dst_mask) + ) + j++; + } + numdesc = j; + Hp_table_v4[numdesc].msk.v4.src_mask = + output_v4[i].msk.v4.src_mask; + Hp_table_v4[numdesc].msk.v4.dst_mask = + output_v4[i].msk.v4.dst_mask; + Hp_table_v4[numdesc].key = output_v4[i].key; + numdesc++; + while (numdesc >= hpspace) + hpspace *= 2; + Hp_table_v4 = (Descendant *) realloc( + Hp_table_v4, sizeof(Descendant) * hpspace); + } + } + + dblcount = 0; + for(i = 0; i < numdesc; i++) { + dblcount += SSEstLow(counter_ip4[i], &Hp_table_v4[i].key); + } + + for(i = 0; i < numdesc; i++) { + uint32_t Hp_src1 = Hp_table_v4[i].key.k.v4.src.s_addr; + uint32_t Hp_dst1 = Hp_table_v4[i].key.k.v4.dst.s_addr; + uint32_t Hp_src_mask1 = mask_v4[Hp_table_v4[i].msk.v4.src_mask]; + uint32_t Hp_dst_mask1 = mask_v4[Hp_table_v4[i].msk.v4.dst_mask]; + for(j = i + 1; j < numdesc; j++) { + uint32_t Hp_src2 = Hp_table_v4[j].key.k.v4.src.s_addr; + uint32_t Hp_dst2 = Hp_table_v4[j].key.k.v4.dst.s_addr; + uint32_t Hp_src_mask2 = + mask_v4[Hp_table_v4[j].msk.v4.src_mask]; + uint32_t Hp_dst_mask2 = + mask_v4[Hp_table_v4[j].msk.v4.dst_mask]; + uint32_t src_msk = Hp_src_mask1 & Hp_src_mask2; + uint32_t dst_msk = Hp_dst_mask1 & Hp_dst_mask2; + uint32_t src_or = Hp_src1 | Hp_src2; + uint32_t dst_or = Hp_dst1 | Hp_dst2; + uint32_t src_msk_or = Hp_src_mask1 | Hp_src_mask2; + uint32_t dst_msk_or = Hp_dst_mask1 | Hp_dst_mask2; + + if ( + (Hp_src1 & src_msk) != (Hp_src2 & src_msk) || + (Hp_dst1 & dst_msk) != (Hp_dst2 & dst_msk) + ) { + /* There is no IP common to subnets i and j. */ + continue; + } + + newIP.proto = ETHER_TYPE_IPv4; + newIP.k.v4.src.s_addr = src_or; + newIP.k.v4.dst.s_addr = dst_or; + + /* Compute the right mask for new IP. */ + src_msk_ptr = 0; + while (mask_v4[src_msk_ptr] != src_msk_or) { + dst_msk_ptr = 0; + while (mask_v4[dst_msk_ptr] != dst_msk_or) + dst_msk_ptr++; + src_msk_ptr++; + } + assert( (mask_v4[src_msk_ptr] == src_msk_or) && + (mask_v4[dst_msk_ptr] == dst_msk_or)); + + cntr = (src_msk_ptr * NUM_V4_COUNTERS) + dst_msk_ptr; + dblcount -= SSEstUpp(counter_ip4[cntr], &newIP); + } + } + return dblcount; +} + +extern int +rhhh2D_v4_output(double threshold, unsigned int socket_id) +{ + int ret; + int i, bkt_ptr, element_ptr, dblcount, src_ptr, dst_ptr; + int z = 4; + numhit = 0;; + + struct counter_bucket* min_bkt = list_first_entry(&bkt_head_ip4, + struct counter_bucket, list); + int min_bkt_id = min_bkt->bkt_id; + +#ifdef PROB + double adjustedThreshold = + (1 - ignoreProb) * (threshold / ((double)NUM_V4_COUNTERS)); +#else + double adjustedThreshold = threshold / ((double) NUM_V4_COUNTERS); +#endif + + output_v4 = (HeavyHitter *) calloc(opspace, sizeof(HeavyHitter)); + Hp_table_v4 = (Descendant *) calloc(hpspace, sizeof(Descendant)); + + for(i = 0; i < NUM_V4_COUNTERS; i++) { + struct counter_bucket *entry, *next; + src_ptr = i / 5; + dst_ptr = i % 5; + list_for_each_entry_safe(entry, next, &bkt_head_ip4, list) { + struct rte_hash *bkt_ip4 = entry->bkt.bkt_ip4; + struct ip_key * key; + struct ip_data *element; + uint32_t next = 0; + while (1) { + ret = rte_hash_iterate(bkt_ip4, (const void **) + &key, (void **)&element, &next); + if (ret < 0) + break; + + int cnt = element->bkt_id; + if (cnt < adjustedThreshold) + continue; + + dblcount = calcPred2D_v4(key, mask_v4[src_ptr], + mask_v4[dst_ptr]); + + double freq; +#ifdef PROB + freq = (cnt - dblcount) + (2 * z * sqrt( + (1 - ignoreProb) * 2 * dblcount); +#else + freq = (cnt - dblcount) + + (2 * z * sqrt(2 * dblcount)); +#endif + if (freq >= adjustedThreshold) { + while (opspace <= numhit) + opspace *= 2; + output_v4 = (HeavyHitter *)realloc( + output_v4, + opspace*sizeof(HeavyHitter)); + output_v4[numhit].key = *key; + output_v4[numhit].msk.v4.src_mask = i; + output_v4[numhit].upr_bnd = cnt; + output_v4[numhit].lwr_bnd = + cnt - element->err; + numhit++; + } + + } + } + } + + free(Hp_table_v4); + return ret; +} + +extern int +rhhh1D_v6_output(double threshold, unsigned int socket_id) +{ + /* TODO : Implement 1D RHHH output function for IPV6. */ + int ret; + //struct counter_bucket ct_bkt; + //struct ip_key key; + //struct ip_data element; + //uint32_t next = 0; + int src_ptr; + double SSepsval = 0.001; + + int htsize = (((int)(1.0/SSepsval)) + 1) | 1; + struct rte_hash *hashtable = create_dblcounter(socket_id, + ETHER_TYPE_IPv6, 0, htsize); + +#ifdef PROB + double adjustedThreshold = + (1 - ignoreProb) * (threshold / ((double)NUM_V6_COUNTERS)); +#else + double adjustedThreshold = threshold / ((double) NUM_V6_COUNTERS); +#endif + + numhit = 0; + int output_space = 2; + + int i, j, k; + + unsigned long long * tmp; + + int d_cnt; + int z = 4; + + output_v6 = (HeavyHitter *) calloc(sizeof(HeavyHitter), output_space); + + for (i = 0; i < NUM_V6_COUNTERS; i++) { + for (j = (int)adjustedThreshold; j < streamlen; j++) { + + struct counter_bucket *entry, *next; + src_ptr = i; + //dst_ptr = i % 5; + list_for_each_entry_safe(entry, next, &bkt_head_ip4, + list) { + struct rte_hash *bkt_ip4 = entry->bkt.bkt_ip4; + struct ip_key *key; + struct ip_data *element; + uint32_t next = 0; + while (1) { + ret = rte_hash_iterate(bkt_ip4, + (const void **)&key, + (void **)&element, &next); + if (ret < 0) + break; + + int cnt = element->bkt_id; + if (cnt < adjustedThreshold) + continue; + + //dblcount = calcPred1D(key, + //mask_v6[src_ptr], + //mask_v6[dst_ptr]); + + uint16_t src[16], src_key[16]; + + for (k = 0; k < 16; k++) { + src[k] = + (key->k.v6.src.s6_addr[k]); + src_key[k] = + (src[k] << 8)|((uint16_t)i); + } + + ret = rte_hash_lookup_data(hashtable, + (const void *)&src_key, + (void **)&d_cnt); + if (ret < 0) + continue; + + ret = rte_hash_del_key(hashtable, + &src_key); + if (ret < 0) + goto out; + + int freq; + #ifdef PROB + freq = (j - d_cnt) + (2 * z * + sqrt((1 - ignoreProb) * 2 * j)); + #else + freq = (j - d_cnt) + (2 * z * + sqrt(2 * j)); + #endif + if (freq >= adjustedThreshold) { + while (output_space <= numhit) + output_space *= 2; + output_v6 = (HeavyHitter *) + realloc (output_v6, + output_space * + sizeof(HeavyHitter)); + output_v6[numhit].key = *key; + int l; + for(l = 0; l < 16; l++) + output_v6[numhit]. + msk.v6.src_mask[l] = + mask_v6[i][l]; + output_v6[numhit].upr_bnd = j; + output_v6[numhit].lwr_bnd = + j-element->err; + d_cnt = output_v6[numhit].lwr_bnd; + numhit++; + } + + if (d_cnt > 0 && i+1 < NUM_V6_COUNTERS) + { + uint16_t pkey[NUM_V6_COUNTERS]; + for(k = 0; k < 16; k++) + pkey[k] = ((src[k] & + (uint16_t) + mask_v6[i+1][k]) + << 8)|(i+1); + ret = rte_hash_add_key_data( + hashtable, &pkey, + (void **)&d_cnt); + if (ret < 0) + goto out; + } + } + } + } + } + + rte_hash_free(hashtable); + output_v6 = (HeavyHitter *)realloc(output_v6, + (numhit) * sizeof(HeavyHitter)); + + return ret; +out: + RTE_LOG(ERR, HASH, "Heavy Hitter output could not be generated!\n"); + ret = -1; +} \ No newline at end of file