get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/110172/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 110172,
    "url": "http://patches.dpdk.org/api/patches/110172/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220422130343.44060-1-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20220422130343.44060-1-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220422130343.44060-1-cristian.dumitrescu@intel.com",
    "date": "2022-04-22T13:03:41",
    "name": "[V2,1/3] table: improve learner table timers",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "1be2fe57ffee9e960c26e3672e53dee83ee83586",
    "submitter": {
        "id": 19,
        "url": "http://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220422130343.44060-1-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 22635,
            "url": "http://patches.dpdk.org/api/series/22635/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=22635",
            "date": "2022-04-22T13:03:41",
            "name": "[V2,1/3] table: improve learner table timers",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/22635/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/110172/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/110172/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9B858A0093;\n\tFri, 22 Apr 2022 15:03:48 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 3537A410D5;\n\tFri, 22 Apr 2022 15:03:48 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n by mails.dpdk.org (Postfix) with ESMTP id 33FD740042\n for <dev@dpdk.org>; Fri, 22 Apr 2022 15:03:46 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 Apr 2022 06:03:45 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by fmsmga005.fm.intel.com with ESMTP; 22 Apr 2022 06:03:43 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1650632626; x=1682168626;\n h=from:to:subject:date:message-id:in-reply-to:references;\n bh=NjDKsYNbHVnlEob7Y5/VaMioIurz0iAfmIi1YhEAgSE=;\n b=Z9YOfvIeN6AE0y4VHz1/wM3DmdANKox2Yzzl/GDkooBC2dgzk5b6N/sJ\n coqrLftzDlpsA8bqK216sSDk/MFpWYf8Y9ywcjpp8BEq4VCizb3Dyz7j8\n TyJeDvbY0xzQBFM4N8ek6B7xbKXkMvIuR1oLeGcZVFz7oCjUu/brN8CUy\n PRnNps+XQt+CkgU9j/Lfg4UCQ3DJ/cB1GVRQ8g+yZrE1KairAU5RO4vsD\n fdNyaH05O73Wykdyb2p9GU29rKWIryy2zuHQJ4HoHi0UlxOL36Ttxyb1T\n 5ddBRNkoZSmyhBvHp8g3PglT4PXPMHxTM+UD/wmHXHEWOPTdxJH6uajj1 Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6400,9594,10324\"; a=\"264445311\"",
            "E=Sophos;i=\"5.90,281,1643702400\"; d=\"scan'208\";a=\"264445311\"",
            "E=Sophos;i=\"5.90,281,1643702400\"; d=\"scan'208\";a=\"867669100\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Subject": "[PATCH V2 1/3] table: improve learner table timers",
        "Date": "Fri, 22 Apr 2022 14:03:41 +0100",
        "Message-Id": "<20220422130343.44060-1-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20220421155951.31811-1-cristian.dumitrescu@intel.com>",
        "References": "<20220421155951.31811-1-cristian.dumitrescu@intel.com>",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "Previously, on lookup hit, the hit key had its timer automatically\nrearmed with the same timeout in order to prevent its expiration. Now,\na broader set of actions is available on lookup hit, which has to be\nmanaged explicitly: the key can have its timer rearmed with the same\nor with a different timeout, or the key timer can be left unmodified.\nThe latter option allows the key to expire naturally when the timer\neventually runs out, unless the key is hit again and its timer rearmed\nat that point. Needed by the TCP connection tracking state machine.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\nDepends-on: series-22386 (\"[V5,1/6] port: support packet mirroring\")\nDepends-on: patch-22480 (\"[V4] pipeline: support default action arguments\")\n\n lib/pipeline/rte_swx_pipeline.c          |   3 +-\n lib/pipeline/rte_swx_pipeline_internal.h |   3 +-\n lib/table/rte_swx_table_learner.c        | 110 ++++++++++++++++++++---\n lib/table/rte_swx_table_learner.h        |  90 +++++++++++++++++--\n lib/table/version.map                    |   4 +\n 5 files changed, 190 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c\nindex dfbac929c7..17be31d5a4 100644\n--- a/lib/pipeline/rte_swx_pipeline.c\n+++ b/lib/pipeline/rte_swx_pipeline.c\n@@ -8788,7 +8788,8 @@ learner_params_get(struct learner *l)\n \tparams->n_keys_max = l->size;\n \n \t/* Timeout. */\n-\tparams->key_timeout = l->timeout;\n+\tparams->key_timeout[0] = l->timeout;\n+\tparams->n_key_timeouts = 1;\n \n \treturn params;\n \ndiff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h\nindex 381a35c6e0..51bb464f5f 100644\n--- a/lib/pipeline/rte_swx_pipeline_internal.h\n+++ b/lib/pipeline/rte_swx_pipeline_internal.h\n@@ -2215,7 +2215,8 @@ __instr_learn_exec(struct rte_swx_pipeline *p,\n \t\t\t\t\t   l->mailbox,\n \t\t\t\t\t   t->time,\n \t\t\t\t\t   action_id,\n-\t\t\t\t\t   &t->metadata[mf_offset]);\n+\t\t\t\t\t   &t->metadata[mf_offset],\n+\t\t\t\t\t   0);\n \n \tTRACE(\"[Thread %2u] learner %u learn %s\\n\",\n \t      p->thread_id,\ndiff --git a/lib/table/rte_swx_table_learner.c b/lib/table/rte_swx_table_learner.c\nindex 15576c2aa3..3c98b8ce81 100644\n--- a/lib/table/rte_swx_table_learner.c\n+++ b/lib/table/rte_swx_table_learner.c\n@@ -230,12 +230,16 @@ table_keycmp(void *a, void *b, void *b_mask, uint32_t n_bytes)\n \n #define TABLE_KEYS_PER_BUCKET 4\n \n+#define TABLE_BUCKET_USEFUL_SIZE \\\n+\t(TABLE_KEYS_PER_BUCKET * (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t)))\n+\n #define TABLE_BUCKET_PAD_SIZE \\\n-\t(RTE_CACHE_LINE_SIZE - TABLE_KEYS_PER_BUCKET * (sizeof(uint32_t) + sizeof(uint32_t)))\n+\t(RTE_CACHE_LINE_SIZE - TABLE_BUCKET_USEFUL_SIZE)\n \n struct table_bucket {\n \tuint32_t time[TABLE_KEYS_PER_BUCKET];\n \tuint32_t sig[TABLE_KEYS_PER_BUCKET];\n+\tuint8_t key_timeout_id[TABLE_KEYS_PER_BUCKET];\n \tuint8_t pad[TABLE_BUCKET_PAD_SIZE];\n \tuint8_t key[0];\n };\n@@ -284,8 +288,11 @@ struct table_params {\n \t/* log2(bucket_size). Purpose: avoid multiplication with non-power of 2 numbers. */\n \tsize_t bucket_size_log2;\n \n-\t/* Timeout in CPU clock cycles. */\n-\tuint64_t key_timeout;\n+\t/* Set of all possible key timeout values measured in CPU clock cycles. */\n+\tuint64_t key_timeout[RTE_SWX_TABLE_LEARNER_N_KEY_TIMEOUTS_MAX];\n+\n+\t/* Number of key timeout values. */\n+\tuint32_t n_key_timeouts;\n \n \t/* Total memory size. */\n \tsize_t total_size;\n@@ -305,15 +312,23 @@ struct table {\n static int\n table_params_get(struct table_params *p, struct rte_swx_table_learner_params *params)\n {\n+\tuint32_t i;\n+\n \t/* Check input parameters. */\n \tif (!params ||\n \t    !params->key_size ||\n \t    (params->key_size > 64) ||\n \t    !params->n_keys_max ||\n \t    (params->n_keys_max > 1U << 31) ||\n-\t    !params->key_timeout)\n+\t    !params->key_timeout ||\n+\t    !params->n_key_timeouts ||\n+\t    (params->n_key_timeouts > RTE_SWX_TABLE_LEARNER_N_KEY_TIMEOUTS_MAX))\n \t\treturn -EINVAL;\n \n+\tfor (i = 0; i < params->n_key_timeouts; i++)\n+\t\tif (!params->key_timeout[i])\n+\t\t\treturn -EINVAL;\n+\n \t/* Key. */\n \tp->key_size = params->key_size;\n \n@@ -346,7 +361,17 @@ table_params_get(struct table_params *p, struct rte_swx_table_learner_params *pa\n \tp->bucket_size_log2 = __builtin_ctzll(p->bucket_size);\n \n \t/* Timeout. */\n-\tp->key_timeout = params->key_timeout * rte_get_tsc_hz();\n+\tfor (i = 0; i < params->n_key_timeouts; i++) {\n+\t\tp->key_timeout[i] = params->key_timeout[i] * rte_get_tsc_hz();\n+\n+\t\tif (!(p->key_timeout[i] >> 32))\n+\t\t\tp->key_timeout[i] = 1LLU << 32;\n+\t}\n+\n+\tp->n_key_timeouts = rte_align32pow2(params->n_key_timeouts);\n+\n+\tfor ( ; i < p->n_key_timeouts; i++)\n+\t\tp->key_timeout[i] = p->key_timeout[0];\n \n \t/* Total size. */\n \tp->total_size = sizeof(struct table) + p->n_buckets * p->bucket_size;\n@@ -505,8 +530,6 @@ rte_swx_table_learner_lookup(void *table,\n \t\t\t\t/* Hit. */\n \t\t\t\trte_prefetch0(data);\n \n-\t\t\t\tb->time[i] = (input_time + t->params.key_timeout) >> 32;\n-\n \t\t\t\tm->hit = 1;\n \t\t\t\tm->bucket_key_pos = i;\n \t\t\t\tm->state = 0;\n@@ -536,23 +559,83 @@ rte_swx_table_learner_lookup(void *table,\n \t}\n }\n \n+void\n+rte_swx_table_learner_rearm(void *table,\n+\t\t\t    void *mailbox,\n+\t\t\t    uint64_t input_time)\n+{\n+\tstruct table *t = table;\n+\tstruct mailbox *m = mailbox;\n+\tstruct table_bucket *b;\n+\tsize_t bucket_key_pos;\n+\tuint64_t key_timeout;\n+\tuint32_t key_timeout_id;\n+\n+\tif (!m->hit)\n+\t\treturn;\n+\n+\tb = m->bucket;\n+\tbucket_key_pos = m->bucket_key_pos;\n+\n+\tkey_timeout_id = b->key_timeout_id[bucket_key_pos];\n+\tkey_timeout = t->params.key_timeout[key_timeout_id];\n+\tb->time[bucket_key_pos] = (input_time + key_timeout) >> 32;\n+}\n+\n+void\n+rte_swx_table_learner_rearm_new(void *table,\n+\t\t\t\tvoid *mailbox,\n+\t\t\t\tuint64_t input_time,\n+\t\t\t\tuint32_t key_timeout_id)\n+{\n+\tstruct table *t = table;\n+\tstruct mailbox *m = mailbox;\n+\tstruct table_bucket *b;\n+\tsize_t bucket_key_pos;\n+\tuint64_t key_timeout;\n+\n+\tif (!m->hit)\n+\t\treturn;\n+\n+\tb = m->bucket;\n+\tbucket_key_pos = m->bucket_key_pos;\n+\n+\tkey_timeout_id &= t->params.n_key_timeouts - 1;\n+\tkey_timeout = t->params.key_timeout[key_timeout_id];\n+\tb->time[bucket_key_pos] = (input_time + key_timeout) >> 32;\n+\tb->key_timeout_id[bucket_key_pos] = (uint8_t)key_timeout_id;\n+}\n+\n uint32_t\n rte_swx_table_learner_add(void *table,\n \t\t\t  void *mailbox,\n \t\t\t  uint64_t input_time,\n \t\t\t  uint64_t action_id,\n-\t\t\t  uint8_t *action_data)\n+\t\t\t  uint8_t *action_data,\n+\t\t\t  uint32_t key_timeout_id)\n {\n \tstruct table *t = table;\n \tstruct mailbox *m = mailbox;\n \tstruct table_bucket *b = m->bucket;\n+\tuint64_t key_timeout;\n \tuint32_t i;\n \n-\t/* Lookup hit: The key, key signature and key time are already properly configured (the key\n-\t * time was bumped by lookup), only the key data need to be updated.\n+\t/* Adjust the key timeout ID to fit the valid range. */\n+\tkey_timeout_id &= t->params.n_key_timeouts - 1;\n+\tkey_timeout = t->params.key_timeout[key_timeout_id];\n+\n+\t/* Lookup hit: The following bucket fields need to be updated:\n+\t * - key (key, sig): NO (already correctly set).\n+\t * - key timeout (key_timeout_id, time): YES.\n+\t * - key data (data): YES.\n \t */\n \tif (m->hit) {\n-\t\tuint64_t *data = table_bucket_data_get(t, b, m->bucket_key_pos);\n+\t\tsize_t bucket_key_pos = m->bucket_key_pos;\n+\t\tuint64_t *data = table_bucket_data_get(t, b, bucket_key_pos);\n+\n+\t\t/* Install the key timeout. */\n+\t\tb->time[bucket_key_pos] = (input_time + key_timeout) >> 32;\n+\t\tb->key_timeout_id[bucket_key_pos] = (uint8_t)key_timeout_id;\n \n \t\t/* Install the key data. */\n \t\tdata[0] = action_id;\n@@ -576,9 +659,10 @@ rte_swx_table_learner_add(void *table,\n \t\t\tuint8_t *key = table_bucket_key_get(t, b, i);\n \t\t\tuint64_t *data = table_bucket_data_get(t, b, i);\n \n-\t\t\t/* Install the key. */\n-\t\t\tb->time[i] = (input_time + t->params.key_timeout) >> 32;\n+\t\t\t/* Install the key and the key timeout. */\n+\t\t\tb->time[i] = (input_time + key_timeout) >> 32;\n \t\t\tb->sig[i] = m->input_sig;\n+\t\t\tb->key_timeout_id[i] = (uint8_t)key_timeout_id;\n \t\t\tmemcpy(key, m->input_key, t->params.key_size);\n \n \t\t\t/* Install the key data. */\ndiff --git a/lib/table/rte_swx_table_learner.h b/lib/table/rte_swx_table_learner.h\nindex eb9d7689fd..8b3128ec5d 100644\n--- a/lib/table/rte_swx_table_learner.h\n+++ b/lib/table/rte_swx_table_learner.h\n@@ -18,13 +18,43 @@ extern \"C\" {\n  * implementation of the \"add on miss\" scenario: whenever the lookup key is not found in the table\n  * (lookup miss), the data plane can decide to add this key to the table with a given action with no\n  * control plane intervention. Likewise, the table keys expire based on a configurable timeout and\n- * are automatically deleted from the table with no control plane intervention.\n+ * are thus automatically removed from the table with no control plane intervention.\n+ *\n+ * The keys are not automatically rearmed on lookup hit. To delay the key expiration, the key timer\n+ * has to be explicitly reinitialized on lookup hit. The key will be kept in the table as long as it\n+ * is frequently hit and explicitly rearmed on every hit.\n+ *\n+ * Operation overview:\n+ * 1) Lookup miss:\n+ *      a) add: Add the current input key (the key that missed the lookup) to the table with given\n+ *              action, action parameters and expiration timeout. This is the way to populate the\n+ *              table (which is empty initially). Data plane operation.\n+ *      b) Do nothing: Keep the current input key out of the table.\n+ * 2) Lookup hit:\n+ *      a) add: Update the action, action parameters and/or the expiration timeout for the current\n+ *              input key, which is already in the table. The expiration timer of the key is\n+ *              automatically rearmed. Data plane operation.\n+ *      b) rearm: Rearm the expiration timer for the current input key, which is already in the\n+ *              table. The timeout value used for the expiration timer is either the same as the one\n+ *              currently associated with the key or a new one can be provided as input. Data plane\n+ *              operation.\n+ *      c) delete: Delete the current input key from the table. The purpose of this operation is to\n+ *              force the deletion of the key from the table before the key expires on timeout due\n+ *              to inactivity. Data plane operation.\n+ *      d) Do nothing: Keep the expiration timer of the current input key running down. This key\n+ *              will thus expire naturally, unless it is hit again as part of a subsequent lookup\n+ *              operation, when the key timer can be rearmed or re-added to prolong its life.\n  */\n \n #include <stdint.h>\n \n #include <rte_compat.h>\n \n+/** Maximum number of key timeout values per learner table. */\n+#ifndef RTE_SWX_TABLE_LEARNER_N_KEY_TIMEOUTS_MAX\n+#define RTE_SWX_TABLE_LEARNER_N_KEY_TIMEOUTS_MAX 16\n+#endif\n+\n /** Learner table creation parameters. */\n struct rte_swx_table_learner_params {\n \t/** Key size in bytes. Must be non-zero. */\n@@ -50,10 +80,16 @@ struct rte_swx_table_learner_params {\n \t/** Maximum number of keys to be stored in the table together with their associated data. */\n \tuint32_t n_keys_max;\n \n-\t/** Key timeout in seconds. Must be non-zero. Each table key expires and is automatically\n-\t * deleted from the table after this many seconds.\n+\t/** The set of all possible key timeout values measured in seconds. Each value must be\n+\t * non-zero. Each table key expires and is automatically deleted from the table after\n+\t * this many seconds.\n \t */\n-\tuint32_t key_timeout;\n+\tuint32_t *key_timeout;\n+\n+\t/** Number of possible key timeout values present in the *key_timeout* set. It must be less\n+\t * than or equal to *RTE_SWX_TABLE_LEARNER_N_KEY_TIMEOUTS_MAX*.\n+\t */\n+\tuint32_t n_key_timeouts;\n };\n \n /**\n@@ -160,6 +196,8 @@ rte_swx_table_learner_lookup(void *table,\n  *   ID of the action associated with the key.\n  * @param[out] action_data\n  *   Action data for the *action_id* action.\n+ * @param[in] key_timeout_id\n+ *   Key timeout ID.\n  * @return\n  *   0 on success, 1 or error (table full).\n  */\n@@ -169,7 +207,49 @@ rte_swx_table_learner_add(void *table,\n \t\t\t  void *mailbox,\n \t\t\t  uint64_t time,\n \t\t\t  uint64_t action_id,\n-\t\t\t  uint8_t *action_data);\n+\t\t\t  uint8_t *action_data,\n+\t\t\t  uint32_t key_timeout_id);\n+\n+/**\n+ * Learner table key rearm with same timeout value\n+ *\n+ * This operation takes the latest key that was looked up in the table and, in case of lookup hit,\n+ * it rearms its expiration timer using the same timeout value currently associated with the key.\n+ *\n+ * @param[in] table\n+ *   Table handle.\n+ * @param[in] mailbox\n+ *   Mailbox for the current operation.\n+ * @param[in] time\n+ *   Current time measured in CPU clock cycles.\n+ */\n+__rte_experimental\n+void\n+rte_swx_table_learner_rearm(void *table,\n+\t\t\t    void *mailbox,\n+\t\t\t    uint64_t time);\n+\n+/**\n+ * Learner table key rearm with given timeout value\n+ *\n+ * This operation takes the latest key that was looked up in the table and, in case of lookup hit,\n+ * it rearms its expiration timer using the given timeout value.\n+ *\n+ * @param[in] table\n+ *   Table handle.\n+ * @param[in] mailbox\n+ *   Mailbox for the current operation.\n+ * @param[in] time\n+ *   Current time measured in CPU clock cycles.\n+ * @param[in] key_timeout_id\n+ *   Key timeout ID.\n+ */\n+__rte_experimental\n+void\n+rte_swx_table_learner_rearm_new(void *table,\n+\t\t\t\tvoid *mailbox,\n+\t\t\t\tuint64_t time,\n+\t\t\t\tuint32_t key_timeout_id);\n \n /**\n  * Learner table key delete\ndiff --git a/lib/table/version.map b/lib/table/version.map\nindex efe5f6e52c..d27d649332 100644\n--- a/lib/table/version.map\n+++ b/lib/table/version.map\n@@ -45,4 +45,8 @@ EXPERIMENTAL {\n \trte_swx_table_learner_free;\n \trte_swx_table_learner_lookup;\n \trte_swx_table_learner_mailbox_size_get;\n+\n+\t#added in 22.07\n+\trte_swx_table_learner_rearm;\n+\trte_swx_table_learner_rearm_new;\n };\n",
    "prefixes": [
        "V2",
        "1/3"
    ]
}