Pinned maps usage
-----------------
-Pnned maps stay attached to the system if the creating process disappear and
+Pinned maps stay attached to the system if the creating process disappear and
they can also be accessed by external tools. In Suricata bypass case, this can be
used to keep active bypassed flow tables so Suricata is not hit by previsouly bypassed flows when
restarting. In the socket filter case, this can be used to maintain a map from tools outside
aconf->ebpf_t_config.mode = AFP_MODE_XDP_BYPASS;
aconf->ebpf_t_config.flags |= EBPF_XDP_CODE;
aconf->xdp_filter_file = ebpf_file;
+ /* TODO FIXME Do we really have a usage of setting XDP and not bypassing ? */
ConfGetChildValueBoolWithDefault(if_root, if_default, "bypass", &conf_val);
if (conf_val) {
#ifdef HAVE_PACKET_XDP
return bpf_maps->array[i].fd;
}
}
+
+ /* Fallback by getting pinned maps ? */
+
return -1;
}
+static int EBPFLoadPinnedMapsFile(LiveDevice *livedev, const char *file)
+{
+ char pinnedpath[1024];
+ snprintf(pinnedpath, sizeof(pinnedpath),
+ "/sys/fs/bpf/suricata-%s-%s",
+ livedev->dev,
+ file);
+
+ return bpf_obj_get(pinnedpath);
+}
+
+static int EBPFLoadPinnedMaps(LiveDevice *livedev, uint8_t flags)
+{
+ int fd_v4 = -1, fd_v6 = -1;
+
+ /* Get flow v4 table */
+ fd_v4 = EBPFLoadPinnedMapsFile(livedev, "flow_table_v4");
+ if (fd_v4 < 0) {
+ return fd_v4;
+ }
+
+ /* Get flow v6 table */
+ fd_v6 = EBPFLoadPinnedMapsFile(livedev, "flow_table_v6");
+ if (fd_v6 < 0) {
+ SCLogWarning(SC_ERR_INVALID_ARGUMENT,
+ "Found a flow_table_v4 map but no flow_table_v6 map");
+ return fd_v6;
+ }
+
+ struct bpf_maps_info *bpf_map_data = SCCalloc(1, sizeof(*bpf_map_data));
+ if (bpf_map_data == NULL) {
+ SCLogError(SC_ERR_MEM_ALLOC, "Can't allocate bpf map array");
+ return -1;
+ }
+ SC_ATOMIC_INIT(bpf_map_data->ipv4_hash_count);
+ SC_ATOMIC_INIT(bpf_map_data->ipv6_hash_count);
+ bpf_map_data->array[0].fd = fd_v4;
+ bpf_map_data->array[0].name = SCStrdup("flow_table_v4");
+ bpf_map_data->array[1].fd = fd_v6;
+ bpf_map_data->array[1].name = SCStrdup("flow_table_v6");
+ bpf_map_data->last = 2;
+
+ return 0;
+}
+
/**
* Load a section of an eBPF file
*
if (livedev == NULL)
return -1;
+ if (flags & EBPF_XDP_CODE) {
+ /* We try to get our flow table maps and if we have them we can simply return */
+ if (EBPFLoadPinnedMaps(livedev, flags) == 0) {
+ return 0;
+ }
+ }
+
if (! path) {
SCLogError(SC_ERR_INVALID_VALUE, "No file defined to load eBPF from");
return -1;