#include <stdio.h>
#include <rte_eal.h>
#include <rte_hash.h>
#include <rte_jhash.h>
#include <rte_lcore.h>
#include <rte_ethdev.h>
//define net key 5 tuple
struct net_key {
uint32_t sip;
uint32_t dip;
uint16_t sport;
uint16_t dport;
char proto;
};
#define HASH_KEY_COUNT 32
static void print_key(struct net_key *key) {
printf("sip: %x, dip: %x, sport: %x, dport: %x, proto: %d\n",
key->sip, key->dip, key->sport, key->dport, key->proto);
}
static struct rte_hash *create_hash_table(const char *name) {
struct rte_hash_parameters *params = (struct rte_hash_parameters*)malloc(sizeof(struct rte_hash_parameters));
if (!params) return NULL;
//set parameter entry member //this fun use rte_jhash entrys 8k
params->name = name;
params->entries = 8192;
params->key_len = sizeof(struct net_key);
params->hash_func = rte_jhash;
params->hash_func_init_val = 0;
params->socket_id = rte_socket_id();
params->extra_flag = 0;
struct rte_hash *hash = rte_hash_create(params);
return hash;
}
int main(int argc, char *argv[]) {
//rte eal init
rte_eal_init(argc, argv);
// key // key hash // key data // key hash, data //4ways set//
struct rte_hash *hash = create_hash_table("hash-table");
if (hash == NULL) {
printf("-->create_hash_table ret null\n");
}
int i = 0;
//set hash 4 ways
for (i = 0; i < HASH_KEY_COUNT; i++) {
//define and set hash net key //5 tuple
// struct net_key nk;
// nk.sip = 0x11111111+i;
// nk.dip = 0x22222222+i;
// nk.sport = 0x3333+i;
// nk.dport = 0x4444+i;
// nk.proto = i%2;
struct net_key *nk = malloc(sizeof(struct net_key));
nk->sip = 0x11111111 + i;
nk->dip = 0x22222222 + i;
nk->sport = 0x3333 + i;
nk->dport = 0x4444 + i;
nk->proto = i % 2;
if (i % 4 == 0) { //use key way by rte hash add key
rte_hash_add_key(hash, nk);
} else if (i % 4 == 1) { //use key hash way by get hash_value by rte hash hash
hash_sig_t hs_value = rte_hash_hash(hash, nk);
rte_hash_add_key_with_hash(hash, nk, hs_value);
} else if (i % 4 == 2) {// key data way // construct data by malloc uint32 tmp and set it with i
uint32_t *tp = malloc(sizeof(uint32_t));
*tp = i;
rte_hash_add_key_data(hash, nk, tp);
} else { // key hash, data way
hash_sig_t hs_value = rte_hash_hash(hash, nk);
uint32_t *tp = malloc(sizeof(uint32_t));
*tp = i;
rte_hash_add_key_with_hash_data(hash, nk, hs_value, tp);
}
}
// define *key by net_key
struct net_key *key = NULL;
//define void vlue point and uint32 next val
void *value = NULL;
uint32_t next = 0;
//traverse hash to get value and key by call rte hash iterate condition >= 0
while(rte_hash_iterate(hash, (const void **)&key, &value, &next) >= 0) {
// if found, value not null print value and key else print key only
if (value != NULL) {
printf("iterate get value:%d, next:%d \t", *(uint32_t *)value, next);
print_key(key);
} else {
printf("iterate get value NULL , next:%d \t",next);
print_key(key);
}
}
//hash lookup by
for (i = 0; i < HASH_KEY_COUNT; i++) {
//define nk and set net key for hash//5 tuple
struct net_key *nk = malloc(sizeof(struct net_key));
nk->sip = 0x11111111 + i;
nk->dip = 0x22222222 + i;
nk->sport = 0x3333 + i;
nk->dport = 0x4444 + i;
nk->proto = i % 2;
int32_t idx = rte_hash_lookup(hash, nk);
printf("hash-->lookup:sip:%x, dip:%x, idx:%d, i:%d \n", nk->sip,nk->dip, idx, i);
rte_hash_del_key(hash, nk);
free(nk);
}
return 0;
}