Page MenuHomeFreeBSD

ndp(8): add structured output formatting via libxo
ClosedPublic

Authored by melifaro on Jun 30 2022, 2:11 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, May 27, 3:49 AM
Unknown Object (File)
Mon, May 27, 3:37 AM
Unknown Object (File)
Mon, May 27, 3:37 AM
Unknown Object (File)
Mon, May 27, 3:37 AM
Unknown Object (File)
Sat, May 25, 4:24 AM
Unknown Object (File)
May 8 2024, 1:37 PM
Unknown Object (File)
Apr 27 2024, 11:04 AM
Unknown Object (File)
Apr 27 2024, 11:04 AM
Subscribers

Details

Summary

Add structured output for all ndp(8) operations.

This change mostly leverages arp(8) structured output structure with some differences described below.

  • use more generic "neighbor-cache" instead of "ndp-cache" (contrary to "arp-cache")
  • use "address" instead of "ip-address" for IPv6 addresses
    1. Questions
  • Do we really want to continue using kebab-case for field naming? It sometimes makes life harder ("-" treated as minus sign, apps like jq requires escaping to address these field, etc..) and I'm not sure I see json kebab case in the real world (with the notable exception of Juniper).
Test Plan

Normal output:

Dump cache:

14:11 [0] m@devel2 ndp -an
Neighbor                             Linklayer Address  Netif Expire    S Flags
2a01:4f8:13a:70c:ffff::1             52:54:00:d7:5f:09 vtnet0 23h45m25s S R
2a01:4f8:13a:70d::7                  52:54:00:14:e3:19 vtnet0 permanent R
2a01:4f8:13a:70c:ffff::8             52:54:00:14:e3:19 vtnet0 permanent R
fe80::5054:ff:fe14:e319%vtnet0       52:54:00:14:e3:19 vtnet0 permanent R
fe80::5054:ff:fed7:5f09%vtnet0       52:54:00:d7:5f:09 vtnet0 18s       R R
14:26 [0] m@devel2 /usr/obj/usr/home/melifaro/free/head/amd64.amd64/usr.sbin/ndp/ndp -an
Neighbor                             Linklayer Address  Netif Expire    1s 5s
2a01:4f8:13a:70c:ffff::1             52:54:00:d7:5f:09 vtnet0 23h45m21s S R
2a01:4f8:13a:70d::7                  52:54:00:14:e3:19 vtnet0 permanent R
2a01:4f8:13a:70c:ffff::8             52:54:00:14:e3:19 vtnet0 permanent R
fe80::5054:ff:fe14:e319%vtnet0       52:54:00:14:e3:19 vtnet0 permanent R
fe80::5054:ff:fed7:5f09%vtnet0       52:54:00:d7:5f:09 vtnet0 14s       R R

Dump routers:

14:26 [0] m@devel2 ndp -r
fe80::5054:ff:fed7:5f09%vtnet0 if=vtnet0, flags=, pref=medium, expire=25s
14:27 [0] m@devel2 /usr/obj/usr/home/melifaro/free/head/amd64.amd64/usr.sbin/ndp/ndp -r
fe80::5054:ff:fed7:5f09%vtnet0 if=vtnet0, flags=, pref=medium, expire=27s

Dump prefixes:

14:36 [0] m@devel2 /usr/obj/usr/home/melifaro/free/head/amd64.amd64/usr.sbin/ndp/ndp -p
2a01:4f8:13a:70d::/64 if=vtnet0
flags=LO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
2a01:4f8:13a:70c:ffff::/96 if=vtnet0
flags=LO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
fe80::%vtnet0/64 if=vtnet0
flags=LAO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
fe80::%lo0/64 if=lo0
flags=LAO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
14:36 [0] m@devel2
14:36 [0] m@devel2 ndp -p
2a01:4f8:13a:70d::/64 if=vtnet0
flags=LO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
2a01:4f8:13a:70c:ffff::/96 if=vtnet0
flags=LO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
fe80::%vtnet0/64 if=vtnet0
flags=LAO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
fe80::%lo0/64 if=lo0
flags=LAO vltime=infinity, pltime=infinity, expire=Never, ref=1
  No advertising router
Structured(neighbors)
{
  "__version": "1",
  "ndp": {
    "neighbor-cache": [
      {
        "address": "2a01:4f8:13a:70c:ffff::1",
        "mac-address": "52:54:00:d7:5f:09",
        "interface": "vtnet0",
        "expires_sec": 84772,
        "neighbor-state": "S",
        "nd-flags": "R"
      },
      {
        "address": "2a01:4f8:13a:70d::7",
        "mac-address": "52:54:00:14:e3:19",
        "interface": "vtnet0",
        "permanent": true,
        "neighbor-state": "R",
        "nd-flags": ""
      },
      {
        "address": "2a01:4f8:13a:70c:ffff::8",
        "mac-address": "52:54:00:14:e3:19",
        "interface": "vtnet0",
        "permanent": true,
        "neighbor-state": "R",
        "nd-flags": ""
      },
      {
        "address": "fe80::5054:ff:fe14:e319%vtnet0",
        "mac-address": "52:54:00:14:e3:19",
        "interface": "vtnet0",
        "permanent": true,
        "neighbor-state": "R",
        "nd-flags": ""
      },
      {
        "address": "fe80::5054:ff:fed7:5f09%vtnet0",
        "mac-address": "52:54:00:d7:5f:09",
        "interface": "vtnet0",
        "expires_sec": 1,
        "neighbor-state": "R",
        "nd-flags": "R"
      }
    ]
  }
}
Structured(routers)
{
  "__version": "1",
  "ndp": {
    "router-list": [
      {
        "hostname": "fe80::5054:ff:fed7:5f09%vtnet0",
        "address": "fe80::5054:ff:fed7:5f09",
        "interface": "vtnet0",
        "flags_pretty": [],
        "flags": "",
        "preference": "medium",
        "expires_sec": 24
      }
    ]
  }
}
Structured(prefixes)
{
  "__version": "1",
  "ndp": {
    "prefix-list": [
      {
        "prefix": "2a01:4f8:13a:70d::/64",
        "interface": "vtnet0",
        "flags_pretty": [
          "ra_onlink",
          "is_onlink"
        ],
        "flags": "LO",
        "valid-lifetime": 4294967295,
        "preferred-lifetime": 4294967295,
        "permanent": true,
        "refcount": 1
      },
      {
        "prefix": "2a01:4f8:13a:70c:ffff::/96",
        "interface": "vtnet0",
        "flags_pretty": [
          "ra_onlink",
          "is_onlink"
        ],
        "flags": "LO",
        "valid-lifetime": 4294967295,
        "preferred-lifetime": 4294967295,
        "permanent": true,
        "refcount": 1
      },
      {
        "prefix": "fe80::%vtnet0/64",
        "interface": "vtnet0",
        "flags_pretty": [
          "ra_onlink",
          "ra_autonomous",
          "is_onlink"
        ],
        "flags": "LAO",
        "valid-lifetime": 4294967295,
        "preferred-lifetime": 4294967295,
        "permanent": true,
        "refcount": 1
      },
      {
        "prefix": "fe80::%lo0/64",
        "interface": "lo0",
        "flags_pretty": [
          "ra_onlink",
          "ra_autonomous",
          "is_onlink"
        ],
        "flags": "LAO",
        "valid-lifetime": 4294967295,
        "preferred-lifetime": 4294967295,
        "permanent": true,
        "refcount": 1
      }
    ]
  }
}
Structured(deletion)
{
  "__version": "1",
  "ndp": {
    "neighbor-cache": [
      {
        "hostname": "2a01:4f8:13a:70c:ffff::1",
        "address": "2a01:4f8:13a:70c:ffff::1",
        "interface": "vtnet0"
      },
      {
        "hostname": "fe80::5054:ff:fed7:5f09%vtnet0",
        "address": "fe80::5054:ff:fed7:5f09",
        "interface": "vtnet0"
      }
    ]
  }
}

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

melifaro retitled this revision from ndp(8): add libxo formatting to ndp(8): add structured output formatting via libxo.Jun 30 2022, 2:51 PM
melifaro edited the summary of this revision. (Show Details)
melifaro edited the test plan for this revision. (Show Details)
melifaro added a reviewer: network.
usr.sbin/ndp/ndp.c
779

flgbuf could be empty string, then nd-flags can be omitted IMO.

1162

rflags could also be empty string.

usr.sbin/ndp/ndp.c
779

That's true. I'd rather keep nd-flags as always present to simplify handling in the client code (e.g. don't need additional check for field existence).

1162

Same here - I'd prefer to have ..flags field always present so consumers can rely on that.

melifaro edited the summary of this revision. (Show Details)
melifaro edited the test plan for this revision. (Show Details)

Fix some libxo formatting.

This revision was not accepted when it landed; it landed in state Needs Review.Jul 8 2022, 11:41 AM
This revision was automatically updated to reflect the committed changes.