get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2230921,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2230921/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/openvswitch/patch/20260430082325.1111443-1-hayatake396@gmail.com/",
    "project": {
        "id": 47,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/47/?format=api",
        "name": "Open vSwitch",
        "link_name": "openvswitch",
        "list_id": "ovs-dev.openvswitch.org",
        "list_email": "ovs-dev@openvswitch.org",
        "web_url": "http://openvswitch.org/",
        "scm_url": "git@github.com:openvswitch/ovs.git",
        "webscm_url": "https://github.com/openvswitch/ovs"
    },
    "msgid": "<20260430082325.1111443-1-hayatake396@gmail.com>",
    "date": "2026-04-30T08:23:21",
    "name": "[ovs-dev,v2] ofproto-dpif: Allow fdb/show to accept multiple bridges.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "5561b83fdfa0acb683f6e00838ae055910e040ca",
    "submitter": {
        "id": 87325,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/87325/?format=api",
        "name": "Takeru Hayasaka",
        "email": "hayatake396@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/openvswitch/patch/20260430082325.1111443-1-hayatake396@gmail.com/mbox/",
    "series": [
        {
            "id": 502233,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/502233/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/openvswitch/list/?series=502233",
            "date": "2026-04-30T08:23:21",
            "name": "[ovs-dev,v2] ofproto-dpif: Allow fdb/show to accept multiple bridges.",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/502233/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2230921/comments/",
    "check": "success",
    "checks": "http://patchwork.ozlabs.org/api/patches/2230921/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<ovs-dev-bounces@openvswitch.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "dev@openvswitch.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@legolas.ozlabs.org",
            "ovs-dev@lists.linuxfoundation.org"
        ],
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=L6UW49dn;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)",
            "smtp4.osuosl.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=L6UW49dn",
            "smtp1.osuosl.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "smtp1.osuosl.org; dkim=pass (2048-bit key,\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=L6UW49dn"
        ],
        "Received": [
            "from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5nHy4dKRz1yGq\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 18:23:42 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby smtp4.osuosl.org (Postfix) with ESMTP id AECFB42981;\n\tThu, 30 Apr 2026 08:23:35 +0000 (UTC)",
            "from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id g2GF2ew-gDu3; Thu, 30 Apr 2026 08:23:34 +0000 (UTC)",
            "from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56])\n\tby smtp4.osuosl.org (Postfix) with ESMTPS id 2E96D42979;\n\tThu, 30 Apr 2026 08:23:34 +0000 (UTC)",
            "from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 13672C04FB;\n\tThu, 30 Apr 2026 08:23:34 +0000 (UTC)",
            "from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n by lists.linuxfoundation.org (Postfix) with ESMTP id D19F4C04FA\n for <dev@openvswitch.org>; Thu, 30 Apr 2026 08:23:32 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n by smtp1.osuosl.org (Postfix) with ESMTP id B465184BCB\n for <dev@openvswitch.org>; Thu, 30 Apr 2026 08:23:32 +0000 (UTC)",
            "from smtp1.osuosl.org ([127.0.0.1])\n by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id w66gwCk6Ndsz for <dev@openvswitch.org>;\n Thu, 30 Apr 2026 08:23:31 +0000 (UTC)",
            "from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com\n [IPv6:2607:f8b0:4864:20::42a])\n by smtp1.osuosl.org (Postfix) with ESMTPS id 5FA5584BCD\n for <dev@openvswitch.org>; Thu, 30 Apr 2026 08:23:31 +0000 (UTC)",
            "by mail-pf1-x42a.google.com with SMTP id\n d2e1a72fcca58-82fb2d0c5d1so1190591b3a.0\n for <dev@openvswitch.org>; Thu, 30 Apr 2026 01:23:31 -0700 (PDT)",
            "from lab-kiba-ocxma-dut-01.. (191.68.231.218.rev.ocx2915.net.\n [218.231.68.191]) by smtp.gmail.com with ESMTPSA id\n d2e1a72fcca58-834ed6df1f6sm4436981b3a.30.2026.04.30.01.23.28\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 30 Apr 2026 01:23:29 -0700 (PDT)"
        ],
        "X-Virus-Scanned": [
            "amavis at osuosl.org",
            "amavis at osuosl.org"
        ],
        "X-Comment": "SPF check N/A for local connections - client-ip=140.211.9.56;\n helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ",
        "DKIM-Filter": [
            "OpenDKIM Filter v2.11.0 smtp4.osuosl.org 2E96D42979",
            "OpenDKIM Filter v2.11.0 smtp1.osuosl.org 5FA5584BCD"
        ],
        "Received-SPF": "Pass (mailfrom) identity=mailfrom;\n client-ip=2607:f8b0:4864:20::42a; helo=mail-pf1-x42a.google.com;\n envelope-from=hayatake396@gmail.com; receiver=<UNKNOWN>",
        "DMARC-Filter": "OpenDMARC Filter v1.4.2 smtp1.osuosl.org 5FA5584BCD",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1777537410; x=1778142210; darn=openvswitch.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=bF8dfJ8wsS5HCTarL+m1M/ut326lmH+UBCnkd/78u+o=;\n b=L6UW49dnvsuoIDSkJCjh2sKAMn0WxxEnr2+ceBIKDV446qNcF7Kx438i/nAzgs3pod\n CpBAjGwOygQBY+2eLEJkUUPeiUCvbBDsLJe8alASVStRMaQeDGspA0XNOOuGWAHgr5uA\n ZUaa7TYv/IUK/MmidHOeDxFPbNUsHta7bQIwg662AyfyFQCXX7ILxI3q3Imc5gTLgxFp\n 9W9rpnhEse7HhQMzgyu8eyoCyvZe+AEnJAKMwpxaHna85LIOsE6ZtaEUCJ16oyu07LJ9\n B9buZ+TDMt1D8kdvVdSjDTOhtPDndsSf0ZfJbsO1URkxQum3CZpJS4zVrgp6HKteu29Z\n RR/A==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777537410; x=1778142210;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=bF8dfJ8wsS5HCTarL+m1M/ut326lmH+UBCnkd/78u+o=;\n b=gtHdE4JTEwa7Ec0dL6sC0HTGBphXh1FYYR2Ezg2J1rbaSfMS7S3pva2vl961u+hu6v\n 4kQDwig9XnNorfq1ydQQ7l1Shn/KbPgJ5B+dVfyRZ9UOL8Wi8Qfw93Llfgyv2sLREscM\n gwln3/1BkSAdSdRgJDYi2IQrHh320rMvWy5BxPT6Gtr/GnZZ2nOAyM4XJjOxmTVLBlUY\n MMAGthgq+3ycUgAr3+F0hjXM6plP3A+VSZflznleX+/jXEe9lWohFZTeTly4m1y+uIDg\n NlQRRlJBF+GTD3J+OMZTfNUcLv22l6rdCjLtGKJARr+3SB9XhOMg3IS6oHZHD4ebu7/c\n kcGA==",
        "X-Gm-Message-State": "AOJu0Yyk+1CBvyigkhSQsqfHyyECdSPRiArb10HhqSGuTnZU416o8u33\n kmaZMc3RwdTmQE3CJ2/zJfL5E4iI5U3Sllk2n0rrSDsjEHyUg8KTBAqwlgC/Sg==",
        "X-Gm-Gg": "AeBDievOVloH9bZVoZPU1FwEHCAcTTZafbYEO1ZxLAzkFThbgSRSil9gHQGJtjpz3co\n ceECIJDPoxBrJLAgLcblfCVeUs7FMubTGFG/vijWFQVGr4EU0UtT8GJH3dZTCzmXcVol7t6Cf83\n 13iIzbiWmB8ylaM7dRu/tycxoyeqC2eBLVFz72bta/SjqfA8euYRsBFyGd8nJoudaOcdRr1uDKi\n fo4p5R/pOY+XbMtRvcOiN3joSatGVeP/Hgid4mZQPTzXO2SmsKEjIR/20BuDngOUPWBCf9rmSCe\n WyoFZJxOM4FnNsE0YI9GcS/AcrXtQMPvsuhjFlnn5PN74w8QThjwMVpVIG9Fh4Yeqw2sglO6QRY\n UxRPwRuuCDr1ofafz+/mss2BLz7HTsQwsOsnXyxhRXy+swJer2BgxX5f2J0TrMGOGyRu9hCXNWp\n m0qhTb/TFbUGu6hwCN1TWygDFr9qQb6aasgnpXllCJEwVYnV8Gc3cEdCqva2rV7uQ2kaEU7RDNB\n 2+g3wFVn6hrLumqKoZR7iD3NQtTR0w4dlhtAY12ER6Y",
        "X-Received": "by 2002:a05:6a00:94c2:b0:82f:47ec:944f with SMTP id\n d2e1a72fcca58-8350014a465mr1628669b3a.16.1777537409908;\n Thu, 30 Apr 2026 01:23:29 -0700 (PDT)",
        "From": "Takeru Hayasaka <hayatake396@gmail.com>",
        "To": "dev@openvswitch.org",
        "Date": "Thu, 30 Apr 2026 08:23:21 +0000",
        "Message-ID": "<20260430082325.1111443-1-hayatake396@gmail.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "MIME-Version": "1.0",
        "Subject": "[ovs-dev] [PATCH v2] ofproto-dpif: Allow fdb/show to accept\n multiple bridges.",
        "X-BeenThere": "ovs-dev@openvswitch.org",
        "X-Mailman-Version": "2.1.30",
        "Precedence": "list",
        "List-Id": "<ovs-dev.openvswitch.org>",
        "List-Unsubscribe": "<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>",
        "List-Archive": "<http://mail.openvswitch.org/pipermail/ovs-dev/>",
        "List-Post": "<mailto:ovs-dev@openvswitch.org>",
        "List-Help": "<mailto:ovs-dev-request@openvswitch.org?subject=help>",
        "List-Subscribe": "<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>",
        "Cc": "Takeru Hayasaka <hayatake396@gmail.com>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "ovs-dev-bounces@openvswitch.org",
        "Sender": "\"dev\" <ovs-dev-bounces@openvswitch.org>"
    },
    "content": "Previously fdb/show required exactly one bridge argument.  This\nchange allows specifying multiple bridge names in a single call,\nreducing the number of unixctl round-trips for clients that need\nto poll FDB entries across many bridges (e.g. EVPN agents managing\nmultiple VNIs).\n\nThe output format is now consistent regardless of how many bridges\nare passed.  Text output always prefixes each bridge's table with\na \"bridge <name>\" header line.  JSON output is always an array of\nobjects, each containing \"bridge\" and \"entries\" keys.  This is a\nbackward-incompatible change for the single-bridge case but keeps\nthe per-bridge formatting fully encapsulated in the helper\nfunctions.\n\nSigned-off-by: Takeru Hayasaka <hayatake396@gmail.com>\n---\nv2:\n- Moved the \"bridge <name>\" prefixing into the per-bridge text and\n  JSON helpers so the formatting lives in one place and the caller\n  no longer has to switch on the bridge count (suggested by Mike\n  Pattrick).\n- As a result, single-bridge output now also includes the header\n  line (\"bridge <name>\" in text mode, {\"bridge\", \"entries\"} wrapper\n  in JSON mode).  Updated existing fdb/show tests to match.\n- Updated the unixctl usage hint to \"bridge...\" for consistency\n  with other variadic commands such as \"ofctl/send\".\n- Updated the ovs-vswitchd(8) man page to document multi-bridge\n  support and the output format.\n- Added tests for an empty-FDB JSON response and for the error\n  path when one of the requested bridges does not exist.\n- NEWS entry expanded to describe the format change.\n\n NEWS                       |   8 +-\n ofproto/ofproto-dpif.c     |  46 +++++++----\n tests/ofproto-dpif.at      | 160 ++++++++++++++++++++++++++-----------\n tests/stp.at               |   3 +\n vswitchd/ovs-vswitchd.8.in |   7 +-\n 5 files changed, 159 insertions(+), 65 deletions(-)",
    "diff": "diff --git a/NEWS b/NEWS\nindex 1a3044cbfb2f..cc8ec48d37b3 100644\n--- a/NEWS\n+++ b/NEWS\n@@ -3,7 +3,13 @@ Post-v3.7.0\n    - Userspace datapath:\n      * ARP/ND lookups for native tunnel are now rate limited. The holdout\n        timer can be configured with 'tnl/neigh/retrans_time'.\n-\n+   - ovs-appctl:\n+     * \"fdb/show\" now accepts multiple bridge names in a single call,\n+       reducing the number of unixctl round-trips for clients that poll\n+       FDB entries across many bridges.  The output format now always\n+       prefixes a \"bridge <name>\" header line in text mode and wraps\n+       each bridge's entries in {\"bridge\", \"entries\"} in JSON mode,\n+       regardless of how many bridges were requested.\n \n v3.7.0 - 16 Feb 2026\n --------------------\ndiff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c\nindex a02afe8ef335..3333139e7c39 100644\n--- a/ofproto/ofproto-dpif.c\n+++ b/ofproto/ofproto-dpif.c\n@@ -6178,6 +6178,7 @@ ofproto_unixctl_fdb_show_text(const struct ofproto_dpif *ofproto,\n {\n     const struct mac_entry *e;\n \n+    ds_put_format(ds, \"bridge %s\\n\", ofproto->up.name);\n     ds_put_cstr(ds, \" port  VLAN  MAC                Age\\n\");\n     ovs_rwlock_rdlock(&ofproto->ml->rwlock);\n     LIST_FOR_EACH (e, lru_node, &ofproto->ml->lrus) {\n@@ -6200,9 +6201,10 @@ ofproto_unixctl_fdb_show_text(const struct ofproto_dpif *ofproto,\n \n static void\n ofproto_unixctl_fdb_show_json(const struct ofproto_dpif *ofproto,\n-                              struct json **fdb_entries)\n+                              struct json **bridge_entry)\n {\n     struct json **json_entries = NULL;\n+    struct json *obj = json_object_create();\n     const struct mac_entry *entry;\n     size_t num_entries;\n     int i = 0;\n@@ -6238,29 +6240,45 @@ ofproto_unixctl_fdb_show_json(const struct ofproto_dpif *ofproto,\n     }\n done_unlock:\n     ovs_rwlock_unlock(&ofproto->ml->rwlock);\n-    *fdb_entries = json_array_create(json_entries, i);\n+    json_object_put_string(obj, \"bridge\", ofproto->up.name);\n+    json_object_put(obj, \"entries\", json_array_create(json_entries, i));\n+    *bridge_entry = obj;\n }\n \n static void\n-ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,\n-                          const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)\n+ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc,\n+                          const char *argv[], void *aux OVS_UNUSED)\n {\n-    const struct ofproto_dpif *ofproto = ofproto_dpif_lookup_by_name(argv[1]);\n-\n-    if (!ofproto) {\n-        unixctl_command_reply_error(conn, \"no such bridge\");\n-        return;\n+    for (int i = 1; i < argc; i++) {\n+        if (!ofproto_dpif_lookup_by_name(argv[i])) {\n+            unixctl_command_reply_error(conn, \"no such bridge\");\n+            return;\n+        }\n     }\n \n     if (unixctl_command_get_output_format(conn) == UNIXCTL_OUTPUT_FMT_JSON) {\n-        struct json *fdb_entries;\n+        struct json **bridge_entries = xmalloc((argc - 1)\n+                                               * sizeof *bridge_entries);\n+\n+        for (int i = 1; i < argc; i++) {\n+            const struct ofproto_dpif *ofproto =\n+                ofproto_dpif_lookup_by_name(argv[i]);\n+\n+            ofproto_unixctl_fdb_show_json(ofproto, &bridge_entries[i - 1]);\n+        }\n \n-        ofproto_unixctl_fdb_show_json(ofproto, &fdb_entries);\n-        unixctl_command_reply_json(conn, fdb_entries);\n+        unixctl_command_reply_json(\n+            conn, json_array_create(bridge_entries, argc - 1));\n     } else {\n         struct ds ds = DS_EMPTY_INITIALIZER;\n \n-        ofproto_unixctl_fdb_show_text(ofproto, &ds);\n+        for (int i = 1; i < argc; i++) {\n+            const struct ofproto_dpif *ofproto =\n+                ofproto_dpif_lookup_by_name(argv[i]);\n+\n+            ofproto_unixctl_fdb_show_text(ofproto, &ds);\n+        }\n+\n         unixctl_command_reply(conn, ds_cstr(&ds));\n         ds_destroy(&ds);\n     }\n@@ -7131,7 +7149,7 @@ ofproto_unixctl_init(void)\n                              ofproto_unixctl_fdb_delete, NULL);\n     unixctl_command_register(\"fdb/flush\", \"[bridge]\", 0, 1,\n                              ofproto_unixctl_fdb_flush, NULL);\n-    unixctl_command_register(\"fdb/show\", \"bridge\", 1, 1,\n+    unixctl_command_register(\"fdb/show\", \"bridge...\", 1, INT_MAX,\n                              ofproto_unixctl_fdb_show, NULL);\n     unixctl_command_register(\"fdb/stats-clear\", \"[bridge]\", 0, 1,\n                              ofproto_unixctl_fdb_stats_clear, NULL);\ndiff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at\nindex 39e43d376849..514bd2a2f249 100644\n--- a/tests/ofproto-dpif.at\n+++ b/tests/ofproto-dpif.at\n@@ -7228,21 +7228,24 @@ br_flow=\"arp,in_port=3,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=ff:ff:ff:\n # Test command: ofproto/trace odp_flow\n AT_CHECK([ovs-appctl ofproto/trace \"$odp_flow\"], [0], [stdout])\n # Check for no MAC learning entry\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n ])\n \n # Test command: ofproto/trace br_name br_flow\n AT_CHECK([ovs-appctl ofproto/trace br0 \"$br_flow\"], [0], [stdout])\n # Check for no MAC learning entry\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n ])\n \n # Test command: ofproto/trace odp_flow -generate\n AT_CHECK([ovs-appctl ofproto/trace \"$odp_flow\" -generate], [0], [stdout])\n # Check for the MAC learning entry\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     3     0  50:54:00:00:00:05    ?\n ])\n@@ -7252,7 +7255,8 @@ AT_CHECK([ovs-appctl ofproto/trace ovs-dummy \\\n   \"in_port(1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05)\" \\\n   -generate], [0], [stdout])\n # Check for both MAC learning entries\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     3     0  50:54:00:00:00:05    ?\n     1     0  50:54:00:00:00:06    ?\n@@ -7263,7 +7267,8 @@ AT_CHECK([ovs-appctl ofproto/trace br0 \\\n   \"in_port=2,dl_src=50:54:00:00:00:07,dl_dst=50:54:00:00:00:06\" \\\n   -generate], [0], [stdout])\n # Check for both MAC learning entries.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     3     0  50:54:00:00:00:05    ?\n     1     0  50:54:00:00:00:06    ?\n@@ -7543,6 +7548,14 @@ add_of_ports br0 1 2 3\n \n arp='eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)'\n \n+dnl Check json output for an empty FDB.\n+AT_CHECK([ovs-appctl --format json --pretty fdb/show br0], [0], [dnl\n+[[\n+  {\n+    \"bridge\": \"br0\",\n+    \"entries\": []}]]\n+])\n+\n # Trace an ARP packet arriving on p3, to create a MAC learning entry.\n OFPROTO_TRACE(\n   [ovs-dummy],\n@@ -7551,7 +7564,8 @@ OFPROTO_TRACE(\n   [1,2,100])\n \n # Check for the MAC learning entry.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     3     0  50:54:00:00:00:05    ?\n ])\n@@ -7565,7 +7579,8 @@ OFPROTO_TRACE(\n   [3])\n \n # Check for both MAC learning entries.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     3     0  50:54:00:00:00:05    ?\n     1     0  50:54:00:00:00:06    ?\n@@ -7576,15 +7591,18 @@ AT_CHECK([ovs-appctl --format json --pretty fdb/show br0 \\\n           | sed 's/\"age\": [[0-9]]*/\"age\": ?/g'], [0], [dnl\n [[\n   {\n-    \"age\": ?,\n-    \"mac\": \"50:54:00:00:00:05\",\n-    \"port\": 3,\n-    \"vlan\": 0},\n-  {\n-    \"age\": ?,\n-    \"mac\": \"50:54:00:00:00:06\",\n-    \"port\": 1,\n-    \"vlan\": 0}]]\n+    \"bridge\": \"br0\",\n+    \"entries\": [\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:05\",\n+        \"port\": 3,\n+        \"vlan\": 0},\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:06\",\n+        \"port\": 1,\n+        \"vlan\": 0}]}]]\n ])\n \n # Trace a packet arrival that updates the first learned MAC entry.\n@@ -7595,7 +7613,8 @@ OFPROTO_TRACE(\n   [1,3,100])\n \n # Check that the MAC learning entry was updated.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     1     0  50:54:00:00:00:06    ?\n     2     0  50:54:00:00:00:05    ?\n@@ -7621,7 +7640,8 @@ OFPROTO_TRACE(\n   [4,101])\n \n # Check that the MAC learning entries were added.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br1\n  port  VLAN  MAC                Age\n     4     0  50:54:00:00:00:06    ?\n     5     0  50:54:00:00:00:07    ?\n@@ -7630,15 +7650,56 @@ AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [d\n # Delete port p1 and see that its MAC learning entry disappeared, and\n # that the MAC learning entry for the same MAC was also deleted from br1.\n AT_CHECK([ovs-vsctl del-port p1])\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n     2     0  50:54:00:00:00:05    ?\n ])\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br1\n+ port  VLAN  MAC                Age\n+    5     0  50:54:00:00:00:07    ?\n+])\n+\n+# Test fdb/show with multiple bridges.\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 br1 | sed '/^ /s/[[0-9]]\\{1,\\}$/?/'], [0], [dnl\n+bridge br0\n+ port  VLAN  MAC                Age\n+    2     0  50:54:00:00:00:05    ?\n+bridge br1\n  port  VLAN  MAC                Age\n     5     0  50:54:00:00:00:07    ?\n ])\n \n+dnl Check json output with multiple bridges.\n+AT_CHECK([ovs-appctl --format json --pretty fdb/show br0 br1 \\\n+          | sed 's/\"age\": [[0-9]]*/\"age\": ?/g'], [0], [dnl\n+[[\n+  {\n+    \"bridge\": \"br0\",\n+    \"entries\": [\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:05\",\n+        \"port\": 2,\n+        \"vlan\": 0}]},\n+  {\n+    \"bridge\": \"br1\",\n+    \"entries\": [\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:07\",\n+        \"port\": 5,\n+        \"vlan\": 0}]}]]\n+])\n+\n+# Test fdb/show with a non-existent bridge mixed in: must reply with an\n+# error and emit no partial output.\n+AT_CHECK([ovs-appctl fdb/show br0 nonexistent], [2], [],\n+  [no such bridge\n+ovs-appctl: ovs-vswitchd: server returned an error\n+])\n+\n OVS_VSWITCHD_STOP\n AT_CLEANUP\n \n@@ -7662,7 +7723,7 @@ for i in 0 1 2 3 4 5 6 7 8 9; do\n done\n \n # Check for the MAC learning entries.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | sort],\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v '^bridge ' | sort],\n   [0], [dnl\n     3     0  50:54:00:00:00:00\n     3     0  50:54:00:00:00:01\n@@ -7685,7 +7746,7 @@ OFPROTO_TRACE(\n   [1,2,100])\n \n # Check that the new one chased the oldest one out of the table.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/' | sort],\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\\{1,\\}$/?/' | grep -v '^bridge ' | sort],\n   [0], [dnl\n     3     0  50:54:00:00:00:01    ?\n     3     0  50:54:00:00:00:02    ?\n@@ -7720,7 +7781,7 @@ for i in 0 1 2 3 4 5 6 7 8 9; do\n done\n \n # Check for the MAC learning entries.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | sort],\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v '^bridge ' | sort],\n   [0], [dnl\n     1     0  50:54:00:00:00:00\n     1     0  50:54:00:00:00:01\n@@ -7751,7 +7812,7 @@ done\n # (If someone changes lib/heap.c to do something different with equal-priority\n # nodes, then the output below could change, but it would still follow the\n # rules explained above.)\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | sort],\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v '^bridge ' | sort],\n   [0], [dnl\n     1     0  50:54:00:00:00:01\n     2     0  50:54:00:00:00:03\n@@ -8188,7 +8249,7 @@ AT_CHECK([ovs-appctl fdb/add br0 p1 0 50:54:00:00:01:01])\n AT_CHECK([ovs-appctl fdb/add br0 p2 0 50:54:00:00:02:02])\n \n dnl Check initial fdb.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v port | sort], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v -e port -e '^bridge ' | sort], [0], [dnl\n     1     0  50:54:00:00:00:01\n     1     0  50:54:00:00:01:01  static\n     2     0  50:54:00:00:00:02\n@@ -8200,25 +8261,28 @@ AT_CHECK([ovs-appctl --format json --pretty fdb/show br0 \\\n           | sed 's/\"age\": [[0-9]]*/\"age\": ?/g'], [0], [dnl\n [[\n   {\n-    \"age\": ?,\n-    \"mac\": \"50:54:00:00:00:01\",\n-    \"port\": 1,\n-    \"vlan\": 0},\n-  {\n-    \"age\": ?,\n-    \"mac\": \"50:54:00:00:00:02\",\n-    \"port\": 2,\n-    \"vlan\": 0},\n-  {\n-    \"mac\": \"50:54:00:00:01:01\",\n-    \"port\": 1,\n-    \"static\": true,\n-    \"vlan\": 0},\n-  {\n-    \"mac\": \"50:54:00:00:02:02\",\n-    \"port\": 2,\n-    \"static\": true,\n-    \"vlan\": 0}]]\n+    \"bridge\": \"br0\",\n+    \"entries\": [\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:01\",\n+        \"port\": 1,\n+        \"vlan\": 0},\n+      {\n+        \"age\": ?,\n+        \"mac\": \"50:54:00:00:00:02\",\n+        \"port\": 2,\n+        \"vlan\": 0},\n+      {\n+        \"mac\": \"50:54:00:00:01:01\",\n+        \"port\": 1,\n+        \"static\": true,\n+        \"vlan\": 0},\n+      {\n+        \"mac\": \"50:54:00:00:02:02\",\n+        \"port\": 2,\n+        \"static\": true,\n+        \"vlan\": 0}]}]]\n ])\n \n dnl Remove static mac entry.\n@@ -8264,7 +8328,7 @@ Overriding already existing dynamic entry on 1\n ])\n \n dnl Check fdb.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v port | sort], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v -e port -e '^bridge ' | sort], [0], [dnl\n     1     0  50:54:00:00:00:00  static\n ])\n \n@@ -8274,7 +8338,7 @@ Overriding already existing static entry on 1\n ])\n \n dnl Check fdb.\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v port | sort], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v -e port -e '^bridge ' | sort], [0], [dnl\n     2     0  50:54:00:00:00:00  static\n ])\n \n@@ -8282,13 +8346,13 @@ dnl static-mac should not be converted to a dynamic one when a packet with same\n dnl arrives on any port of the switch.\n dnl Packet arriving on p1.\n OFPROTO_TRACE([ovs-dummy], [in_port(1),eth(src=50:54:00:00:00:00)], [-generate], [100,2])\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v port | sort], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v -e port -e '^bridge ' | sort], [0], [dnl\n     2     0  50:54:00:00:00:00  static\n ])\n \n dnl Packet arriving on p2.\n OFPROTO_TRACE([ovs-dummy], [in_port(2),eth(src=50:54:00:00:00:00)], [-generate], [100,1])\n-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v port | sort], [0], [dnl\n+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\\{1,\\}$//' | grep -v -e port -e '^bridge ' | sort], [0], [dnl\n     2     0  50:54:00:00:00:00  static\n ])\n \ndiff --git a/tests/stp.at b/tests/stp.at\nindex 75abe8e5ca07..89ba0f682303 100644\n--- a/tests/stp.at\n+++ b/tests/stp.at\n@@ -632,12 +632,15 @@ ovs-appctl time/warp 36000 3000\n \n # check fdb and mdb\n AT_CHECK([ovs-appctl fdb/show br0], [0], [dnl\n+bridge br0\n  port  VLAN  MAC                Age\n ])\n AT_CHECK([ovs-appctl fdb/show br1], [0], [dnl\n+bridge br1\n  port  VLAN  MAC                Age\n ])\n AT_CHECK([ovs-appctl fdb/show br2], [0], [dnl\n+bridge br2\n  port  VLAN  MAC                Age\n ])\n \ndiff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in\nindex 98e58951dcff..73ba1a47c00d 100644\n--- a/vswitchd/ovs-vswitchd.8.in\n+++ b/vswitchd/ovs-vswitchd.8.in\n@@ -178,10 +178,13 @@ Deletes \\fImac\\fR address from a \\fIport\\fR and \\fIvlan\\fR on a \\fIbridge\\fR.\n .IP \"\\fBfdb/flush\\fR [\\fIbridge\\fR]\"\n Flushes \\fIbridge\\fR MAC address learning table, or all learning tables\n if no \\fIbridge\\fR is given.\n-.IP \"\\fBfdb/show\\fR \\fIbridge\\fR\"\n+.IP \"\\fBfdb/show\\fR \\fIbridge\\fR...\"\n Lists each MAC address/VLAN pair learned by the specified \\fIbridge\\fR,\n along with the port on which it was learned and the age of the entry,\n-in seconds.\n+in seconds.  Multiple bridge names may be given to query several bridges\n+in a single call.  Each bridge's table is preceded by a \"bridge \\fIname\\fR\"\n+header line in text output, or wrapped in a JSON object with \"bridge\"\n+and \"entries\" keys when JSON output is requested.\n .IP \"\\fBfdb/stats-clear\\fR [\\fIbridge\\fR]\"\n Clear \\fIbridge\\fR MAC address learning table statistics, or all\n statistics if no \\fIbridge\\fR is given.\n",
    "prefixes": [
        "ovs-dev",
        "v2"
    ]
}