Skip to content

Add completion spec: ip link - #319

Closed
warp-agent-staging[bot] wants to merge 3 commits into
mainfrom
factory/ip-link-completions
Closed

Add completion spec: ip link#319
warp-agent-staging[bot] wants to merge 3 commits into
mainfrom
factory/ip-link-completions

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Fills in the ip link signature in command-signatures/json/ip.json. It previously carried only a name and a description, so ip link <TAB> offered nothing beyond the object name itself.

Addresses warpdotdev/warp#9768.

What's covered

Actions: add, del/delete, set/change, show/list/lst, xstats, afstats, property (add/del), and help.

Options and arguments, including device selection (dev, link, parentdev, group), up/down, mtu, name, address, broadcast/brd, txqueuelen/txqlen/qlen, index, numtxqueues/numrxqueues, the GSO/GRO sizing knobs, netns, link-netns/link-netnsid, alias, master/nomaster/vrf, addrgenmode, the flag toggles (arp, promisc, multicast, allmulticast, trailers, dynamic, carrier, protodown, protodown_reason), the SR-IOV vf parameters, the XDP attach options, the inet devconf parameters, and the show filters (up, down, master, vrf, type, nomaster, novf).

Link types are suggested for type on add, delete, set, show and help. xstats type is restricted to bond, bond_slave, bridge and bridge_slave, the only four link helpers that define .print_ifla_xstats — every other type exits with link type X doesn't support xstats.

Device and namespace arguments reuse the existing network_interfaces and netns generators, so no new Rust generators were needed.

Sources

Every entry is grounded in one of:

  • ip-link(8) — iproute2 man/man8/ip-link.8.in
  • iproute2's own ip link help output — iplink_usage() / iplink_types_usage() in ip/iplink.c, plus the argument parsers in ip/iplink.c, ip/iplink_xstats.c, and ip/ipaddress.c (ipaddr_list_flush_or_save, which handles the ip link show filters)

iproute2 could not be installed in the build environment (no root), so ip link help was read from its source rather than executed.

Where the two sources disagree, the parser wins, since it decides what ip actually accepts. Three cases came up:

  • peer LLADDRESS is not shipped. ip-link(8) lists it as a synonym for broadcast/brd, but iplink_parse() only accepts prefix-matched broadcast and the exact string brd.
  • ip link property delete is not shipped, only del. iplink_prop() dispatches on matches(*argv, "del"), and matches() only succeeds when the token is a prefix of the pattern, so the longer delete exits with Operator required. The top-level ip link delete is different — it uses matches(*argv, "delete") — so both spellings are offered there.
  • batadv and vti6 are shipped even though neither appears in a documented TYPE list. The rule behind the type lists is: a type is suggested if it is documented in iplink_types_usage() / ip-link(8), or creatable with a link_util helper. That admits batadv (ip/iplink_batadv.c) and vti6 (ip/link_vti6.c), which are registered exactly like can and lowpan — types the man page does list. It excludes tun and vrf_slave, which have helpers too, but ones that define only .print_opt: they exist so ip link show can render those kinds, and neither can be created with ip link add type ....

Position-dependent keywords

state parses differently depending on where it appears. At the device position iplink_parse() routes it to get_operstate(); only after vf NUM does it take auto/enable/disable. Since the completion fires at the device position, the entry carries the operstate value list, and its description notes the virtual-function meaning. This is the one keyword sourced from the parser rather than the docs.

More generally, the vf parameters and the XDP sub-keywords (object, pinned, section, program, verbose) only parse after vf NUM or xdp* respectively, but the Fig schema has no way to nest options under an option, so they are flattened onto set and their descriptions say which keyword they follow. Flagging that tradeoff explicitly for review.

Deliberately left out

  • Per-type ARGS (type vlan id ..., type vxlan ..., type bridge ..., and the ~40 other link types). That is a much larger surface with its own man-page sections and is better handled as follow-up work; type still suggests the type names.
  • ip link replace, and the mode keyword on set. They exist in ip/iplink.c but appear in neither ip link help nor ip-link(8).
  • macaddr on set — it is a macvlan/macvtap type-specific argument, so it belongs with the per-type work above.

Validation

script/presubmit passes:

  • npm run format:check — all matched files use Prettier code style
  • cargo fmt -p warp-command-signatures -p warp-completion-metadata --check
  • cargo clippy -p warp-command-signatures -p warp-completion-metadata --all-targets --all-features -- -D warnings
  • cargo test --verbose — 133 passed in warp-command-signatures (this includes the invariants that every spec deserializes and that every referenced generator name exists), 10 passed in warp-completion-metadata, 0 failed

Follow-up

Once this merges, warp-command-signatures needs a rev bump in warpdotdev/warp's Cargo.toml (currently pinned to fe35266) before the completions reach the app. That PR is not opened yet, since the rev does not exist until this lands.

Fill in the `ip link` signature in json/ip.json, which previously carried
only a name and a description. Covers the actions `add`, `delete`, `set`/
`change`, `show`/`list`/`lst`, `xstats`, `afstats`, `property` and `help`,
along with their options and arguments: device selection, up/down, mtu,
rename, address, txqueuelen, master/nomaster, netns, link types for add,
the SR-IOV `vf` parameters, the XDP attach options and the `inet` devconf
parameters.

Device and namespace arguments reuse the existing `network_interfaces`
and `netns` generators.

Grounded in ip-link(8) (iproute2 man/man8/ip-link.8.in) and iproute2's own
`ip link help` output (ip/iplink.c).

Co-Authored-By: Warp Agent <agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Aug 13, 2026
@warp-agent-staging
warp-agent-staging Bot requested a review from acarl005 August 13, 2026 01:47
@warp-agent-staging

Copy link
Copy Markdown
Contributor Author

This PR was generated with Warp.

View run View conversation

Six fixes, each verified against iproute2 main:

- `ip link property delete` is not a keyword ip accepts. iplink_prop()
  dispatches on matches(*argv, "del"), and matches() only succeeds when the
  token is a prefix of the pattern, so "delete" exits with "Operator
  required". The top-level `ip link delete` uses matches(*argv, "delete")
  and is unaffected.
- `state` on set completes at the device position, where iplink_parse()
  routes it to get_operstate(); auto/enable/disable are only valid after
  `vf NUM`. Retarget it to the oper_states[] value list and note the
  virtual-function meaning in its description.
- `xstats type` only works for the four link helpers that define
  .print_ifla_xstats: bond, bond_slave, bridge, bridge_slave. Every other
  type exits with "link type X doesn't support xstats".
- Add `batadv` to the link type lists. It is registered by
  ip/iplink_batadv.c just like can and lowpan, which the man page lists.
- Add the `qlen` alias, accepted by ip/iplink.c alongside txqueuelen and
  txqlen.
- `property add|del` take a bare positional DEVICE, since iplink_prop_mod()
  treats any non-altname token as the device; mark altname isRepeatable.

Co-Authored-By: Warp Agent <agent@warp.dev>
ip/link_vti6.c registers a link_util with a .parse_opt, so vti6 is creatable
in the same way as batadv, can and lowpan, none of which appear in a
documented TYPE list either.

tun and vrf_slave also have helpers but are left out: theirs define only
.print_opt, so they exist to render a kind in `ip link show` and cannot be
created with `ip link add type ...`. Suggesting them would offer something
ip rejects.

The xstats list is unaffected; it stays restricted to the four types whose
link_util defines .print_ifla_xstats.

Co-Authored-By: Warp Agent <agent@warp.dev>

@warp-agent-staging warp-agent-staging Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Overview

Fills in the previously empty ip link entry in command-signatures/json/ip.json with the link actions, their options and value lists — one file, no Rust. The data was checked keyword-by-keyword against iproute2 main and three position-dependent errors were corrected before this landed in front of you; what remains below are two calls that need a human, not corrections.

Concerns

  • 17 keywords are offered on ip link set but only parse in a nested position (inline comments below). The vf group is only read inside iplink_parse_vf() after vf NUM, qos/proto only after vf NUM vlan VLANID, and the five XDP sub-keywords only after xdp*; standalone, each one hits the parser fallthrough and errors. The Fig schema can't scope a keyword to a preceding option, so the choice is between a discoverable-but-noisy list and only suggesting what parses — the descriptions do name the required vf context, which softens the vf group, but the five XDP keywords have no standalone reading at all and object/pinned are already reachable through the xdp option's own suggestions.
  • The repo's mandatory-screenshot rule may or may not apply here. .agents/skills/review-pr-local/SKILL.md:20-31 names generatorName references in changed json/<command>.json files as a trigger, and this PR adds many; under a strict reading that forces Request changes. The rule's intent — prove new generator code produces completions — isn't engaged, since network_interfaces and netns are unchanged and already exercised by ip rule and ip monitor, so this should be decided rather than left to grep.

Verdict

Checks: build pass, tests pass (133 + 10), CI pending on this head and green on the previous one, visual proof missing (see Concerns)

Found: 0 critical, 1 important, 0 suggestions, 0 nits, 1 question

Responding as wilson: Open session · View factory task

}
},
{
"name": "mac",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

mac, vlan, qos, proto, rate, max_tx_rate, min_tx_rate, spoofchk, query_rss, trust, node_guid and port_guid are parsed only inside iplink_parse_vf(), i.e. after vf NUM — and qos/proto only after vf NUM vlan VLANID, via the PREV_ARG() rewind at ip/iplink.c:307,318. Offered at ip link set dev eth0 <TAB> they fall through to either "dev" is duplicate, or "mac" is a garbage. Their descriptions do name the vf requirement, so this is the milder half of the tradeoff in the review body.

}
},
{
"name": "object",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

object, pinned, section, program and verbose are parsed only after xdp/xdpgeneric/xdpdrv/xdpoffload (ip/iplink_xdp.c, usage at ip/iplink.c:96-102). Unlike the vf keywords these have no standalone reading to describe, and object/pinned are already reachable through the xdp option's own suggestions directly above — so dropping these five loses nothing.

@warp-agent-staging

Copy link
Copy Markdown
Contributor Author

Closing this in favour of #318, which covers the same issue and models the data correctly.

This PR puts every bare ip link keyword (dev, mtu, up, vf, xdp, …) in options. Warp's completer only ever renders an options entry dash-prefixed — format!("-{}", flag.name) in warp_completer/src/completer/engine/flag/legacy.rs:56,93-94, reached only from a LocationType::Flag location — so none of these would be suggested as bare words. #311 established the subcommands pattern and merged at 01:39Z, four minutes into this work; I read ip address/ip route as the schema reference, and they were the pre-#311 shape.

That also retracts the first concern in my review above: the 17 position-dependent keywords were an artefact of the flat options modeling, not a schema limitation. #318 nests them properly under vf and xdp, so there is no tradeoff to decide.

Two things here are worth keeping, and I've left them on #318: the verified 32-parameter inet devconf block (absent there), and the xstats type list restricted to the four types that actually implement print_ifla_xstats. The full source-verified data stays readable on this branch.

Responding as wilson: Open session · View factory task

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant