ebpf: get rid of hash in map value

pull/3952/head
Eric Leblond 6 years ago committed by Victor Julien
parent b07bda7a7b
commit 69d2c8eb75

@ -90,7 +90,6 @@ struct flowv6_keys {
struct pair {
__u32 packets;
__u32 bytes;
__u32 hash;
};
struct bpf_map_def SEC("maps") flow_table_v4 = {

@ -210,6 +210,19 @@ static inline uint32_t FlowGetHash(const Packet *p)
return hash;
}
/**
* Basic hashing function for FlowKey
*
* \note Function only used for bypass
*
* \note this is only used at start to create Flow from pinned maps
* so fairness is not an issue
*/
uint32_t FlowKeyGetHash(FlowKey *fk)
{
return hashword((uint32_t *)fk, sizeof(*fk)/4, flow_config.hash_rand);
}
/* Since two or more flows can have the same hash key, we need to compare
* the flow with the current flow key. */
#define CMP_FLOW(f1,f2) \

@ -78,6 +78,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *,
Flow *FlowGetFromFlowKey(FlowKey *key, struct timespec *ttime, const uint32_t hash);
Flow *FlowGetExistingFlowFromHash(FlowKey * key, uint32_t hash);
uint32_t FlowKeyGetHash(FlowKey *flow_key);
void FlowDisableTcpReuseHandling(void);

@ -2294,8 +2294,7 @@ TmEcode AFPSetBPFFilter(AFPThreadVars *ptv)
* \param key data to use as key in the table
* \return 0 in case of error, 1 if success
*/
static int AFPInsertHalfFlow(int mapd, void *key, uint32_t hash,
unsigned int nr_cpus)
static int AFPInsertHalfFlow(int mapd, void *key, unsigned int nr_cpus)
{
BPF_DECLARE_PERCPU(struct pair, value, nr_cpus);
unsigned int i;
@ -2309,7 +2308,6 @@ static int AFPInsertHalfFlow(int mapd, void *key, uint32_t hash,
for (i = 0; i < nr_cpus; i++) {
BPF_PERCPU(value, i).packets = 0;
BPF_PERCPU(value, i).bytes = 0;
BPF_PERCPU(value, i).hash = hash;
}
if (bpf_map_update_elem(mapd, key, value, BPF_NOEXIST) != 0) {
switch (errno) {
@ -2409,7 +2407,7 @@ static int AFPBypassCallback(Packet *p)
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV4_GET_IPPROTO(p);
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
return 0;
@ -2427,7 +2425,7 @@ static int AFPBypassCallback(Packet *p)
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV4_GET_IPPROTO(p);
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
SCFree(keys[1]);
@ -2458,7 +2456,7 @@ static int AFPBypassCallback(Packet *p)
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV6_GET_NH(p);
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
return 0;
@ -2477,7 +2475,7 @@ static int AFPBypassCallback(Packet *p)
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV6_GET_NH(p);
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
SCFree(keys[1]);
@ -2542,7 +2540,7 @@ static int AFPXDPBypassCallback(Packet *p)
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV4_GET_IPPROTO(p);
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
return 0;
@ -2559,7 +2557,7 @@ static int AFPXDPBypassCallback(Packet *p)
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV4_GET_IPPROTO(p);
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v4_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
SCFree(keys[1]);
@ -2590,7 +2588,7 @@ static int AFPXDPBypassCallback(Packet *p)
keys[0]->vlan_id[0] = p->vlan_id[0];
keys[0]->vlan_id[1] = p->vlan_id[1];
keys[0]->ip_proto = IPV6_GET_NH(p);
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[0],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
return 0;
@ -2609,7 +2607,7 @@ static int AFPXDPBypassCallback(Packet *p)
keys[1]->vlan_id[0] = p->vlan_id[0];
keys[1]->vlan_id[1] = p->vlan_id[1];
keys[1]->ip_proto = IPV6_GET_NH(p);
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1], p->flow_hash,
if (AFPInsertHalfFlow(p->afp_v.v6_map_fd, keys[1],
p->afp_v.nr_cpus) == 0) {
SCFree(keys[0]);
SCFree(keys[1]);

@ -501,11 +501,15 @@ int EBPFSetupXDP(const char *iface, int fd, uint8_t flags)
*
* \return false (this create function never returns true)
*/
static bool EBPFCreateFlowForKey(struct flows_stats *flowstats, FlowKey *flow_key,
uint32_t hash, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt)
static bool EBPFCreateFlowForKey(struct flows_stats *flowstats, void *key,
FlowKey *flow_key, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt,
int mapfd, int cpus_count)
{
Flow *f = FlowGetFromFlowKey(flow_key, ctime, hash);
Flow *f = NULL;
uint32_t hash = FlowKeyGetHash(flow_key);
f = FlowGetFromFlowKey(flow_key, ctime, hash);
if (f == NULL)
return false;
@ -523,6 +527,16 @@ static bool EBPFCreateFlowForKey(struct flows_stats *flowstats, FlowKey *flow_ke
fc->BypassFree = EBPFBypassFree;
fc->todstpktcnt = pkts_cnt;
fc->todstbytecnt = bytes_cnt;
EBPFBypassData *eb = SCCalloc(1, sizeof(EBPFBypassData));
if (eb == NULL) {
SCFree(fc);
FLOWLOCK_UNLOCK(f);
return false;
}
eb->key[0] = key;
eb->mapfd = mapfd;
eb->cpus_count = cpus_count;
fc->bypass_data = eb;
} else {
FLOWLOCK_UNLOCK(f);
return false;
@ -530,6 +544,10 @@ static bool EBPFCreateFlowForKey(struct flows_stats *flowstats, FlowKey *flow_ke
} else {
fc->tosrcpktcnt = pkts_cnt;
fc->tosrcbytecnt = bytes_cnt;
EBPFBypassData *eb = (EBPFBypassData *) fc->bypass_data;
if (eb) {
eb->key[1] = key;
}
}
FLOWLOCK_UNLOCK(f);
return false;
@ -627,9 +645,10 @@ bool EBPFBypassUpdate(Flow *f, void *data, time_t tsec)
return false;
}
typedef bool (*OpFlowForKey)(struct flows_stats *flowstats, FlowKey *flow_key,
uint32_t hash, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt);
typedef bool (*OpFlowForKey)(struct flows_stats *flowstats, void *key,
FlowKey *flow_key, struct timespec *ctime,
uint64_t pkts_cnt, uint64_t bytes_cnt,
int mapfd, int cpus_count);
/**
* Bypassed flows cleaning for IPv4
@ -709,9 +728,9 @@ static int EBPFForEachFlowV4Table(ThreadVars *th_v, LiveDevice *dev, const char
flow_key.vlan_id[1] = next_key.vlan_id[1];
flow_key.proto = next_key.ip_proto;
flow_key.recursion_level = 0;
dead_flow = EBPFOpFlowForKey(flowstats, &flow_key,
BPF_PERCPU(values_array, 0).hash,
ctime, pkts_cnt, bytes_cnt);
dead_flow = EBPFOpFlowForKey(flowstats, &next_key, &flow_key,
ctime, pkts_cnt, bytes_cnt,
mapfd, tcfg->cpus_count);
if (dead_flow) {
found = 1;
}
@ -818,8 +837,9 @@ static int EBPFForEachFlowV6Table(ThreadVars *th_v,
flow_key.vlan_id[1] = next_key.vlan_id[1];
flow_key.proto = next_key.ip_proto;
flow_key.recursion_level = 0;
pkts_cnt = EBPFOpFlowForKey(flowstats, &flow_key, BPF_PERCPU(values_array, 0).hash,
ctime, pkts_cnt, bytes_cnt);
pkts_cnt = EBPFOpFlowForKey(flowstats, &next_key, &flow_key,
ctime, pkts_cnt, bytes_cnt,
mapfd, tcfg->cpus_count);
if (pkts_cnt > 0) {
found = 1;
}

@ -58,7 +58,6 @@ struct flowv6_keys {
struct pair {
uint32_t packets;
uint32_t bytes;
uint32_t hash;
};
typedef struct EBPFBypassData_ {

Loading…
Cancel
Save