Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions docs/release-notes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,42 @@
Please consult [this page](../known-limitations/known-limitations.md) for a list of current limitations
of the Fabric. Unless otherwise stated, these issues affect all the latest versions of Fabric.

## 26.04

Date: September 16, 2026

### Highlights

- Gateway now handles stateless peerings on all gateways of a group at the same time (ECMP), more details
[here](../user-guide/gateway-failover.md)
- A peering is stateless if it requires neither stateful NAT (masquerade or port forwarding) nor stateful ACLs
- Enabled by default, can be disabled per peering with `noMultiPath` in the `GatewayPeering` object
- Significantly expanded LLDP and transceiver metrics (Prometheus) and state exposed through API, more details
[here](../troubleshooting/lldp.md)
- LLDP neighbors now include neighbor MAC, human-readable port name, advertised TTL and last update time
- All major transceiver information is now exposed through Prometheus (part numbers, serial numbers, etc.)

### Other

- Experimental BGP unnumbered support for Fabric links, removing the need to allocate IPs for spine-leaf links
- BFD for External attachments is now configurable per attachment, falling back to the Fabric defaults

### Notes

- Upgrade is supported only from 26.03.x
- Broadcom SONiC 4.5.2 is required (see [upgrade SONiC](../install-upgrade/upgrade.md#upgrade-sonic) for instructions)

### Software versions

- fabricator/hhfab: v0.50.4
- fabric: v0.133.0
- broadcom sonic: v4.5.2
- gateway:
- dataplane: v0.28.0
- frr: v0.28.0 (based on FRR 10.6, patched)
- flatcar: v4593.2.5
- k8s (k3s): v1.36.3-k3s1

## 26.03

Date: August 18, 2026
Expand Down
1 change: 1 addition & 0 deletions docs/troubleshooting/.pages
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
nav:
- Overview: overview.md
- Physical Links: physical_links.md
- LLDP Neighbors: lldp.md
- Switch Agent: agent.md
- ...
60 changes: 60 additions & 0 deletions docs/troubleshooting/lldp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# LLDP Neighbors

`kubectl fabric inspect lldp` reports the LLDP neighbors observed on the switch ports next to what the wiring
diagram expects on those ports, highlighting the values that don't match:

```console
core@control-1 ~ $ kubectl fabric inspect lldp
PORT CONNECTION TYPE NEIGHBOR PORT MAC AGE / TTL
E1/1/1 leaf-1--spark-1 unbundled spark-1.lan enP2p1s0f0np0 (want p1) 4c:bb:47:e8:ef:fe 37/120s
E1/2/1 server-1--bundled--leaf-1 bundled server-1 enp2s2 6e:27:d4:e2:6b:f7 30/120s
E1/5/1 server-5--unbundled--leaf-1 unbundled server-5 +1 enp2s1 00:00:00:0b:bb:11 29/120s
E1/61/1 spine-1--fabric--leaf-1 fabric spine-1 E1/61/1 b4:db:91:9b:60:27 14/20s

Note: +N means N more neighbors on the port, use --show-all to see them
```

- A value that disagrees with the wiring is shown as `actual (want expected)`, with only the actual value
highlighted. A port that expects a neighbor and sees none shows the expectation alone.
- When several neighbors answer on one port and one of them is the expected device, only that one is shown and
`+N` notes the rest. `--show-all` lists all of them and marks the additional ones.
- `AGE / TTL` is the age of the neighbor entry against the TTL the neighbor advertises. Fabric links typically
advertise 20 seconds and servers 120, so staleness is best judged against the advertised value rather than a
fixed threshold.

Useful flags:

| Flag | Description |
| --- | --- |
| `--show-all` | Show all neighbors on a port, not just the expected one |
| `--ignore-suffix`, `--ignore-prefix` | Name parts to ignore when matching (see below) |
| `--fabric`, `--server`, `--external`, `--gateway` | Only show ports of the given connection type |

The output can also be formatted as JSON or YAML, like for the other `inspect` commands.

## Hostname matching

A server wired as `server-1` often introduces itself over LLDP as `server-1.lan`, and DPUs are usually named
similar to the hosts they sit in but with a `-dpu` suffix. Those are the same device, so some name suffixes and
prefixes are ignored when comparing the neighbor with the wiring:

- The defaults are the `-dpu`, `.lan` and `.maas` suffixes, and they can be replaced with the
`--ignore-suffix` and `--ignore-prefix` flags.
- A name is only trimmed if trimming produces the expected name, so a device deliberately wired as
`host-1-dpu` still matches on its full name.
- Names, port names and descriptions are compared case-insensitively.
- The ignored parts are reported: dimmed in the table, and as `ignoredPrefix`/`ignoredSuffix` in the JSON and
YAML output.

When a server's advertised hostname is unrelated to the name of its object, it can be declared instead with the
`spec.inspect.expectedSysName` field on the `Server` object, see [Servers](../user-guide/devices.md#servers).

## Metrics

The neighbor and transceiver state above is also exported by the switch agent as Prometheus metrics on every
collection cycle, so a link that goes quiet or an optic that fails is visible without running a command. The
neighbor count, the advertised TTL, the last update time and the neighbor inventory are exported per port, as
are the transceiver presence, activity, CMIS readiness and module identity. Every interface and queue metric
also carries a `transceiver` label naming the cage the port belongs to, so link, neighbor and optic data can be
joined on a single label. See [Observability configuration](../user-guide/o11y-config.md) for how the metrics
are collected.
24 changes: 12 additions & 12 deletions docs/troubleshooting/physical_links.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,25 @@ the fault to a single switch port using `kubectl fabric inspect`.
### 1. Identify the affected port

`kubectl fabric inspect lldp` prints a per-switch table of the LLDP
neighbors it observes against what the wiring expects. A port with a
blank `NEIGHBOR` / `PORT` / `DESCRIPTION` is missing its expected
neighbor entirely:
neighbors it observes against what the wiring expects (see
[LLDP Neighbors](lldp.md)). A port that is missing its expected neighbor
entirely reports the expectation only, with no observed values:

```console
core@control-1 ~ $ kubectl fabric inspect lldp
Switch: ds5000-01 (actual←→expected)
PORT CONNECTION TYPE NEIGHBOR PORT DESCRIPTION
E1/21/1 ds5000-01--mesh--ds5000-02 mesh
E1/22/1 ds5000-01--mesh--ds5000-02 mesh ds5000-02 E1/22/1 Hedgehog Fabric
Switch: ds5000-01
PORT CONNECTION TYPE NEIGHBOR PORT MAC AGE / TTL
E1/21/1 ds5000-01--mesh--ds5000-02 mesh (want ds5000-02)
E1/22/1 ds5000-01--mesh--ds5000-02 mesh ds5000-02 E1/22/1 b4:db:91:9b:60:27 14/20s
...
Switch: ds5000-02 (actual←→expected)
PORT CONNECTION TYPE NEIGHBOR PORT DESCRIPTION
E1/21/1 ds5000-01--mesh--ds5000-02 mesh
E1/22/1 ds5000-01--mesh--ds5000-02 mesh ds5000-01 E1/22/1 Hedgehog Fabric
Switch: ds5000-02
PORT CONNECTION TYPE NEIGHBOR PORT MAC AGE / TTL
E1/21/1 ds5000-01--mesh--ds5000-02 mesh (want ds5000-01)
E1/22/1 ds5000-01--mesh--ds5000-02 mesh ds5000-01 E1/22/1 b4:db:91:9b:60:1f 12/20s
...
```

Both sides of the link report an empty neighbor on `E1/21/1` while the
Both sides of the link report no neighbor on `E1/21/1` while the
sibling port `E1/22/1` on the same connection reports its peer normally.
The fault is on that specific physical link between `ds5000-01` and
`ds5000-02`, not on either switch as a whole. A working sibling on the
Expand Down
17 changes: 17 additions & 0 deletions docs/user-guide/devices.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,20 @@ metadata:
spec:
description: MH s5248-01/E1 s5248-02/E1
```

If a server advertises an LLDP system name that isn't the name of its `Server` object, it can be declared with
the optional `spec.inspect.expectedSysName` field:

```{.yaml .annotate linenums="1" title="Server.yaml"}
apiVersion: wiring.githedgehog.com/v1beta1
kind: Server
metadata:
name: server-1
namespace: default
spec:
inspect:
expectedSysName: server-1.example.com
```

The field is optional: servers that don't set it are matched by the object name, with some common suffixes and
prefixes ignored. See [LLDP Neighbors](../troubleshooting/lldp.md) for how the matching works.
Loading