Patch Detail
Show a patch.
GET /api/patches/24312/?format=api
{ "id": 24312, "url": "https://patchwork.libcamera.org/api/patches/24312/?format=api", "web_url": "https://patchwork.libcamera.org/patch/24312/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20250911092945.16517-6-mzamazal@redhat.com>", "date": "2025-09-11T09:29:35", "name": "[v17,05/12] config: Look up IPA configurables in configuration file", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "034cd15a4944263dbadf8a6266052abcd20077a9", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/24312/mbox/", "series": [ { "id": 5431, "url": "https://patchwork.libcamera.org/api/series/5431/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5431", "date": "2025-09-11T09:29:30", "name": "Add global configuration file", "version": 17, "mbox": "https://patchwork.libcamera.org/series/5431/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/24312/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/24312/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 22A8EC328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 11 Sep 2025 09:30:17 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 32B456937A;\n\tThu, 11 Sep 2025 11:30:16 +0200 (CEST)", "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CEA936935A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 11 Sep 2025 11:30:13 +0200 (CEST)", "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-635-ooD5nlpnPy6XDLCqM5inZQ-1;\n\tThu, 11 Sep 2025 05:30:09 -0400", "from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.12])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 7A2C21800447; Thu, 11 Sep 2025 09:30:08 +0000 (UTC)", "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.34.98])\n\tby mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 0429119560B1; Thu, 11 Sep 2025 09:30:05 +0000 (UTC)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"DTwdt3Bf\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1757583012;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=6LMVQ+nq8t/v6uElAGgjnybmofVcM3zUkbFRTVX7dzg=;\n\tb=DTwdt3BfmaJ6v7URAyaLfNnvp67uzzMcbHv9knUcjLeuu4zcTXgnsKI6W5Obbc0GIMxEYt\n\ts6scRHWYuNPX6MDgvHwm+Hbj7H0YP5KvG4LneH7gcBZ0qOtj4NUzS49vlkSjEeTNu3ryGa\n\tLLheFbJa9TXNp7TwMwkp4z4P8QwFhr4=", "X-MC-Unique": "ooD5nlpnPy6XDLCqM5inZQ-1", "X-Mimecast-MFC-AGG-ID": "ooD5nlpnPy6XDLCqM5inZQ_1757583008", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Milan Zamazal <mzamazal@redhat.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?=\n\t<barnabas.pocze@ideasonboard.com>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, Paul Elder\n\t<paul.elder@ideasonboard.com>", "Subject": "[PATCH v17 05/12] config: Look up IPA configurables in configuration\n\tfile", "Date": "Thu, 11 Sep 2025 11:29:35 +0200", "Message-ID": "<20250911092945.16517-6-mzamazal@redhat.com>", "In-Reply-To": "<20250911092945.16517-1-mzamazal@redhat.com>", "References": "<20250911092945.16517-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.12", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "6Wc6DoVkD1f6zZ3FkI2R_ujxDsQYYxmDsDXpb_651ZY_1757583008", "X-Mimecast-Originator": "redhat.com", "Content-Transfer-Encoding": "8bit", "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "This patch adds configuration options for environment variables used in\nthe IPA proxy.\n\nThe configuration snippet:\n\n configuration:\n ipa:\n config_paths:\n - config path 1\n - config path 2\n - ...\n module_paths:\n - module path 1\n - module path 2\n - ...\n proxy_paths:\n - proxy path 1\n - proxy path 2\n - ...\n force_isolation: BOOL\n\nLIBCAMERA_<IPA_NAME>_TUNING_FILE remains configurable only via the\nenvironment variable; this is supposed to be used only for testing and\ndebugging and it's not clear what to do about IPA names like \"rpi/vc4\"\nand \"rpi/pisp\" exactly.\n\nThere are two ways to pass the configuration to the places where it is\nneeded: Either to pass it as an argument to the method calls that need\nit, or to pass it to the class constructors and extract the needed\nconfiguration from there. This patch uses the second method as it is\nless polluting the code.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n include/libcamera/internal/ipa_manager.h | 7 ++-\n include/libcamera/internal/ipa_proxy.h | 8 ++-\n src/libcamera/camera_manager.cpp | 2 +-\n src/libcamera/ipa_manager.cpp | 39 ++++++++-----\n src/libcamera/ipa_proxy.cpp | 58 +++++++++----------\n .../module_ipa_proxy.cpp.tmpl | 4 +-\n .../module_ipa_proxy.h.tmpl | 2 +-\n 7 files changed, 68 insertions(+), 52 deletions(-)", "diff": "diff --git a/include/libcamera/internal/ipa_manager.h b/include/libcamera/internal/ipa_manager.h\nindex a0d448cf9..b0b44c74a 100644\n--- a/include/libcamera/internal/ipa_manager.h\n+++ b/include/libcamera/internal/ipa_manager.h\n@@ -17,6 +17,7 @@\n #include <libcamera/ipa/ipa_module_info.h>\n \n #include \"libcamera/internal/camera_manager.h\"\n+#include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/ipa_module.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/pub_key.h\"\n@@ -28,7 +29,7 @@ LOG_DECLARE_CATEGORY(IPAManager)\n class IPAManager\n {\n public:\n-\tIPAManager();\n+\tIPAManager(const GlobalConfiguration &configuration);\n \t~IPAManager();\n \n \ttemplate<typename T>\n@@ -42,7 +43,8 @@ public:\n \t\tif (!m)\n \t\t\treturn nullptr;\n \n-\t\tstd::unique_ptr<T> proxy = std::make_unique<T>(m, !self->isSignatureValid(m));\n+\t\tconst GlobalConfiguration &configuration = cm->_d()->configuration();\n+\t\tstd::unique_ptr<T> proxy = std::make_unique<T>(m, !self->isSignatureValid(m), configuration);\n \t\tif (!proxy->isValid()) {\n \t\t\tLOG(IPAManager, Error) << \"Failed to load proxy\";\n \t\t\treturn nullptr;\n@@ -73,6 +75,7 @@ private:\n #if HAVE_IPA_PUBKEY\n \tstatic const uint8_t publicKeyData_[];\n \tstatic const PubKey pubKey_;\n+\tbool forceIsolation_;\n #endif\n };\n \ndiff --git a/include/libcamera/internal/ipa_proxy.h b/include/libcamera/internal/ipa_proxy.h\nindex 983bcc5fa..f1865d67e 100644\n--- a/include/libcamera/internal/ipa_proxy.h\n+++ b/include/libcamera/internal/ipa_proxy.h\n@@ -7,10 +7,14 @@\n \n #pragma once\n \n+#include <optional>\n #include <string>\n+#include <vector>\n \n #include <libcamera/ipa/ipa_interface.h>\n \n+#include \"libcamera/internal/global_configuration.h\"\n+\n namespace libcamera {\n \n class IPAModule;\n@@ -24,7 +28,7 @@ public:\n \t\tProxyRunning,\n \t};\n \n-\tIPAProxy(IPAModule *ipam);\n+\tIPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration);\n \t~IPAProxy();\n \n \tbool isValid() const { return valid_; }\n@@ -40,6 +44,8 @@ protected:\n \n private:\n \tIPAModule *ipam_;\n+\tstd::vector<std::string> configPaths_;\n+\tstd::vector<std::string> execPaths_;\n };\n \n } /* namespace libcamera */\ndiff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp\nindex dca3d9a83..64df62444 100644\n--- a/src/libcamera/camera_manager.cpp\n+++ b/src/libcamera/camera_manager.cpp\n@@ -41,7 +41,7 @@ LOG_DEFINE_CATEGORY(Camera)\n CameraManager::Private::Private()\n \t: initialized_(false)\n {\n-\tipaManager_ = std::make_unique<IPAManager>();\n+\tipaManager_ = std::make_unique<IPAManager>(this->configuration());\n }\n \n int CameraManager::Private::start()\ndiff --git a/src/libcamera/ipa_manager.cpp b/src/libcamera/ipa_manager.cpp\nindex 830750dcc..000d56efa 100644\n--- a/src/libcamera/ipa_manager.cpp\n+++ b/src/libcamera/ipa_manager.cpp\n@@ -9,13 +9,17 @@\n \n #include <algorithm>\n #include <dirent.h>\n+#include <numeric>\n #include <string.h>\n+#include <string>\n #include <sys/types.h>\n+#include <vector>\n \n #include <libcamera/base/file.h>\n #include <libcamera/base/log.h>\n #include <libcamera/base/utils.h>\n \n+#include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/ipa_module.h\"\n #include \"libcamera/internal/ipa_proxy.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n@@ -101,30 +105,36 @@ LOG_DEFINE_CATEGORY(IPAManager)\n * The IPAManager class is meant to only be instantiated once, by the\n * CameraManager.\n */\n-IPAManager::IPAManager()\n+IPAManager::IPAManager(const GlobalConfiguration &configuration)\n {\n #if HAVE_IPA_PUBKEY\n \tif (!pubKey_.isValid())\n \t\tLOG(IPAManager, Warning) << \"Public key not valid\";\n+\n+\tchar *force = utils::secure_getenv(\"LIBCAMERA_IPA_FORCE_ISOLATION\");\n+\tforceIsolation_ = (force && force[0] != '\\0') ||\n+\t\t\t (!force && configuration.option<bool>({ \"ipa\", \"force_isolation\" })\n+\t\t\t\t\t .value_or(false));\n #endif\n \n \tunsigned int ipaCount = 0;\n \n \t/* User-specified paths take precedence. */\n-\tconst char *modulePaths = utils::secure_getenv(\"LIBCAMERA_IPA_MODULE_PATH\");\n-\tif (modulePaths) {\n-\t\tfor (const auto &dir : utils::split(modulePaths, \":\")) {\n-\t\t\tif (dir.empty())\n-\t\t\t\tcontinue;\n-\n-\t\t\tipaCount += addDir(dir.c_str());\n-\t\t}\n+\tconst auto modulePaths =\n+\t\tconfiguration.envListOption(\n+\t\t\t\"LIBCAMERA_IPA_MODULE_PATH\", { \"ipa\", \"module_paths\" });\n+\tfor (const auto &dir : modulePaths.value_or(std::vector<std::string>())) {\n+\t\tif (dir.empty())\n+\t\t\tcontinue;\n \n-\t\tif (!ipaCount)\n-\t\t\tLOG(IPAManager, Warning)\n-\t\t\t\t<< \"No IPA found in '\" << modulePaths << \"'\";\n+\t\tipaCount += addDir(dir.c_str());\n \t}\n \n+\tif (!ipaCount)\n+\t\tLOG(IPAManager, Warning) << \"No IPA found in '\"\n+\t\t\t\t\t << utils::join(modulePaths.value_or(std::vector<std::string>()), \":\")\n+\t\t\t\t\t << \"'\";\n+\n \t/*\n \t * When libcamera is used before it is installed, load IPAs from the\n \t * same build directory as the libcamera library itself.\n@@ -279,11 +289,10 @@ IPAModule *IPAManager::module(PipelineHandler *pipe, uint32_t minVersion,\n bool IPAManager::isSignatureValid([[maybe_unused]] IPAModule *ipa) const\n {\n #if HAVE_IPA_PUBKEY\n-\tchar *force = utils::secure_getenv(\"LIBCAMERA_IPA_FORCE_ISOLATION\");\n-\tif (force && force[0] != '\\0') {\n+\tif (forceIsolation_) {\n \t\tLOG(IPAManager, Debug)\n \t\t\t<< \"Isolation of IPA module \" << ipa->path()\n-\t\t\t<< \" forced through environment variable\";\n+\t\t\t<< \" forced through configuration\";\n \t\treturn false;\n \t}\n \ndiff --git a/src/libcamera/ipa_proxy.cpp b/src/libcamera/ipa_proxy.cpp\nindex b5c13a30f..9d2acd716 100644\n--- a/src/libcamera/ipa_proxy.cpp\n+++ b/src/libcamera/ipa_proxy.cpp\n@@ -7,13 +7,16 @@\n \n #include \"libcamera/internal/ipa_proxy.h\"\n \n+#include <string>\n #include <sys/stat.h>\n #include <sys/types.h>\n #include <unistd.h>\n+#include <vector>\n \n #include <libcamera/base/log.h>\n #include <libcamera/base/utils.h>\n \n+#include \"libcamera/internal/global_configuration.h\"\n #include \"libcamera/internal/ipa_module.h\"\n \n /**\n@@ -27,7 +30,8 @@ LOG_DEFINE_CATEGORY(IPAProxy)\n \n namespace {\n \n-std::string ipaConfigurationFile(const std::string &ipaName, const std::string &name)\n+std::string ipaConfigurationFile(const std::string &ipaName, const std::string &name,\n+\t\t\t\t const std::vector<std::string> &configPaths)\n {\n \t/*\n \t * Start with any user override through the module-specific environment\n@@ -47,20 +51,15 @@ std::string ipaConfigurationFile(const std::string &ipaName, const std::string &\n \tint ret;\n \n \t/*\n-\t * Check the directory pointed to by the IPA config path environment\n-\t * variable next.\n+\t * Check the directory pointed to by the IPA config path next.\n \t */\n-\tconst char *confPaths = utils::secure_getenv(\"LIBCAMERA_IPA_CONFIG_PATH\");\n-\tif (confPaths) {\n-\t\tfor (const auto &dir : utils::split(confPaths, \":\")) {\n-\t\t\tif (dir.empty())\n-\t\t\t\tcontinue;\n-\n-\t\t\tstd::string confPath = dir + \"/\" + ipaName + \"/\" + name;\n-\t\t\tret = stat(confPath.c_str(), &statbuf);\n-\t\t\tif (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)\n-\t\t\t\treturn confPath;\n-\t\t}\n+\tfor (const auto &dir : configPaths) {\n+\t\tif (dir.empty())\n+\t\t\tcontinue;\n+\t\tstd::string confPath = dir + \"/\" + ipaName + \"/\" + name;\n+\t\tret = stat(confPath.c_str(), &statbuf);\n+\t\tif (ret == 0 && (statbuf.st_mode & S_IFMT) == S_IFREG)\n+\t\t\treturn confPath;\n \t}\n \n \tstd::string root = utils::libcameraSourcePath();\n@@ -120,9 +119,12 @@ std::string ipaConfigurationFile(const std::string &ipaName, const std::string &\n /**\n * \\brief Construct an IPAProxy instance\n * \\param[in] ipam The IPA module\n+ * \\param[in] configuration The global configuration\n */\n-IPAProxy::IPAProxy(IPAModule *ipam)\n-\t: valid_(false), state_(ProxyStopped), ipam_(ipam)\n+IPAProxy::IPAProxy(IPAModule *ipam, const GlobalConfiguration &configuration)\n+\t: valid_(false), state_(ProxyStopped), ipam_(ipam),\n+\t configPaths_(configuration.envListOption(\"LIBCAMERA_IPA_CONFIG_PATH\", { \"ipa\", \"config_paths\" }).value_or(std::vector<std::string>())),\n+\t execPaths_(configuration.envListOption(\"LIBCAMERA_IPA_PROXY_PATH\", { \"ipa\", \"proxy_paths\" }).value_or(std::vector<std::string>()))\n {\n }\n \n@@ -175,7 +177,7 @@ std::string IPAProxy::configurationFile(const std::string &name,\n \t * has been validated when loading the module.\n \t */\n \tconst std::string ipaName = ipam_->info().name;\n-\tstd::string confPath = ipaConfigurationFile(ipaName, name);\n+\tstd::string confPath = ipaConfigurationFile(ipaName, name, configPaths_);\n \tif (!confPath.empty()) {\n \t\tLOG(IPAProxy, Info) << \"Using tuning file \" << confPath;\n \t\treturn confPath;\n@@ -188,7 +190,7 @@ std::string IPAProxy::configurationFile(const std::string &name,\n \t\treturn std::string();\n \t}\n \n-\tconfPath = ipaConfigurationFile(ipaName, fallbackName);\n+\tconfPath = ipaConfigurationFile(ipaName, fallbackName, configPaths_);\n \tLOG(IPAProxy, Warning)\n \t\t<< \"Configuration file '\" << name\n \t\t<< \"' not found for IPA module '\" << ipaName\n@@ -214,18 +216,14 @@ std::string IPAProxy::resolvePath(const std::string &file) const\n {\n \tstd::string proxyFile = \"/\" + file;\n \n-\t/* Check env variable first. */\n-\tconst char *execPaths = utils::secure_getenv(\"LIBCAMERA_IPA_PROXY_PATH\");\n-\tif (execPaths) {\n-\t\tfor (const auto &dir : utils::split(execPaths, \":\")) {\n-\t\t\tif (dir.empty())\n-\t\t\t\tcontinue;\n-\n-\t\t\tstd::string proxyPath = dir;\n-\t\t\tproxyPath += proxyFile;\n-\t\t\tif (!access(proxyPath.c_str(), X_OK))\n-\t\t\t\treturn proxyPath;\n-\t\t}\n+\t/* Check the configuration first. */\n+\tfor (const auto &dir : execPaths_) {\n+\t\tif (dir.empty())\n+\t\t\tcontinue;\n+\n+\t\tstd::string proxyPath = dir + proxyFile;\n+\t\tif (!access(proxyPath.c_str(), X_OK))\n+\t\t\treturn proxyPath;\n \t}\n \n \t/*\ndiff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\nindex beb646e2d..18b4ab5e5 100644\n--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\n+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.cpp.tmpl\n@@ -45,8 +45,8 @@ namespace {{ns}} {\n {% endfor %}\n {%- endif %}\n \n-{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate)\n-\t: IPAProxy(ipam), isolate_(isolate),\n+{{proxy_name}}::{{proxy_name}}(IPAModule *ipam, bool isolate, const GlobalConfiguration &configuration)\n+\t: IPAProxy(ipam, configuration), isolate_(isolate),\n \t controlSerializer_(ControlSerializer::Role::Proxy), seq_(0)\n {\n \tLOG(IPAProxy, Debug)\ndiff --git a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\nindex a0312a7c1..057c3ab03 100644\n--- a/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\n+++ b/utils/codegen/ipc/generators/libcamera_templates/module_ipa_proxy.h.tmpl\n@@ -37,7 +37,7 @@ namespace {{ns}} {\n class {{proxy_name}} : public IPAProxy, public {{interface_name}}, public Object\n {\n public:\n-\t{{proxy_name}}(IPAModule *ipam, bool isolate);\n+\t{{proxy_name}}(IPAModule *ipam, bool isolate, const GlobalConfiguration &configuration);\n \t~{{proxy_name}}();\n \n {% for method in interface_main.methods %}\n", "prefixes": [ "v17", "05/12" ] }