]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
af-packet: implement pinned-maps-name
authorEric Leblond <eric@regit.org>
Sun, 20 Jan 2019 18:53:09 +0000 (19:53 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 18 Jun 2019 05:07:02 +0000 (07:07 +0200)
src/runmode-af-packet.c
src/source-af-packet.h
src/util-ebpf.c
src/util-ebpf.h

index b6d235616b2d731ccc6fda9f1bbcc8fe6a5ba4a1..59ccb82a8e41be5119afe7ace6ff3fd214576173 100644 (file)
@@ -393,6 +393,14 @@ static void *ParseAFPConfig(const char *iface)
                         aconf->iface);
             aconf->ebpf_t_config.flags |= EBPF_PINNED_MAPS;
         }
+        const char *pinned_maps_name;
+        if (ConfGetChildValueWithDefault(if_root, if_default,
+                    "pinned-maps-name",
+                    &pinned_maps_name) != 1) {
+            aconf->ebpf_t_config.pinned_maps_name = pinned_maps_name;
+        } else {
+            aconf->ebpf_t_config.pinned_maps_name = NULL;
+        }
     }
 #endif
 
@@ -401,7 +409,7 @@ static void *ParseAFPConfig(const char *iface)
     if (aconf->ebpf_lb_file && cluster_type == PACKET_FANOUT_EBPF) {
         int ret = EBPFLoadFile(aconf->iface, aconf->ebpf_lb_file, "loadbalancer",
                                &aconf->ebpf_lb_fd,
-                               aconf->ebpf_t_config.flags);
+                               &aconf->ebpf_t_config);
         if (ret != 0) {
             SCLogWarning(SC_ERR_INVALID_VALUE, "Error when loading eBPF lb file");
         }
@@ -441,7 +449,7 @@ static void *ParseAFPConfig(const char *iface)
 #ifdef HAVE_PACKET_EBPF
         int ret = EBPFLoadFile(aconf->iface, aconf->ebpf_filter_file, "filter",
                                &aconf->ebpf_filter_fd,
-                               aconf->ebpf_t_config.flags);
+                               &aconf->ebpf_t_config);
         if (ret != 0) {
             SCLogWarning(SC_ERR_INVALID_VALUE,
                          "Error when loading eBPF filter file");
@@ -505,7 +513,7 @@ static void *ParseAFPConfig(const char *iface)
 #ifdef HAVE_PACKET_XDP
         int ret = EBPFLoadFile(aconf->iface, aconf->xdp_filter_file, "xdp",
                                &aconf->xdp_filter_fd,
-                               aconf->ebpf_t_config.flags);
+                               &aconf->ebpf_t_config);
         if (ret != 0) {
             SCLogWarning(SC_ERR_INVALID_VALUE,
                          "Error when loading XDP filter file");
index f9d135fdbe38e2f122ee9f8b3ef9956811cc47a1..88a277d9ac2aa69d8fd7893194ad3e4480e7267a 100644 (file)
@@ -47,6 +47,7 @@
 #define AFP_MODE_XDP_BYPASS 1
 #define AFP_MODE_EBPF_BYPASS 2
 struct ebpf_timeout_config {
+    const char *pinned_maps_name;
     uint16_t cpus_count;
     uint8_t mode;
     uint8_t flags;
index 0bb1b4ffac87cc7f49331fb88406644a6353ff46..48038570b1555e5c44cac0924fcc4b5930901fcd 100644 (file)
@@ -170,10 +170,20 @@ static int EBPFLoadPinnedMapsFile(LiveDevice *livedev, const char *file)
     return bpf_obj_get(pinnedpath);
 }
 
-static int EBPFLoadPinnedMaps(LiveDevice *livedev, uint8_t flags)
+static int EBPFLoadPinnedMaps(LiveDevice *livedev, struct ebpf_timeout_config *config)
 {
     int fd_v4 = -1, fd_v6 = -1;
 
+    /* First try to load the eBPF check map and return if found */
+    if (config->pinned_maps_name) {
+        int ret = -1;
+        ret = EBPFLoadPinnedMapsFile(livedev, config->pinned_maps_name);
+        if (ret == 0) {
+            /* pinned maps found, let's just exit as XDP filter is in place */
+            return ret;
+        }
+    }
+
     /* Get flow v4 table */
     fd_v4 = EBPFLoadPinnedMapsFile(livedev, "flow_table_v4");
     if (fd_v4 < 0) {
@@ -200,6 +210,8 @@ static int EBPFLoadPinnedMaps(LiveDevice *livedev, uint8_t flags)
     bpf_map_data->array[1].fd = fd_v6;
     bpf_map_data->array[1].name = SCStrdup("flow_table_v6");
     bpf_map_data->last = 2;
+    /* Attach the bpf_maps_info to the LiveDevice via the device storage */
+    LiveDevSetStorageById(livedev, g_livedev_storage_id, bpf_map_data);
 
     return 0;
 }
@@ -217,7 +229,7 @@ static int EBPFLoadPinnedMaps(LiveDevice *livedev, uint8_t flags)
  * \return -1 in case of error and 0 in case of success
  */
 int EBPFLoadFile(const char *iface, const char *path, const char * section,
-                 int *val, uint8_t flags)
+                 int *val, struct ebpf_timeout_config *config)
 {
     int err, pfd;
     bool found = false;
@@ -231,9 +243,9 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section,
     if (livedev == NULL)
         return -1;
 
-    if (flags & EBPF_XDP_CODE) {
+    if (config->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) {
+        if (EBPFLoadPinnedMaps(livedev, config) == 0) {
             return 0;
         }
     }
@@ -269,7 +281,7 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section,
     bpf_object__for_each_program(bpfprog, bpfobj) {
         const char *title = bpf_program__title(bpfprog, 0);
         if (!strcmp(title, section)) {
-            if (flags & EBPF_SOCKET_FILTER) {
+            if (config->flags & EBPF_SOCKET_FILTER) {
                 bpf_program__set_socket_filter(bpfprog);
             } else {
                 bpf_program__set_xdp(bpfprog);
@@ -334,7 +346,7 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section,
             return -1;
         }
         bpf_map_data->array[bpf_map_data->last].unlink = 0;
-        if (flags & EBPF_PINNED_MAPS) {
+        if (config->flags & EBPF_PINNED_MAPS) {
             SCLogNotice("Pinning: %d to %s", bpf_map_data->array[bpf_map_data->last].fd,
                     bpf_map_data->array[bpf_map_data->last].name);
             char buf[1024];
@@ -345,7 +357,7 @@ int EBPFLoadFile(const char *iface, const char *path, const char * section,
                 SCLogError(SC_ERR_AFP_CREATE, "Can not pin: %s", strerror(errno));
             }
             /* Don't unlink pinned maps in XDP mode to avoid a state reset */
-            if (flags & EBPF_XDP_CODE) {
+            if (config->flags & EBPF_XDP_CODE) {
                 bpf_map_data->array[bpf_map_data->last].unlink = 0;
             } else {
                 bpf_map_data->array[bpf_map_data->last].unlink = 1;
index f9dbefe1e3b872516737fa0becccac9bbdd7be14..5adf75e2c233d4db3371088b1a13aa89528deaae 100644 (file)
@@ -67,7 +67,7 @@ struct pair {
 
 int EBPFGetMapFDByName(const char *iface, const char *name);
 int EBPFLoadFile(const char *iface, const char *path, const char * section,
-                 int *val, uint8_t flags);
+                 int *val, struct ebpf_timeout_config *config);
 int EBPFSetupXDP(const char *iface, int fd, uint8_t flags);
 
 int EBPFCheckBypassedFlowTimeout(struct flows_stats *bypassstats,