mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
Merge pull request #1495 from kernelkit/speed-duplex
This commit is contained in:
+35
-4
@@ -11,21 +11,53 @@ All notable changes to the project are documented in this file.
|
||||
- Upgrade Linux kernel to 6.18.33 (LTS)
|
||||
- Upgrade Buildroot to 2025.02.14 (LTS)
|
||||
- Upgrade FRR to 10.5.4
|
||||
- Add support for [Acer Connect Vero W6m][AcerConnectVero], a COTS home router,
|
||||
based upon the same hardware as [Banana Pi BPI-R3][BPI-R3], but
|
||||
- Add support for [Acer Connect Vero W6m][AcerConnectVero], a low-cost COTS
|
||||
home router, based on the same hardware as [Banana Pi BPI-R3][BPI-R3], but
|
||||
with a Wi-Fi 6E (6 GHz band) chip.
|
||||
- Add configurable channel-width in Wi-Fi configuration.
|
||||
- Upgrade `ieee802-ethernet-interface` YANG model to revision 2025-09-10 (IEEE
|
||||
Std 802.3.2-2025), adding the standard `phy-type` and `pmd-type` operational
|
||||
leaves. Speed is now exposed via `ietf-interfaces:speed` (bps, RFC 8343);
|
||||
the now obsolete `eth:speed` is no longer returned
|
||||
- Rework `show interface` summary output as layered protocol rows. When a
|
||||
port has link, a physical-medium row (e.g. `1000baseT`, `10GbaseLR`) appears
|
||||
above the `ethernet` row. VLAN, GRE, VXLAN and WiFi interfaces likewise get
|
||||
one row per protocol layer, with type-specific data on each (`vid:`,
|
||||
`remote:`, `vni:`, `station ssid:`, etc.), issue #530
|
||||
- New `auto-negotiation/advertised-pmd-types` leaf-list replaces the
|
||||
retired `enable=false + speed + duplex` idiom for pinned link modes
|
||||
(IEEE Std 802.3.2-2025 obsoleted `eth:speed`), issue #805. Existing
|
||||
startup configurations are migrated automatically on upgrade; see
|
||||
[ethernet.md](ethernet.md#restricting-advertised-link-modes) for the
|
||||
new model, the duplex × PMD mapping, and the `enable=false` escape
|
||||
hatch for non-autoneg peers
|
||||
- New `ethernet/mdi-x` boolean leaf to force the copper MDI/MDI-X pinout
|
||||
(true = MDI-X, false = MDI, absent = Auto-MDIX). Needed on some PHYs
|
||||
where Auto-MDIX stops working once auto-negotiation is disabled; see
|
||||
[ethernet.md](ethernet.md#restricting-advertised-link-modes)
|
||||
- New operational `supported-pmd-types` leaf-list on each Ethernet interface,
|
||||
exposing the set of PMD types currently supported. Useful for SFP/SFP+
|
||||
diagnosis: an LR-only optic narrows the list to a single entry, confirming
|
||||
the transceiver without `ethtool -m`
|
||||
- New CLI command `show operational`, and XPath filtering for this and any of
|
||||
the other datastores, using `[path /path/to/subtree]`
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix #1493: container with a physical interface not properly removed
|
||||
when switching to a configuration without containers
|
||||
- Fix #1506: add documentation on how to configure VLAN interfaces,
|
||||
including stacked (Q-in-Q) VLAN interfaces, in a dedicated `vlan.md`
|
||||
- Fix long-standing typo `auto-negotation` in `yanger`, which caused
|
||||
the operational `auto-negotiation/enable` leaf to always read as
|
||||
`unknown` regardless of the actual port setting
|
||||
- Handle unclean daemon exits better, e.g., `dbus-daemon` crashing and
|
||||
leaving a stale pidfile behind, causing it to refuse to be restarted
|
||||
- Fix occasional blank or garbled `[ OK ]` lines at startup
|
||||
- Disallow multicast MAC addresses in custom MAC address configuration
|
||||
- Fix broken Wi-Fi 6 GHz band configuration.
|
||||
|
||||
[BPI-R3]: https://docs.banana-pi.org/en/BPI-R3/BananaPi_BPI-R3
|
||||
[AcerConnectVero]: ../board/aarch64/acer-connect-vero-w6m/
|
||||
|
||||
[v26.04.0][] - 2026-04-30
|
||||
@@ -73,7 +105,6 @@ All notable changes to the project are documented in this file.
|
||||
- Fix [BPI-R3][] PCIe devices failing to initialize on boot due to a missing
|
||||
clock definition in the device tree
|
||||
|
||||
[BPI-R3]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3
|
||||
[BPI-R4]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
|
||||
[ESPRESSObin]: https://espressobin.net/
|
||||
[SAMA7G54]: https://www.microchip.com/en-us/development-tool/ev21h18a
|
||||
@@ -177,7 +208,7 @@ All notable changes to the project are documented in this file.
|
||||
|
||||
- Fix CLI `copy` command problem to copy to scp/sftp destinations
|
||||
|
||||
[BPI-R3-MINI]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3_Mini
|
||||
[BPI-R3-MINI]: https://docs.banana-pi.org/en/BPI-R3_Mini/BananaPi_BPI-R3_Mini
|
||||
[SAMA7G54-EK]: https://www.microchip.com/en-us/development-tool/ev21h18a
|
||||
|
||||
[v26.01.0][] - 2026-02-03
|
||||
|
||||
+2
-2
@@ -73,8 +73,8 @@ admin@example:/config/interface/br0/> <b>set bridge vlans vlan 20 tagged br0</b>
|
||||
</code></pre>
|
||||
|
||||
To route or to manage via a VLAN, a VLAN interface needs to be created
|
||||
on top of the bridge, see section [VLAN Interfaces](ethernet.md#vlan-interfaces)
|
||||
for more on this topic.
|
||||
on top of the bridge, see section [VLAN Interfaces](vlan.md) for more
|
||||
on this topic.
|
||||
|
||||
> [!NOTE]
|
||||
> In some use-cases only a single management VLAN on the bridge is used.
|
||||
|
||||
@@ -164,7 +164,7 @@ interfaces {
|
||||
}
|
||||
}
|
||||
admin@host-12-34-56:/config/interface/eth0/> leave
|
||||
admin@host-12-34-56:/> show interfaces
|
||||
admin@host-12-34-56:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
lo loopback UNKNOWN 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
|
||||
+4
-4
@@ -109,11 +109,11 @@ When configuring, e.g., `dns-server`, or `router` options with the value
|
||||
`auto`, the system uses the IP address from the interface matching the
|
||||
subnet. For example:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 192.168.1.1/24 (static)
|
||||
eth1 ethernet UP 02:00:00:00:00:01
|
||||
eth1 ethernet UP 02:00:00:00:00:01
|
||||
ipv4 192.168.2.1/24 (static)
|
||||
|
||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>edit option dns-server</b>
|
||||
|
||||
+184
-120
@@ -1,52 +1,8 @@
|
||||
# Ethernet Interfaces
|
||||
|
||||
This document covers VLAN interfaces, physical Ethernet interfaces,
|
||||
and virtual Ethernet (VETH) pairs.
|
||||
|
||||
|
||||
## VLAN Interfaces
|
||||
|
||||
Creating a VLAN can be done in many ways. This section assumes VLAN
|
||||
interfaces created atop another Linux interface. E.g., the VLAN
|
||||
interfaces created on top of the Ethernet interface or bridge in the
|
||||
picture below.
|
||||
|
||||

|
||||
|
||||
A VLAN interface is basically a filtering abstraction. When you run
|
||||
`tcpdump` on a VLAN interface you will only see the frames matching the
|
||||
VLAN ID of the interface, compared to *all* the VLAN IDs if you run
|
||||
`tcpdump` on the lower-layer interface.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0.20</b>
|
||||
admin@example:/config/interface/eth0.20/> <b>show</b>
|
||||
type vlan;
|
||||
vlan {
|
||||
tag-type c-vlan;
|
||||
id 20;
|
||||
lower-layer-if eth0;
|
||||
}
|
||||
admin@example:/config/interface/eth0.20/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The example below assumes bridge br0 is already created, see [VLAN
|
||||
Filtering Bridge](bridging.md#vlan-filtering-bridge).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface vlan10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan id 10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan lower-layer-if br0</b>
|
||||
admin@example:/config/interface/vlan10/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
As conventions, a VLAN interface for VID 20 on top of an Ethernet
|
||||
interface *eth0* is named *eth0.20*, and a VLAN interface for VID 10 on
|
||||
top of a bridge interface *br0* is named *vlan10*.
|
||||
|
||||
> [!NOTE]
|
||||
> If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a
|
||||
> number, the CLI infers the interface type automatically.
|
||||
This document covers physical Ethernet interfaces and virtual Ethernet
|
||||
(VETH) pairs. For VLAN interfaces stacked on top of an Ethernet port
|
||||
or bridge, see [VLAN Interfaces](vlan.md).
|
||||
|
||||
|
||||
## Physical Ethernet Interfaces
|
||||
@@ -56,111 +12,219 @@ top of a bridge interface *br0* is named *vlan10*.
|
||||
Physical Ethernet interfaces provide low-level settings for speed/duplex as
|
||||
well as packet status and [statistics](#ethernet-statistics).
|
||||
|
||||
By default, Ethernet interfaces defaults to auto-negotiating
|
||||
speed/duplex modes, advertising all speed and duplex modes available.
|
||||
In the example below, the switch would by default auto-negotiate speed
|
||||
1 Gbit/s on port eth1 and 100 Mbit/s on port eth4, as those are the
|
||||
highest speeds supported by H1 and H2 respectively.
|
||||
By default, Ethernet interfaces defaults to auto-negotiating speed/duplex
|
||||
modes, advertising all speed and duplex modes available. In the example
|
||||
below, the switch would by default auto-negotiate speed 1 Gbps on port eth1
|
||||
and 100 Mbps on port eth4, as those are the highest speeds supported by H1 and
|
||||
H2 respectively.
|
||||
|
||||

|
||||
|
||||
The speed and duplex status for the links can be listed as shown
|
||||
below, assuming the link operational status is 'up'.
|
||||
A quick at-a-glance view of the physical link is available in the summary
|
||||
listing. When a port is up, a physical-layer row appears above the ethernet
|
||||
row, naming the IEEE PMD type (e.g. `1000baseT`, `10GbaseLR`) in the PROTOCOL
|
||||
column and the negotiated duplex in DATA. When the link is down the row is
|
||||
omitted and the interface name falls onto the ethernet row.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth1 1000baseT UP duplex: full
|
||||
ethernet 00:53:00:06:11:01
|
||||
eth2 1000baseT UP duplex: full
|
||||
ethernet 00:53:00:06:11:02
|
||||
eth3 ethernet DOWN 00:53:00:06:11:03
|
||||
eth4 100baseTX UP duplex: full
|
||||
ethernet 00:53:00:06:11:04
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
The detail view spells everything out, including auto-negotiation
|
||||
state and the speed in Mbit/s.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:01
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
link mode : 1000baseT
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:01
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
...
|
||||
admin@example:/> <b>show interface eth4</b>
|
||||
name : eth4
|
||||
index : 5
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 100
|
||||
physical address : 00:53:00:06:11:04
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75439
|
||||
out-octets : 550704
|
||||
name : eth4
|
||||
index : 5
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
link mode : 100baseTX
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 100
|
||||
physical address : 00:53:00:06:11:04
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75439
|
||||
out-octets : 550704
|
||||
...
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
### Configuring fixed speed and duplex
|
||||
### Restricting advertised link modes
|
||||
|
||||
Auto-negotiation of speed/duplex mode is desired in almost all
|
||||
use-cases, but it is possible to disable auto-negotiation and specify
|
||||
a fixed speed and duplex mode.
|
||||
Auto-negotiation is the right default for almost all links, but sometimes a
|
||||
port has to come up at a fixed speed, usually when talking to old hardware
|
||||
that won't auto-negotiate or does it badly. IEEE Std 802.3.2-2025 dropped
|
||||
the old "turn off auto-negotiation, then set a fixed speed and duplex"
|
||||
approach. Instead you restrict the set of PMD types the port may advertise:
|
||||
list a single PMD and the link pins to that mode against any peer that
|
||||
supports it.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> When setting a fixed speed and duplex mode, ensure both sides of the
|
||||
> link have matching configuration. If speed does not match, the link
|
||||
> will not come up. If duplex mode does not match, the result is
|
||||
> reported collisions and/or bad throughput.
|
||||
> [!NOTE]
|
||||
> Earlier Infix releases needed `enable false` plus explicit `speed` and
|
||||
> `duplex` leaves. IEEE Std 802.3.2-2025 retired the `eth:speed` leaf, so
|
||||
> the speed now comes from the `advertised-pmd-types` entry instead.
|
||||
> Existing `startup-config.cfg` files are migrated automatically on upgrade.
|
||||
|
||||
The example below configures port eth3 to fixed speed 100 Mbit/s
|
||||
half-duplex mode.
|
||||
Each entry in `auto-negotiation/advertised-pmd-types` is an IEEE PMD-type
|
||||
identity (`ieee802-ethernet-phy-type:pmd-type-*`). The separate `duplex`
|
||||
leaf controls half vs full duplex.
|
||||
|
||||
The example below pins port `eth3` to 100 Mbit/s half-duplex.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth3 ethernet</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set speed 0.1</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation advertised-pmd-types pmd-type-100BASE-TX</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set duplex half</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation enable false</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>show</b>
|
||||
auto-negotiation {
|
||||
enable false;
|
||||
advertised-pmd-types [ ieee802-ethernet-phy-type:pmd-type-100BASE-TX ];
|
||||
}
|
||||
duplex half;
|
||||
speed 0.1;
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>leave</b>
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
Speed metric is in Gbit/s. Auto-negotiation needs to be disabled in
|
||||
order for fixed speed/duplex to apply. Only speeds `0.1`(100 Mbit/s)
|
||||
and `0.01` (10 Mbit/s) can be specified. 1 Gbit/s and higher speeds
|
||||
require auto-negotiation to be enabled.
|
||||
List several PMDs to advertise all of them; auto-negotiation then settles
|
||||
on the highest mode both ends support.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> When pinning a link mode, make sure both ends share at least one common
|
||||
> (PMD, duplex) combination, otherwise the link will not come up.
|
||||
|
||||
#### Duplex and advertised modes
|
||||
|
||||
A PMD type like `10BASE-T` or `100BASE-TX` says nothing about duplex on its
|
||||
own, but the kernel tracks half and full duplex as separate link modes.
|
||||
Infix advertises both variants of every PMD you list, then narrows to one
|
||||
duplex when the `duplex` leaf is set:
|
||||
|
||||
| `advertised-pmd-types` | `duplex` | Resulting advertised modes |
|
||||
|----------------------------|----------|------------------------------------------|
|
||||
| `[10BASE-T]` | _unset_ | `10baseT/Half` + `10baseT/Full` |
|
||||
| `[10BASE-T]` | `full` | `10baseT/Full` |
|
||||
| `[10BASE-T]` | `half` | `10baseT/Half` |
|
||||
| `[10BASE-T, 100BASE-TX]` | _unset_ | all four half/full combinations |
|
||||
| `[10BASE-T, 100BASE-TX]` | `full` | `10baseT/Full` + `100baseT/Full` |
|
||||
| _unset_ | _unset_ | every mode the PHY supports (default) |
|
||||
|
||||
So `duplex` filters the PMDs you listed. PMDs with no half-duplex variant
|
||||
(everything above 1 Gbps) only ever advertise full.
|
||||
|
||||
#### Disabling auto-negotiation
|
||||
|
||||
The method above keeps auto-negotiation on and only limits what it
|
||||
advertises, so the peer still negotiates as usual. That doesn't help with
|
||||
gear that won't negotiate at all, like some old switches or a back-to-back
|
||||
copper link. For those, set `auto-negotiation/enable false` together with a
|
||||
single `advertised-pmd-types` entry to force a fixed speed and duplex with
|
||||
negotiation off:
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation enable false</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set auto-negotiation advertised-pmd-types pmd-type-100BASE-TX</b>
|
||||
admin@example:/config/interface/eth3/ethernet/> <b>set duplex full</b>
|
||||
</code></pre>
|
||||
|
||||
With `enable false` you must list exactly one PMD: it sets the speed, and
|
||||
the `duplex` leaf sets half or full. Leave `duplex` out and Infix uses
|
||||
whatever the PMD supports, normally full.
|
||||
|
||||
Auto-MDIX usually rides along with auto-negotiation, so turning negotiation
|
||||
off can leave both ends picking the same MDI/MDI-X pinout. The link then
|
||||
comes up electrically but carries no traffic. When that happens, force
|
||||
opposite pinouts with the `mdi-x` leaf — set one end true (MDI-X) and the
|
||||
other false (MDI):
|
||||
|
||||
<pre class="cli"><code>admin@example:/config/interface/eth3/ethernet/> <b>set mdi-x false</b>
|
||||
</code></pre>
|
||||
|
||||
Leaving `mdi-x` unset keeps Auto-MDIX in charge, which is correct whenever
|
||||
auto-negotiation is on.
|
||||
|
||||
> [!NOTE]
|
||||
> Whether `enable false` reaches the external PHY depends on the driver.
|
||||
> Direct-attach NICs handle it directly. Switch user ports go through the
|
||||
> switch driver, and some accept the request at the MAC but leave the PHY
|
||||
> auto-negotiating: the kernel reports the configured speed while the wire
|
||||
> runs at whatever was negotiated, and traffic stalls. If that happens,
|
||||
> read the PHY's BMCR register (e.g. with `mdio` from `mdiotools`) to see
|
||||
> what the PHY is actually doing.
|
||||
|
||||
The detail view exposes a `supported` block (operational state,
|
||||
backed by the `supported-pmd-types` leaf-list) listing the PMD types
|
||||
the kernel currently believes the interface can operate at. For
|
||||
SFP/SFP+ cages this set reflects the inserted module: plug in a 10G
|
||||
LR optic and `supported` will narrow to `10GbaseLR` only. Combined
|
||||
with the operational `link mode` row above it, this makes it trivial
|
||||
to confirm what an unknown transceiver actually is — no `ethtool -m`
|
||||
round-trip needed.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth13</b>
|
||||
name : eth13
|
||||
type : ethernet
|
||||
operational status : up
|
||||
link mode : 10GbaseLR
|
||||
auto-negotiation : off
|
||||
supported : 10GbaseLR
|
||||
duplex : full
|
||||
speed : 10000
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
### Ethernet statistics
|
||||
|
||||
Ethernet packet statistics[^1] can be listed as shown below.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:0a
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
|
||||
eth-in-frames : 434
|
||||
eth-in-multicast-frames : 296
|
||||
eth-in-broadcast-frames : 138
|
||||
eth-in-error-fcs-frames : 0
|
||||
eth-in-error-oversize-frames : 0
|
||||
eth-out-frames : 310
|
||||
eth-out-multicast-frames : 310
|
||||
eth-out-broadcast-frames : 0
|
||||
eth-out-good-octets : 76821
|
||||
eth-in-good-octets : 60598
|
||||
name : eth1
|
||||
index : 2
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
link mode : 1000baseT
|
||||
auto-negotiation : on
|
||||
duplex : full
|
||||
speed : 1000
|
||||
physical address : 00:53:00:06:11:0a
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 75581
|
||||
out-octets : 43130
|
||||
───────────────────
|
||||
<b>Ethernet Statistics</b>
|
||||
in-frames : 434
|
||||
in-multicast-frames : 296
|
||||
in-broadcast-frames : 138
|
||||
in-error-fcs-frames : 0
|
||||
in-error-oversize-frames : 0
|
||||
out-frames : 310
|
||||
out-multicast-frames : 310
|
||||
out-broadcast-frames : 0
|
||||
out-good-octets : 76821
|
||||
in-good-octets : 60598
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
|
||||
+13
-7
@@ -61,13 +61,19 @@ admin@example:/config/interface/eth0/> <b>leave</b>
|
||||
The operational status can be inspected to see both administrative and
|
||||
actual link state:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
|
||||
eth1 ethernet UP 02:00:00:00:00:01
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
|
||||
eth1 1000baseT UP duplex: full
|
||||
ethernet 02:00:00:00:00:01
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
The rows are layered bottom-up by protocol: a physical-medium row (only
|
||||
emitted when the link is up) on top, then the ethernet row carrying the
|
||||
bare MAC, then any ipv4/ipv6 sub-rows. See [Ethernet](ethernet.md) for the
|
||||
full set of summary fields.
|
||||
|
||||
|
||||
## Description
|
||||
|
||||
@@ -84,9 +90,9 @@ The description is visible in the operational datastore and in `show`
|
||||
commands:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth0</b>
|
||||
name : eth0
|
||||
description : Uplink to core switch
|
||||
index : 2
|
||||
name : eth0
|
||||
description : Uplink to core switch
|
||||
index : 2
|
||||
...
|
||||
</code></pre>
|
||||
|
||||
|
||||
@@ -117,11 +117,11 @@ will be ignored. For details on how to enable the NTP client, see the
|
||||
|
||||

|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -153,13 +153,13 @@ admin@example:/config/interface/eth0/ipv4/> <b>diff</b>
|
||||
+ }
|
||||
+}
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 169.254.1.3/16 (random)
|
||||
ipv4 10.0.1.1/24 (static)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -188,12 +188,12 @@ admin@example:/config/interface/eth0/ipv4/autoconf/> <b>leave</b>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv4</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>set dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv4 10.1.2.100/24 (dhcp)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -235,11 +235,11 @@ admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set dhcp</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8::42/128 (dhcp)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -291,10 +291,10 @@ on the interface.
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set enabled false</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -308,12 +308,12 @@ admin@example:/>
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set address 2001:db8::1 prefix-length 64</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8::1/64 (static)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -330,12 +330,12 @@ advertised by the router (here 2001:db8:0:1::0/64) and the interface
|
||||
identifier. The resulting address is of type *link-layer*, as it is
|
||||
formed based on the interface identifier ([ietf-ip.yang][2]).
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -348,11 +348,11 @@ below.
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-global-addresses false</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -366,12 +366,12 @@ admin@example:/>
|
||||
By default, the auto-configured link-local and global IPv6 addresses
|
||||
are formed from a link-identifier based on the MAC address.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||
ipv6 fe80::ff:fe00:0/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -385,12 +385,12 @@ possible to specify use of a random identifier ([ietf-ip.yang][2] and
|
||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>set autoconf create-temporary-addresses true</b>
|
||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0 ethernet UP 02:00:00:00:00:00
|
||||
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
|
||||
ipv6 fe80::ad3d:b274:885a:9ffb/64 (random)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
|
||||
+66
-66
@@ -87,34 +87,34 @@ Like other interfaces, link aggregates are also available in the general
|
||||
interfaces overview in the CLI admin-exec context. Here is the above
|
||||
static mode aggregate:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP static: balance-xor, hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE
|
||||
└ eth8 lag ACTIVE
|
||||
lag0 lag UP static: balance-xor, hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE
|
||||
└ eth8 lag ACTIVE
|
||||
</code></pre>
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
.
|
||||
.
|
||||
.
|
||||
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
||||
│ ethernet UP 00:a0:85:00:02:00
|
||||
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
</code></pre>
|
||||
|
||||
|
||||
@@ -124,45 +124,45 @@ In addition to basic status shown in the interface overview, detailed
|
||||
LAG status can be inspected:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||
name : lag0
|
||||
index : 25
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : static
|
||||
lag type : balance-xor
|
||||
lag hash : layer2
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 0
|
||||
out-octets : 2142
|
||||
name : lag0
|
||||
index : 25
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : static
|
||||
lag type : balance-xor
|
||||
lag hash : layer2
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 0
|
||||
out-octets : 2142
|
||||
</code></pre>
|
||||
|
||||
Same aggregate, but in LACP mode:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||
name : lag0
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : lacp
|
||||
lag hash : layer2
|
||||
lacp mode : active
|
||||
lacp rate : fast (1s)
|
||||
lacp aggregate id : 1
|
||||
name : lag0
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag mode : lacp
|
||||
lag hash : layer2
|
||||
lacp mode : active
|
||||
lacp rate : fast (1s)
|
||||
lacp aggregate id : 1
|
||||
lacp system priority: 65535
|
||||
lacp actor key : 9
|
||||
lacp partner key : 9
|
||||
lacp partner mac : 00:a0:85:00:03:00
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 100892
|
||||
out-octets : 111776
|
||||
lacp actor key : 9
|
||||
lacp partner key : 9
|
||||
lacp partner mac : 00:a0:85:00:03:00
|
||||
link debounce up : 0 msec
|
||||
link debounce down : 0 msec
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 100892
|
||||
out-octets : 111776
|
||||
</code></pre>
|
||||
|
||||
Member ports provide additional status information:
|
||||
@@ -184,21 +184,21 @@ Member ports provide additional status information:
|
||||
Example member port status:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface eth7</b>
|
||||
name : eth7
|
||||
index : 8
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag member : lag0
|
||||
lag member state : active
|
||||
lacp aggregate id : 1
|
||||
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
link failure count : 0
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 473244
|
||||
out-octets : 499037
|
||||
name : eth7
|
||||
index : 8
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
physical address : 00:a0:85:00:02:00
|
||||
lag member : lag0
|
||||
lag member state : active
|
||||
lacp aggregate id : 1
|
||||
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||
link failure count : 0
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 473244
|
||||
out-octets : 499037
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
+5
-5
@@ -109,13 +109,13 @@ CLI can be entered from shell in the same way as for SSH.
|
||||
|
||||
See the 'help' command for an introduction to the system
|
||||
|
||||
admin@example:/> <b>show interfaces</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
|
||||
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
|
||||
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
|
||||
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
|
||||
...
|
||||
admin@example:/>
|
||||
</code></pre>
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ other traffic would be bridged as usual.
|
||||
|----------|----------------------------|--------------------------------------------------------------|
|
||||
| [bridge](bridging.md) | infix-if-bridge | SW implementation of an IEEE 802.1Q bridge |
|
||||
| [ip](ip.md) | ietf-ip, infix-ip | IP address to the subordinate interface |
|
||||
| [vlan](ethernet.md#vlan-interfaces) | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
|
||||
| [vlan](vlan.md) | infix-if-vlan | Capture all traffic belonging to a specific 802.1Q VID |
|
||||
| [lag](lag.md) | infix-if-lag | Link aggregation, static and IEEE 802.3ad (LACP) |
|
||||
| lo | ietf-interfaces | Software loopback interface |
|
||||
| [eth](ethernet.md#physical-ethernet-interfaces) | ieee802-ethernet-interface | Physical Ethernet device/port |
|
||||
|
||||
+61
-61
@@ -39,20 +39,20 @@ Starting out, we assume a configuration where all ports are network
|
||||
interfaces (possibly with IPv6 enabled).
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
admin@example:/> show interface
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
|
||||
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
|
||||
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
|
||||
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
|
||||
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
|
||||
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
|
||||
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
|
||||
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
|
||||
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
|
||||
e10 ethernet UP 00:53:00:06:11:0a
|
||||
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
|
||||
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
|
||||
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
|
||||
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
|
||||
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
|
||||
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
|
||||
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
|
||||
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
|
||||
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
|
||||
e10 ethernet UP 00:53:00:06:11:0a
|
||||
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
|
||||
admin@example:/>
|
||||
```
|
||||
@@ -80,7 +80,7 @@ admin@example:/config/> set interface e10 bridge-port bridge br0
|
||||
admin@example:/config/>
|
||||
```
|
||||
|
||||
The interface status can be viewed using `show interfaces` after leaving
|
||||
The interface status can be viewed using `show interface` after leaving
|
||||
configuration context. When configuring via SSH, first assign an IP
|
||||
address to `br0` *before leaving* configuration context, e.g.
|
||||
|
||||
@@ -95,10 +95,10 @@ setup, including [setting IP address](#set-ip-address).
|
||||
```
|
||||
admin@example:/config/> leave
|
||||
admin@example:/>
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@example:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
br0 bridge
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge LOWER-DOWN
|
||||
├ e2 bridge LOWER-DOWN
|
||||
├ e3 bridge LOWER-DOWN
|
||||
@@ -109,7 +109,7 @@ br0 bridge
|
||||
├ e8 bridge LOWER-DOWN
|
||||
├ e9 bridge LOWER-DOWN
|
||||
└ e10 bridge FORWARDING
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -154,21 +154,21 @@ admin@example:/>
|
||||
Interface status would now should something like the following
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@example:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
br0 bridge
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
|
||||
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
|
||||
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
|
||||
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
|
||||
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
|
||||
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
|
||||
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
|
||||
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
|
||||
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge LOWER-DOWN vlan:10u pvid: 10
|
||||
├ e2 bridge LOWER-DOWN vlan:10u pvid: 10
|
||||
├ e3 bridge LOWER-DOWN vlan:20u pvid: 20
|
||||
├ e4 bridge LOWER-DOWN vlan:20u pvid: 20
|
||||
├ e5 bridge LOWER-DOWN vlan:30u pvid: 30
|
||||
├ e6 bridge LOWER-DOWN vlan:30u pvid: 30
|
||||
├ e7 bridge LOWER-DOWN vlan:40u pvid: 40
|
||||
├ e8 bridge LOWER-DOWN vlan:40u pvid: 40
|
||||
├ e9 bridge LOWER-DOWN vlan:50u pvid: 50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -181,21 +181,21 @@ patched according to [above](#vlan-snake). We should see link up and
|
||||
*FORWARDING* on all ports in the bridge.
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@example:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
br0 bridge
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge FORWARDING vlan:10u pvid: 10
|
||||
├ e2 bridge FORWARDING vlan:10u pvid: 10
|
||||
├ e3 bridge FORWARDING vlan:20u pvid: 20
|
||||
├ e4 bridge FORWARDING vlan:20u pvid: 20
|
||||
├ e5 bridge FORWARDING vlan:30u pvid: 30
|
||||
├ e6 bridge FORWARDING vlan:30u pvid: 30
|
||||
├ e7 bridge FORWARDING vlan:40u pvid: 40
|
||||
├ e8 bridge FORWARDING vlan:40u pvid: 40
|
||||
├ e9 bridge FORWARDING vlan:50u pvid: 50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@example:/>
|
||||
@@ -284,26 +284,26 @@ admin@example:/>
|
||||
Interface *vlan10* with an auto-configured IPv6 address should appear.
|
||||
|
||||
```
|
||||
admin@example:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
admin@example:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
br0 bridge vlan:10t
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
│ ethernet UP 00:53:00:06:11:01
|
||||
├ e1 bridge FORWARDING vlan:10u pvid: 10
|
||||
├ e2 bridge FORWARDING vlan:10u pvid: 10
|
||||
├ e3 bridge FORWARDING vlan:20u pvid: 20
|
||||
├ e4 bridge FORWARDING vlan:20u pvid: 20
|
||||
├ e5 bridge FORWARDING vlan:30u pvid: 30
|
||||
├ e6 bridge FORWARDING vlan:30u pvid: 30
|
||||
├ e7 bridge FORWARDING vlan:40u pvid: 40
|
||||
├ e8 bridge FORWARDING vlan:40u pvid: 40
|
||||
├ e9 bridge FORWARDING vlan:50u pvid: 50
|
||||
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
vlan10 ethernet UP 00:53:00:06:11:01
|
||||
vlan10 ethernet UP 00:53:00:06:11:01
|
||||
│ ipv6 fe80::0053:00ff:fe06:1101/64 (link-layer)
|
||||
└ br0 ethernet UP 00:53:00:06:11:01
|
||||
└ br0 ethernet UP 00:53:00:06:11:01
|
||||
admin@example:/>
|
||||
```
|
||||
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
# VLAN Interfaces
|
||||
|
||||
A VLAN interface is an interface stacked on top of another Linux interface
|
||||
that filters traffic for a single 802.1Q VID. `tcpdump` on a VLAN interface
|
||||
shows only frames matching that VID, compared to *all* VIDs when listening
|
||||
on the lower-layer interface.
|
||||
|
||||

|
||||
|
||||
This page covers VLAN interfaces stacked on Ethernet, on a VLAN-filtering
|
||||
bridge, and on other VLAN interfaces. For VLAN handling *inside* a bridge
|
||||
(port VIDs, tagged/untagged membership, pvid), see [VLAN Filtering
|
||||
Bridge](bridging.md#vlan-filtering-bridge).
|
||||
|
||||
## On Top of an Ethernet Interface
|
||||
|
||||
A VLAN interface for VID 20 on top of an Ethernet interface `eth0` is by
|
||||
convention named `eth0.20`.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0.20</b>
|
||||
admin@example:/config/interface/eth0.20/> <b>show</b>
|
||||
type vlan;
|
||||
vlan {
|
||||
tag-type c-vlan;
|
||||
id 20;
|
||||
lower-layer-if eth0;
|
||||
}
|
||||
admin@example:/config/interface/eth0.20/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The `tag-type` defaults to `c-vlan` (802.1Q customer VLAN, EtherType 0x8100).
|
||||
Set to `s-vlan` (802.1ad service VLAN, EtherType 0x88A8) to terminate an outer
|
||||
S-Tag.
|
||||
|
||||
> [!TIP]
|
||||
> If you name your VLAN interface `foo0.N` or `vlanN`, where `N` is a
|
||||
> number, the CLI infers the interface type automatically. Otherwise
|
||||
> the type must be set explicitly.
|
||||
|
||||
## On Top of a Bridge
|
||||
|
||||
When the lower-layer interface is a VLAN-filtering bridge, the VLAN interface
|
||||
gives the CPU an IP-addressable endpoint inside the bridged broadcast domain
|
||||
for that VID. This pattern is named `vlanN` by convention.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface vlan10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan id 10</b>
|
||||
admin@example:/config/interface/vlan10/> <b>set vlan lower-layer-if br0</b>
|
||||
admin@example:/config/interface/vlan10/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The bridge `br0` must have VLAN 10 configured with the bridge itself as a
|
||||
tagged member. See [VLAN Filtering Bridge](bridging.md#vlan-filtering-bridge)
|
||||
for the bridge-side configuration.
|
||||
|
||||
## Stacked (Q-in-Q)
|
||||
|
||||
VLAN interfaces can be stacked. A VLAN interface whose lower-layer is itself
|
||||
a VLAN interface terminates the inner tag, leaving the outer tag for the
|
||||
parent to handle.
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||
admin@example:/config/> <b>edit interface eth0.10</b>
|
||||
admin@example:/config/interface/eth0.10/> <b>set vlan tag-type s-vlan</b>
|
||||
admin@example:/config/interface/eth0.10/> <b>leave</b>
|
||||
admin@example:/config/> <b>edit interface eth0.10.20</b>
|
||||
admin@example:/config/interface/eth0.10.20/> <b>show</b>
|
||||
type vlan;
|
||||
vlan {
|
||||
tag-type c-vlan;
|
||||
id 20;
|
||||
lower-layer-if eth0.10;
|
||||
}
|
||||
admin@example:/config/interface/eth0.10.20/> <b>leave</b>
|
||||
</code></pre>
|
||||
|
||||
The summary view shows each VLAN row pointing at its immediate parent:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||
eth0.10 vlan UP vid: 10
|
||||
│ ipv4 10.0.10.1/24 (static)
|
||||
└ eth0
|
||||
eth0.10.20 vlan UP vid: 20
|
||||
│ ipv4 10.0.10.20/28 (static)
|
||||
└ eth0.10
|
||||
</code></pre>
|
||||
@@ -345,17 +345,17 @@ tunnel endpoints use IPv4 or IPv6.
|
||||
|
||||
Check WireGuard interface status and peer connections:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||
wg0 wireguard UP 2 peers (1 up)
|
||||
ipv4 10.0.0.1/24 (static)
|
||||
ipv6 fd00::1/64 (static)
|
||||
|
||||
admin@example:/> <b>show interfaces wg0</b>
|
||||
name : wg0
|
||||
type : wireguard
|
||||
index : 12
|
||||
operational status : up
|
||||
peers : 2
|
||||
admin@example:/> <b>show interface wg0</b>
|
||||
name : wg0
|
||||
type : wireguard
|
||||
index : 12
|
||||
operational status : up
|
||||
peers : 2
|
||||
|
||||
Peer 1:
|
||||
status : UP
|
||||
|
||||
+23
-23
@@ -223,22 +223,22 @@ access-point).
|
||||
Use `show interface` to see discovered networks and their signal strength:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||
name : wifi0
|
||||
type : wifi
|
||||
index : 3
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : enabled
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
ipv4 addresses : 192.168.1.100/24 (dhcp)
|
||||
ipv6 addresses :
|
||||
in-octets : 148388
|
||||
out-octets : 24555
|
||||
mode : station
|
||||
ssid : MyNetwork
|
||||
signal : -45 dBm (good)
|
||||
rx bitrate : 72.2 Mbps
|
||||
tx bitrate : 86.6 Mbps
|
||||
name : wifi0
|
||||
type : wifi
|
||||
index : 3
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : enabled
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
ipv4 addresses : 192.168.1.100/24 (dhcp)
|
||||
ipv6 addresses :
|
||||
in-octets : 148388
|
||||
out-octets : 24555
|
||||
mode : station
|
||||
ssid : MyNetwork
|
||||
signal : -45 dBm (good)
|
||||
rx bitrate : 72.2 Mbps
|
||||
tx bitrate : 86.6 Mbps
|
||||
──────────────────────────────────────────────────────────────────────
|
||||
<span class="title">Available Networks</span>
|
||||
<span class="header">SSID BSSID SECURITY SIGNAL CHANNEL</span>
|
||||
@@ -304,13 +304,13 @@ admin@example:/config/interface/wifi0/> <b>leave</b>
|
||||
The connection attempt will start immediately. You can verify the connection status:
|
||||
|
||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||
name : wifi0
|
||||
type : wifi
|
||||
operational status : up
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
mode : station
|
||||
ssid : MyHomeNetwork
|
||||
signal : -52 dBm (good)
|
||||
name : wifi0
|
||||
type : wifi
|
||||
operational status : up
|
||||
physical address : f0:09:0d:36:5f:86
|
||||
mode : station
|
||||
ssid : MyHomeNetwork
|
||||
signal : -52 dBm (good)
|
||||
</code></pre>
|
||||
|
||||
**Station configuration parameters:**
|
||||
|
||||
@@ -33,6 +33,7 @@ nav:
|
||||
- Bridging: bridging.md
|
||||
- Link Aggregation: lag.md
|
||||
- Ethernet Interfaces: ethernet.md
|
||||
- VLAN Interfaces: vlan.md
|
||||
- IP Addressing: ip.md
|
||||
- Routing: routing.md
|
||||
- Firewall Configuration: firewall.md
|
||||
|
||||
+5
-1
@@ -283,6 +283,7 @@ static void rmtmp(const char *path)
|
||||
static void sysrepo_print_error(sr_session_ctx_t *sess)
|
||||
{
|
||||
const sr_error_info_t *erri = NULL;
|
||||
const char *msg;
|
||||
int err;
|
||||
|
||||
if (!sess)
|
||||
@@ -292,7 +293,10 @@ static void sysrepo_print_error(sr_session_ctx_t *sess)
|
||||
if (err || !erri || !erri->err_count)
|
||||
return;
|
||||
|
||||
warnx("%s (%d)", erri->err->message, erri->err->err_code);
|
||||
msg = erri->err->message;
|
||||
if (!msg)
|
||||
msg = sr_strerror(erri->err->err_code);
|
||||
warnx("%s (%d)", msg, erri->err->err_code);
|
||||
}
|
||||
|
||||
/* Connect to sysrepo and create NACM-aware session on running datastore */
|
||||
|
||||
+23
-17
@@ -17,17 +17,18 @@ def get_json(xpath: str, datastore: str = "operational", quiet: bool = False) ->
|
||||
print("Invalid XPATH. It must be a valid string starting with '/'.")
|
||||
return {}
|
||||
|
||||
try:
|
||||
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
|
||||
capture_output=True, text=True, check=True)
|
||||
if not result.stdout.strip():
|
||||
return {}
|
||||
json_data = json.loads(result.stdout)
|
||||
return json_data
|
||||
except subprocess.CalledProcessError as e:
|
||||
if not quiet:
|
||||
print(f"Error running copy: {e}")
|
||||
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
|
||||
capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
# copy already wrote a 'failed retrieving …' message (and a
|
||||
# sysrepo error line) to stderr; relay it verbatim.
|
||||
if not quiet and result.stderr:
|
||||
print(result.stderr.rstrip())
|
||||
return {}
|
||||
if not result.stdout.strip():
|
||||
return {}
|
||||
try:
|
||||
return json.loads(result.stdout)
|
||||
except json.JSONDecodeError as e:
|
||||
if not quiet:
|
||||
print(f"Error parsing JSON output: {e}")
|
||||
@@ -40,15 +41,20 @@ def cli_pretty(json_data: dict, command: str, *args: str):
|
||||
return
|
||||
|
||||
safe_args = [shlex.quote(arg) for arg in args]
|
||||
json_input = json.dumps(json_data)
|
||||
result = subprocess.run([
|
||||
"/usr/libexec/statd/cli-pretty", command, *safe_args
|
||||
], input=json_input, capture_output=True, text=True)
|
||||
|
||||
try:
|
||||
json_input = json.dumps(json_data) # Keep as string, not bytes
|
||||
result = subprocess.run([
|
||||
"/usr/libexec/statd/cli-pretty", command, *safe_args
|
||||
], input=json_input, capture_output=True, text=True, check=True)
|
||||
# cli-pretty prints a user-facing message on stdout before any
|
||||
# sys.exit(1) (e.g. 'Interface "w" not found'). Relay it regardless
|
||||
# of the exit status, and only surface the generic exec error when
|
||||
# nothing useful was produced.
|
||||
if result.stdout:
|
||||
print(result.stdout, end="")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error running cli-pretty: {e}")
|
||||
elif result.returncode != 0:
|
||||
msg = result.stderr.strip() or f"exit status {result.returncode}"
|
||||
print(f"Error running cli-pretty: {msg}")
|
||||
|
||||
|
||||
def dhcp(args: List[str]) -> None:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
AC_PREREQ(2.61)
|
||||
# confd version is same as system YANG model version, step on breaking changes
|
||||
AC_INIT([confd], [1.8], [https://github.com/kernelkit/infix/issues])
|
||||
AC_INIT([confd], [1.9], [https://github.com/kernelkit/infix/issues])
|
||||
AM_INIT_AUTOMAKE(1.11 foreign subdir-objects)
|
||||
AM_SILENT_RULES(yes)
|
||||
|
||||
@@ -22,6 +22,7 @@ AC_CONFIG_FILES([
|
||||
share/migrate/1.6/Makefile
|
||||
share/migrate/1.7/Makefile
|
||||
share/migrate/1.8/Makefile
|
||||
share/migrate/1.9/Makefile
|
||||
yang/Makefile
|
||||
yang/confd/Makefile
|
||||
yang/test-mode/Makefile
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
# Migrate fixed-speed ethernet configs to auto-negotiation/advertised-pmd-types.
|
||||
#
|
||||
# IEEE Std 802.3.2-2025 obsoleted the ieee802-ethernet-interface speed leaf,
|
||||
# leaving no standards-blessed config-true location to pin a port to a fixed
|
||||
# speed. Infix expresses the same intent via a new infix-augmented
|
||||
# 'advertised-pmd-types' leaf-list inside the auto-negotiation container: when
|
||||
# the list names exactly one PMD type, the link comes up at that mode against
|
||||
# any cooperating peer — the standards-correct interpretation of "fixed speed".
|
||||
#
|
||||
# Rewrites
|
||||
# ethernet { auto-negotiation { enable false; } speed S; duplex D; }
|
||||
# into
|
||||
# ethernet { auto-negotiation { enable false;
|
||||
# advertised-pmd-types [PMD]; } duplex D; }
|
||||
# where PMD is derived from (S, D) using a static lookup table. D and
|
||||
# enable=false are preserved verbatim — confd's apply path treats
|
||||
# enable=false plus a single advertised-pmd-types entry as "force
|
||||
# autoneg off and pin to this speed/duplex", matching the legacy
|
||||
# semantics for link partners that don't run auto-negotiation.
|
||||
#
|
||||
# Interfaces that don't disable auto-negotiation, or that lack a speed leaf,
|
||||
# are left untouched.
|
||||
|
||||
file=$1
|
||||
temp=${file}.tmp
|
||||
|
||||
#
|
||||
# The (speed Gb/s, copper-T-implicit-duplex) → PMD table below is a subset
|
||||
# of the canonical map in src/statd/python/yanger/ietf_interfaces/ethernet.py
|
||||
# (_LINK_MODES, key by (port, speed, duplex)). Migrate only covers the
|
||||
# copper-T cases that the old legacy syntax supported in the first place;
|
||||
# fiber/DAC pinning was never expressible via the deprecated speed leaf.
|
||||
#
|
||||
jq '
|
||||
def speed_to_pmd:
|
||||
if . == "0.01" then "ieee802-ethernet-phy-type:pmd-type-10BASE-T"
|
||||
elif . == "0.1" then "ieee802-ethernet-phy-type:pmd-type-100BASE-TX"
|
||||
elif . == "1.0" then "ieee802-ethernet-phy-type:pmd-type-1000BASE-T"
|
||||
elif . == "2.5" then "ieee802-ethernet-phy-type:pmd-type-2.5GBASE-T"
|
||||
elif . == "5.0" then "ieee802-ethernet-phy-type:pmd-type-5GBASE-T"
|
||||
elif . == "10.0" then "ieee802-ethernet-phy-type:pmd-type-10GBASE-T"
|
||||
else null
|
||||
end;
|
||||
|
||||
(.["ietf-interfaces:interfaces"].interface // [])
|
||||
|= [ .[] |
|
||||
. as $iface
|
||||
| if ($iface["ieee802-ethernet-interface:ethernet"]?
|
||||
["auto-negotiation"]?.enable == false)
|
||||
and ($iface["ieee802-ethernet-interface:ethernet"]?.speed != null)
|
||||
then
|
||||
($iface["ieee802-ethernet-interface:ethernet"].speed | speed_to_pmd) as $pmd
|
||||
| if $pmd == null then
|
||||
$iface # leave unmappable speeds alone; admin must fix
|
||||
else
|
||||
$iface
|
||||
| .["ieee802-ethernet-interface:ethernet"]
|
||||
["auto-negotiation"]
|
||||
+= {"infix-ethernet-interface:advertised-pmd-types": [$pmd]}
|
||||
| del(.["ieee802-ethernet-interface:ethernet"].speed)
|
||||
end
|
||||
else
|
||||
$iface
|
||||
end ]
|
||||
' "$file" > "$temp" && mv "$temp" "$file"
|
||||
@@ -0,0 +1,2 @@
|
||||
migratedir = $(pkgdatadir)/migrate/1.9
|
||||
dist_migrate_DATA = 10-ethernet-advertise.sh
|
||||
@@ -1,2 +1,2 @@
|
||||
SUBDIRS = 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8
|
||||
SUBDIRS = 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
|
||||
migratedir = $(pkgdatadir)/migrate
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <jansson.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#include <srx/common.h>
|
||||
#include <srx/lyx.h>
|
||||
@@ -12,18 +15,96 @@
|
||||
|
||||
#include "interfaces.h"
|
||||
|
||||
/*
|
||||
* Map IEEE pmd-type identity suffixes (everything after
|
||||
* "ieee802-ethernet-phy-type:pmd-type-") to the Linux
|
||||
* ETHTOOL_LINK_MODE_*_BIT_* indices that ethtool's --advertise mask
|
||||
* uses. Half/full are separate bits in the kernel API but a single
|
||||
* PMD identity in IEEE; the half_bit field is -1 for PMDs that have
|
||||
* no half-duplex variant (everything past 1G).
|
||||
*
|
||||
* Where the kernel collapses several IEEE variants into one
|
||||
* "family" bit (e.g. 1000baseX covers LX/SX/ZX/CX) the same bit
|
||||
* appears in multiple rows by design — selecting any of them yields
|
||||
* the same on-wire behaviour because ethtool can't distinguish them
|
||||
* either.
|
||||
*/
|
||||
struct pmd_link_mode {
|
||||
const char *pmd;
|
||||
int speed_mbps;
|
||||
int half_bit;
|
||||
int full_bit;
|
||||
};
|
||||
|
||||
#define NO_BIT (-1)
|
||||
|
||||
static const struct pmd_link_mode pmd_link_modes[] = {
|
||||
{"10BASE-T", 10, ETHTOOL_LINK_MODE_10baseT_Half_BIT,
|
||||
ETHTOOL_LINK_MODE_10baseT_Full_BIT},
|
||||
{"100BASE-TX", 100, ETHTOOL_LINK_MODE_100baseT_Half_BIT,
|
||||
ETHTOOL_LINK_MODE_100baseT_Full_BIT},
|
||||
{"100BASE-FX", 100, NO_BIT, ETHTOOL_LINK_MODE_100baseFX_Full_BIT},
|
||||
{"1000BASE-T", 1000, ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
|
||||
ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
|
||||
/* 1000baseX_Full covers the LX/SX/ZX/CX family in the kernel —
|
||||
* the API can't distinguish them; selecting any yields the same
|
||||
* on-wire behaviour. */
|
||||
{"1000BASE-LX", 1000, NO_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
|
||||
{"1000BASE-SX", 1000, NO_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
|
||||
{"1000BASE-ZX", 1000, NO_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
|
||||
{"1000BASE-CX", 1000, NO_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
|
||||
{"2.5GBASE-T", 2500, NO_BIT, ETHTOOL_LINK_MODE_2500baseT_Full_BIT},
|
||||
{"2.5GBASE-X", 2500, NO_BIT, ETHTOOL_LINK_MODE_2500baseX_Full_BIT},
|
||||
{"5GBASE-T", 5000, NO_BIT, ETHTOOL_LINK_MODE_5000baseT_Full_BIT},
|
||||
{"10GBASE-T", 10000, NO_BIT, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
|
||||
{"10GBASE-SR", 10000, NO_BIT, ETHTOOL_LINK_MODE_10000baseSR_Full_BIT},
|
||||
{"10GBASE-LR", 10000, NO_BIT, ETHTOOL_LINK_MODE_10000baseLR_Full_BIT},
|
||||
{"10GBASE-LRM", 10000, NO_BIT, ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT},
|
||||
{"10GBASE-ER", 10000, NO_BIT, ETHTOOL_LINK_MODE_10000baseER_Full_BIT},
|
||||
/* SFP+ DAC has no standardised IEEE pmd-type identity for 10G;
|
||||
* users can't restrict advertise to DAC-only at this rate. */
|
||||
{"25GBASE-CR", 25000, NO_BIT, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT},
|
||||
{"25GBASE-SR", 25000, NO_BIT, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT},
|
||||
/* Kernel collapses LR/SR onto the same 25G bit. */
|
||||
{"25GBASE-LR", 25000, NO_BIT, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT},
|
||||
{"40GBASE-CR4", 40000, NO_BIT, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT},
|
||||
{"40GBASE-SR4", 40000, NO_BIT, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT},
|
||||
{"40GBASE-LR4", 40000, NO_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT},
|
||||
{"100GBASE-CR4", 100000, NO_BIT, ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT},
|
||||
{"100GBASE-SR4", 100000, NO_BIT, ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT},
|
||||
{"100GBASE-LR4", 100000, NO_BIT, ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT},
|
||||
{NULL, 0, NO_BIT, NO_BIT}
|
||||
};
|
||||
|
||||
static const struct pmd_link_mode *pmd_lookup(const char *identity)
|
||||
{
|
||||
const char *suffix;
|
||||
const struct pmd_link_mode *m;
|
||||
|
||||
if (!identity)
|
||||
return NULL;
|
||||
suffix = strchr(identity, ':');
|
||||
suffix = suffix ? suffix + 1 : identity;
|
||||
if (strncmp(suffix, "pmd-type-", 9) == 0)
|
||||
suffix += 9;
|
||||
|
||||
for (m = pmd_link_modes; m->pmd; m++) {
|
||||
if (strcmp(m->pmd, suffix) == 0)
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static bool iface_uses_autoneg(struct lyd_node *cif)
|
||||
{
|
||||
struct lyd_node *aneg = lydx_get_descendant(lyd_child(cif), "ethernet",
|
||||
"auto-negotiation", NULL);
|
||||
|
||||
/* Because `ieee802-ethernet-interface` declares
|
||||
* `auto-negotiation` as a presence container, the `enabled`
|
||||
* leaf, although `true` by default, is not set if the whole
|
||||
* container is absent. Since auto-negotiation is the expected
|
||||
* default behavior for most Ethernet links, we choose to
|
||||
* enable it in these situations.
|
||||
*/
|
||||
/* `auto-negotiation` is a presence container; when absent the port
|
||||
* auto-negotiates (the modern default). When present, `enable`
|
||||
* defaults to true and is materialised in the config tree, so
|
||||
* lydx_get_bool() reads it correctly. */
|
||||
return !aneg || lydx_get_bool(aneg, "enable");
|
||||
}
|
||||
|
||||
@@ -60,13 +141,42 @@ static int netdag_gen_ethtool_flow_control(struct dagger *net, struct lyd_node *
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Walk the advertised-pmd-types leaf-list + duplex constraint, OR matching
|
||||
* bits into *mask. *unmapped is filled with the first identity suffix we
|
||||
* didn't recognise so the caller can produce a useful sysrepo error.
|
||||
*/
|
||||
static void pmd_list_to_mask(struct lyd_node *aneg, const char *duplex,
|
||||
uint64_t *mask, const char **unmapped)
|
||||
{
|
||||
struct lyd_node *node;
|
||||
|
||||
*mask = 0;
|
||||
LYX_LIST_FOR_EACH(lyd_child(aneg), node, "advertised-pmd-types") {
|
||||
const char *id = lyd_get_value(node);
|
||||
const struct pmd_link_mode *m = pmd_lookup(id);
|
||||
|
||||
if (!m) {
|
||||
if (*unmapped == NULL)
|
||||
*unmapped = id;
|
||||
continue;
|
||||
}
|
||||
if ((!duplex || strcmp(duplex, "half") == 0) && m->half_bit != NO_BIT)
|
||||
*mask |= (1ULL << m->half_bit);
|
||||
if ((!duplex || strcmp(duplex, "full") == 0) && m->full_bit != NO_BIT)
|
||||
*mask |= (1ULL << m->full_bit);
|
||||
}
|
||||
}
|
||||
|
||||
static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
|
||||
{
|
||||
struct lyd_node *eth = lydx_get_child(cif, "ethernet");
|
||||
struct lyd_node *aneg = lydx_get_child(eth, "auto-negotiation");
|
||||
const char *ifname = lydx_get_cattr(cif, "name");
|
||||
enum netdag_init phase = NETDAG_INIT_PHYS;
|
||||
const char *speed, *duplex;
|
||||
int mbps, err = 0;
|
||||
const char *duplex, *mdix, *unmapped = NULL;
|
||||
const char *mdix_arg = "";
|
||||
uint64_t mask = 0;
|
||||
int err = 0;
|
||||
FILE *fp;
|
||||
|
||||
if (iface_has_quirk(ifname, "broken-autoneg"))
|
||||
@@ -79,45 +189,109 @@ static int netdag_gen_ethtool_autoneg(struct dagger *net, struct lyd_node *cif)
|
||||
if (!fp)
|
||||
return -EIO;
|
||||
|
||||
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supports-auto-negotiation\" == false)') ]] && exit 0\n", ifname);
|
||||
|
||||
if (iface_uses_autoneg(cif)) {
|
||||
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supports-auto-negotiation\" == false)') ]] && exit 0\n", ifname);
|
||||
fprintf(fp, "ethtool --change %s autoneg on", ifname);
|
||||
} else {
|
||||
speed = lydx_get_cattr(eth, "speed");
|
||||
if (!speed) {
|
||||
sr_session_set_error_message(net->session, "%s: "
|
||||
"\"speed\" must be specified "
|
||||
"when auto-negotiation is disabled", ifname);
|
||||
duplex = lydx_get_cattr(eth, "duplex");
|
||||
|
||||
/* MDI/MDI-X pinout. The `mdi-x` boolean has no default, so an absent
|
||||
* leaf (read as NULL here, hence lydx_get_cattr not lydx_get_bool) means
|
||||
* Auto-MDIX — emit nothing, leaving the PHY alone and not poking drivers
|
||||
* that reject the `mdix` arg. ethtool's `mdix on` is MDI-X (crossover),
|
||||
* `off` is MDI. */
|
||||
mdix = lydx_get_cattr(eth, "mdi-x");
|
||||
if (mdix && !strcmp(mdix, "true"))
|
||||
mdix_arg = " mdix on";
|
||||
else if (mdix && !strcmp(mdix, "false"))
|
||||
mdix_arg = " mdix off";
|
||||
|
||||
/* enable=false: force a fixed speed/duplex with autoneg off, for link
|
||||
* partners that don't run autoneg (legacy fixed-speed switches, some
|
||||
* back-to-back direct copper links). Standards-correct fixed-mode is
|
||||
* advertised-pmd-types with autoneg on; this branch is the escape
|
||||
* hatch for peers that won't even speak autoneg. Requires exactly one
|
||||
* advertised-pmd-types entry — that PMD picks the speed; duplex comes
|
||||
* from the explicit leaf or defaults to the only variant available.
|
||||
*/
|
||||
if (aneg && !lydx_get_bool(aneg, "enable")) {
|
||||
const struct pmd_link_mode *forced = NULL;
|
||||
const char *fixed_duplex;
|
||||
struct lyd_node *node;
|
||||
int n = 0;
|
||||
|
||||
LYX_LIST_FOR_EACH(lyd_child(aneg), node, "advertised-pmd-types") {
|
||||
const char *id = lyd_get_value(node);
|
||||
const struct pmd_link_mode *m = pmd_lookup(id);
|
||||
|
||||
if (!m) {
|
||||
if (!unmapped)
|
||||
unmapped = id;
|
||||
} else if (!forced) {
|
||||
forced = m;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (unmapped) {
|
||||
sr_session_set_error_message(net->session,
|
||||
"%s: advertised-pmd-types entry \"%s\" is not a known PMD type",
|
||||
ifname, unmapped);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (n != 1) {
|
||||
sr_session_set_error_message(net->session,
|
||||
"%s: auto-negotiation/enable=false requires exactly one "
|
||||
"advertised-pmd-types entry (have %d)", ifname, n);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mbps = (int)(atof(speed) * 1000.);
|
||||
if (!((mbps == 10) || (mbps == 100))) {
|
||||
sr_session_set_error_message(net->session, "%s: "
|
||||
"\"speed\" must be either 0.01 or 0.1 "
|
||||
"when auto-negotiation is disabled", ifname);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (duplex)
|
||||
fixed_duplex = duplex;
|
||||
else if (forced->full_bit != NO_BIT)
|
||||
fixed_duplex = "full";
|
||||
else
|
||||
fixed_duplex = "half";
|
||||
|
||||
duplex = lydx_get_cattr(eth, "duplex");
|
||||
if (!duplex || (strcmp(duplex, "full") && strcmp(duplex, "half"))) {
|
||||
sr_session_set_error_message(net->session, "%s: "
|
||||
"\"duplex\" must be either "
|
||||
"\"full\" or \"half\" "
|
||||
"when auto-negotiation is disabled", ifname);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fprintf(fp,"ethtool --change %s autoneg off speed %d duplex %s\n", ifname, mbps, duplex);
|
||||
fprintf(fp, "ethtool --change %s autoneg off speed %d duplex %s%s\n",
|
||||
ifname, forced->speed_mbps, fixed_duplex, mdix_arg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (aneg)
|
||||
pmd_list_to_mask(aneg, duplex, &mask, &unmapped);
|
||||
|
||||
if (unmapped) {
|
||||
sr_session_set_error_message(net->session,
|
||||
"%s: advertised-pmd-types entry \"%s\" is not a known PMD type",
|
||||
ifname, unmapped);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
/* Restrict autoneg to the advertised set (single entry == fixed). */
|
||||
fprintf(fp, "ethtool --change %s autoneg on advertise 0x%" PRIx64 "%s\n",
|
||||
ifname, mask, mdix_arg);
|
||||
} else {
|
||||
/* No advertise restriction configured → advertise everything the
|
||||
* PHY supports. Plain `autoneg on` is a no-op when autoneg is
|
||||
* already enabled and does NOT restore a previously narrowed
|
||||
* advertise mask, so query supported and re-enable each mode.
|
||||
* ethtool's symbolic advertise syntax is bare NAME on|off pairs
|
||||
* (despite what `--help` suggests, there is no `mode` keyword). */
|
||||
fprintf(fp,
|
||||
"args=$(ethtool --json %s | jq -r '.[0][\"supported-link-modes\"][]? | \"\\(.) on\"' | tr '\\n' ' ')\n"
|
||||
"if [ -n \"$args\" ]; then\n"
|
||||
"\tethtool --change %s autoneg on advertise $args%s\n"
|
||||
"else\n"
|
||||
"\tethtool --change %s autoneg on%s\n"
|
||||
"fi\n",
|
||||
ifname, ifname, mdix_arg, ifname, mdix_arg);
|
||||
}
|
||||
|
||||
out:
|
||||
fclose(fp);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node *dif)
|
||||
@@ -129,16 +303,16 @@ int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node
|
||||
return 0;
|
||||
|
||||
if (dagger_is_bootstrap(net) ||
|
||||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL)) {
|
||||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", NULL)) {
|
||||
err = netdag_gen_ethtool_flow_control(net, cif);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (dagger_is_bootstrap(net) ||
|
||||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL) ||
|
||||
lydx_get_child(eth, "speed") ||
|
||||
lydx_get_child(eth, "duplex")) {
|
||||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", NULL) ||
|
||||
lydx_get_child(eth, "duplex") ||
|
||||
lydx_get_child(eth, "mdi-x")) {
|
||||
err = netdag_gen_ethtool_autoneg(net, cif);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -44,10 +44,11 @@ MODULES=(
|
||||
"infix-meta@2025-12-10.yang"
|
||||
"infix-system@2026-03-09.yang"
|
||||
"infix-services@2026-03-20.yang"
|
||||
"ieee802-ethernet-interface@2019-06-21.yang"
|
||||
"infix-ethernet-interface@2024-02-27.yang"
|
||||
"ieee802-ethernet-interface@2025-09-10.yang"
|
||||
"ieee802-ethernet-phy-type@2025-09-10.yang"
|
||||
"infix-ethernet-interface@2026-05-21.yang"
|
||||
"infix-factory-default@2023-06-28.yang"
|
||||
"infix-interfaces@2026-05-13.yang -e vlan-filtering"
|
||||
"infix-interfaces@2026-05-18.yang -e vlan-filtering"
|
||||
"ietf-crypto-types -e cleartext-symmetric-keys"
|
||||
"infix-crypto-types@2026-02-14.yang"
|
||||
"ietf-keystore -e symmetric-keys"
|
||||
|
||||
@@ -1,928 +0,0 @@
|
||||
module ieee802-ethernet-interface {
|
||||
yang-version 1.1;
|
||||
|
||||
namespace
|
||||
"urn:ieee:std:802.3:yang:ieee802-ethernet-interface";
|
||||
|
||||
prefix ieee802-eth-if;
|
||||
|
||||
import ietf-yang-types {
|
||||
prefix yang;
|
||||
reference "IETF RFC 6991";
|
||||
}
|
||||
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
reference "IETF RFC 8343";
|
||||
}
|
||||
|
||||
import iana-if-type {
|
||||
prefix ianaift;
|
||||
reference "http://www.iana.org/assignments/yang-parameters/
|
||||
iana-if-type@2018-07-03.yang";
|
||||
}
|
||||
|
||||
organization
|
||||
"IEEE Std 802.3 Ethernet Working Group
|
||||
Web URL: http://www.ieee802.org/3/";
|
||||
|
||||
contact
|
||||
"Web URL: http://www.ieee802.org/3/";
|
||||
|
||||
description
|
||||
"This module contains YANG definitions for configuring IEEE Std
|
||||
802.3 Ethernet Interfaces.
|
||||
In this YANG module, 'Ethernet interface' can be interpreted
|
||||
as referring to 'IEEE Std 802.3 compliant Ethernet
|
||||
interfaces'.";
|
||||
|
||||
revision 2019-06-21{
|
||||
description "Initial revision.";
|
||||
reference "IEEE Std 802.3-2018, unless dated explicitly";
|
||||
}
|
||||
|
||||
typedef eth-if-speed-type {
|
||||
type decimal64 {
|
||||
fraction-digits 3;
|
||||
}
|
||||
units "Gb/s";
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual speed
|
||||
of an Ethernet interface in Gigabits per second (Gb/s),
|
||||
accurate to 3 decimal places (i.e., accurate to 1 Mb/s).";
|
||||
}
|
||||
|
||||
typedef duplex-type {
|
||||
type enumeration {
|
||||
enum full {
|
||||
description
|
||||
"Full duplex.";
|
||||
}
|
||||
enum half {
|
||||
description
|
||||
"Half duplex.";
|
||||
}
|
||||
enum unknown {
|
||||
description
|
||||
"Link is currently disconnected or initializing.";
|
||||
}
|
||||
}
|
||||
default full;
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual
|
||||
duplex mode of an Ethernet interface.";
|
||||
reference "IEEE Std 802.3, 30.3.1.1.32, aDuplexStatus";
|
||||
}
|
||||
|
||||
typedef pause-fc-direction-type {
|
||||
type enumeration {
|
||||
enum "disabled" {
|
||||
description
|
||||
"Flow-control disabled in both ingress and egress
|
||||
directions, i.e., PAUSE frames are not transmitted and
|
||||
PAUSE frames received in the ingress direction are
|
||||
discarded without processing.";
|
||||
}
|
||||
enum "ingress-only" {
|
||||
description
|
||||
"PAUSE frame based flow control is enabled in the ingress
|
||||
direction only, i.e., PAUSE frames may be transmitted to
|
||||
reduce the ingress traffic flow, but PAUSE frames received
|
||||
in the ingress direction are discarded without reducing
|
||||
the egress traffic rate.";
|
||||
}
|
||||
enum "egress-only" {
|
||||
description
|
||||
"PAUSE frame based flow control is enabled in the egress
|
||||
direction only, i.e., PAUSE frames are not transmitted,
|
||||
but PAUSE frames received in the ingress direction are
|
||||
processed to reduce the egress traffic rate.";
|
||||
}
|
||||
enum "bi-directional" {
|
||||
description
|
||||
"PAUSE frame based flow control is enabled in both ingress
|
||||
and egress directions, i.e., PAUSE frames may be
|
||||
transmitted to reduce the ingress traffic flow, and
|
||||
PAUSE frames received on ingress are processed to reduce
|
||||
the egress traffic rate.";
|
||||
}
|
||||
enum "undefined" {
|
||||
description
|
||||
"Link is currently disconnected or initializing.";
|
||||
}
|
||||
}
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual
|
||||
PAUSE frame-based flow control setting.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3PauseAdminMode and dot3PauseOperMode";
|
||||
}
|
||||
|
||||
feature ethernet-pfc {
|
||||
description
|
||||
"This device supports Ethernet priority flow-control.";
|
||||
}
|
||||
|
||||
feature ethernet-pause {
|
||||
description
|
||||
"This device supports Ethernet PAUSE.";
|
||||
}
|
||||
|
||||
augment "/if:interfaces/if:interface" {
|
||||
when "derived-from-or-self(if:type, 'ianaift:ethernetCsmacd')" {
|
||||
description
|
||||
"Applies to all P2P Ethernet interfaces.";
|
||||
}
|
||||
description
|
||||
"Augment interface model with Ethernet interface
|
||||
specific configuration nodes.";
|
||||
|
||||
container ethernet {
|
||||
description
|
||||
"Contains all Ethernet interface related configuration.";
|
||||
|
||||
container auto-negotiation {
|
||||
presence
|
||||
"The presence of this container indicates that
|
||||
auto-negotiation is supported on this Ethernet
|
||||
interface.";
|
||||
description
|
||||
"Contains auto-negotiation transmission parameters
|
||||
|
||||
This container contains a data node that allows the
|
||||
advertised duplex value in the negotiation to be
|
||||
restricted.
|
||||
|
||||
If not specified then the default behavior for the duplex
|
||||
data node is to negotiate all available values for the
|
||||
particular type of Ethernet PHY associated with the
|
||||
interface.
|
||||
|
||||
If auto-negotiation is enabled, and PAUSE frame based flow
|
||||
control has not been explicitly configured, then the
|
||||
default PAUSE frame based flow control capabilities that
|
||||
are negotiated allow for bi-directional or egress-only
|
||||
PAUSE frame based flow control.
|
||||
|
||||
If auto-negotiation is enabled, and PAUSE frame based flow
|
||||
control has been explicitly configured, then the
|
||||
configuration settings restrict the values that may be
|
||||
negotiated. However, it should be noted that the protocol
|
||||
does not allow only egress PAUSE frame based flow control
|
||||
to be negotiated without also allowing bi-directional
|
||||
PAUSE frame based flow control.";
|
||||
reference
|
||||
"IEEE Std 802.3, Clause 28 and Annexes 28A-D";
|
||||
|
||||
leaf enable {
|
||||
type boolean;
|
||||
default true;
|
||||
|
||||
description
|
||||
"Controls whether auto-negotiation is enabled or
|
||||
disabled.
|
||||
For interface types that support auto-negotiation then
|
||||
it defaults to being enabled.
|
||||
|
||||
For interface types that do not support auto-negotiation,
|
||||
the related configuration data is ignored.";
|
||||
}
|
||||
leaf negotiation-status {
|
||||
when "../enable = 'true'";
|
||||
type enumeration {
|
||||
enum in-progress {
|
||||
description
|
||||
"The auto-negotiation protocol is running and
|
||||
negotiation is currently in-progress.";
|
||||
}
|
||||
enum complete {
|
||||
description
|
||||
"The auto-negotiation protocol has completed
|
||||
successfully.";
|
||||
}
|
||||
enum failed {
|
||||
description
|
||||
"The auto-negotiation protocol has failed.";
|
||||
}
|
||||
enum unknown {
|
||||
description
|
||||
"The auto-negotiation status is not currently known,
|
||||
this could be because it is still negotiating or the
|
||||
protocol cannot run (e.g., if no medium is present).";
|
||||
}
|
||||
enum no-negotiation {
|
||||
description
|
||||
"No auto-negotiation is executed.
|
||||
The auto-negotation function is either not supported
|
||||
on this interface or has not been enabled.";
|
||||
}
|
||||
}
|
||||
config false;
|
||||
description
|
||||
"The status of the auto-negotiation protocol.";
|
||||
reference
|
||||
"IEEE 802.3, 30.6.1.1.4, aAutoNegAutoConfig";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
leaf duplex {
|
||||
type duplex-type;
|
||||
description
|
||||
"Operational duplex mode of the Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.32 aDuplexStatus";
|
||||
}
|
||||
|
||||
leaf speed {
|
||||
type eth-if-speed-type;
|
||||
units "Gb/s";
|
||||
description
|
||||
"Operational speed (data rate) of the Ethernet interface.
|
||||
The default value is implementation-dependent.";
|
||||
}
|
||||
|
||||
container flow-control {
|
||||
description
|
||||
"Holds the different types of Ethernet PAUSE frame based
|
||||
flow control that can be enabled.";
|
||||
container pause {
|
||||
if-feature "ethernet-pause";
|
||||
description
|
||||
"IEEE Std 802.3 PAUSE frame based PAUSE frame based flow
|
||||
control.";
|
||||
reference
|
||||
"IEEE Std 802.3, Annex 31B";
|
||||
leaf direction {
|
||||
type pause-fc-direction-type;
|
||||
description
|
||||
"Indicates which direction PAUSE frame based flow
|
||||
control is enabled in, or whether it is disabled.
|
||||
The default flow-control settings are vendor specific.
|
||||
If auto-negotiation is enabled, then PAUSE based
|
||||
flow-control is negotiated by default.
|
||||
The default value is implementation-dependent.";
|
||||
}
|
||||
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"Contains the number of PAUSE frames received or
|
||||
transmitted.";
|
||||
leaf in-frames-pause {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of PAUSE MAC Control frames transmitted on
|
||||
this Ethernet interface.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of the
|
||||
management system, and at other times as indicated
|
||||
by the value of the 'discontinuity-time' leaf
|
||||
defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.3 aPAUSEMACCtrlFramesReceived";
|
||||
}
|
||||
leaf out-frames-pause {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of PAUSE MAC Control frames transmitted on
|
||||
this Ethernet interface.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of the
|
||||
management system, and at other times as indicated
|
||||
by the value of the 'discontinuity-time' leaf
|
||||
defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.2
|
||||
aPAUSEMACCtrlFramesTransmitted";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
container pfc {
|
||||
if-feature "ethernet-pfc";
|
||||
description
|
||||
"IEEE Std 802.3 Priority-based flow control.";
|
||||
reference
|
||||
"IEEE Std 802.3, Annex 31D";
|
||||
|
||||
leaf enable {
|
||||
type boolean;
|
||||
|
||||
description
|
||||
"True indicates that IEEE Std 802.3 priority-based
|
||||
flow control is enabled, false indicates that
|
||||
IEEE Std 802.3 priority-based flow control is disabled.
|
||||
For interfaces that have auto-negotiation,
|
||||
the priority-based flow control is enabled by default.";
|
||||
}
|
||||
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"This container collects all statistics for
|
||||
Ethernet interfaces.";
|
||||
|
||||
leaf in-frames-pfc {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of PFC MAC Control frames received on this
|
||||
Ethernet interface.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of the
|
||||
management system, and at other times as indicated
|
||||
by the value of the 'discontinuity-time' leaf
|
||||
defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3HCInPFCFrames";
|
||||
}
|
||||
|
||||
leaf out-frames-pfc {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of PFC MAC Control frames transmitted on
|
||||
this interface.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of the
|
||||
management system, and at other times as indicated
|
||||
by the value of the 'discontinuity-time' leaf
|
||||
defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3HCInPFCFrames";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leaf force-flow-control {
|
||||
type boolean;
|
||||
default false;
|
||||
description
|
||||
"Explicitly forces the local PAUSE frame based flow control
|
||||
settings regardless of what has been negotiated.
|
||||
|
||||
Since the auto-negotiation of flow-control settings
|
||||
does not allow all sane combinations to be negotiated
|
||||
(e.g., consider a device that is only capable of sending
|
||||
PAUSE frames connected to a peer device that is only
|
||||
capable of receiving and acting on PAUSE frames) and
|
||||
failing to agree on the flow-control settings does not
|
||||
cause the auto-negotiation to fail completely, then it is
|
||||
sometimes useful to be able to explicitly enable
|
||||
particular PAUSE frame based flow control settings on
|
||||
the local device regardless of what is being advertised
|
||||
or negotiated.";
|
||||
reference
|
||||
"IEEE Std 802.3, Table 28B-3";
|
||||
}
|
||||
}
|
||||
|
||||
leaf max-frame-length {
|
||||
type uint16;
|
||||
units octets;
|
||||
config false;
|
||||
description
|
||||
"This indicates the MAC frame length (including FCS bytes)
|
||||
at which frames are dropped for being too long.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.37 aMaxFrameLength";
|
||||
}
|
||||
|
||||
leaf mac-control-extension-control {
|
||||
type boolean;
|
||||
config false;
|
||||
description
|
||||
"A value that identifies the current EXTENSION MAC Control
|
||||
function, as specified in IEEE Std 802.3, Annex 31C.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.3 aEXTENSIONMACCtrlStatus
|
||||
IEEE Std 802.3.1, dot3ExtensionMacCtrlStatus ";
|
||||
}
|
||||
|
||||
leaf frame-limit-slow-protocol {
|
||||
type uint64;
|
||||
units f/s;
|
||||
default 10;
|
||||
config false;
|
||||
description
|
||||
"The maximum number of Slow Protocol frames of a given
|
||||
subtype that can be transmitted in a one second interval.
|
||||
The default value is 10.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.38 aSlowProtocolFrameLimit";
|
||||
}
|
||||
|
||||
container capabilities {
|
||||
config false;
|
||||
description
|
||||
"Container all Ethernet interface specific capabilities.";
|
||||
|
||||
leaf auto-negotiation {
|
||||
type boolean;
|
||||
description
|
||||
"Indicates whether auto-negotiation may be configured on
|
||||
this interface.";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"Contains statistics specific to Ethernet interfaces.
|
||||
|
||||
Discontinuities in the values of counters in the
|
||||
container can occur at re-initialization of the management
|
||||
system, and at other times as indicated by the value of
|
||||
the 'discontinuity-time' leaf defined in the
|
||||
ietf-interfaces YANG module (IETF RFC 8343).";
|
||||
|
||||
container frame {
|
||||
description
|
||||
"Contains frame statistics specific to Ethernet
|
||||
interfaces.
|
||||
|
||||
All octet frame lengths include the 4 byte FCS.
|
||||
|
||||
Error counters are only reported once ... The count
|
||||
represented by an instance of this object is incremented
|
||||
when the frameCheckError status is returned by the MAC
|
||||
service to the LLC (or other MAC user). Received frames
|
||||
for which multiple error conditions pertain are,
|
||||
according to the conventions of IEEE Std 802.3 Layer
|
||||
Management, counted exclusively according to the error
|
||||
status presented to the LLC.
|
||||
|
||||
A frame that is counted by an instance of this object is
|
||||
also counted by the corresponding instance of 'in-errors'
|
||||
leaf defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).
|
||||
|
||||
Discontinuities in the values of counters in the
|
||||
container can occur at re-initialization of the
|
||||
management system, and at other times as indicated by
|
||||
the value of the 'discontinuity-time' leaf defined in
|
||||
the ietf-interfaces YANG module (IETF RFC 8343).";
|
||||
|
||||
leaf in-total-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"The total number of frames (including bad frames)
|
||||
received on the Ethernet interface.
|
||||
|
||||
This counter is calculated by summing the following
|
||||
IEEE Std 802.3, Clause 30 counters:
|
||||
aFramesReceivedOK +
|
||||
aFrameCheckSequenceErrors +
|
||||
aAlignmentErrors +
|
||||
aFrameTooLongErrors +
|
||||
aFramesLostDueToIntMACRcvError
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, Clause 30 counters, as specified
|
||||
in the description above.";
|
||||
}
|
||||
|
||||
leaf in-total-octets {
|
||||
type yang:counter64;
|
||||
units octets;
|
||||
description
|
||||
"The total number of octets of data (including those in
|
||||
bad frames) received on the Ethernet interface.
|
||||
|
||||
Includes the 4-octet FCS.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IETF RFC 2819, etherStatsOctets";
|
||||
}
|
||||
|
||||
leaf in-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames (including unicast, multicast and
|
||||
broadcast) that have been successfully received on the
|
||||
Ethernet interface.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.5 aFramesReceivedOK";
|
||||
}
|
||||
|
||||
leaf in-multicast-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of multicast frames that have been
|
||||
successfully received on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames counted
|
||||
by in-frames.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.21 aMulticastFramesReceivedOK";
|
||||
}
|
||||
|
||||
leaf in-broadcast-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of broadcast frames that have been
|
||||
successfully received on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames counted
|
||||
by in-frames.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.22 aBroadcastFramesReceivedOK";
|
||||
}
|
||||
|
||||
leaf in-error-fcs-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of receive frames that are of valid length,
|
||||
but do not pass the FCS check, regardless of whether
|
||||
or not the frames are an integral number of octets in
|
||||
length.
|
||||
|
||||
This count effectively comprises
|
||||
aFrameCheckSequenceErrors and aAlignmentErrors added
|
||||
together.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.6 aFrameCheckSequenceErrors;
|
||||
IEEE Std 802.3, 30.3.1.1.7 aAlignmentErrors";
|
||||
}
|
||||
|
||||
leaf in-error-undersize-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames received on a particular Ethernet
|
||||
interface that are less than 64 bytes in length, and
|
||||
are discarded.
|
||||
|
||||
This counter is incremented regardless of whether the
|
||||
frame passes the FCS check.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IETF RFC 2819, etherStatsUndersizePkts and
|
||||
etherStatsFragments";
|
||||
}
|
||||
|
||||
leaf in-error-oversize-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames received on a particular Ethernet
|
||||
interface that exceed the maximum permitted frame
|
||||
size, that is specified in max-frame-length, and are
|
||||
discarded.
|
||||
|
||||
This counter is incremented regardless of whether the
|
||||
frame passes the FCS check.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference "IEEE Std 802.3, 30.3.1.1.25 aFrameTooLongErrors";
|
||||
}
|
||||
|
||||
leaf in-error-mac-internal-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames for which reception on a particular
|
||||
Ethernet interface fails due to an internal MAC
|
||||
sublayer receive error.
|
||||
|
||||
A frame is only counted by an instance of this object
|
||||
if it is not counted by the corresponding instance of
|
||||
either the in-error-fcs-frames, in-error-undersize-frames,
|
||||
or in-error-oversize-frames. The precise meaning of the
|
||||
count represented by an instance of this object is
|
||||
implementation-specific.
|
||||
|
||||
In particular, an instance of this object may
|
||||
represent a count of receive errors on a particular
|
||||
Ethernet interface that are not otherwise counted.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.15
|
||||
aFramesLostDueToIntMACRcvError";
|
||||
}
|
||||
|
||||
leaf out-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames (including unicast, multicast and
|
||||
broadcast) that have been successfully transmitted on
|
||||
the Ethernet interface.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.2 aFramesTransmittedOK";
|
||||
}
|
||||
|
||||
leaf out-multicast-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of multicast frames that have been
|
||||
successfully transmitted on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames counted
|
||||
by out-frames.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.18 aMulticastFramesXmittedOK";
|
||||
}
|
||||
|
||||
leaf out-broadcast-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of broadcast frames that have been
|
||||
successfully transmitted on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames counted
|
||||
by out-frames.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.19 aBroadcastFramesXmittedOK";
|
||||
}
|
||||
|
||||
leaf out-error-mac-internal-frames {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of frames for which transmission on a
|
||||
particular Ethernet interface fails due to an internal
|
||||
MAC sublayer transmit error.
|
||||
|
||||
The precise meaning of the count represented by an
|
||||
instance of this object is implementation-specific. In
|
||||
particular, an instance of this object may represent a
|
||||
count of transmission errors on a particular Ethernet
|
||||
interface that are not otherwise counted.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.12
|
||||
aFramesLostDueToIntMACXmitError";
|
||||
}
|
||||
}
|
||||
|
||||
container phy {
|
||||
description
|
||||
"Ethernet statistics related to the PHY layer.
|
||||
|
||||
Discontinuities in the values of counters in the
|
||||
container can occur at re-initialization of the
|
||||
management system, and at other times as indicated by
|
||||
the value of the 'discontinuity-time' leaf defined in
|
||||
the ietf-interfaces YANG module (IETF RFC 8343).";
|
||||
|
||||
leaf in-error-symbol {
|
||||
type yang:counter64;
|
||||
units errors;
|
||||
description
|
||||
"A count of the number of symbol errors that have
|
||||
occurred.
|
||||
|
||||
For the precise definition of when the symbol error
|
||||
counter is incremented, please see the 'description'
|
||||
text associated with aSymbolErrorDuringCarrier,
|
||||
specified in IEEE Std 802.3, 30.3.2.1.5.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'phy-statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.5 aSymbolErrorDuringCarrier";
|
||||
}
|
||||
|
||||
container lpi {
|
||||
description
|
||||
"Physical Ethernet statistics for the energy efficiency
|
||||
related low power idle indications.";
|
||||
|
||||
leaf in-lpi-transitions {
|
||||
type yang:counter64;
|
||||
units transitions;
|
||||
description
|
||||
"A count of occurrences of the transition from
|
||||
DEASSERT to ASSERT of the LPI_INDICATE
|
||||
parameter. The indication reflects the state of the
|
||||
PHY according to the requirements of the RS (see
|
||||
IEEE Std 802.3, 22.7, 35.4, and 46.4).
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'phy-statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.11 aReceiveLPITransitions";
|
||||
}
|
||||
|
||||
leaf in-lpi-time {
|
||||
type decimal64 {
|
||||
fraction-digits 6;
|
||||
}
|
||||
units seconds;
|
||||
description
|
||||
"A count reflecting the total amount of time (in
|
||||
seconds) that the LPI_REQUEST parameter has the
|
||||
value ASSERT. The request is indicated to the PHY
|
||||
according to the requirements of the RS (see IEEE Std
|
||||
802.3, 22.7, 35.4, and 46.4).
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'phy-statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.9 aReceiveLPIMicroseconds";
|
||||
}
|
||||
|
||||
leaf out-lpi-transitions {
|
||||
type yang:counter64;
|
||||
units transitions;
|
||||
description
|
||||
"A count of occurrences of the transition from state
|
||||
LPI_DEASSERTED to state LPI_ASSERTED in the LPI
|
||||
transmit state diagram of the RS. The state
|
||||
transition corresponds to the assertion of the
|
||||
LPI_REQUEST parameter. The request is indicated to
|
||||
the PHY according to the requirements of the RS (see
|
||||
IEEE Std 802.3, 22.7, 35.4, 46.4.)
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'phy-statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.10 aTransmitLPITransitions";
|
||||
}
|
||||
|
||||
leaf out-lpi-time {
|
||||
type decimal64 {
|
||||
fraction-digits 6;
|
||||
}
|
||||
units seconds;
|
||||
description
|
||||
"A count reflecting the total amount of time (in
|
||||
seconds) that the LPI_INDICATION parameter has the
|
||||
value ASSERT. The request is indicated to the PHY
|
||||
according to the requirements of the RS (see IEEE
|
||||
802.3, 22.7, 35.4, and 46.4).
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'phy-statistics' container for additional
|
||||
common semantics related to this counter.";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.8 aTransmitLPIMicroseconds";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
container mac-control {
|
||||
description
|
||||
"A group of statistics specific to MAC Control operation
|
||||
of selected Ethernet interfaces.
|
||||
|
||||
Discontinuities in the values of counters in the
|
||||
container can occur at re-initialization of the
|
||||
management system, and at other times as indicated by
|
||||
the value of the 'discontinuity-time' leaf defined in
|
||||
the ietf-interfaces YANG module (IETF RFC 8343).";
|
||||
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3ExtensionTable";
|
||||
|
||||
leaf in-frames-mac-control-unknown {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"A count of MAC Control frames with an unsupported
|
||||
opcode received on this Ethernet interface.
|
||||
|
||||
Frames counted against this counter are also counted
|
||||
against in-discards defined in the ietf-interfaces
|
||||
YANG module (IETF RFC 8343).
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'mac-control-statistics' container for
|
||||
additional semantics.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.3.5 aUnsupportedOpcodesReceived";
|
||||
}
|
||||
|
||||
leaf in-frames-mac-control-extension {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"The count of Extension MAC Control frames received on
|
||||
this Ethernet interface.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'mac-control-statistics' container for
|
||||
additional semantics.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.2
|
||||
aEXTENSIONMACCtrlFramesReceived";
|
||||
}
|
||||
|
||||
leaf out-frames-mac-control-extension {
|
||||
type yang:counter64;
|
||||
units frames;
|
||||
description
|
||||
"The count of Extension MAC Control frames transmitted
|
||||
on this Ethernet interface.
|
||||
|
||||
Also see the 'description' statement associated with
|
||||
the parent 'mac-control-statistics' container for
|
||||
additional semantics.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.1
|
||||
aEXTENSIONMACCtrlFramesTransmitted";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,860 @@
|
||||
module ieee802-ethernet-interface {
|
||||
yang-version 1.1;
|
||||
namespace "urn:ieee:std:802.3:yang:ieee802-ethernet-interface";
|
||||
prefix ieee802-eth-if;
|
||||
|
||||
import ietf-yang-types {
|
||||
prefix yang;
|
||||
reference
|
||||
"IETF RFC 6991";
|
||||
}
|
||||
import iana-if-type {
|
||||
prefix ianaift;
|
||||
reference
|
||||
"http://www.iana.org/assignments/yang-parameters/
|
||||
iana-if-type@2023-01-26.yang";
|
||||
}
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
reference
|
||||
"IETF RFC 8343";
|
||||
}
|
||||
import ieee802-ethernet-phy-type {
|
||||
prefix ieee802-phy;
|
||||
reference
|
||||
"IEEE Std 802.3-2022";
|
||||
}
|
||||
|
||||
organization
|
||||
"IEEE Std 802.3 Ethernet Working Group
|
||||
Web URL: http://www.ieee802.org/3/";
|
||||
contact
|
||||
"Web URL: http://www.ieee802.org/3/";
|
||||
description
|
||||
"This module contains YANG definitions for configuring IEEE Std
|
||||
802.3 Ethernet Interfaces.
|
||||
In this YANG module, 'Ethernet interface' can be interpreted
|
||||
as referring to 'IEEE Std 802.3 compliant Ethernet
|
||||
interfaces'.";
|
||||
|
||||
revision 2025-09-10 {
|
||||
description
|
||||
"Updates under IEEE Std 802.3.2-2025";
|
||||
reference
|
||||
"IEEE Std 802.3-2022 and IEEE Std 802.3.1-2024, unless dated
|
||||
explicitly";
|
||||
}
|
||||
|
||||
feature ethernet-pfc {
|
||||
description
|
||||
"This device supports Ethernet priority flow control.";
|
||||
}
|
||||
|
||||
feature ethernet-pause {
|
||||
description
|
||||
"This device supports Ethernet PAUSE.";
|
||||
}
|
||||
|
||||
typedef eth-if-speed-type {
|
||||
type decimal64 {
|
||||
fraction-digits 3;
|
||||
}
|
||||
units "Gb/s";
|
||||
status obsolete;
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual
|
||||
speed of an Ethernet interface in Gigabits per second
|
||||
(Gb/s), accurate to 3 decimal places (i.e., accurate to
|
||||
1 Mb/s).";
|
||||
}
|
||||
|
||||
typedef duplex-type {
|
||||
type enumeration {
|
||||
enum full {
|
||||
description
|
||||
"Full duplex.";
|
||||
}
|
||||
enum half {
|
||||
description
|
||||
"Half duplex.";
|
||||
}
|
||||
enum unknown {
|
||||
description
|
||||
"Link is currently disconnected or initializing.";
|
||||
}
|
||||
}
|
||||
default "full";
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual
|
||||
duplex mode of an Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.32, aDuplexStatus";
|
||||
}
|
||||
|
||||
typedef pause-fc-direction-type {
|
||||
type enumeration {
|
||||
enum disabled {
|
||||
description
|
||||
"Flow control disabled in both ingress and egress
|
||||
directions.";
|
||||
}
|
||||
enum ingress-only {
|
||||
description
|
||||
"PAUSE frame-based flow control is enabled in the ingress
|
||||
direction only.";
|
||||
}
|
||||
enum egress-only {
|
||||
description
|
||||
"PAUSE frame-based flow control is enabled in the egress
|
||||
direction only.";
|
||||
}
|
||||
enum bi-directional {
|
||||
description
|
||||
"PAUSE frame-based flow control is enabled in both
|
||||
ingress and egress directions.";
|
||||
}
|
||||
enum undefined {
|
||||
description
|
||||
"Link is currently disconnected or initializing.";
|
||||
}
|
||||
}
|
||||
description
|
||||
"Used to represent the configured, negotiated, or actual
|
||||
PAUSE frame-based flow control setting.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3PauseAdminMode and dot3PauseOperMode";
|
||||
}
|
||||
|
||||
augment "/if:interfaces/if:interface" {
|
||||
when "derived-from-or-self(if:type, 'ianaift:ethernetCsmacd')" {
|
||||
description
|
||||
"Applies to all Ethernet interfaces.";
|
||||
}
|
||||
description
|
||||
"Augment interface model with Ethernet interface
|
||||
specific configuration nodes.";
|
||||
container ethernet {
|
||||
description
|
||||
"Contains all Ethernet interface related configuration.";
|
||||
container auto-negotiation {
|
||||
presence "The presence of this container indicates that
|
||||
auto-negotiation is supported on this Ethernet
|
||||
interface.";
|
||||
description
|
||||
"Contains auto-negotiation transmission parameters.
|
||||
|
||||
This container contains a data node that allows the
|
||||
advertised duplex value in the negotiation to be
|
||||
restricted.
|
||||
|
||||
If not specified then the default behavior for the
|
||||
duplex data node is to negotiate all available values for
|
||||
the particular type of Ethernet PHY associated with the
|
||||
interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, Clause 28 and Annexes 28A-D";
|
||||
leaf enable {
|
||||
type boolean;
|
||||
default "true";
|
||||
description
|
||||
"Controls whether auto-negotiation is enabled or
|
||||
disabled.
|
||||
For interface types that support auto-negotiation then
|
||||
it defaults to being enabled.
|
||||
|
||||
For interface types that do not support
|
||||
auto-negotiation, the related configuration data is
|
||||
ignored.";
|
||||
}
|
||||
leaf negotiation-status {
|
||||
when "../enable = 'true'";
|
||||
type enumeration {
|
||||
enum in-progress {
|
||||
description
|
||||
"The auto-negotiation protocol is running and
|
||||
negotiation is currently in-progress.";
|
||||
}
|
||||
enum complete {
|
||||
description
|
||||
"The auto-negotiation protocol has completed
|
||||
successfully.";
|
||||
}
|
||||
enum failed {
|
||||
description
|
||||
"The auto-negotiation protocol has failed.";
|
||||
}
|
||||
enum unknown {
|
||||
description
|
||||
"The auto-negotiation status is not currently known,
|
||||
this could be because it is still negotiating or the
|
||||
protocol cannot run
|
||||
(e.g., if no medium is present).";
|
||||
}
|
||||
enum no-negotiation {
|
||||
description
|
||||
"No auto-negotiation is executed.
|
||||
The auto-negotiation function is either not
|
||||
supported on this interface or has not been
|
||||
enabled.";
|
||||
}
|
||||
}
|
||||
config false;
|
||||
description
|
||||
"The status of the auto-negotiation protocol.";
|
||||
reference
|
||||
"IEEE 802.3, 30.6.1.1.4, aAutoNegAutoConfig";
|
||||
}
|
||||
}
|
||||
leaf phy-type {
|
||||
type identityref {
|
||||
base ieee802-phy:phy-type;
|
||||
}
|
||||
config false;
|
||||
description
|
||||
"A value that uniquely identifies the IEEE 802.3 PHY type
|
||||
of the interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.2 aPhyType";
|
||||
}
|
||||
leaf pmd-type {
|
||||
type identityref {
|
||||
base ieee802-phy:pmd-type;
|
||||
}
|
||||
config false;
|
||||
description
|
||||
"A value that uniquely identifies the IEEE 802.3 PMD type
|
||||
of the interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.5.1.1.2 aMAUType";
|
||||
}
|
||||
leaf duplex {
|
||||
type duplex-type;
|
||||
description
|
||||
"Operational duplex mode of the Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.32 aDuplexStatus";
|
||||
}
|
||||
leaf speed {
|
||||
type eth-if-speed-type;
|
||||
units "Gb/s";
|
||||
status obsolete;
|
||||
description
|
||||
"Operational speed (data rate) of the Ethernet interface.
|
||||
The default value is implementation dependent.
|
||||
Superseded by speed in /if:interfaces/if:interface";
|
||||
}
|
||||
/* deprecated flow-control container */
|
||||
container flow-control {
|
||||
status deprecated;
|
||||
description
|
||||
"Holds the different types of Ethernet PAUSE frame-based
|
||||
flow control that can be enabled.
|
||||
Superseded by new container - pause.";
|
||||
container pause {
|
||||
if-feature "ethernet-pause";
|
||||
description
|
||||
"IEEE Std 802.3 PAUSE frame-based flow control.";
|
||||
reference
|
||||
"IEEE Std 802.3, Annex 31B";
|
||||
leaf direction {
|
||||
type pause-fc-direction-type;
|
||||
description
|
||||
"Indicates which direction PAUSE frame-based flow
|
||||
control is enabled in, or whether it is disabled.
|
||||
The default flow-control settings are vendor
|
||||
specific. If auto-negotiation is enabled, then PAUSE
|
||||
based flow control is negotiated by default.
|
||||
The default value is implementation dependent.";
|
||||
}
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"Contains the number of PAUSE frames received or
|
||||
transmitted.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of
|
||||
the management system, and at other times as
|
||||
indicated by the value of the 'discontinuity-time'
|
||||
leaf defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
leaf in-frames-pause {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of PAUSE MAC Control frames transmitted on
|
||||
this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.3
|
||||
aPAUSEMACCtrlFramesReceived";
|
||||
}
|
||||
leaf out-frames-pause {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of PAUSE MAC Control frames transmitted on
|
||||
this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.2
|
||||
aPAUSEMACCtrlFramesTransmitted";
|
||||
}
|
||||
}
|
||||
}
|
||||
container pfc {
|
||||
if-feature "ethernet-pfc";
|
||||
description
|
||||
"IEEE Std 802.3 Priority-based flow control.";
|
||||
reference
|
||||
"IEEE Std 802.3, Annex 31D";
|
||||
leaf enable {
|
||||
type boolean;
|
||||
description
|
||||
"True indicates that IEEE Std 802.3 priority-based
|
||||
flow control is enabled, false indicates that
|
||||
IEEE Std 802.3 priority-based flow control is
|
||||
disabled. For interfaces that have auto-negotiation,
|
||||
the priority-based flow control is enabled by
|
||||
default.";
|
||||
}
|
||||
container statistics {
|
||||
config false;
|
||||
status deprecated;
|
||||
description
|
||||
"This container collects all statistics for
|
||||
Ethernet interfaces.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of
|
||||
the management system, and at other times as
|
||||
indicated by the value of the 'discontinuity-time'
|
||||
leaf defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
leaf in-frames-pfc {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"Deprecated in-frames-pfc as not defined in base
|
||||
standard. A count of PFC MAC Control frames
|
||||
received on this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3HCInPFCFrames";
|
||||
}
|
||||
leaf out-frames-pfc {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"Deprecated out-frames-pfc as not defined in base
|
||||
standard. A count of PFC MAC Control frames
|
||||
transmitted on this interface.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3HCInPFCFrames";
|
||||
}
|
||||
}
|
||||
}
|
||||
leaf force-flow-control {
|
||||
type boolean;
|
||||
default "false";
|
||||
description
|
||||
"Explicitly forces the local PAUSE frame-based flow
|
||||
control settings regardless of what has been
|
||||
negotiated.
|
||||
|
||||
Since the auto-negotiation of flow control settings
|
||||
does not allow all sane combinations to be negotiated
|
||||
(e.g., consider a device that is only capable of
|
||||
sending PAUSE frames connected to a peer device that
|
||||
is only capable of receiving and acting on PAUSE
|
||||
frames) and failing to agree on the flow control
|
||||
settings does not cause the auto-negotiation to fail
|
||||
completely, then it is sometimes useful to be able to
|
||||
explicitly enable particular PAUSE frame-based flow
|
||||
control settings on the local device regardless of
|
||||
what is being advertised or negotiated.";
|
||||
reference
|
||||
"IEEE Std 802.3, Table 28B-3";
|
||||
}
|
||||
}
|
||||
leaf max-frame-length {
|
||||
type uint16;
|
||||
units "octets";
|
||||
config false;
|
||||
description
|
||||
"This indicates the MAC frame length (including FCS bytes)
|
||||
at which frames are dropped for being too long.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.37 aMaxFrameLength";
|
||||
}
|
||||
leaf mac-control-extension-control {
|
||||
type boolean;
|
||||
config false;
|
||||
description
|
||||
"A value that identifies the current EXTENSION
|
||||
MAC Control function, as specified in
|
||||
IEEE Std 802.3, Annex 31C.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.3 aEXTENSIONMACCtrlStatus
|
||||
IEEE Std 802.3.1, dot3ExtensionMacCtrlStatus ";
|
||||
}
|
||||
leaf frame-limit-slow-protocol {
|
||||
type uint64;
|
||||
units "f/s";
|
||||
default "10";
|
||||
config false;
|
||||
description
|
||||
"The maximum number of Slow Protocol frames of a given
|
||||
subtype that can be transmitted in a one second
|
||||
interval.
|
||||
The default value is 10.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.38 aSlowProtocolFrameLimit";
|
||||
}
|
||||
container capabilities {
|
||||
config false;
|
||||
description
|
||||
"Contains all Ethernet interface specific capabilities.";
|
||||
leaf auto-negotiation {
|
||||
type boolean;
|
||||
description
|
||||
"Indicates whether auto-negotiation may be configured on
|
||||
this interface.";
|
||||
}
|
||||
}
|
||||
container ethernet-pause {
|
||||
if-feature "ethernet-pause";
|
||||
description
|
||||
"IEEE Std 802.3 PAUSE flow control.
|
||||
|
||||
Discontinuities in the values of counters in
|
||||
this container can occur at re-initialization of
|
||||
the management system, and at other times as
|
||||
indicated by the value of the 'discontinuity-time'
|
||||
leaf defined in the ietf-interfaces YANG module
|
||||
(IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4 PAUSE entity managed object class
|
||||
and Clause 31, Annex 31B)";
|
||||
container control-and-status {
|
||||
description
|
||||
"PAUSE function control and status objects.";
|
||||
leaf pause-admin-control {
|
||||
type pause-fc-direction-type;
|
||||
default "disabled";
|
||||
description
|
||||
"What PAUSE functionality will run on this interface
|
||||
when Auto-Negotiation is not implemented
|
||||
or disabled.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3PauseAdminMode";
|
||||
}
|
||||
leaf pause-oper-status {
|
||||
type pause-fc-direction-type;
|
||||
config false;
|
||||
description
|
||||
"What PAUSE functionality is running on this
|
||||
interface, as a result of Auto-Negotiation or
|
||||
setting pause-admin-control.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3PauseOperMode";
|
||||
}
|
||||
leaf link-delay-allowance {
|
||||
type uint32;
|
||||
description
|
||||
"The value in bit-times of the allowance made by the
|
||||
MAC Control PAUSE entity for round-trip propagation
|
||||
delay.
|
||||
The default value is implementation dependent.";
|
||||
}
|
||||
leaf pfc-enable-status {
|
||||
type boolean;
|
||||
config false;
|
||||
description
|
||||
"Is IEEE 802.1 Priority-based Flow Control (PFC)
|
||||
enabled on the interface. If PFC is enabled, then
|
||||
802.3 PAUSE flow control is disabled.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.3.6 aPFCEnableStatus";
|
||||
}
|
||||
}
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"PAUSE frame counters.";
|
||||
leaf in-frames-pause {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of MAC Control PAUSE frames transmitted on
|
||||
this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.3
|
||||
aPAUSEMACCtrlFramesReceived";
|
||||
}
|
||||
leaf out-frames-pause {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of MAC Control PAUSE frames transmitted on
|
||||
this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.4.2
|
||||
aPAUSEMACCtrlFramesTransmitted";
|
||||
}
|
||||
}
|
||||
}
|
||||
container statistics {
|
||||
config false;
|
||||
description
|
||||
"Contains statistics specific to Ethernet interfaces.
|
||||
|
||||
Discontinuities in the values of counters in the
|
||||
container can occur at re-initialization of the
|
||||
management system, and at other times as indicated by
|
||||
the value of the 'discontinuity-time' leaf defined in
|
||||
the ietf-interfaces YANG module (IETF RFC 8343).";
|
||||
container frame {
|
||||
description
|
||||
"Contains frame statistics specific to Ethernet
|
||||
interfaces.
|
||||
|
||||
All octet frame lengths include the 4-byte FCS.
|
||||
|
||||
Error counters are only reported once. The count
|
||||
represented by an instance of this object is
|
||||
incremented when the frameCheckError status is
|
||||
returned by the MAC service to the MAC Client.
|
||||
Received frames for which multiple error conditions
|
||||
pertain are, according to the conventions of
|
||||
IEEE Std 802.3 Layer Management, counted exclusively
|
||||
according to the error status presented to the MAC
|
||||
Client.
|
||||
|
||||
A frame that is counted by an instance of this object
|
||||
is also counted by the corresponding instance of
|
||||
'in-errors' leaf defined in the ietf-interfaces YANG
|
||||
module (IETF RFC 8343).";
|
||||
leaf in-total-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"The total number of frames (including bad frames)
|
||||
received on the Ethernet interface.
|
||||
|
||||
This counter is calculated by summing the following
|
||||
IEEE Std 802.3, Clause 30 counters:
|
||||
aFramesReceivedOK +
|
||||
aFrameCheckSequenceErrors +
|
||||
aAlignmentErrors +
|
||||
aFrameTooLongErrors +
|
||||
aFramesLostDueToIntMACRcvError";
|
||||
reference
|
||||
"IEEE Std 802.3, Clause 30 counters, as specified
|
||||
in the description above.";
|
||||
}
|
||||
leaf in-total-octets {
|
||||
type yang:counter64;
|
||||
units "octets";
|
||||
description
|
||||
"The total number of octets of data (including those
|
||||
in bad frames) received on the Ethernet interface.
|
||||
|
||||
Includes the 4-octet FCS.";
|
||||
reference
|
||||
"IETF RFC 2819, etherStatsOctets";
|
||||
}
|
||||
leaf in-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of frames (including unicast, multicast, and
|
||||
broadcast) that have been successfully received on
|
||||
the Ethernet interface.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length, or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.5 aFramesReceivedOK";
|
||||
}
|
||||
leaf in-multicast-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of multicast frames that have been
|
||||
successfully received on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames
|
||||
counted by in-frames.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length, or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.21
|
||||
aMulticastFramesReceivedOK";
|
||||
}
|
||||
leaf in-broadcast-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of broadcast frames that have been
|
||||
successfully received on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames
|
||||
counted by in-frames.
|
||||
|
||||
This count does not include frames received with
|
||||
frame-too-long, FCS, length, or alignment errors, or
|
||||
frames lost due to internal MAC sublayer error.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.22
|
||||
aBroadcastFramesReceivedOK";
|
||||
}
|
||||
leaf in-error-fcs-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of receive frames that are of valid length,
|
||||
but do not pass the FCS check, regardless of whether
|
||||
or not the frames are an integral number of octets
|
||||
in length.
|
||||
|
||||
This counter is calculated by summing the following
|
||||
counters:
|
||||
aFrameCheckSequenceErrors +
|
||||
aAlignmentErrors";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.6 aFrameCheckSequenceErrors;
|
||||
IEEE Std 802.3, 30.3.1.1.7 aAlignmentErrors";
|
||||
}
|
||||
leaf in-error-undersize-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
status deprecated;
|
||||
description
|
||||
"Deprecated in-error-undersize-frames as not defined
|
||||
in base standard. A count of frames received on a
|
||||
particular Ethernet interface that are less than
|
||||
64 bytes in length, and are discarded.
|
||||
|
||||
This counter is incremented regardless of whether
|
||||
the frame passes the FCS check.";
|
||||
reference
|
||||
"IETF RFC 2819, etherStatsUndersizePkts and
|
||||
etherStatsFragments";
|
||||
}
|
||||
leaf in-error-oversize-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of frames received on a particular Ethernet
|
||||
interface that exceed the maximum permitted frame
|
||||
size, that is specified in max-frame-length, and are
|
||||
discarded.
|
||||
|
||||
This counter is incremented regardless of whether
|
||||
the frame passes the FCS check.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.25
|
||||
aFrameTooLongErrors";
|
||||
}
|
||||
leaf in-error-mac-internal-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of frames for which reception on a
|
||||
particular Ethernet interface fails due to an
|
||||
internal MAC sublayer receive error.
|
||||
|
||||
A frame is only counted by an instance of this
|
||||
object if it is not counted by the corresponding
|
||||
instance of either the in-error-fcs-frames,
|
||||
in-error-undersize-frames, or
|
||||
in-error-oversize-frames. The precise meaning of
|
||||
the count represented by an instance of this object
|
||||
is implementation-specific.
|
||||
|
||||
In particular, an instance of this object may
|
||||
represent a count of receive errors on a particular
|
||||
Ethernet interface that are not otherwise counted.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.15
|
||||
aFramesLostDueToIntMACRcvError";
|
||||
}
|
||||
leaf out-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of frames (including unicast, multicast, and
|
||||
broadcast) that have been successfully transmitted
|
||||
on the Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.2 aFramesTransmittedOK";
|
||||
}
|
||||
leaf out-multicast-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of multicast frames that have been
|
||||
successfully transmitted on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames
|
||||
counted by out-frames.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.18
|
||||
aMulticastFramesXmittedOK";
|
||||
}
|
||||
leaf out-broadcast-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of broadcast frames that have been
|
||||
successfully transmitted on the Ethernet interface.
|
||||
|
||||
This counter represents a subset of the frames
|
||||
counted by out-frames.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.19
|
||||
aBroadcastFramesXmittedOK";
|
||||
}
|
||||
leaf out-error-mac-internal-frames {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of frames for which transmission on a
|
||||
particular Ethernet interface fails due to an
|
||||
internal MAC sublayer transmit error.
|
||||
|
||||
The precise meaning of the count represented by an
|
||||
instance of this object is implementation-specific.
|
||||
In particular, an instance of this object may
|
||||
represent a count of transmission errors on a
|
||||
particular Ethernet interface that are not otherwise
|
||||
counted.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.1.1.12
|
||||
aFramesLostDueToIntMACXmitError";
|
||||
}
|
||||
}
|
||||
container phy {
|
||||
description
|
||||
"Ethernet statistics related to the PHY layer.";
|
||||
leaf in-error-symbol {
|
||||
type yang:counter64;
|
||||
units "errors";
|
||||
description
|
||||
"A count of the number of symbol errors that have
|
||||
occurred.
|
||||
|
||||
For the precise definition of when the symbol error
|
||||
counter is incremented, please see the 'description'
|
||||
text associated with aSymbolErrorDuringCarrier,
|
||||
specified in IEEE Std 802.3, 30.3.2.1.5.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.5
|
||||
aSymbolErrorDuringCarrier";
|
||||
}
|
||||
container lpi {
|
||||
description
|
||||
"Physical Ethernet statistics for the energy
|
||||
efficiency related low power idle indications.";
|
||||
leaf in-lpi-transitions {
|
||||
type yang:counter64;
|
||||
units "transitions";
|
||||
description
|
||||
"The number of times the link partner transitioned to
|
||||
Low Power Idle.
|
||||
This counter has a maximum per second increment rate
|
||||
of:
|
||||
50 thousand for 100 Mb/s;
|
||||
90 thousand for 1000 Mb/s
|
||||
230 thousand for 10 Gb/s.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.11
|
||||
aReceiveLPITransitions";
|
||||
}
|
||||
leaf in-lpi-time {
|
||||
type decimal64 {
|
||||
fraction-digits 6;
|
||||
}
|
||||
units "seconds";
|
||||
description
|
||||
"The amount of time the link partner has
|
||||
been in Low Power Idle.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.9
|
||||
aReceiveLPIMicroseconds";
|
||||
}
|
||||
leaf out-lpi-transitions {
|
||||
type yang:counter64;
|
||||
units "transitions";
|
||||
description
|
||||
"The number of times this port transitioned to
|
||||
Low Power Idle.
|
||||
This counter has a maximum per second increment rate
|
||||
of:
|
||||
50 thousand for 100 Mb/s;
|
||||
90 thousand for 1000 Mb/s
|
||||
230 thousand for 10 Gb/s.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.10
|
||||
aTransmitLPITransitions";
|
||||
}
|
||||
leaf out-lpi-time {
|
||||
type decimal64 {
|
||||
fraction-digits 6;
|
||||
}
|
||||
units "seconds";
|
||||
description
|
||||
"The amount of time in this port has
|
||||
been in Low Power Idle.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.2.1.8
|
||||
aTransmitLPIMicroseconds";
|
||||
}
|
||||
}
|
||||
}
|
||||
container mac-control {
|
||||
description
|
||||
"A group of statistics specific to MAC Control
|
||||
operation of selected Ethernet interfaces.";
|
||||
reference
|
||||
"IEEE Std 802.3.1, dot3ExtensionTable";
|
||||
leaf in-frames-mac-control-unknown {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"A count of MAC Control frames with an unsupported
|
||||
opcode received on this Ethernet interface.
|
||||
|
||||
Frames counted against this counter are also counted
|
||||
against in-discards defined in the ietf-interfaces
|
||||
YANG module (IETF RFC 8343).";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.3.5
|
||||
aUnsupportedOpcodesReceived";
|
||||
}
|
||||
leaf in-frames-mac-control-extension {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"The count of Extension MAC Control frames received
|
||||
on this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.2
|
||||
aEXTENSIONMACCtrlFramesReceived";
|
||||
}
|
||||
leaf out-frames-mac-control-extension {
|
||||
type yang:counter64;
|
||||
units "frames";
|
||||
description
|
||||
"The count of Extension MAC Control frames
|
||||
transmitted on this Ethernet interface.";
|
||||
reference
|
||||
"IEEE Std 802.3, 30.3.8.1
|
||||
aEXTENSIONMACCtrlFramesTransmitted";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,18 @@ module infix-ethernet-interface {
|
||||
|
||||
import ieee802-ethernet-interface {
|
||||
prefix eth;
|
||||
revision-date 2025-09-10;
|
||||
}
|
||||
import ieee802-ethernet-phy-type {
|
||||
prefix ieee802-phy;
|
||||
revision-date 2025-09-10;
|
||||
}
|
||||
import ietf-interfaces {
|
||||
prefix if;
|
||||
}
|
||||
import iana-if-type {
|
||||
prefix ianaift;
|
||||
}
|
||||
import ietf-yang-types {
|
||||
prefix yang;
|
||||
reference "IETF RFC 6991";
|
||||
@@ -18,6 +26,34 @@ module infix-ethernet-interface {
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "Extensions and deviations to ieee802-ethernet-interface.yang";
|
||||
|
||||
revision 2026-05-21 {
|
||||
description "Augment auto-negotiation with an 'advertise' leaf-list
|
||||
of PMD-type identities, modelling the standards-correct
|
||||
way to express what older configurations called 'fixed
|
||||
speed': restrict the set of modes auto-negotiation may
|
||||
advertise. IEEE Std 802.3.2-2025 obsoleted the eth:speed
|
||||
leaf without providing a config-true replacement; this
|
||||
augment fills that gap using existing IEEE PMD identities.
|
||||
Old configurations using auto-negotiation/enable=false
|
||||
plus speed+duplex are migrated by confd/share/migrate/1.9.
|
||||
|
||||
Also add an 'mdi-x' boolean leaf under ethernet for forcing
|
||||
the copper MDI/MDI-X pinout, needed on some PHYs when
|
||||
auto-negotiation is disabled and Auto-MDIX stops working.
|
||||
Absent = Auto-MDIX, true = MDI-X, false = MDI; gated by a
|
||||
when-expression on auto-negotiation/enable = false.";
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
revision 2026-05-18 {
|
||||
description "Updated to ieee802-ethernet-interface@2025-09-10 base
|
||||
(IEEE Std 802.3.2-2025). No path or semantic changes
|
||||
to Infix-exposed config; new operational leaves
|
||||
phy-type and pmd-type from the upstream model are
|
||||
used directly without deviation.";
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
revision 2024-02-27 {
|
||||
description "Add augment for in-good-octets and out-good-octets";
|
||||
reference "internal";
|
||||
@@ -36,6 +72,62 @@ module infix-ethernet-interface {
|
||||
/*
|
||||
* Data Nodes
|
||||
*/
|
||||
augment "/if:interfaces/if:interface/eth:ethernet/eth:auto-negotiation" {
|
||||
when "derived-from-or-self(../../if:type, 'ianaift:ethernetCsmacd')";
|
||||
description "Configuration knobs that constrain auto-negotiation.";
|
||||
|
||||
leaf-list advertised-pmd-types {
|
||||
type identityref {
|
||||
base ieee802-phy:pmd-type;
|
||||
}
|
||||
description "Restrict auto-negotiation to advertise only these PMD types.
|
||||
When empty, the PHY advertises every mode it supports.";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mdi-x has deliberately NO default: the absent state is what carries
|
||||
* the Auto-MDIX meaning, so adding a default would remove it. The C
|
||||
* apply path must therefore read it with lydx_get_cattr() (absent vs
|
||||
* true vs false), not lydx_get_bool() which collapses absent and false.
|
||||
*
|
||||
* The when-expression confines it to auto-negotiation/enable = false:
|
||||
* Auto-MDIX is negotiated together with the link when autoneg is on, so
|
||||
* forcing a pinout only makes sense once negotiation is disabled.
|
||||
*/
|
||||
augment "/if:interfaces/if:interface/eth:ethernet" {
|
||||
when "derived-from-or-self(../if:type, 'ianaift:ethernetCsmacd')";
|
||||
description "Copper PHY configuration knobs.";
|
||||
|
||||
leaf mdi-x {
|
||||
when "../eth:auto-negotiation/eth:enable = 'false'";
|
||||
type boolean;
|
||||
description "Force the copper MDI/MDI-X crossover pinout. Only
|
||||
available with auto-negotiation disabled, since Auto-MDIX
|
||||
otherwise rides along with negotiation:
|
||||
true force MDI-X (crossover)
|
||||
false force MDI (straight)
|
||||
The two ends of the link must use opposite values.
|
||||
|
||||
Leave unset for Auto-MDIX, the right choice for any link
|
||||
that negotiates.";
|
||||
}
|
||||
}
|
||||
|
||||
augment "/if:interfaces/if:interface/eth:ethernet" {
|
||||
when "derived-from-or-self(../if:type, 'ianaift:ethernetCsmacd')";
|
||||
description "Operational facets for diagnosis.";
|
||||
|
||||
leaf-list supported-pmd-types {
|
||||
type identityref {
|
||||
base ieee802-phy:pmd-type;
|
||||
}
|
||||
config false;
|
||||
description "PMD types this interface currently supports.
|
||||
On SFP/SFP+ cages the set reflects the inserted module.";
|
||||
}
|
||||
}
|
||||
|
||||
augment "/if:interfaces/if:interface/eth:ethernet/eth:statistics/eth:frame" {
|
||||
leaf out-good-octets {
|
||||
type yang:counter64;
|
||||
|
||||
@@ -41,6 +41,15 @@ module infix-interfaces {
|
||||
contact "kernelkit@googlegroups.com";
|
||||
description "Linux bridge and lag extensions for ietf-interfaces.";
|
||||
|
||||
revision 2026-05-18 {
|
||||
description "Track ieee802-ethernet-interface@2025-09-10 upgrade
|
||||
(IEEE Std 802.3.2-2025): operational data now exposes
|
||||
phy-type/pmd-type leaves and the interface speed via
|
||||
ietf-interfaces:speed (bits/s) rather than the obsolete
|
||||
eth:speed.";
|
||||
reference "internal";
|
||||
}
|
||||
|
||||
revision 2026-05-13 {
|
||||
description "Add limitations on custom mac addresses on interfaces, now needs to be a correct unicast mac-address";
|
||||
reference "internal";
|
||||
|
||||
@@ -737,15 +737,39 @@ echo "Public: $pub"
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="factory-config" help="Show factory-config">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory | jq -C . |pager</ACTION>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
|
||||
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy factory ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="running-config" help="Show running-config">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running | jq -C . |pager</ACTION>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
|
||||
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy running ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="startup-config" help="Show startup-config">
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup | jq -C . |pager</ACTION>
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
|
||||
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy startup ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="operational" help="Show operational data (running config + system state)">
|
||||
<SWITCH name="optional" min="0">
|
||||
<COMMAND name="path" help="Filter by XPath, e.g. /ietf-interfaces:interfaces">
|
||||
<PARAM name="xpath" ptype="/STRING" help="XPath into the datastore"/>
|
||||
</COMMAND>
|
||||
</SWITCH>
|
||||
<ACTION sym="script" in="tty" out="tty" interrupt="true">copy operational ${KLISH_PARAM_xpath:+-x $KLISH_PARAM_xpath} | jq -C . |pager</ACTION>
|
||||
</COMMAND>
|
||||
|
||||
<COMMAND name="firewall" help="Show firewall status and configuration">
|
||||
|
||||
@@ -106,14 +106,15 @@ interfaces {
|
||||
}
|
||||
}
|
||||
admin@infix-12-34-56:/config/interface/eth0/> leave
|
||||
admin@infix-12-34-56:/> show interfaces
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 ethernet UP 52:54:00:12:34:56
|
||||
ipv4 192.168.2.200/24 (static)
|
||||
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
||||
lo ethernet UP 00:00:00:00:00:00
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@infix-12-34-56:/> show interface
|
||||
INTERFACE PROTOCOL STATE DATA
|
||||
eth0 1000baseT UP duplex: full
|
||||
ethernet 52:54:00:12:34:56
|
||||
ipv4 192.168.2.200/24 (static)
|
||||
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
||||
lo loopback UP
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
admin@infix-12-34-56:/> copy running-config startup-config</code></pre>
|
||||
<a href="doc/cli/introduction.md">Click here</a> for more details.
|
||||
</details>
|
||||
|
||||
@@ -101,7 +101,7 @@ def compress_interface_list(interfaces):
|
||||
class Pad:
|
||||
flags = 2
|
||||
iface = 16
|
||||
proto = 11
|
||||
proto = 14
|
||||
state = 12
|
||||
data = 41
|
||||
|
||||
@@ -1042,7 +1042,15 @@ class Iface:
|
||||
self.autoneg = get_json_data('unknown', self.data, 'ieee802-ethernet-interface:ethernet',
|
||||
'auto-negotiation', 'enable')
|
||||
self.duplex = get_json_data('', self.data,'ieee802-ethernet-interface:ethernet','duplex')
|
||||
self.speed = get_json_data('', self.data, 'ieee802-ethernet-interface:ethernet', 'speed')
|
||||
self.speed = get_json_data('', self.data, 'speed')
|
||||
self.pmd_type = get_json_data('', self.data, 'ieee802-ethernet-interface:ethernet', 'pmd-type')
|
||||
self.phy_type = get_json_data('', self.data, 'ieee802-ethernet-interface:ethernet', 'phy-type')
|
||||
self.advertised = get_json_data([], self.data, 'ieee802-ethernet-interface:ethernet',
|
||||
'auto-negotiation',
|
||||
'infix-ethernet-interface:advertised-pmd-types')
|
||||
self.supported = get_json_data([], self.data,
|
||||
'ieee802-ethernet-interface:ethernet',
|
||||
'infix-ethernet-interface:supported-pmd-types')
|
||||
self.phys_address = data.get('phys-address', '')
|
||||
|
||||
self.br_mdb = get_json_data({}, self.data, 'infix-interfaces:bridge', 'multicast-filters')
|
||||
@@ -1107,9 +1115,12 @@ class Iface:
|
||||
self.wireguard = self.data.get('infix-interfaces:wireguard')
|
||||
|
||||
if self.data.get('infix-interfaces:vlan'):
|
||||
self.lower_if = self.data.get('infix-interfaces:vlan', None).get('lower-layer-if',None)
|
||||
vlan_data = self.data.get('infix-interfaces:vlan')
|
||||
self.lower_if = vlan_data.get('lower-layer-if', None)
|
||||
self.vid = vlan_data.get('id', None)
|
||||
else:
|
||||
self.lower_if = ''
|
||||
self.vid = None
|
||||
|
||||
def is_wifi(self):
|
||||
return self.type == "infix-if-type:wifi"
|
||||
@@ -1173,66 +1184,130 @@ class Iface:
|
||||
row += f"{'':<{Pad.state}}{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||
print(row)
|
||||
|
||||
def _pr_proto_common(self, name, phys_address, pipe=''):
|
||||
@staticmethod
|
||||
def _pr_label_list(label, values):
|
||||
"""Print label-prefixed values, one per row.
|
||||
|
||||
First row carries the label and a colon; later rows are blank-
|
||||
prefixed continuations. When 'values' is empty, prints just the
|
||||
label and a trailing colon — matching how 'ipv4 addresses' has
|
||||
always been rendered when the interface has no IPs.
|
||||
"""
|
||||
if not values:
|
||||
print(f"{label:<{19}}:")
|
||||
return
|
||||
first = True
|
||||
for value in values:
|
||||
key = label if first else ''
|
||||
colon = ':' if first else ' '
|
||||
print(f"{key:<{19}}{colon} {value}")
|
||||
first = False
|
||||
|
||||
@staticmethod
|
||||
def _pmd_label(identity):
|
||||
"""Render an IEEE pmd-type / phy-type identityref as a display string.
|
||||
|
||||
Strips the module/leaf prefix and rewrites the IEEE 'BASE-' literal
|
||||
to the lowercase 'base' the rest of the codebase uses (matching
|
||||
ethtool's link-mode string format). Returns empty for empty input.
|
||||
"""
|
||||
if not identity:
|
||||
return ""
|
||||
return identity.removeprefix(
|
||||
"ieee802-ethernet-phy-type:pmd-type-"
|
||||
).removeprefix(
|
||||
"ieee802-ethernet-phy-type:phy-type-"
|
||||
).replace("BASE-", "base")
|
||||
|
||||
def _phy_label(self):
|
||||
"""Display label for the active link.
|
||||
|
||||
Prefers pmd-type (specific medium, e.g. '10GbaseLR') over phy-type
|
||||
(family-level, e.g. '10GbaseR') when both are populated. Empty
|
||||
when neither is reported — non-ethernet interfaces don't have these
|
||||
leaves, and yanger skips them for ethernet ports with no link or
|
||||
unmapped (port, speed, duplex) tuple.
|
||||
"""
|
||||
return self._pmd_label(self.pmd_type or self.phy_type)
|
||||
|
||||
def _pr_proto_common(self, name, pipe='', data='', show_state=True):
|
||||
# pipe="" means this row follows pr_name() on the same line, so col 1-2
|
||||
# are already on screen. A non-empty pipe (" ", "│", "└ ") prints col
|
||||
# 1-2 with that marker. show_state=False blanks the STATE column for
|
||||
# sub-rows whose state was already reflected in the row above.
|
||||
row = ""
|
||||
if len(pipe) > 0:
|
||||
row = f"{'':<{Pad.flags}}"
|
||||
row += f"{pipe:<{Pad.iface}}"
|
||||
|
||||
row += f"{name:<{Pad.proto}}"
|
||||
dec = Decore.green if self.oper() == "up" else Decore.red
|
||||
row += dec(f"{self.oper().upper():<{Pad.state}}")
|
||||
if phys_address:
|
||||
row += f"{self.phys_address:<{Pad.data}}"
|
||||
if show_state:
|
||||
dec = Decore.green if self.oper() == "up" else Decore.red
|
||||
row += dec(f"{self.oper().upper():<{Pad.state}}")
|
||||
else:
|
||||
row += f"{'':<{Pad.state}}"
|
||||
if data:
|
||||
row += f"{data:<{Pad.data}}"
|
||||
return row
|
||||
|
||||
def _pr_phy_row(self, pipe=''):
|
||||
"""Emit the physical-medium row when applicable. Return True if printed.
|
||||
|
||||
Skipped when pmd-type is unknown or the link is not up — keeping the
|
||||
common 'boring port' cases quiet and falling back to the ethernet row.
|
||||
"""
|
||||
label = self._phy_label()
|
||||
if not label or self.oper() != "up":
|
||||
return False
|
||||
data = f"duplex: {self.duplex}" if self.duplex else ""
|
||||
print(self._pr_proto_common(label, pipe, data))
|
||||
return True
|
||||
|
||||
def pr_proto_eth(self, pipe=''):
|
||||
row = self._pr_proto_common("ethernet", True, pipe);
|
||||
print(row)
|
||||
print(self._pr_proto_common("ethernet", pipe, self.phys_address or ""))
|
||||
|
||||
def pr_proto_eth_subrow(self, pipe=' '):
|
||||
"""Ethernet row beneath another protocol row: bare MAC, no STATE column."""
|
||||
print(self._pr_proto_common("ethernet", pipe, self.phys_address or "",
|
||||
show_state=False))
|
||||
|
||||
def pr_proto_veth(self, pipe=''):
|
||||
row = self._pr_proto_common("veth", True, pipe);
|
||||
|
||||
parts = []
|
||||
if self.phys_address:
|
||||
parts.append(self.phys_address)
|
||||
if self.lower_if:
|
||||
row = f"{'':<{Pad.iface}}"
|
||||
row += f"{'veth':<{Pad.proto}}"
|
||||
row += f"{'':<{Pad.state}}"
|
||||
row += f"peer:{self.lower_if}"
|
||||
|
||||
print(row)
|
||||
|
||||
def pr_proto_gretap(self, pipe=''):
|
||||
row = self._pr_proto_common("gretap", True, pipe);
|
||||
print(row)
|
||||
parts.append(f"peer: {self.lower_if}")
|
||||
print(self._pr_proto_common("veth", pipe, " ".join(parts)))
|
||||
|
||||
def pr_proto_gre(self, pipe=''):
|
||||
row = self._pr_proto_common("gre", False, pipe);
|
||||
print(row)
|
||||
data = ""
|
||||
if self.gre and (remote := self.gre.get('remote')):
|
||||
data = f"remote: {remote}"
|
||||
print(self._pr_proto_common("gre", pipe, data))
|
||||
|
||||
def pr_proto_vxlan(self, pipe=''):
|
||||
row = self._pr_proto_common("vxlan", True, pipe);
|
||||
print(row)
|
||||
parts = []
|
||||
if self.vxlan:
|
||||
if (vni := self.vxlan.get('vni')) is not None:
|
||||
parts.append(f"vni: {vni}")
|
||||
if remote := self.vxlan.get('remote'):
|
||||
parts.append(f"remote: {remote}")
|
||||
print(self._pr_proto_common("vxlan", pipe, " ".join(parts)))
|
||||
|
||||
def pr_proto_wireguard(self, pipe=''):
|
||||
row = self._pr_proto_common("wireguard", False, pipe)
|
||||
|
||||
data = ""
|
||||
if self.wireguard:
|
||||
peer_status = self.wireguard.get('peer-status', {})
|
||||
peers = peer_status.get('peer', [])
|
||||
total_peers = len(peers)
|
||||
up_peers = sum(1 for p in peers if p.get('connection-status') == 'up')
|
||||
|
||||
if total_peers > 0:
|
||||
row += f"{total_peers} peer"
|
||||
if total_peers != 1:
|
||||
row += "s"
|
||||
row += f" ({up_peers} up)"
|
||||
|
||||
print(row)
|
||||
plural = "s" if total_peers != 1 else ""
|
||||
data = f"{total_peers} peer{plural} ({up_peers} up)"
|
||||
print(self._pr_proto_common("wireguard", pipe, data))
|
||||
|
||||
def pr_proto_loopack(self, pipe=''):
|
||||
row = self._pr_proto_common("loopback", False, pipe);
|
||||
print(row)
|
||||
print(self._pr_proto_common("loopback", pipe))
|
||||
|
||||
def pr_wifi_ssids(self):
|
||||
width = 70
|
||||
@@ -1309,42 +1384,19 @@ class Iface:
|
||||
|
||||
|
||||
def pr_proto_wifi(self, pipe=''):
|
||||
row = self._pr_proto_common("ethernet", True, pipe);
|
||||
print(row)
|
||||
ssid = None
|
||||
signal = None
|
||||
mode = None
|
||||
|
||||
if self.wifi:
|
||||
# Detect mode: AP has "stations", Station has "signal-strength" or "scan-results"
|
||||
ap=self.wifi.get("access-point", {})
|
||||
if ap:
|
||||
ssid = ap.get("ssid", "------")
|
||||
mode = "AP"
|
||||
stations_data = ap.get("stations", {})
|
||||
stations = stations_data.get("station", [])
|
||||
station_count = len(stations)
|
||||
data_str = f"{mode}, ssid: {ssid}, stations: {station_count}"
|
||||
else:
|
||||
station=self.wifi.get("station", {})
|
||||
ssid = station.get("ssid", "------")
|
||||
signal = station.get("signal-strength")
|
||||
mode = "Station"
|
||||
if signal is not None:
|
||||
signal_str = signal_to_status(signal)
|
||||
data_str = f"{mode}, ssid: {ssid}, signal: {signal_str}"
|
||||
else:
|
||||
data_str = f"{mode}, ssid: {ssid}"
|
||||
if self.wifi and (ap := self.wifi.get("access-point", {})):
|
||||
ssid = ap.get("ssid", "------")
|
||||
stations = ap.get("stations", {}).get("station", [])
|
||||
data_str = f"access-point ssid: {ssid} stations: {len(stations)}"
|
||||
elif self.wifi and (station := self.wifi.get("station", {})):
|
||||
ssid = station.get("ssid", "------")
|
||||
data_str = f"station ssid: {ssid}"
|
||||
if (signal := station.get("signal-strength")) is not None:
|
||||
data_str += f" signal: {signal_to_status(signal)}"
|
||||
else:
|
||||
data_str = "ssid: ------"
|
||||
|
||||
row = f"{'':<{Pad.flags}}"
|
||||
row += f"{pipe:<{Pad.iface}}"
|
||||
row = f"{'':<{Pad.flags}}"
|
||||
row += f"{pipe:<{Pad.iface}}"
|
||||
row += f"{'wifi':<{Pad.proto}}"
|
||||
row += f"{'':<{Pad.state}}{data_str}"
|
||||
print(row)
|
||||
print(self._pr_proto_common("wifi", pipe, data_str))
|
||||
|
||||
def pr_proto_br(self, br_vlans):
|
||||
data_str = ""
|
||||
@@ -1357,23 +1409,18 @@ class Iface:
|
||||
else:
|
||||
row += Decore.red(f"{self.oper().upper():<{Pad.state}}")
|
||||
|
||||
vlans = []
|
||||
for vlan in br_vlans:
|
||||
if 'tagged' in vlan:
|
||||
for tagged in vlan['tagged']:
|
||||
if tagged == self.name:
|
||||
if data_str:
|
||||
data_str += f",{vlan['vid']}t"
|
||||
else:
|
||||
data_str += f"vlan:{vlan['vid']}t"
|
||||
if 'untagged' in vlan:
|
||||
for untagged in vlan['untagged']:
|
||||
if untagged == self.name:
|
||||
if data_str:
|
||||
data_str += f",{vlan['vid']}u"
|
||||
else:
|
||||
data_str += f"vlan:{vlan['vid']}u"
|
||||
if 'tagged' in vlan and self.name in vlan['tagged']:
|
||||
vlans.append(f"{vlan['vid']}t")
|
||||
if 'untagged' in vlan and self.name in vlan['untagged']:
|
||||
vlans.append(f"{vlan['vid']}u")
|
||||
tokens = []
|
||||
if vlans:
|
||||
tokens.append(f"vlan: {','.join(vlans)}")
|
||||
if self.pvid:
|
||||
data_str += f" pvid:{self.pvid}"
|
||||
tokens.append(f"pvid: {self.pvid}")
|
||||
data_str = " ".join(tokens)
|
||||
|
||||
if data_str:
|
||||
row += f"{data_str:<{Pad.data}}"
|
||||
@@ -1390,11 +1437,11 @@ class Iface:
|
||||
lowers.append(_iface)
|
||||
|
||||
if lowers:
|
||||
self.pr_proto_eth(pipe='│')
|
||||
self.pr_proto_eth_subrow(pipe='│')
|
||||
self.pr_proto_ipv4(pipe='│')
|
||||
self.pr_proto_ipv6(pipe='│')
|
||||
else:
|
||||
self.pr_proto_eth(pipe=' ')
|
||||
self.pr_proto_eth_subrow()
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
@@ -1449,11 +1496,11 @@ class Iface:
|
||||
lowers.append(_iface)
|
||||
|
||||
if lowers:
|
||||
self.pr_proto_eth(pipe='│')
|
||||
self.pr_proto_eth_subrow(pipe='│')
|
||||
self.pr_proto_ipv4(pipe='│')
|
||||
self.pr_proto_ipv6(pipe='│')
|
||||
else:
|
||||
self.pr_proto_eth(pipe=' ')
|
||||
self.pr_proto_eth_subrow()
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
@@ -1476,13 +1523,15 @@ class Iface:
|
||||
|
||||
def pr_gretap(self):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_gretap()
|
||||
self.pr_proto_gre()
|
||||
self.pr_proto_eth_subrow()
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
def pr_vxlan(self):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_vxlan()
|
||||
self.pr_proto_eth_subrow()
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
@@ -1495,12 +1544,14 @@ class Iface:
|
||||
def pr_wifi(self):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_wifi()
|
||||
self.pr_proto_eth_subrow()
|
||||
self.pr_proto_ipv4()
|
||||
self.pr_proto_ipv6()
|
||||
|
||||
def pr_vlan(self, _ifaces):
|
||||
self.pr_name(pipe="")
|
||||
self.pr_proto_eth()
|
||||
data = f"vid: {self.vid}" if self.vid is not None else ""
|
||||
print(self._pr_proto_common("vlan", "", data))
|
||||
|
||||
if self.lower_if:
|
||||
self.pr_proto_ipv4(pipe='│')
|
||||
@@ -1515,7 +1566,7 @@ class Iface:
|
||||
print(f"Error, didn't find parent interface for vlan {self.name}")
|
||||
sys.exit(1)
|
||||
parent.pr_name(pipe='└ ')
|
||||
parent.pr_proto_eth()
|
||||
print()
|
||||
|
||||
def pr_container(self):
|
||||
# Add ⇅ flag for interfaces with IP forwarding enabled
|
||||
@@ -1532,92 +1583,85 @@ class Iface:
|
||||
|
||||
def pr_iface(self):
|
||||
if self.is_in_container():
|
||||
print(Decore.gray_bg(f"{'owned by container':<{20}}: {', ' . join(self.containers)}"))
|
||||
print(Decore.gray_bg(f"{'owned by container':<{19}}: {', ' . join(self.containers)}"))
|
||||
|
||||
print(f"{'name':<{20}}: {self.name}")
|
||||
print(f"{'type':<{20}}: {self.type.split(':')[1]}")
|
||||
print(f"{'index':<{20}}: {self.index}")
|
||||
print(f"{'name':<{19}}: {self.name}")
|
||||
print(f"{'type':<{19}}: {self.type.split(':')[1]}")
|
||||
print(f"{'index':<{19}}: {self.index}")
|
||||
|
||||
if self.mtu:
|
||||
print(f"{'mtu':<{20}}: {self.mtu}")
|
||||
print(f"{'mtu':<{19}}: {self.mtu}")
|
||||
if self.oper():
|
||||
print(f"{'operational status':<{20}}: {self.oper(detail=True)}")
|
||||
print(f"{'operational status':<{19}}: {self.oper(detail=True)}")
|
||||
|
||||
forwarding = "enabled" if self.name in Iface._routing_ifaces else "disabled"
|
||||
print(f"{'ip forwarding':<{20}}: {forwarding}")
|
||||
print(f"{'ip forwarding':<{19}}: {forwarding}")
|
||||
|
||||
if self.lower_if:
|
||||
print(f"{'lower-layer-if':<{20}}: {self.lower_if}")
|
||||
print(f"{'lower-layer-if':<{19}}: {self.lower_if}")
|
||||
|
||||
if label := self._phy_label():
|
||||
print(f"{'link mode':<{19}}: {label}")
|
||||
|
||||
if self.speed:
|
||||
mbps = int(self.speed) // 1_000_000
|
||||
print(f"{'speed':<{19}}: {mbps}")
|
||||
|
||||
if self.duplex:
|
||||
print(f"{'duplex':<{19}}: {self.duplex}")
|
||||
|
||||
if self.autoneg != 'unknown':
|
||||
val = "on" if self.autoneg else "off"
|
||||
print(f"{'auto-negotiation':<{20}}: {val}")
|
||||
print(f"{'auto-negotiation':<{19}}: {val}")
|
||||
|
||||
if self.duplex:
|
||||
print(f"{'duplex':<{20}}: {self.duplex}")
|
||||
if self.advertised:
|
||||
self._pr_label_list('advertised',
|
||||
[self._pmd_label(pmd) for pmd in self.advertised])
|
||||
|
||||
if self.speed:
|
||||
mbs = float(self.speed) * 1000
|
||||
print(f"{'speed':<{20}}: {int(mbs)}")
|
||||
if self.supported:
|
||||
self._pr_label_list('supported',
|
||||
[self._pmd_label(pmd) for pmd in self.supported])
|
||||
|
||||
if self.phys_address:
|
||||
print(f"{'physical address':<{20}}: {self.phys_address}")
|
||||
print(f"{'physical address':<{19}}: {self.phys_address}")
|
||||
|
||||
if self.lag_mode:
|
||||
print(f"{'lag mode':<{20}}: {self.lag_mode}")
|
||||
print(f"{'lag mode':<{19}}: {self.lag_mode}")
|
||||
if self.lag_mode == "lacp":
|
||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
||||
print(f"{'lacp mode':<{20}}: {self.lacp_mode}")
|
||||
print(f"{'lacp rate':<{20}}: {self.lacp_rate}")
|
||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
||||
print(f"{'lacp system priority':<{20}}: {self.lacp_sys_prio}")
|
||||
print(f"{'lacp actor key':<{20}}: {self.lacp_actor_key}")
|
||||
print(f"{'lacp partner key':<{20}}: {self.lacp_partner_key}")
|
||||
print(f"{'lacp partner mac':<{20}}: {self.lacp_partner_mac}")
|
||||
print(f"{'lag hash':<{19}}: {self.lag_hash}")
|
||||
print(f"{'lacp mode':<{19}}: {self.lacp_mode}")
|
||||
print(f"{'lacp rate':<{19}}: {self.lacp_rate}")
|
||||
print(f"{'lacp aggregate id':<{19}}: {self.lacp_id}")
|
||||
print(f"{'lacp sys priority':<{19}}: {self.lacp_sys_prio}")
|
||||
print(f"{'lacp actor key':<{19}}: {self.lacp_actor_key}")
|
||||
print(f"{'lacp partner key':<{19}}: {self.lacp_partner_key}")
|
||||
print(f"{'lacp partner mac':<{19}}: {self.lacp_partner_mac}")
|
||||
else:
|
||||
print(f"{'lag type':<{20}}: {self.lag_type}")
|
||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
||||
print(f"{'link debounce up':<{20}}: {self.link_updelay} msec")
|
||||
print(f"{'link debounce down':<{20}}: {self.link_downdelay} msec")
|
||||
print(f"{'lag type':<{19}}: {self.lag_type}")
|
||||
print(f"{'lag hash':<{19}}: {self.lag_hash}")
|
||||
print(f"{'link debounce up':<{19}}: {self.link_updelay} msec")
|
||||
print(f"{'link debounce down':<{19}}: {self.link_downdelay} msec")
|
||||
|
||||
if self.lag:
|
||||
print(f"{'lag member':<{20}}: {self.lag}")
|
||||
print(f"{'lag member state':<{20}}: {self.lag_state}")
|
||||
print(f"{'lag member':<{19}}: {self.lag}")
|
||||
print(f"{'lag member state':<{19}}: {self.lag_state}")
|
||||
if self.lacp_state:
|
||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
||||
print(f"{'lacp actor state':<{20}}: {', '.join(self.lacp_state)}")
|
||||
print(f"{'lacp partner state':<{20}}: {', '.join(self.lacp_pstate)}")
|
||||
print(f"{'link failure count':<{20}}: {self.link_failures}")
|
||||
print(f"{'lacp aggregate id':<{19}}: {self.lacp_id}")
|
||||
print(f"{'lacp actor state':<{19}}: {', '.join(self.lacp_state)}")
|
||||
print(f"{'lacp partner state':<{19}}: {', '.join(self.lacp_pstate)}")
|
||||
print(f"{'link failure count':<{19}}: {self.link_failures}")
|
||||
|
||||
if self.ipv4_addr:
|
||||
first = True
|
||||
for addr in self.ipv4_addr:
|
||||
def _addr_lines(addrs):
|
||||
for addr in addrs:
|
||||
origin = f"({addr['origin']})" if addr.get('origin') else ""
|
||||
key = 'ipv4 addresses' if first else ''
|
||||
colon = ':' if first else ' '
|
||||
row = f"{key:<{20}}{colon} "
|
||||
row += f"{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||
print(row)
|
||||
first = False
|
||||
else:
|
||||
print(f"{'ipv4 addresses':<{20}}:")
|
||||
yield f"{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||
|
||||
if self.ipv6_addr:
|
||||
first = True
|
||||
for addr in self.ipv6_addr:
|
||||
origin = f"({addr['origin']})" if addr.get('origin') else ""
|
||||
key = 'ipv6 addresses' if first else ''
|
||||
colon = ':' if first else ' '
|
||||
row = f"{key:<{20}}{colon} "
|
||||
row += f"{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||
print(row)
|
||||
first = False
|
||||
else:
|
||||
print(f"{'ipv6 addresses':<{20}}:")
|
||||
self._pr_label_list('ipv4 addresses', list(_addr_lines(self.ipv4_addr)))
|
||||
self._pr_label_list('ipv6 addresses', list(_addr_lines(self.ipv6_addr)))
|
||||
|
||||
if self.in_octets and self.out_octets:
|
||||
print(f"{'in-octets':<{20}}: {self.in_octets}")
|
||||
print(f"{'out-octets':<{20}}: {self.out_octets}")
|
||||
print(f"{'in-octets':<{19}}: {self.in_octets}")
|
||||
print(f"{'out-octets':<{19}}: {self.out_octets}")
|
||||
|
||||
if self.wifi:
|
||||
# Detect mode: AP has "stations", Station has "signal-strength" or "scan-results"
|
||||
@@ -1627,43 +1671,43 @@ class Iface:
|
||||
ssid = ap.get('ssid', "----")
|
||||
stations_data = ap.get("stations", {})
|
||||
stations = stations_data.get("station", [])
|
||||
print(f"{'mode':<{20}}: {mode}")
|
||||
print(f"{'ssid':<{20}}: {ssid}")
|
||||
print(f"{'connected stations':<{20}}: {len(stations)}")
|
||||
print(f"{'mode':<{19}}: {mode}")
|
||||
print(f"{'ssid':<{19}}: {ssid}")
|
||||
print(f"{'connected stations':<{19}}: {len(stations)}")
|
||||
self.pr_wifi_stations()
|
||||
else:
|
||||
mode = "station"
|
||||
station = self.wifi.get('station', {})
|
||||
signal = station.get('signal-strength')
|
||||
ssid = station.get('ssid', "----")
|
||||
print(f"{'mode':<{20}}: {mode}")
|
||||
print(f"{'ssid':<{20}}: {ssid}")
|
||||
print(f"{'mode':<{19}}: {mode}")
|
||||
print(f"{'ssid':<{19}}: {ssid}")
|
||||
if signal is not None:
|
||||
signal_status = signal_to_status(signal)
|
||||
print(f"{'signal':<{20}}: {signal} dBm ({signal_status})")
|
||||
print(f"{'signal':<{19}}: {signal} dBm ({signal_status})")
|
||||
rx_speed = station.get('rx-speed')
|
||||
tx_speed = station.get('tx-speed')
|
||||
if rx_speed is not None:
|
||||
print(f"{'rx bitrate':<{20}}: {rx_speed / 10:.1f} Mbps")
|
||||
print(f"{'rx bitrate':<{19}}: {rx_speed / 10:.1f} Mbps")
|
||||
if tx_speed is not None:
|
||||
print(f"{'tx bitrate':<{20}}: {tx_speed / 10:.1f} Mbps")
|
||||
print(f"{'tx bitrate':<{19}}: {tx_speed / 10:.1f} Mbps")
|
||||
if "scan-results" in station:
|
||||
self.pr_wifi_ssids()
|
||||
|
||||
if self.gre:
|
||||
print(f"{'local address':<{20}}: {self.gre['local']}")
|
||||
print(f"{'remote address':<{20}}: {self.gre['remote']}")
|
||||
print(f"{'local address':<{19}}: {self.gre['local']}")
|
||||
print(f"{'remote address':<{19}}: {self.gre['remote']}")
|
||||
|
||||
if self.vxlan:
|
||||
print(f"{'local address':<{20}}: {self.vxlan['local']}")
|
||||
print(f"{'remote address':<{20}}: {self.vxlan['remote']}")
|
||||
print(f"{'VxLAN id':<{20}}: {self.vxlan['vni']}")
|
||||
print(f"{'local address':<{19}}: {self.vxlan['local']}")
|
||||
print(f"{'remote address':<{19}}: {self.vxlan['remote']}")
|
||||
print(f"{'VxLAN id':<{19}}: {self.vxlan['vni']}")
|
||||
|
||||
if self.wireguard:
|
||||
peer_status = self.wireguard.get('peer-status', {})
|
||||
peers = peer_status.get('peer', [])
|
||||
if peers:
|
||||
print(f"{'peers':<{20}}: {len(peers)}")
|
||||
print(f"{'peers':<{19}}: {len(peers)}")
|
||||
for idx, peer in enumerate(peers, 1):
|
||||
print(f"\n Peer {idx}:")
|
||||
|
||||
@@ -1700,10 +1744,10 @@ class Iface:
|
||||
frame = get_json_data([], self.data,'ieee802-ethernet-interface:ethernet',
|
||||
'statistics', 'frame')
|
||||
if frame:
|
||||
print("")
|
||||
Decore.title("Ethernet Statistics")
|
||||
for key, val in frame.items():
|
||||
key = remove_yang_prefix(key)
|
||||
print(f"eth-{key:<{25}}: {val}")
|
||||
print(f"{key:<{25}}: {val}")
|
||||
|
||||
def pr_mdb(self, bridge):
|
||||
for group in self.br_mdb.get("multicast-filter", {}):
|
||||
@@ -1804,7 +1848,10 @@ def brport_sort(iface):
|
||||
|
||||
def print_interface(iface):
|
||||
iface.pr_name()
|
||||
iface.pr_proto_eth()
|
||||
if iface._pr_phy_row():
|
||||
iface.pr_proto_eth_subrow()
|
||||
else:
|
||||
iface.pr_proto_eth()
|
||||
iface.pr_proto_ipv4()
|
||||
iface.pr_proto_ipv6()
|
||||
|
||||
|
||||
@@ -68,31 +68,172 @@ def statistics(ifname):
|
||||
|
||||
return statistics
|
||||
|
||||
# ethtool reports SPEED_UNKNOWN as UINT32_MAX when no link / no medium.
|
||||
_ETHTOOL_SPEED_UNKNOWN = (1 << 32) - 1
|
||||
|
||||
# Map (ethtool port string, speed in Mb/s, duplex) -> (phy-type, pmd-type)
|
||||
# identity suffixes per IEEE Std 802.3.2-2025 (ieee802-ethernet-phy-type).
|
||||
#
|
||||
# phy-type names the PHY family / line coding (e.g. 1000BASE-X is the 8B/10B
|
||||
# family covering LX/SX/ZX/CX); pmd-type names the specific physical medium
|
||||
# (1000BASE-LX vs 1000BASE-SX). For media where ethtool's (port, speed,
|
||||
# duplex) tuple uniquely identifies the variant — copper, DAC, copper-T —
|
||||
# both leaves are populated with the right identities (often the same name).
|
||||
# For generic fiber where the same tuple can be SR/LR/ER/etc., we only
|
||||
# populate phy-type (family) and leave pmd-type as None — emitting a guess
|
||||
# would be misleading. Refining the PMD on fiber needs the SFP EEPROM
|
||||
# (ethtool -m), deferred.
|
||||
_LINK_MODES = {
|
||||
# (port, speed Mb/s, duplex): (phy-type, pmd-type or None)
|
||||
("Twisted Pair", 10, "full"): ("10BASE-T", "10BASE-T"),
|
||||
("Twisted Pair", 10, "half"): ("10BASE-T", "10BASE-T"),
|
||||
("Twisted Pair", 100, "full"): ("100BASE-X", "100BASE-TX"),
|
||||
("Twisted Pair", 100, "half"): ("100BASE-X", "100BASE-TX"),
|
||||
("Twisted Pair", 1000, "full"): ("1000BASE-T", "1000BASE-T"),
|
||||
("Twisted Pair", 1000, "half"): ("1000BASE-T", "1000BASE-T"),
|
||||
("Twisted Pair", 2500, "full"): ("2.5GBASE-T", "2.5GBASE-T"),
|
||||
("Twisted Pair", 5000, "full"): ("5GBASE-T", "5GBASE-T"),
|
||||
("Twisted Pair", 10000, "full"): ("10GBASE-T", "10GBASE-T"),
|
||||
("Twisted Pair", 25000, "full"): ("25GBASE-T", "25GBASE-T"),
|
||||
("Twisted Pair", 40000, "full"): ("40GBASE-T", "40GBASE-T"),
|
||||
("MII", 10, "full"): ("10BASE-T", "10BASE-T"),
|
||||
("MII", 10, "half"): ("10BASE-T", "10BASE-T"),
|
||||
("MII", 100, "full"): ("100BASE-X", "100BASE-TX"),
|
||||
("MII", 100, "half"): ("100BASE-X", "100BASE-TX"),
|
||||
("FIBRE", 100, "full"): ("100BASE-X", None),
|
||||
("FIBRE", 1000, "full"): ("1000BASE-X", None),
|
||||
("FIBRE", 10000, "full"): ("10GBASE-R", None),
|
||||
("FIBRE", 25000, "full"): ("25GBASE-R", None),
|
||||
("FIBRE", 40000, "full"): ("40GBASE-R", None),
|
||||
("FIBRE", 100000, "full"): ("100GBASE-R", None),
|
||||
# SFP+ DAC has no IEEE-standardised pmd-type (10GBASE-CR is industry
|
||||
# shorthand, not a YANG identity); the phy-type-10GBASE-R family is as
|
||||
# specific as we honestly get.
|
||||
("Direct Attach Copper", 10000, "full"): ("10GBASE-R", None),
|
||||
("Direct Attach Copper", 25000, "full"): ("25GBASE-R", "25GBASE-CR"),
|
||||
("Direct Attach Copper", 40000, "full"): ("40GBASE-R", "40GBASE-CR4"),
|
||||
("Direct Attach Copper", 100000, "full"): ("100GBASE-R", "100GBASE-CR4"),
|
||||
}
|
||||
|
||||
|
||||
# Map ethtool link-mode string (e.g. '10000baseLR') to IEEE pmd-type identity
|
||||
# suffix. The kernel reports a separate entry per (mode, duplex) — we strip
|
||||
# the trailing '/Full' or '/Half' before lookup, then dedupe in the caller.
|
||||
# Where the kernel collapses several IEEE variants into one family bit
|
||||
# (e.g. 1000baseX covers LX/SX/ZX/CX) we pick the most common long-reach
|
||||
# variant as our representative — same convention as _LINK_MODES.
|
||||
_ETHTOOL_TO_PMD = {
|
||||
"10baseT": "10BASE-T",
|
||||
"10baseT1L": "10BASE-T1L",
|
||||
"100baseT": "100BASE-TX", # kernel uses 100baseT for 100BASE-TX
|
||||
"100baseT1": "100BASE-T1",
|
||||
"100baseFX": "100BASE-FX",
|
||||
"1000baseT": "1000BASE-T",
|
||||
"1000baseT1": "1000BASE-T1",
|
||||
"1000baseX": "1000BASE-LX", # 8B/10B family — could be SX/LX/ZX
|
||||
"1000baseKX": "1000BASE-KX",
|
||||
"2500baseT": "2.5GBASE-T",
|
||||
"2500baseX": "2.5GBASE-X",
|
||||
"5000baseT": "5GBASE-T",
|
||||
"10000baseT": "10GBASE-T",
|
||||
"10000baseSR": "10GBASE-SR",
|
||||
"10000baseLR": "10GBASE-LR",
|
||||
"10000baseLRM": "10GBASE-LRM",
|
||||
"10000baseER": "10GBASE-ER",
|
||||
"10000baseKR": "10GBASE-KR",
|
||||
"10000baseKX4": "10GBASE-KX4",
|
||||
"25000baseCR": "25GBASE-CR",
|
||||
"25000baseSR": "25GBASE-SR",
|
||||
"25000baseKR": "25GBASE-KR",
|
||||
"40000baseCR4": "40GBASE-CR4",
|
||||
"40000baseSR4": "40GBASE-SR4",
|
||||
"40000baseLR4": "40GBASE-LR4",
|
||||
"40000baseKR4": "40GBASE-KR4",
|
||||
"100000baseCR4": "100GBASE-CR4",
|
||||
"100000baseSR4": "100GBASE-SR4",
|
||||
"100000baseLR4_ER4": "100GBASE-LR4",
|
||||
"100000baseKR4": "100GBASE-KR4",
|
||||
}
|
||||
|
||||
|
||||
def _ethtool_modes_to_pmd_identities(modes):
|
||||
"""Translate ethtool 'supported/advertised-link-modes' to PMD identities.
|
||||
|
||||
'modes' is the list of strings ethtool emits, e.g. ['1000baseT/Full',
|
||||
'10000baseLR/Full']. Returns a deduped, order-preserving list of
|
||||
fully-qualified ieee802-ethernet-phy-type:pmd-type-* identities, skipping
|
||||
entries we don't have a mapping for (kernel-only "filler" bits like
|
||||
Autoneg, TP, FIBRE, Pause, Asym_Pause that share the link-modes bitset
|
||||
namespace but aren't link modes).
|
||||
"""
|
||||
seen = set()
|
||||
out = []
|
||||
for entry in modes or []:
|
||||
# Drop '/Full' or '/Half' suffix
|
||||
base = entry.split("/", 1)[0]
|
||||
pmd = _ETHTOOL_TO_PMD.get(base)
|
||||
if pmd is None or pmd in seen:
|
||||
continue
|
||||
seen.add(pmd)
|
||||
out.append(f"ieee802-ethernet-phy-type:pmd-type-{pmd}")
|
||||
return out
|
||||
|
||||
|
||||
def link(ifname):
|
||||
"""Parse speed/duplex/autoneg from ethtool output"""
|
||||
"""Read link properties from ethtool.
|
||||
|
||||
Returns (eth_container_dict, interface_speed_bps_or_None); the
|
||||
interface speed is lifted onto ietf-interfaces:speed by the caller.
|
||||
"""
|
||||
if data := HOST.run_json(["ethtool", "--json", ifname], {}):
|
||||
data = data[0]
|
||||
else:
|
||||
return None
|
||||
return {}, None
|
||||
|
||||
eth = {}
|
||||
eth["auto-negotation"] = { "enable": data.get("auto-negotation", False) }
|
||||
eth = {"auto-negotiation": {"enable": data.get("auto-negotiation", False)}}
|
||||
|
||||
if data.get("speed"):
|
||||
gbps = round((int(data["speed"]) / 1000), 3)
|
||||
eth["speed"] = str(gbps)
|
||||
if data.get("duplex"):
|
||||
eth["duplex"] = data["duplex"].lower()
|
||||
return eth
|
||||
duplex = (data.get("duplex") or "").lower()
|
||||
if duplex in ("full", "half"):
|
||||
eth["duplex"] = duplex
|
||||
|
||||
# Expose what the kernel currently considers supported as a config-false
|
||||
# leaf-list — varies on SFP cages with the inserted module, so it's a
|
||||
# useful diagnosis facet on its own.
|
||||
supported = _ethtool_modes_to_pmd_identities(data.get("supported-link-modes"))
|
||||
if supported:
|
||||
eth["infix-ethernet-interface:supported-pmd-types"] = supported
|
||||
|
||||
# Suppress when advertised == supported — that's the default
|
||||
# "advertise everything" state with no diagnostic value.
|
||||
advertised = _ethtool_modes_to_pmd_identities(data.get("advertised-link-modes"))
|
||||
if advertised and set(advertised) != set(supported):
|
||||
eth["auto-negotiation"]["infix-ethernet-interface:advertised-pmd-types"] = advertised
|
||||
|
||||
speed_bps = None
|
||||
speed_mbps = data.get("speed")
|
||||
if isinstance(speed_mbps, int) and 0 < speed_mbps < _ETHTOOL_SPEED_UNKNOWN:
|
||||
speed_bps = speed_mbps * 1_000_000
|
||||
port = data.get("port") or ""
|
||||
if mapping := _LINK_MODES.get((port, speed_mbps, duplex)):
|
||||
phy, pmd = mapping
|
||||
eth["phy-type"] = f"ieee802-ethernet-phy-type:phy-type-{phy}"
|
||||
if pmd is not None:
|
||||
eth["pmd-type"] = f"ieee802-ethernet-phy-type:pmd-type-{pmd}"
|
||||
# Refine pmd-type from supported list when the kernel reports
|
||||
# exactly one mode (typically an SFP/SFP+ with a specific optic
|
||||
# plugged in) — strictly more accurate than the (port, speed,
|
||||
# duplex) lookup since the SFP nailed it down for us.
|
||||
if len(supported) == 1:
|
||||
eth["pmd-type"] = supported[0]
|
||||
|
||||
return eth, speed_bps
|
||||
|
||||
|
||||
def ethernet(iplink):
|
||||
eth = link(iplink["ifname"])
|
||||
|
||||
if eth is None:
|
||||
eth = {}
|
||||
"""Return (ethernet container, interface speed in bits/s or None)."""
|
||||
eth, speed_bps = link(iplink["ifname"])
|
||||
|
||||
if stats := statistics(iplink["ifname"]):
|
||||
eth["statistics"] = stats
|
||||
|
||||
return eth
|
||||
return eth, speed_bps
|
||||
|
||||
@@ -159,8 +159,11 @@ def interface(iplink, ipaddr, systemjson=None):
|
||||
if lg := lag.lag(iplink):
|
||||
interface["infix-interfaces:lag"] = lg
|
||||
case "infix-if-type:ethernet":
|
||||
if eth := ethernet.ethernet(iplink):
|
||||
eth, speed_bps = ethernet.ethernet(iplink)
|
||||
if eth:
|
||||
interface["ieee802-ethernet-interface:ethernet"] = eth
|
||||
if speed_bps:
|
||||
interface["speed"] = str(speed_bps)
|
||||
case "infix-if-type:vxlan":
|
||||
if vxlan := tun.vxlan(iplink):
|
||||
interface["infix-interfaces:vxlan"] = vxlan
|
||||
|
||||
@@ -4,11 +4,24 @@ ifdef::topdoc[:imagesdir: {topdoc}../../test/case/interfaces/speed_duplex_copper
|
||||
|
||||
==== Description
|
||||
|
||||
Verify that the interface operates at the expected speed/duplex in two scenarios:
|
||||
Verify that the interface operates at the expected speed/duplex by
|
||||
restricting the set of PMD types auto-negotiation may advertise:
|
||||
|
||||
1. Fixed configuration – host and target are both manually set to a specific speed/duplex
|
||||
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
||||
to the highest common speed/duplex.
|
||||
1. Single-mode advertise — host and target both advertise exactly
|
||||
one PMD/duplex combination; the link comes up at that mode.
|
||||
2. Multi-mode advertise — host advertises a set, target advertises
|
||||
another set; the link comes up at the highest common.
|
||||
3. Auto-negotiation off — both peers forced to a fixed speed/duplex,
|
||||
the escape hatch for link partners that don't speak auto-negotiation.
|
||||
Disabling autoneg also disables Auto-MDIX, so the ends use opposite
|
||||
MDI/MDI-X pinouts (host mdix on, DUT mdi). The link bounces and can
|
||||
take a few seconds to settle, so the forced steps poll for it.
|
||||
|
||||
The legacy "auto-negotiation: off + fixed speed + fixed duplex"
|
||||
configuration was retired together with the obsoletion of eth:speed
|
||||
in IEEE Std 802.3.2-2025; the standards-correct way to pin a link to
|
||||
a specific mode is to advertise only that mode. See the augment in
|
||||
infix-ethernet-interface.yang.
|
||||
|
||||
==== Topology
|
||||
|
||||
@@ -18,16 +31,18 @@ image::topology.svg[Interface Speed Duplex (Copper) topology, align=center, scal
|
||||
|
||||
. Set up topology and attach to target DUT
|
||||
. Enable target interface
|
||||
. Verify fixed 10/full
|
||||
. Verify fixed 10/half
|
||||
. Verify fixed 100/full
|
||||
. Verify fixed 100/half
|
||||
. Switch to auto-negotiation mode for target and host
|
||||
. Verify auto-negotiation to 10/Full only
|
||||
. Verify auto-negotiation to 10/Half only
|
||||
. Verify auto-negotiation to 100/Full only
|
||||
. Verify auto-negotiation to 100/Half only
|
||||
. Verify auto-negotiation to 10/half + 10/full + 100/half
|
||||
. Verify auto-negotiation to 10/half + 10/full + 100/half + 100/full + 1000/full
|
||||
. Advertise 10/full only on both peers
|
||||
. Advertise 10/half only on both peers
|
||||
. Advertise 100/full only on both peers
|
||||
. Advertise 100/half only on both peers
|
||||
. Switch target back to advertising all supported modes
|
||||
. Host advertises 10/full only
|
||||
. Host advertises 10/half only
|
||||
. Host advertises 100/full only
|
||||
. Host advertises 100/half only
|
||||
. Host advertises 10/half + 10/full + 100/half
|
||||
. Host advertises every mode up to 1G
|
||||
. Both sides forced to 100/full, autoneg off
|
||||
. Both sides forced to 10/full, autoneg off
|
||||
|
||||
|
||||
|
||||
@@ -2,98 +2,233 @@
|
||||
"""
|
||||
Interface Speed Duplex (Copper)
|
||||
|
||||
Verify that the interface operates at the expected speed/duplex in two scenarios:
|
||||
Verify that the interface operates at the expected speed/duplex by
|
||||
restricting the set of PMD types auto-negotiation may advertise:
|
||||
|
||||
1. Fixed configuration – host and target are both manually set to a specific speed/duplex
|
||||
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
||||
to the highest common speed/duplex.
|
||||
1. Single-mode advertise — host and target both advertise exactly
|
||||
one PMD/duplex combination; the link comes up at that mode.
|
||||
2. Multi-mode advertise — host advertises a set, target advertises
|
||||
another set; the link comes up at the highest common.
|
||||
3. Auto-negotiation off — both peers forced to a fixed speed/duplex,
|
||||
the escape hatch for link partners that don't speak auto-negotiation.
|
||||
Disabling autoneg also disables Auto-MDIX, so the ends use opposite
|
||||
MDI/MDI-X pinouts (host mdix on, DUT mdi). The link bounces and can
|
||||
take a few seconds to settle, so the forced steps poll for it.
|
||||
|
||||
The legacy "auto-negotiation: off + fixed speed + fixed duplex"
|
||||
configuration was retired together with the obsoletion of eth:speed
|
||||
in IEEE Std 802.3.2-2025; the standards-correct way to pin a link to
|
||||
a specific mode is to advertise only that mode. See the augment in
|
||||
infix-ethernet-interface.yang.
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.iface as iface
|
||||
import subprocess
|
||||
from infamy.util import until
|
||||
|
||||
ADVERTISE_MODES = {
|
||||
# Values from ethtool's ETHTOOL_LINK_MODE bit positions
|
||||
# See: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ethtool.h
|
||||
"10half": 0x0001,
|
||||
"10full": 0x0002,
|
||||
"100half": 0x0004,
|
||||
"100full": 0x0008,
|
||||
"1000full": 0x0020
|
||||
"10half": 0x0001,
|
||||
"10full": 0x0002,
|
||||
"100half": 0x0004,
|
||||
"100full": 0x0008,
|
||||
"1000full": 0x0020,
|
||||
}
|
||||
|
||||
# Mapping from (ethtool advertise key) → (IEEE PMD identity, duplex enum).
|
||||
# Mirrors the migration table in src/confd/share/migrate/1.9/.
|
||||
TARGET_MODES = {
|
||||
"10half": ("ieee802-ethernet-phy-type:pmd-type-10BASE-T", "half", 10),
|
||||
"10full": ("ieee802-ethernet-phy-type:pmd-type-10BASE-T", "full", 10),
|
||||
"100half": ("ieee802-ethernet-phy-type:pmd-type-100BASE-TX", "half", 100),
|
||||
"100full": ("ieee802-ethernet-phy-type:pmd-type-100BASE-TX", "full", 100),
|
||||
"1000full": ("ieee802-ethernet-phy-type:pmd-type-1000BASE-T", "full", 1000),
|
||||
}
|
||||
|
||||
|
||||
def advertise_host_modes(interface, modes):
|
||||
mask = 0
|
||||
for mode in modes:
|
||||
mask |= ADVERTISE_MODES[mode]
|
||||
try:
|
||||
subprocess.run([
|
||||
"ethtool", "-s", interface,
|
||||
"advertise", hex(mask)
|
||||
], check=True)
|
||||
subprocess.run(["ethtool", "-s", interface, "advertise", hex(mask)],
|
||||
check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Failed to advertise modes via ethtool: {e}")
|
||||
|
||||
|
||||
def enable_host_autoneg_full(interface):
|
||||
"""Restore the host NIC to autoneg-on with Auto-MDIX.
|
||||
|
||||
'autoneg on' re-enables negotiation and advertises all supported modes;
|
||||
each test step sets the host advertise explicitly, so no extra mask
|
||||
handling is needed here. Separately clear any forced MDI/MDI-X pinout
|
||||
left by force_host_fixed — best-effort, since not every NIC exposes mdix.
|
||||
"""
|
||||
try:
|
||||
subprocess.run(["ethtool", "-s", interface, "autoneg", "on"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Failed to restore host autoneg: {e}")
|
||||
subprocess.run(["ethtool", "-s", interface, "mdix", "auto"], check=False)
|
||||
|
||||
|
||||
def force_host_fixed(interface, speed_mbps, duplex, mdix="on"):
|
||||
"""Pin host to a fixed speed/duplex with auto-negotiation OFF.
|
||||
|
||||
Auto-MDIX is disabled in forced mode, so host and DUT take opposite
|
||||
pinouts; default mdix=on (MDI-X) to pair with the DUT's mdi.
|
||||
"""
|
||||
try:
|
||||
subprocess.run(["ethtool", "-s", interface, "autoneg", "off",
|
||||
"speed", str(speed_mbps), "duplex", duplex,
|
||||
"mdix", mdix],
|
||||
check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Failed to force host fixed mode: {e}")
|
||||
|
||||
|
||||
def get_target_speed_duplex(target, interface):
|
||||
data = target.get_data(f"/ietf-interfaces:interfaces/interface[name='{interface}']") \
|
||||
data = target.get_data(iface.get_xpath(interface)) \
|
||||
["interfaces"]["interface"][interface]
|
||||
eth = data.get("ethernet", {})
|
||||
|
||||
return eth.get("speed"), eth.get("duplex")
|
||||
# Operational speed under ietf-interfaces:speed (bits/s, RFC 8343).
|
||||
speed_bps = data.get("speed")
|
||||
return speed_bps, eth.get("duplex")
|
||||
|
||||
|
||||
def set_target_advertise(target, interface, mode_keys):
|
||||
"""Configure the target interface to advertise the given set of PMDs.
|
||||
|
||||
mode_keys is a list of host-side mode names (e.g. ['10full', '100full']).
|
||||
Translates to the corresponding (pmd-type, duplex) for the target.
|
||||
When all entries share the same duplex, that duplex is also set on the
|
||||
interface as an additional restriction.
|
||||
"""
|
||||
pmds = []
|
||||
duplexes = set()
|
||||
for key in mode_keys:
|
||||
pmd, duplex, _ = TARGET_MODES[key]
|
||||
if pmd not in pmds:
|
||||
pmds.append(pmd)
|
||||
duplexes.add(duplex)
|
||||
|
||||
eth = {
|
||||
"auto-negotiation": {
|
||||
"infix-ethernet-interface:advertised-pmd-types": pmds,
|
||||
},
|
||||
}
|
||||
if len(duplexes) == 1:
|
||||
eth["duplex"] = duplexes.pop()
|
||||
|
||||
def set_target_speed_duplex(target, interface, speed, duplex):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": interface,
|
||||
"ethernet": {
|
||||
"auto-negotiation": {
|
||||
"enable": False
|
||||
},
|
||||
"speed": speed / 1000,
|
||||
"duplex": duplex
|
||||
}
|
||||
}]
|
||||
}
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{"name": interface, "ethernet": eth}]
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
def set_host_speed_duplex(interface, speed, duplex):
|
||||
|
||||
def force_target_fixed(target, interface, mode_key, mdi_x=False):
|
||||
"""Configure the target with auto-negotiation disabled, pinned to one PMD.
|
||||
|
||||
Exercises confd's enable=false escape hatch: the apply path emits
|
||||
'ethtool --change <if> autoneg off speed N duplex D mdix ...' from the
|
||||
single advertised-pmd-types entry, the duplex leaf, and the mdi-x leaf.
|
||||
Default mdi_x=False (MDI) pairs with the host's forced MDI-X.
|
||||
"""
|
||||
pmd, duplex, _ = TARGET_MODES[mode_key]
|
||||
# enable=false requires exactly one advertised-pmd-types entry, but
|
||||
# put_config_dicts (PATCH) merges leaf-lists, so successive forced
|
||||
# steps would accumulate entries. Reset the ethernet sub-config first
|
||||
# (tolerate absence on the first call).
|
||||
try:
|
||||
subprocess.run([
|
||||
"ethtool", "-s", interface,
|
||||
"speed", str(speed),
|
||||
"duplex", duplex,
|
||||
"autoneg", "off"
|
||||
], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Failed to set speed/duplex via ethtool: {e}")
|
||||
clear_target_advertise(target, interface)
|
||||
except Exception:
|
||||
pass
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": interface,
|
||||
"ethernet": {
|
||||
"auto-negotiation": {
|
||||
"enable": False,
|
||||
"infix-ethernet-interface:advertised-pmd-types": [pmd],
|
||||
},
|
||||
"duplex": duplex,
|
||||
"infix-ethernet-interface:mdi-x": mdi_x,
|
||||
},
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def verify_speed_duplex(target, ns, interface, exp_speed, exp_duplex):
|
||||
until(lambda: speed_duplex_present(target, interface))
|
||||
act_speed, act_duplex = get_target_speed_duplex(target, interface)
|
||||
if act_speed is None or act_duplex is None:
|
||||
print(f"Could not fetch speed or duplex from target for interface {interface}")
|
||||
|
||||
def clear_target_advertise(target, interface):
|
||||
"""Drop the entire ethernet sub-config on the target.
|
||||
|
||||
Targets the parent container rather than the individual leaves because
|
||||
RESTCONF DELETE on a leaf-list URI without a '=value' key is a silent
|
||||
no-op (RFC 8040 §3.5.3.2: leaf-list instance URIs must carry the value
|
||||
as the key — rousette/libyang materialise an empty leaf-list node that
|
||||
matches no entry). Deleting the container removes all descendants in
|
||||
one go, which is exactly what this test needs.
|
||||
"""
|
||||
target.delete_xpath(iface.get_xpath(interface, "ieee802-ethernet-interface:ethernet"))
|
||||
|
||||
|
||||
def verify_speed_duplex(target, ns, interface, exp_mbps, exp_duplex):
|
||||
until(lambda: _speed_duplex_present(target, interface))
|
||||
speed_bps, duplex = get_target_speed_duplex(target, interface)
|
||||
if speed_bps is None or duplex is None:
|
||||
print(f"Could not fetch speed/duplex from target for interface {interface}")
|
||||
test.fail()
|
||||
|
||||
exp_speed_gbps = exp_speed / 1000
|
||||
if float(act_speed) != exp_speed_gbps:
|
||||
print(f"act_speed: {act_speed}, exp_speed: {exp_speed_gbps}")
|
||||
act_mbps = int(speed_bps) // 1_000_000
|
||||
if act_mbps != exp_mbps:
|
||||
print(f"act_mbps: {act_mbps}, exp_mbps: {exp_mbps}")
|
||||
test.fail()
|
||||
|
||||
if act_duplex.lower() != exp_duplex.lower():
|
||||
print(f"act_duplex: {act_duplex}, exp_duplex: {exp_duplex}")
|
||||
if duplex.lower() != exp_duplex.lower():
|
||||
print(f"act_duplex: {duplex}, exp_duplex: {exp_duplex}")
|
||||
test.fail()
|
||||
|
||||
ns.must_reach("10.0.0.2")
|
||||
print(f"Verified: {interface} is operating at {act_mbps} Mbps, {duplex} duplex")
|
||||
|
||||
print(f"Verified: {interface} is operating at {act_speed} Gbps, {act_duplex} duplex")
|
||||
|
||||
def speed_duplex_present(target, interface):
|
||||
speed, duplex = get_target_speed_duplex(target, interface)
|
||||
return speed is not None and duplex is not None
|
||||
def _speed_duplex_present(target, interface):
|
||||
speed_bps, duplex = get_target_speed_duplex(target, interface)
|
||||
return speed_bps is not None and duplex is not None
|
||||
|
||||
|
||||
def verify_forced_speed_duplex(target, ns, interface, exp_mbps, exp_duplex):
|
||||
"""Verify a forced (autoneg off) link reaches exp speed/duplex.
|
||||
|
||||
Turning auto-negotiation off bounces the link; it can take a few
|
||||
seconds to settle, so poll the operational speed/duplex AND a ping
|
||||
together until both hold instead of checking once.
|
||||
"""
|
||||
def settled():
|
||||
speed_bps, duplex = get_target_speed_duplex(target, interface)
|
||||
if not speed_bps or not duplex:
|
||||
return False
|
||||
if int(speed_bps) // 1_000_000 != exp_mbps:
|
||||
return False
|
||||
if duplex.lower() != exp_duplex.lower():
|
||||
return False
|
||||
try:
|
||||
ns.ping("10.0.0.2", timeout=3)
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
until(settled, attempts=30)
|
||||
print(f"Verified: {interface} forced to {exp_mbps} Mbps, {exp_duplex} duplex")
|
||||
|
||||
|
||||
def enable_target_interface(target, interface):
|
||||
target.put_config_dicts({
|
||||
@@ -102,54 +237,26 @@ def enable_target_interface(target, interface):
|
||||
"interface": [{
|
||||
"name": interface,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [
|
||||
{
|
||||
"ip": "10.0.0.2",
|
||||
"prefix-length": 24
|
||||
}
|
||||
]
|
||||
}
|
||||
"ipv4": {"address": [{"ip": "10.0.0.2", "prefix-length": 24}]}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def enable_target_autoneg(target, interface):
|
||||
target.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": interface,
|
||||
"ethernet": {
|
||||
"auto-negotiation": {
|
||||
"enable": True
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
def enable_host_autoneg(interface):
|
||||
subprocess.run(["ethtool", "-s", interface, "autoneg", "on"], check=True)
|
||||
|
||||
def cleanup(target, hdata, tdata):
|
||||
"""
|
||||
Restore both host and target interfaces to autonegotiation mode
|
||||
to ensure clean state for future tests.
|
||||
"""
|
||||
|
||||
print("Restoring interfaces to default (autoneg on)")
|
||||
"""Restore both host and target to 'advertise everything supported'."""
|
||||
print("Restoring interfaces to default (advertise all)")
|
||||
try:
|
||||
enable_host_autoneg(hdata)
|
||||
enable_host_autoneg_full(hdata)
|
||||
except Exception as e:
|
||||
print(f"Host autoneg restore failed: {e}")
|
||||
print(f"Host restore failed: {e}")
|
||||
try:
|
||||
enable_target_interface(target, tdata)
|
||||
enable_target_autoneg(target, tdata)
|
||||
clear_target_advertise(target, tdata)
|
||||
except Exception as e:
|
||||
print(f"Target autoneg restore failed: {e}")
|
||||
print(f"Target restore failed: {e}")
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
@@ -157,64 +264,78 @@ with infamy.Test() as test:
|
||||
target = env.attach("target", "mgmt")
|
||||
_, hdata = env.ltop.xlate("host", "data")
|
||||
_, tdata = env.ltop.xlate("target", "data")
|
||||
|
||||
# Append a test cleanup function
|
||||
test.push_test_cleanup(lambda: cleanup(target, hdata, tdata))
|
||||
|
||||
|
||||
with test.step("Enable target interface"):
|
||||
enable_target_interface(target, tdata)
|
||||
|
||||
with infamy.IsolatedMacVlan(hdata) as ns:
|
||||
ns.addip("10.0.0.1")
|
||||
|
||||
# Fixed mode tests
|
||||
with test.step("Verify fixed 10/full"):
|
||||
set_host_speed_duplex(hdata, 10, "full")
|
||||
set_target_speed_duplex(target, tdata, 10, "full")
|
||||
# Pinned-mode tests: both peers advertise exactly one mode.
|
||||
with test.step("Advertise 10/full only on both peers"):
|
||||
advertise_host_modes(hdata, ["10full"])
|
||||
set_target_advertise(target, tdata, ["10full"])
|
||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
||||
|
||||
with test.step("Verify fixed 10/half"):
|
||||
set_host_speed_duplex(hdata, 10, "half")
|
||||
set_target_speed_duplex(target, tdata, 10, "half")
|
||||
with test.step("Advertise 10/half only on both peers"):
|
||||
advertise_host_modes(hdata, ["10half"])
|
||||
set_target_advertise(target, tdata, ["10half"])
|
||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
||||
|
||||
with test.step("Verify fixed 100/full"):
|
||||
set_host_speed_duplex(hdata, 100, "full")
|
||||
set_target_speed_duplex(target, tdata, 100, "full")
|
||||
with test.step("Advertise 100/full only on both peers"):
|
||||
advertise_host_modes(hdata, ["100full"])
|
||||
set_target_advertise(target, tdata, ["100full"])
|
||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
||||
|
||||
with test.step("Verify fixed 100/half"):
|
||||
set_host_speed_duplex(hdata, 100, "half")
|
||||
set_target_speed_duplex(target, tdata, 100, "half")
|
||||
with test.step("Advertise 100/half only on both peers"):
|
||||
advertise_host_modes(hdata, ["100half"])
|
||||
set_target_advertise(target, tdata, ["100half"])
|
||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||
|
||||
# Auto-negotiation tests: host advertises, Infix negotiates
|
||||
with test.step("Switch to auto-negotiation mode for target and host"):
|
||||
enable_host_autoneg(hdata)
|
||||
enable_target_autoneg(target, tdata)
|
||||
# Multi-mode advertise tests: host restricted, target advertises all.
|
||||
with test.step("Switch target back to advertising all supported modes"):
|
||||
advertise_host_modes(hdata, ["100half"])
|
||||
clear_target_advertise(target, tdata)
|
||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||
|
||||
with test.step("Verify auto-negotiation to 10/Full only"):
|
||||
with test.step("Host advertises 10/full only"):
|
||||
advertise_host_modes(hdata, ["10full"])
|
||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
||||
|
||||
with test.step("Verify auto-negotiation to 10/Half only"):
|
||||
with test.step("Host advertises 10/half only"):
|
||||
advertise_host_modes(hdata, ["10half"])
|
||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
||||
|
||||
with test.step("Verify auto-negotiation to 100/Full only"):
|
||||
with test.step("Host advertises 100/full only"):
|
||||
advertise_host_modes(hdata, ["100full"])
|
||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
||||
|
||||
with test.step("Verify auto-negotiation to 100/Half only"):
|
||||
with test.step("Host advertises 100/half only"):
|
||||
advertise_host_modes(hdata, ["100half"])
|
||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||
|
||||
with test.step("Verify auto-negotiation to 10/half + 10/full + 100/half"):
|
||||
with test.step("Host advertises 10/half + 10/full + 100/half"):
|
||||
advertise_host_modes(hdata, ["10half", "10full", "100half"])
|
||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||
|
||||
with test.step("Verify auto-negotiation to 10/half + 10/full + 100/half + 100/full + 1000/full"):
|
||||
advertise_host_modes(hdata, ["10half", "10full", "100half", "100full", "1000full"])
|
||||
with test.step("Host advertises every mode up to 1G"):
|
||||
advertise_host_modes(hdata, ["10half", "10full", "100half",
|
||||
"100full", "1000full"])
|
||||
verify_speed_duplex(target, ns, tdata, 1000, "full")
|
||||
|
||||
test.succeed()
|
||||
# Auto-negotiation off — escape hatch for non-autoneg peers. Both
|
||||
# ends forced to a fixed mode with autoneg disabled (host mdix on,
|
||||
# DUT mdi). The link bounces, so verify_forced_speed_duplex polls
|
||||
# until it settles.
|
||||
with test.step("Both sides forced to 100/full, autoneg off"):
|
||||
force_host_fixed(hdata, 100, "full")
|
||||
force_target_fixed(target, tdata, "100full")
|
||||
verify_forced_speed_duplex(target, ns, tdata, 100, "full")
|
||||
|
||||
with test.step("Both sides forced to 10/full, autoneg off"):
|
||||
force_host_fixed(hdata, 10, "full")
|
||||
force_target_fixed(target, tdata, "10full")
|
||||
verify_forced_speed_duplex(target, ns, tdata, 10, "full")
|
||||
|
||||
test.succeed()
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -120,7 +120,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -160,7 +160,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -207,7 +207,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -237,7 +237,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -267,7 +267,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -105,7 +105,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -145,7 +145,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -185,7 +185,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -215,7 +215,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -245,7 +245,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||
lo loopback [32mUP [39m
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
br0 bridge [33m [39mvlan:1u pvid:1
|
||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
│ ipv4 169.254.1.1/16 (random)
|
||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
├ e3 bridge [32mFORWARDING [39mvlan:1u pvid:1
|
||||
├ e4 bridge [32mFORWARDING [39mvlan:1u pvid:1
|
||||
├ veth0b bridge [32mFORWARDING [39mvlan:1u pvid:1
|
||||
└ veth2b bridge [32mFORWARDING [39mvlan:1u pvid:1
|
||||
br1 bridge [33m [39m
|
||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
├ veth1b bridge [32mFORWARDING [39mvlan:6u pvid:6
|
||||
└ veth3b bridge [32mFORWARDING [39m
|
||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||
e3.8 ethernet [32mUP [39m00:a0:85:00:03:03
|
||||
│ ipv4 10.1.1.1/32 (static)
|
||||
└ e3 ethernet [32mUP [39m00:a0:85:00:03:03
|
||||
e4.8 ethernet [32mUP [39m00:a0:85:00:03:04
|
||||
│ ipv4 10.1.1.1/32 (static)
|
||||
└ e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||
ipv4 10.1.1.101/24 (static)
|
||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||
[100mveth0a container container-A [0m
|
||||
veth0b veth [32mUP [39me6:19:75:86:80:dd
|
||||
[100mveth1a container container-A [0m
|
||||
veth1b veth [32mUP [39m3e:67:0f:15:24:14
|
||||
[100mveth2a container container-B [0m
|
||||
veth2b veth [32mUP [39mb2:fa:30:63:98:f0
|
||||
[100mveth3a container container-B [0m
|
||||
veth3b veth [32mUP [39mb2:1c:fa:a7:45:eb
|
||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||
lo loopback [32mUP [39m
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
br0 bridge [33m [39mvlan: 1u pvid: 1
|
||||
│ ethernet 00:a0:85:00:03:00
|
||||
│ ipv4 169.254.1.1/16 (random)
|
||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
├ e3 bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||
├ e4 bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||
├ veth0b bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||
└ veth2b bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||
br1 bridge [33m [39m
|
||||
│ ethernet 00:a0:85:00:03:00
|
||||
├ veth1b bridge [32mFORWARDING [39mvlan: 6u pvid: 6
|
||||
└ veth3b bridge [32mFORWARDING [39m
|
||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||
e3.8 vlan [32mUP [39mvid: 8
|
||||
│ ipv4 10.1.1.1/32 (static)
|
||||
└ e3
|
||||
e4.8 vlan [32mUP [39mvid: 8
|
||||
│ ipv4 10.1.1.1/32 (static)
|
||||
└ e4
|
||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||
ipv4 10.1.1.101/24 (static)
|
||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||
[100mveth0a container container-A [0m
|
||||
veth0b veth [32mUP [39me6:19:75:86:80:dd
|
||||
[100mveth1a container container-A [0m
|
||||
veth1b veth [32mUP [39m3e:67:0f:15:24:14
|
||||
[100mveth2a container container-B [0m
|
||||
veth2b veth [32mUP [39mb2:fa:30:63:98:f0
|
||||
[100mveth3a container container-B [0m
|
||||
veth3b veth [32mUP [39mb2:1c:fa:a7:45:eb
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -151,7 +151,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -199,7 +199,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -236,7 +236,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -266,7 +266,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -95,7 +95,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -136,7 +136,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -177,7 +177,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -207,7 +207,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -244,7 +244,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,51 +1,55 @@
|
||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||
lo loopback [32mUP [39m
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
br-0 bridge [31mDOWN [39m
|
||||
ethernet [31mDOWN [39m00:a0:85:00:03:00
|
||||
br-D bridge [33m [39m
|
||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
│ ipv4 10.0.0.1/8 (static)
|
||||
│ ipv4 192.168.20.1/24 (static)
|
||||
│ ipv6 2001:db8::1/64 (static)
|
||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
└ veth0a.20 bridge [32mFORWARDING [39m
|
||||
br-Q bridge [33m [39mvlan:20u,30u,40t
|
||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
├ e3 bridge [32mFORWARDING [39mvlan:20t,30t,40t
|
||||
└ veth0b bridge [32mFORWARDING [39mvlan:20t,30t,40t
|
||||
br-Q.40 ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
└ br-Q ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
br-X bridge [33m [39m
|
||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
||||
└ e2.30 bridge [32mFORWARDING [39m
|
||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||
e2.30 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
└ e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
e3.10 ethernet [32mUP [39m00:a0:85:00:03:03
|
||||
└ e3 ethernet [32mUP [39m00:a0:85:00:03:03
|
||||
e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
||||
ipv6 fe80::2a0:85ff:fe00:304/64 (link-layer)
|
||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||
gre-v4 gre [32mUP [39m
|
||||
gre-v6 gre [32mUP [39m
|
||||
ipv4 192.168.50.2/16 (static)
|
||||
gretap-v4 gretap [32mUP [39mf6:d4:96:d8:9f:96
|
||||
gretap-v6 gretap [32mUP [39m7a:46:13:bd:fa:e6
|
||||
veth0a veth [32mUP [39m6e:d0:98:c4:e7:ef
|
||||
veth0a.20 ethernet [32mUP [39m6e:d0:98:c4:e7:ef
|
||||
└ veth0a ethernet [32mUP [39m6e:d0:98:c4:e7:ef
|
||||
veth0b veth [32mUP [39m36:da:80:06:7f:99
|
||||
vxlan-v4 vxlan [32mUP [39m8a:ea:59:32:df:70
|
||||
ipv4 192.168.30.2/24 (static)
|
||||
vxlan-v6 vxlan [32mUP [39m3e:30:c6:a1:71:64
|
||||
ipv4 192.168.40.2/24 (static)
|
||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||
lo loopback [32mUP [39m
|
||||
ipv4 127.0.0.1/8 (static)
|
||||
ipv6 ::1/128 (static)
|
||||
br-0 bridge [31mDOWN [39m
|
||||
ethernet 00:a0:85:00:03:00
|
||||
br-D bridge [33m [39m
|
||||
│ ethernet 00:a0:85:00:03:00
|
||||
│ ipv4 10.0.0.1/8 (static)
|
||||
│ ipv4 192.168.20.1/24 (static)
|
||||
│ ipv6 2001:db8::1/64 (static)
|
||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
└ veth0a.20 bridge [32mFORWARDING [39m
|
||||
br-Q bridge [33m [39mvlan: 20u,30u,40t
|
||||
│ ethernet 00:a0:85:00:03:00
|
||||
├ e3 bridge [32mFORWARDING [39mvlan: 20t,30t,40t
|
||||
└ veth0b bridge [32mFORWARDING [39mvlan: 20t,30t,40t
|
||||
br-Q.40 vlan [32mUP [39mvid: 40
|
||||
└ br-Q
|
||||
br-X bridge [33m [39m
|
||||
│ ethernet 00:a0:85:00:03:00
|
||||
└ e2.30 bridge [32mFORWARDING [39m
|
||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||
e2.30 vlan [32mUP [39mvid: 30
|
||||
└ e2
|
||||
e3.10 vlan [32mUP [39mvid: 10
|
||||
└ e3
|
||||
e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
||||
ipv6 fe80::2a0:85ff:fe00:304/64 (link-layer)
|
||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||
gre-v4 gre [32mUP [39mremote: 192.168.20.2
|
||||
gre-v6 gre [32mUP [39mremote: 2001:db8::2
|
||||
ipv4 192.168.50.2/16 (static)
|
||||
gretap-v4 gre [32mUP [39mremote: 192.168.20.2
|
||||
ethernet f6:d4:96:d8:9f:96
|
||||
gretap-v6 gre [32mUP [39mremote: 2001:db8::2
|
||||
ethernet 7a:46:13:bd:fa:e6
|
||||
veth0a veth [32mUP [39m6e:d0:98:c4:e7:ef
|
||||
veth0a.20 vlan [32mUP [39mvid: 20
|
||||
└ veth0a
|
||||
veth0b veth [32mUP [39m36:da:80:06:7f:99
|
||||
vxlan-v4 vxlan [32mUP [39mvni: 4 remote: 192.168.20.200
|
||||
ethernet 8a:ea:59:32:df:70
|
||||
ipv4 192.168.30.2/24 (static)
|
||||
vxlan-v6 vxlan [32mUP [39mvni: 6 remote: 2001:db8::200
|
||||
ethernet 3e:30:c6:a1:71:64
|
||||
ipv4 192.168.40.2/24 (static)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name : br-0
|
||||
type : bridge
|
||||
index : 9
|
||||
mtu : 1500
|
||||
operational status : down
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
name : br-0
|
||||
type : bridge
|
||||
index : 9
|
||||
mtu : 1500
|
||||
operational status : down
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name : br-D
|
||||
type : bridge
|
||||
index : 15
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses : 10.0.0.1/8 (static)
|
||||
192.168.20.1/24 (static)
|
||||
ipv6 addresses : 2001:db8::1/64 (static)
|
||||
fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
name : br-D
|
||||
type : bridge
|
||||
index : 15
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses : 10.0.0.1/8 (static)
|
||||
192.168.20.1/24 (static)
|
||||
ipv6 addresses : 2001:db8::1/64 (static)
|
||||
fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name : br-Q
|
||||
type : bridge
|
||||
index : 16
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
name : br-Q
|
||||
type : bridge
|
||||
index : 16
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name : br-Q.40
|
||||
type : vlan
|
||||
index : 17
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
lower-layer-if : br-Q
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
name : br-Q.40
|
||||
type : vlan
|
||||
index : 17
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
lower-layer-if : br-Q
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name : br-X
|
||||
type : bridge
|
||||
index : 11
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
name : br-X
|
||||
type : bridge
|
||||
index : 11
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 00:a0:85:00:03:00
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name : gre-v4
|
||||
type : gre
|
||||
index : 19
|
||||
mtu : 1476
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.1
|
||||
remote address : 192.168.20.2
|
||||
name : gre-v4
|
||||
type : gre
|
||||
index : 19
|
||||
mtu : 1476
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.1
|
||||
remote address : 192.168.20.2
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name : gre-v6
|
||||
type : gre
|
||||
index : 20
|
||||
mtu : 1448
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
ipv4 addresses : 192.168.50.2/16 (static)
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::1
|
||||
remote address : 2001:db8::2
|
||||
name : gre-v6
|
||||
type : gre
|
||||
index : 20
|
||||
mtu : 1448
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
ipv4 addresses : 192.168.50.2/16 (static)
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::1
|
||||
remote address : 2001:db8::2
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name : gretap-v4
|
||||
type : gretap
|
||||
index : 21
|
||||
mtu : 1462
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : f6:d4:96:d8:9f:96
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.1
|
||||
remote address : 192.168.20.2
|
||||
name : gretap-v4
|
||||
type : gretap
|
||||
index : 21
|
||||
mtu : 1462
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : f6:d4:96:d8:9f:96
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.1
|
||||
remote address : 192.168.20.2
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name : gretap-v6
|
||||
type : gretap
|
||||
index : 22
|
||||
mtu : 1434
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 7a:46:13:bd:fa:e6
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::1
|
||||
remote address : 2001:db8::2
|
||||
name : gretap-v6
|
||||
type : gretap
|
||||
index : 22
|
||||
mtu : 1434
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 7a:46:13:bd:fa:e6
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::1
|
||||
remote address : 2001:db8::2
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name : veth0a
|
||||
type : veth
|
||||
index : 13
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 6e:d0:98:c4:e7:ef
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 299
|
||||
out-octets : 17190
|
||||
name : veth0a
|
||||
type : veth
|
||||
index : 13
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 6e:d0:98:c4:e7:ef
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 299
|
||||
out-octets : 17190
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
name : veth0a.20
|
||||
type : vlan
|
||||
index : 14
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
lower-layer-if : veth0a
|
||||
physical address : 6e:d0:98:c4:e7:ef
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
name : veth0a.20
|
||||
type : vlan
|
||||
index : 14
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
lower-layer-if : veth0a
|
||||
physical address : 6e:d0:98:c4:e7:ef
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name : veth0b
|
||||
type : veth
|
||||
index : 12
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 36:da:80:06:7f:99
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 17190
|
||||
out-octets : 299
|
||||
name : veth0b
|
||||
type : veth
|
||||
index : 12
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 36:da:80:06:7f:99
|
||||
ipv4 addresses :
|
||||
ipv6 addresses :
|
||||
in-octets : 17190
|
||||
out-octets : 299
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
name : vxlan-v4
|
||||
type : vxlan
|
||||
index : 23
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 8a:ea:59:32:df:70
|
||||
ipv4 addresses : 192.168.30.2/24 (static)
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.100
|
||||
remote address : 192.168.20.200
|
||||
VxLAN id : 4
|
||||
name : vxlan-v4
|
||||
type : vxlan
|
||||
index : 23
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 8a:ea:59:32:df:70
|
||||
ipv4 addresses : 192.168.30.2/24 (static)
|
||||
ipv6 addresses :
|
||||
local address : 192.168.20.100
|
||||
remote address : 192.168.20.200
|
||||
VxLAN id : 4
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
name : vxlan-v6
|
||||
type : vxlan
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 3e:30:c6:a1:71:64
|
||||
ipv4 addresses : 192.168.40.2/24 (static)
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::100
|
||||
remote address : 2001:db8::200
|
||||
VxLAN id : 6
|
||||
name : vxlan-v6
|
||||
type : vxlan
|
||||
index : 24
|
||||
mtu : 1500
|
||||
operational status : up
|
||||
ip forwarding : disabled
|
||||
physical address : 3e:30:c6:a1:71:64
|
||||
ipv4 addresses : 192.168.40.2/24 (static)
|
||||
ipv6 addresses :
|
||||
local address : 2001:db8::100
|
||||
remote address : 2001:db8::200
|
||||
VxLAN id : 6
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@
|
||||
"mtu": 1500
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -156,7 +156,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -216,7 +216,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@
|
||||
]
|
||||
},
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -95,7 +95,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -134,7 +134,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -164,7 +164,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -194,7 +194,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
@@ -224,7 +224,7 @@
|
||||
{
|
||||
"admin-status": "up",
|
||||
"ieee802-ethernet-interface:ethernet": {
|
||||
"auto-negotation": {
|
||||
"auto-negotiation": {
|
||||
"enable": false
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user