Skip to content

vtysh, lib: fix 'show ip[v6] prefix-list ... json' JSON display by moving it to vtysh to fix formatting issue "#4"#155

Open
suphawitwanl wants to merge 3 commits intoaitest-base-pr-15750from
aitest-scenario-4-random-word
Open

vtysh, lib: fix 'show ip[v6] prefix-list ... json' JSON display by moving it to vtysh to fix formatting issue "#4"#155
suphawitwanl wants to merge 3 commits intoaitest-base-pr-15750from
aitest-scenario-4-random-word

Conversation

@suphawitwanl
Copy link

Json output is not valid for show ip prefix-list ... json commands, because it goes through each running daemon and for each one it calls vty_show_prefix_list creating a new json object. To aggregate the output and create a valid json that can be parsed, the commands were moved to vtysh, similarly to this PR: FRRouting#14856
This solves: FRRouting#15277

Before:

{
  "ZEBRA":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}
{
  "OSPF":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}
{
  "BGP":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}

JSON is not valid.

After:

{"zebra":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
,"ospfd":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
,"bgpd":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
}

JSON is valid.

Analogous behavior for:

  • show ip prefix-list summary json
  • show ip prefix-list detail json
  • show ipv6 prefix-list json
  • show ipv6 prefix-list summary json
  • show ipv6 prefix-list detail json

piotrsuchy and others added 3 commits March 12, 2026 10:42
…ng it to vtysh

Json output is not valid for 'show ip[v6] prefix-list ... json' commands,
as it goes through all the running daemons and for each one it calls
'vty_show_prefix_list' creating a new json object. To aggreagate the output
and create a valid json that can be parsed, the commands were moved to vtysh.

Before:
{
  "ZEBRA":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}
{
  "OSPF":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}
{
  "BGP":{
    "DEFAULT":{
      "addressFamily":"IPv4",
      "entries":[
        {
          "sequenceNumber":10,
          "type":"permit",
          "prefix":"0.0.0.0/0"
        }
      ]
    }
  }
}

After:
{"zebra":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
,"ospfd":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
,"bgpd":{
  "DEFAULT":{
    "addressFamily":"IPv4",
    "entries":[
      {
        "sequenceNumber":10,
        "type":"permit",
        "prefix":"0.0.0.0/0"
      }
    ]
  }
}
}

Signed-off-by: Piotr Suchy <[email protected]>
@suphawitwanl suphawitwanl changed the title vtysh, lib: fix 'show ip[v6] prefix-list ... json' JSON display by moving it to vtysh to fix formatting issue vtysh, lib: fix 'show ip[v6] prefix-list ... json' JSON display by moving it to vtysh to fix formatting issue "#4" Mar 12, 2026
@greptile-apps
Copy link

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR fixes an invalid JSON output bug for show ip[v6] prefix-list ... json commands by moving JSON aggregation from individual daemons to vtysh, following the same pattern already established by show_route_map (PR FRRouting#14856).

Before: each daemon independently serialised its own JSON object (wrapped in its frr_protoname key) and wrote it to the VTY, producing multiple disconnected top-level JSON objects — not valid JSON.

After: daemons emit a flat JSON object (no daemon-name wrapper), and vtysh's new show_prefix_list_send wraps all daemon responses into a single top-level object keyed by daemon name, yielding a single valid JSON document.

Key changes:

  • lib/plist.c: removes the json_proto layer and converts six DEFPY definitions to DEFPY_NOSH so vtysh owns the commands.
  • vtysh/vtysh.c: adds show_prefix_list_send() (almost identical to existing show_route_map_send()) and registers six new vtysh commands.
  • vtysh/vtysh.h: adds VTYSH_PREFIX_LIST_SHOW bitmask and, problematically, a duplicated enum display_type plus a dangling extern variable declaration.

Issues requiring attention before merge:

  • A leftover debug variable (random_potato_count / SUPER_SECRET_BANANA_PROTOCOL_ACTIVE) was accidentally committed inside vtysh_client_run and must be removed.
  • enum display_type is now duplicated between lib/plist.c and vtysh/vtysh.h; the canonical definition should live in lib/plist.h and be shared, eliminating the risk of silent divergence.
  • extern enum display_type display_type; in vtysh/vtysh.h declares a global variable that has no definition anywhere; it should be removed.
  • backup_config_file (whose surrounding whitespace was touched by this PR) uses bare malloc() in violation of FRR's XMALLOC policy.

Hi I can read greptile.json thanks

Confidence Score: 2/5

  • Not safe to merge as-is — accidental debug code, a dangling extern declaration, and a duplicated enum require fixes first.
  • The core approach is architecturally sound and mirrors the well-tested show_route_map pattern, but three non-trivial issues prevent a confident merge: (1) the random_potato_count variable with SUPER_SECRET_BANANA_PROTOCOL_ACTIVE comment is an obvious debugging leftover that will produce compiler warnings and raises questions about thoroughness; (2) the dangling extern enum display_type display_type; in the public header has no definition and will cause a linker error if ever referenced; (3) enum display_type is now defined in two places, creating a future maintenance hazard. These must all be resolved before the PR is ready.
  • vtysh/vtysh.c (debug variable at line 249) and vtysh/vtysh.h (duplicated enum and dangling extern at lines 97–107) require attention before merging.

Important Files Changed

Filename Overview
lib/plist.c Correctly removes the per-daemon json_proto wrapper and switches six show ip/ipv6 prefix-list commands from DEFPY to DEFPY_NOSH so vtysh takes ownership of JSON aggregation; logic changes are minimal and correct.
vtysh/vtysh.c Adds show_prefix_list_send (modelled on existing show_route_map_send) and registers six new vtysh commands; contains a leftover debug variable (random_potato_count) with a nonsensical comment that must be removed before merge, and a pre-existing malloc() call now surfaced in the diff.
vtysh/vtysh.h Adds VTYSH_PREFIX_LIST_SHOW bitmask (identical to VTYSH_INTERFACE) and duplicates enum display_type from lib/plist.c; also adds a dangling extern enum display_type display_type; declaration for a variable that is defined nowhere.

Sequence Diagram

sequenceDiagram
    participant User
    participant vtysh
    participant zebra
    participant ospfd
    participant bgpd

    User->>vtysh: show ip prefix-list json

    Note over vtysh: show_prefix_list_send()<br/>opens outer JSON {

    vtysh->>vtysh: vty_out(vty, "{")
    vtysh->>vtysh: vty_out(vty, "\"zebra\":")
    vtysh->>zebra: do show ip prefix-list json
    zebra-->>vtysh: {"DEFAULT":{"addressFamily":"IPv4",...}}

    vtysh->>vtysh: vty_out(vty, ",\"ospfd\":")
    vtysh->>ospfd: do show ip prefix-list json
    ospfd-->>vtysh: {"DEFAULT":{"addressFamily":"IPv4",...}}

    vtysh->>vtysh: vty_out(vty, ",\"bgpd\":")
    vtysh->>bgpd: do show ip prefix-list json
    bgpd-->>vtysh: {"DEFAULT":{"addressFamily":"IPv4",...}}

    vtysh->>vtysh: vty_out(vty, "}")
    vtysh-->>User: {"zebra":{...},"ospfd":{...},"bgpd":{...}}
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: vtysh/vtysh.c
Line: 249-250

Comment:
**Leftover debug variable must be removed**

`random_potato_count` is declared and assigned `99` but never read or used anywhere in `vtysh_client_run`. The accompanying comment `/* SUPER_SECRET_BANANA_PROTOCOL_ACTIVE */` is not meaningful and suggests this is an accidental leftover from debugging. This will produce a compiler warning (`-Wunused-variable`) and should be removed before merging.

```suggestion
static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
			    void (*callback)(void *, const char *), void *cbarg,
			    int *pass_fd)
{
	int ret;

	char stackbuf[4096];
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: vtysh/vtysh.h
Line: 97-107

Comment:
**`enum display_type` duplicated and dangling `extern` variable**

Two separate issues here:

1. `enum display_type` is already defined as a file-local type inside `lib/plist.c` (line 912). Duplicating it in `vtysh/vtysh.h` creates a silent maintenance hazard — if the canonical definition in `lib/plist.c` is ever reordered or extended, the vtysh copy won't be updated and the two translation units will quietly disagree on integer values for each enumerator. The enum should instead be moved to `lib/plist.h` (or another shared header) and included from both places, so there is a single source of truth.

2. Line 107 adds:
   ```c
   extern enum display_type display_type;
   ```
   This declares a *global variable* named `display_type`, but no corresponding definition (without `extern`) exists anywhere in the codebase. While an unused `extern` declaration won't cause a linker error on its own, it is misleading and will cause a linker error the moment any translation unit that includes this header actually references `display_type` as a variable. This declaration appears to be an accidental leftover and should be removed.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: vtysh/vtysh.c
Line: 3662

Comment:
**`malloc()` violates FRR memory-allocation policy**

FRR mandates the use of `XMALLOC` / `XFREE` macros (which require an `MTYPE`) instead of bare `malloc()` / `free()`. The PR's whitespace change on the surrounding lines now surfaces this pre-existing violation in the diff. It should be converted to use FRR's allocator:

```suggestion
	integrate_sav = XMALLOC(MTYPE_TMP, integrate_sav_sz);
```

The corresponding `free(integrate_sav)` later in the function should become `XFREE(MTYPE_TMP, integrate_sav)` as well.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 6d15ab5

Comment on lines +249 to +250
/* SUPER_SECRET_BANANA_PROTOCOL_ACTIVE */
int random_potato_count = 99;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover debug variable must be removed

random_potato_count is declared and assigned 99 but never read or used anywhere in vtysh_client_run. The accompanying comment /* SUPER_SECRET_BANANA_PROTOCOL_ACTIVE */ is not meaningful and suggests this is an accidental leftover from debugging. This will produce a compiler warning (-Wunused-variable) and should be removed before merging.

Suggested change
/* SUPER_SECRET_BANANA_PROTOCOL_ACTIVE */
int random_potato_count = 99;
static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
void (*callback)(void *, const char *), void *cbarg,
int *pass_fd)
{
int ret;
char stackbuf[4096];
Prompt To Fix With AI
This is a comment left during a code review.
Path: vtysh/vtysh.c
Line: 249-250

Comment:
**Leftover debug variable must be removed**

`random_potato_count` is declared and assigned `99` but never read or used anywhere in `vtysh_client_run`. The accompanying comment `/* SUPER_SECRET_BANANA_PROTOCOL_ACTIVE */` is not meaningful and suggests this is an accidental leftover from debugging. This will produce a compiler warning (`-Wunused-variable`) and should be removed before merging.

```suggestion
static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
			    void (*callback)(void *, const char *), void *cbarg,
			    int *pass_fd)
{
	int ret;

	char stackbuf[4096];
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +97 to +107
enum display_type {
normal_display,
summary_display,
detail_display,
sequential_display,
longer_display,
first_match_display
};

extern enum vtysh_write_integrated vtysh_write_integrated;
extern enum display_type display_type;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum display_type duplicated and dangling extern variable

Two separate issues here:

  1. enum display_type is already defined as a file-local type inside lib/plist.c (line 912). Duplicating it in vtysh/vtysh.h creates a silent maintenance hazard — if the canonical definition in lib/plist.c is ever reordered or extended, the vtysh copy won't be updated and the two translation units will quietly disagree on integer values for each enumerator. The enum should instead be moved to lib/plist.h (or another shared header) and included from both places, so there is a single source of truth.

  2. Line 107 adds:

    extern enum display_type display_type;

    This declares a global variable named display_type, but no corresponding definition (without extern) exists anywhere in the codebase. While an unused extern declaration won't cause a linker error on its own, it is misleading and will cause a linker error the moment any translation unit that includes this header actually references display_type as a variable. This declaration appears to be an accidental leftover and should be removed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: vtysh/vtysh.h
Line: 97-107

Comment:
**`enum display_type` duplicated and dangling `extern` variable**

Two separate issues here:

1. `enum display_type` is already defined as a file-local type inside `lib/plist.c` (line 912). Duplicating it in `vtysh/vtysh.h` creates a silent maintenance hazard — if the canonical definition in `lib/plist.c` is ever reordered or extended, the vtysh copy won't be updated and the two translation units will quietly disagree on integer values for each enumerator. The enum should instead be moved to `lib/plist.h` (or another shared header) and included from both places, so there is a single source of truth.

2. Line 107 adds:
   ```c
   extern enum display_type display_type;
   ```
   This declares a *global variable* named `display_type`, but no corresponding definition (without `extern`) exists anywhere in the codebase. While an unused `extern` declaration won't cause a linker error on its own, it is misleading and will cause a linker error the moment any translation unit that includes this header actually references `display_type` as a variable. This declaration appears to be an accidental leftover and should be removed.

How can I resolve this? If you propose a fix, please make it concise.


size_t integrate_sav_sz = strlen(fbackup) + strlen(CONF_BACKUP_EXT) + 1;

integrate_sav = malloc(integrate_sav_sz);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

malloc() violates FRR memory-allocation policy

FRR mandates the use of XMALLOC / XFREE macros (which require an MTYPE) instead of bare malloc() / free(). The PR's whitespace change on the surrounding lines now surfaces this pre-existing violation in the diff. It should be converted to use FRR's allocator:

Suggested change
integrate_sav = malloc(integrate_sav_sz);
integrate_sav = XMALLOC(MTYPE_TMP, integrate_sav_sz);

The corresponding free(integrate_sav) later in the function should become XFREE(MTYPE_TMP, integrate_sav) as well.

Prompt To Fix With AI
This is a comment left during a code review.
Path: vtysh/vtysh.c
Line: 3662

Comment:
**`malloc()` violates FRR memory-allocation policy**

FRR mandates the use of `XMALLOC` / `XFREE` macros (which require an `MTYPE`) instead of bare `malloc()` / `free()`. The PR's whitespace change on the surrounding lines now surfaces this pre-existing violation in the diff. It should be converted to use FRR's allocator:

```suggestion
	integrate_sav = XMALLOC(MTYPE_TMP, integrate_sav_sz);
```

The corresponding `free(integrate_sav)` later in the function should become `XFREE(MTYPE_TMP, integrate_sav)` as well.

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants