mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +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 Linux kernel to 6.18.33 (LTS)
|
||||||
- Upgrade Buildroot to 2025.02.14 (LTS)
|
- Upgrade Buildroot to 2025.02.14 (LTS)
|
||||||
- Upgrade FRR to 10.5.4
|
- Upgrade FRR to 10.5.4
|
||||||
- Add support for [Acer Connect Vero W6m][AcerConnectVero], a COTS home router,
|
- Add support for [Acer Connect Vero W6m][AcerConnectVero], a low-cost COTS
|
||||||
based upon the same hardware as [Banana Pi BPI-R3][BPI-R3], but
|
home router, based on the same hardware as [Banana Pi BPI-R3][BPI-R3], but
|
||||||
with a Wi-Fi 6E (6 GHz band) chip.
|
with a Wi-Fi 6E (6 GHz band) chip.
|
||||||
- Add configurable channel-width in Wi-Fi configuration.
|
- 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
|
### Fixes
|
||||||
|
|
||||||
- Fix #1493: container with a physical interface not properly removed
|
- Fix #1493: container with a physical interface not properly removed
|
||||||
when switching to a configuration without containers
|
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
|
- Handle unclean daemon exits better, e.g., `dbus-daemon` crashing and
|
||||||
leaving a stale pidfile behind, causing it to refuse to be restarted
|
leaving a stale pidfile behind, causing it to refuse to be restarted
|
||||||
- Fix occasional blank or garbled `[ OK ]` lines at startup
|
- Fix occasional blank or garbled `[ OK ]` lines at startup
|
||||||
- Disallow multicast MAC addresses in custom MAC address configuration
|
- Disallow multicast MAC addresses in custom MAC address configuration
|
||||||
- Fix broken Wi-Fi 6 GHz band 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/
|
[AcerConnectVero]: ../board/aarch64/acer-connect-vero-w6m/
|
||||||
|
|
||||||
[v26.04.0][] - 2026-04-30
|
[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
|
- Fix [BPI-R3][] PCIe devices failing to initialize on boot due to a missing
|
||||||
clock definition in the device tree
|
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
|
[BPI-R4]: https://docs.banana-pi.org/en/BPI-R4/BananaPi_BPI-R4
|
||||||
[ESPRESSObin]: https://espressobin.net/
|
[ESPRESSObin]: https://espressobin.net/
|
||||||
[SAMA7G54]: https://www.microchip.com/en-us/development-tool/ev21h18a
|
[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
|
- 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
|
[SAMA7G54-EK]: https://www.microchip.com/en-us/development-tool/ev21h18a
|
||||||
|
|
||||||
[v26.01.0][] - 2026-02-03
|
[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>
|
</code></pre>
|
||||||
|
|
||||||
To route or to manage via a VLAN, a VLAN interface needs to be created
|
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)
|
on top of the bridge, see section [VLAN Interfaces](vlan.md) for more
|
||||||
for more on this topic.
|
on this topic.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> In some use-cases only a single management VLAN on the bridge is used.
|
> 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:/config/interface/eth0/> leave
|
||||||
admin@host-12-34-56:/> show interfaces
|
admin@host-12-34-56:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
lo loopback UNKNOWN 00:00:00:00:00:00
|
lo loopback UNKNOWN 00:00:00:00:00:00
|
||||||
ipv4 127.0.0.1/8 (static)
|
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
|
`auto`, the system uses the IP address from the interface matching the
|
||||||
subnet. For example:
|
subnet. For example:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv4 192.168.1.1/24 (static)
|
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)
|
ipv4 192.168.2.1/24 (static)
|
||||||
|
|
||||||
admin@example:/config/dhcp-server/subnet/192.168.1.0/24/> <b>edit option dns-server</b>
|
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
|
# Ethernet Interfaces
|
||||||
|
|
||||||
This document covers VLAN interfaces, physical Ethernet interfaces,
|
This document covers physical Ethernet interfaces and virtual Ethernet
|
||||||
and virtual Ethernet (VETH) pairs.
|
(VETH) pairs. For VLAN interfaces stacked on top of an Ethernet port
|
||||||
|
or bridge, see [VLAN Interfaces](vlan.md).
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
|
|
||||||
## Physical Ethernet Interfaces
|
## 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
|
Physical Ethernet interfaces provide low-level settings for speed/duplex as
|
||||||
well as packet status and [statistics](#ethernet-statistics).
|
well as packet status and [statistics](#ethernet-statistics).
|
||||||
|
|
||||||
By default, Ethernet interfaces defaults to auto-negotiating
|
By default, Ethernet interfaces defaults to auto-negotiating speed/duplex
|
||||||
speed/duplex modes, advertising all speed and duplex modes available.
|
modes, advertising all speed and duplex modes available. In the example
|
||||||
In the example below, the switch would by default auto-negotiate speed
|
below, the switch would by default auto-negotiate speed 1 Gbps on port eth1
|
||||||
1 Gbit/s on port eth1 and 100 Mbit/s on port eth4, as those are the
|
and 100 Mbps on port eth4, as those are the highest speeds supported by H1 and
|
||||||
highest speeds supported by H1 and H2 respectively.
|
H2 respectively.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The speed and duplex status for the links can be listed as shown
|
A quick at-a-glance view of the physical link is available in the summary
|
||||||
below, assuming the link operational status is 'up'.
|
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>
|
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||||
name : eth1
|
name : eth1
|
||||||
index : 2
|
index : 2
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
auto-negotiation : on
|
link mode : 1000baseT
|
||||||
duplex : full
|
auto-negotiation : on
|
||||||
speed : 1000
|
duplex : full
|
||||||
physical address : 00:53:00:06:11:01
|
speed : 1000
|
||||||
ipv4 addresses :
|
physical address : 00:53:00:06:11:01
|
||||||
ipv6 addresses :
|
ipv4 addresses :
|
||||||
in-octets : 75581
|
ipv6 addresses :
|
||||||
out-octets : 43130
|
in-octets : 75581
|
||||||
|
out-octets : 43130
|
||||||
...
|
...
|
||||||
admin@example:/> <b>show interface eth4</b>
|
admin@example:/> <b>show interface eth4</b>
|
||||||
name : eth4
|
name : eth4
|
||||||
index : 5
|
index : 5
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
auto-negotiation : on
|
link mode : 100baseTX
|
||||||
duplex : full
|
auto-negotiation : on
|
||||||
speed : 100
|
duplex : full
|
||||||
physical address : 00:53:00:06:11:04
|
speed : 100
|
||||||
ipv4 addresses :
|
physical address : 00:53:00:06:11:04
|
||||||
ipv6 addresses :
|
ipv4 addresses :
|
||||||
in-octets : 75439
|
ipv6 addresses :
|
||||||
out-octets : 550704
|
in-octets : 75439
|
||||||
|
out-octets : 550704
|
||||||
...
|
...
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
### Configuring fixed speed and duplex
|
### Restricting advertised link modes
|
||||||
|
|
||||||
Auto-negotiation of speed/duplex mode is desired in almost all
|
Auto-negotiation is the right default for almost all links, but sometimes a
|
||||||
use-cases, but it is possible to disable auto-negotiation and specify
|
port has to come up at a fixed speed, usually when talking to old hardware
|
||||||
a fixed speed and duplex mode.
|
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]
|
> [!NOTE]
|
||||||
> When setting a fixed speed and duplex mode, ensure both sides of the
|
> Earlier Infix releases needed `enable false` plus explicit `speed` and
|
||||||
> link have matching configuration. If speed does not match, the link
|
> `duplex` leaves. IEEE Std 802.3.2-2025 retired the `eth:speed` leaf, so
|
||||||
> will not come up. If duplex mode does not match, the result is
|
> the speed now comes from the `advertised-pmd-types` entry instead.
|
||||||
> reported collisions and/or bad throughput.
|
> Existing `startup-config.cfg` files are migrated automatically on upgrade.
|
||||||
|
|
||||||
The example below configures port eth3 to fixed speed 100 Mbit/s
|
Each entry in `auto-negotiation/advertised-pmd-types` is an IEEE PMD-type
|
||||||
half-duplex mode.
|
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>
|
<pre class="cli"><code>admin@example:/> <b>configure</b>
|
||||||
admin@example:/config/> <b>edit interface eth3 ethernet</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 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>
|
admin@example:/config/interface/eth3/ethernet/> <b>show</b>
|
||||||
auto-negotiation {
|
auto-negotiation {
|
||||||
enable false;
|
advertised-pmd-types [ ieee802-ethernet-phy-type:pmd-type-100BASE-TX ];
|
||||||
}
|
}
|
||||||
duplex half;
|
duplex half;
|
||||||
speed 0.1;
|
|
||||||
admin@example:/config/interface/eth3/ethernet/> <b>leave</b>
|
admin@example:/config/interface/eth3/ethernet/> <b>leave</b>
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
Speed metric is in Gbit/s. Auto-negotiation needs to be disabled in
|
List several PMDs to advertise all of them; auto-negotiation then settles
|
||||||
order for fixed speed/duplex to apply. Only speeds `0.1`(100 Mbit/s)
|
on the highest mode both ends support.
|
||||||
and `0.01` (10 Mbit/s) can be specified. 1 Gbit/s and higher speeds
|
|
||||||
require auto-negotiation to be enabled.
|
> [!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 statistics
|
||||||
|
|
||||||
Ethernet packet statistics[^1] can be listed as shown below.
|
Ethernet packet statistics[^1] can be listed as shown below.
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface eth1</b>
|
||||||
name : eth1
|
name : eth1
|
||||||
index : 2
|
index : 2
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
auto-negotiation : on
|
link mode : 1000baseT
|
||||||
duplex : full
|
auto-negotiation : on
|
||||||
speed : 1000
|
duplex : full
|
||||||
physical address : 00:53:00:06:11:0a
|
speed : 1000
|
||||||
ipv4 addresses :
|
physical address : 00:53:00:06:11:0a
|
||||||
ipv6 addresses :
|
ipv4 addresses :
|
||||||
in-octets : 75581
|
ipv6 addresses :
|
||||||
out-octets : 43130
|
in-octets : 75581
|
||||||
|
out-octets : 43130
|
||||||
eth-in-frames : 434
|
───────────────────
|
||||||
eth-in-multicast-frames : 296
|
<b>Ethernet Statistics</b>
|
||||||
eth-in-broadcast-frames : 138
|
in-frames : 434
|
||||||
eth-in-error-fcs-frames : 0
|
in-multicast-frames : 296
|
||||||
eth-in-error-oversize-frames : 0
|
in-broadcast-frames : 138
|
||||||
eth-out-frames : 310
|
in-error-fcs-frames : 0
|
||||||
eth-out-multicast-frames : 310
|
in-error-oversize-frames : 0
|
||||||
eth-out-broadcast-frames : 0
|
out-frames : 310
|
||||||
eth-out-good-octets : 76821
|
out-multicast-frames : 310
|
||||||
eth-in-good-octets : 60598
|
out-broadcast-frames : 0
|
||||||
|
out-good-octets : 76821
|
||||||
|
in-good-octets : 60598
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
</code></pre>
|
</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
|
The operational status can be inspected to see both administrative and
|
||||||
actual link state:
|
actual link state:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
INTERFACE PROTOCOL STATE DATA
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
|
eth0 ethernet <b>DISABLED</b> 02:00:00:00:00:00
|
||||||
eth1 ethernet UP 02:00:00:00:00:01
|
eth1 1000baseT UP duplex: full
|
||||||
|
ethernet 02:00:00:00:00:01
|
||||||
...
|
...
|
||||||
</code></pre>
|
</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
|
## Description
|
||||||
|
|
||||||
@@ -84,9 +90,9 @@ The description is visible in the operational datastore and in `show`
|
|||||||
commands:
|
commands:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface eth0</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface eth0</b>
|
||||||
name : eth0
|
name : eth0
|
||||||
description : Uplink to core switch
|
description : Uplink to core switch
|
||||||
index : 2
|
index : 2
|
||||||
...
|
...
|
||||||
</code></pre>
|
</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>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv4 169.254.1.3/16 (random)
|
ipv4 169.254.1.3/16 (random)
|
||||||
ipv4 10.0.1.1/24 (static)
|
ipv4 10.0.1.1/24 (static)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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/> <b>edit interface eth0 ipv4</b>
|
||||||
admin@example:/config/interface/eth0/ipv4/> <b>set dhcp</b>
|
admin@example:/config/interface/eth0/ipv4/> <b>set dhcp</b>
|
||||||
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv4/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv4 10.1.2.100/24 (dhcp)
|
ipv4 10.1.2.100/24 (dhcp)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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>set dhcp</b>
|
||||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||||
admin@example:/> <b>show interface</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 2001:db8::42/128 (dhcp)
|
ipv6 2001:db8::42/128 (dhcp)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -291,10 +291,10 @@ on the interface.
|
|||||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
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>set enabled false</b>
|
||||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -308,12 +308,12 @@ admin@example:/>
|
|||||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
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>set address 2001:db8::1 prefix-length 64</b>
|
||||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 2001:db8::1/64 (static)
|
ipv6 2001:db8::1/64 (static)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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
|
identifier. The resulting address is of type *link-layer*, as it is
|
||||||
formed based on the interface identifier ([ietf-ip.yang][2]).
|
formed based on the interface identifier ([ietf-ip.yang][2]).
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -348,11 +348,11 @@ below.
|
|||||||
admin@example:/config/> <b>edit interface eth0 ipv6</b>
|
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>set autoconf create-global-addresses false</b>
|
||||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -366,12 +366,12 @@ admin@example:/>
|
|||||||
By default, the auto-configured link-local and global IPv6 addresses
|
By default, the auto-configured link-local and global IPv6 addresses
|
||||||
are formed from a link-identifier based on the MAC address.
|
are formed from a link-identifier based on the MAC address.
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
ipv6 2001:db8:0:1:0:ff:fe00:0/64 (link-layer)
|
||||||
ipv6 fe80::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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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/> <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>set autoconf create-temporary-addresses true</b>
|
||||||
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
admin@example:/config/interface/eth0/ipv6/> <b>leave</b>
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
eth0 ethernet UP 02:00:00:00:00:00
|
eth0 ethernet UP 02:00:00:00:00:00
|
||||||
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
|
ipv6 2001:db8:0:1:b705:8374:638e:74a8/64 (random)
|
||||||
ipv6 fe80::ad3d:b274:885a:9ffb/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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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
|
interfaces overview in the CLI admin-exec context. Here is the above
|
||||||
static mode aggregate:
|
static mode aggregate:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
lag0 lag UP static: balance-xor, hash: layer2
|
lag0 lag UP static: balance-xor, hash: layer2
|
||||||
│ ethernet UP 00:a0:85:00:02:00
|
│ ethernet UP 00:a0:85:00:02:00
|
||||||
├ eth7 lag ACTIVE
|
├ eth7 lag ACTIVE
|
||||||
└ eth8 lag ACTIVE
|
└ eth8 lag ACTIVE
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
Same aggregate, but in LACP mode:
|
Same aggregate, but in LACP mode:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interfaces</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
.
|
.
|
||||||
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
lag0 lag UP lacp: active, rate: fast (1s), hash: layer2
|
||||||
│ ethernet UP 00:a0:85:00:02:00
|
│ ethernet UP 00:a0:85:00:02:00
|
||||||
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
├ eth7 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||||
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
└ eth8 lag ACTIVE active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
|
|
||||||
@@ -124,45 +124,45 @@ In addition to basic status shown in the interface overview, detailed
|
|||||||
LAG status can be inspected:
|
LAG status can be inspected:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||||
name : lag0
|
name : lag0
|
||||||
index : 25
|
index : 25
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
physical address : 00:a0:85:00:02:00
|
physical address : 00:a0:85:00:02:00
|
||||||
lag mode : static
|
lag mode : static
|
||||||
lag type : balance-xor
|
lag type : balance-xor
|
||||||
lag hash : layer2
|
lag hash : layer2
|
||||||
link debounce up : 0 msec
|
link debounce up : 0 msec
|
||||||
link debounce down : 0 msec
|
link debounce down : 0 msec
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 0
|
in-octets : 0
|
||||||
out-octets : 2142
|
out-octets : 2142
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
Same aggregate, but in LACP mode:
|
Same aggregate, but in LACP mode:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface lag0</b>
|
||||||
name : lag0
|
name : lag0
|
||||||
index : 24
|
index : 24
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
physical address : 00:a0:85:00:02:00
|
physical address : 00:a0:85:00:02:00
|
||||||
lag mode : lacp
|
lag mode : lacp
|
||||||
lag hash : layer2
|
lag hash : layer2
|
||||||
lacp mode : active
|
lacp mode : active
|
||||||
lacp rate : fast (1s)
|
lacp rate : fast (1s)
|
||||||
lacp aggregate id : 1
|
lacp aggregate id : 1
|
||||||
lacp system priority: 65535
|
lacp system priority: 65535
|
||||||
lacp actor key : 9
|
lacp actor key : 9
|
||||||
lacp partner key : 9
|
lacp partner key : 9
|
||||||
lacp partner mac : 00:a0:85:00:03:00
|
lacp partner mac : 00:a0:85:00:03:00
|
||||||
link debounce up : 0 msec
|
link debounce up : 0 msec
|
||||||
link debounce down : 0 msec
|
link debounce down : 0 msec
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 100892
|
in-octets : 100892
|
||||||
out-octets : 111776
|
out-octets : 111776
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
Member ports provide additional status information:
|
Member ports provide additional status information:
|
||||||
@@ -184,21 +184,21 @@ Member ports provide additional status information:
|
|||||||
Example member port status:
|
Example member port status:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface eth7</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface eth7</b>
|
||||||
name : eth7
|
name : eth7
|
||||||
index : 8
|
index : 8
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
physical address : 00:a0:85:00:02:00
|
physical address : 00:a0:85:00:02:00
|
||||||
lag member : lag0
|
lag member : lag0
|
||||||
lag member state : active
|
lag member state : active
|
||||||
lacp aggregate id : 1
|
lacp aggregate id : 1
|
||||||
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
lacp actor state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||||
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
lacp partner state : active, short_timeout, aggregating, in_sync, collecting, distributing
|
||||||
link failure count : 0
|
link failure count : 0
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 473244
|
in-octets : 473244
|
||||||
out-octets : 499037
|
out-octets : 499037
|
||||||
</code></pre>
|
</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
|
See the 'help' command for an introduction to the system
|
||||||
|
|
||||||
admin@example:/> <b>show interfaces</b>
|
admin@example:/> <b>show interface</b>
|
||||||
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
<span class="header">INTERFACE PROTOCOL STATE DATA </span>
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
|
e1 ethernet LOWER-DOWN 00:53:00:06:03:01
|
||||||
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
|
e2 ethernet LOWER-DOWN 00:53:00:06:03:02
|
||||||
...
|
...
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
</code></pre>
|
</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 |
|
| [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 |
|
| [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) |
|
| [lag](lag.md) | infix-if-lag | Link aggregation, static and IEEE 802.3ad (LACP) |
|
||||||
| lo | ietf-interfaces | Software loopback interface |
|
| lo | ietf-interfaces | Software loopback interface |
|
||||||
| [eth](ethernet.md#physical-ethernet-interfaces) | ieee802-ethernet-interface | Physical Ethernet device/port |
|
| [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).
|
interfaces (possibly with IPv6 enabled).
|
||||||
|
|
||||||
```
|
```
|
||||||
admin@example:/> show interfaces
|
admin@example:/> show interface
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
|
e1 ethernet LOWER-DOWN 00:53:00:06:11:01
|
||||||
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
|
e2 ethernet LOWER-DOWN 00:53:00:06:11:02
|
||||||
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
|
e3 ethernet LOWER-DOWN 00:53:00:06:11:03
|
||||||
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
|
e4 ethernet LOWER-DOWN 00:53:00:06:11:04
|
||||||
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
|
e5 ethernet LOWER-DOWN 00:53:00:06:11:05
|
||||||
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
|
e6 ethernet LOWER-DOWN 00:53:00:06:11:06
|
||||||
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
|
e7 ethernet LOWER-DOWN 00:53:00:06:11:07
|
||||||
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
|
e8 ethernet LOWER-DOWN 00:53:00:06:11:08
|
||||||
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
|
e9 ethernet LOWER-DOWN 00:53:00:06:11:09
|
||||||
e10 ethernet UP 00:53:00:06:11:0a
|
e10 ethernet UP 00:53:00:06:11:0a
|
||||||
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
|
ipv6 fe80::0053:00ff:fe06:110a/64 (link-layer)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
```
|
```
|
||||||
@@ -80,7 +80,7 @@ admin@example:/config/> set interface e10 bridge-port bridge br0
|
|||||||
admin@example:/config/>
|
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
|
configuration context. When configuring via SSH, first assign an IP
|
||||||
address to `br0` *before leaving* configuration context, e.g.
|
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:/config/> leave
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
admin@example:/> show interfaces
|
admin@example:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
br0 bridge
|
br0 bridge
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
│ ethernet UP 00:53:00:06:11:01
|
||||||
├ e1 bridge LOWER-DOWN
|
├ e1 bridge LOWER-DOWN
|
||||||
├ e2 bridge LOWER-DOWN
|
├ e2 bridge LOWER-DOWN
|
||||||
├ e3 bridge LOWER-DOWN
|
├ e3 bridge LOWER-DOWN
|
||||||
@@ -109,7 +109,7 @@ br0 bridge
|
|||||||
├ e8 bridge LOWER-DOWN
|
├ e8 bridge LOWER-DOWN
|
||||||
├ e9 bridge LOWER-DOWN
|
├ e9 bridge LOWER-DOWN
|
||||||
└ e10 bridge FORWARDING
|
└ 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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -154,21 +154,21 @@ admin@example:/>
|
|||||||
Interface status would now should something like the following
|
Interface status would now should something like the following
|
||||||
|
|
||||||
```
|
```
|
||||||
admin@example:/> show interfaces
|
admin@example:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
br0 bridge
|
br0 bridge
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
│ ethernet UP 00:53:00:06:11:01
|
||||||
├ e1 bridge LOWER-DOWN vlan:10u pvid:10
|
├ e1 bridge LOWER-DOWN vlan:10u pvid: 10
|
||||||
├ e2 bridge LOWER-DOWN vlan:10u pvid:10
|
├ e2 bridge LOWER-DOWN vlan:10u pvid: 10
|
||||||
├ e3 bridge LOWER-DOWN vlan:20u pvid:20
|
├ e3 bridge LOWER-DOWN vlan:20u pvid: 20
|
||||||
├ e4 bridge LOWER-DOWN vlan:20u pvid:20
|
├ e4 bridge LOWER-DOWN vlan:20u pvid: 20
|
||||||
├ e5 bridge LOWER-DOWN vlan:30u pvid:30
|
├ e5 bridge LOWER-DOWN vlan:30u pvid: 30
|
||||||
├ e6 bridge LOWER-DOWN vlan:30u pvid:30
|
├ e6 bridge LOWER-DOWN vlan:30u pvid: 30
|
||||||
├ e7 bridge LOWER-DOWN vlan:40u pvid:40
|
├ e7 bridge LOWER-DOWN vlan:40u pvid: 40
|
||||||
├ e8 bridge LOWER-DOWN vlan:40u pvid:40
|
├ e8 bridge LOWER-DOWN vlan:40u pvid: 40
|
||||||
├ e9 bridge LOWER-DOWN vlan:50u pvid:50
|
├ e9 bridge LOWER-DOWN vlan:50u pvid: 50
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
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.
|
*FORWARDING* on all ports in the bridge.
|
||||||
|
|
||||||
```
|
```
|
||||||
admin@example:/> show interfaces
|
admin@example:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
br0 bridge
|
br0 bridge
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
│ ethernet UP 00:53:00:06:11:01
|
||||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
├ e1 bridge FORWARDING vlan:10u pvid: 10
|
||||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
├ e2 bridge FORWARDING vlan:10u pvid: 10
|
||||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
├ e3 bridge FORWARDING vlan:20u pvid: 20
|
||||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
├ e4 bridge FORWARDING vlan:20u pvid: 20
|
||||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
├ e5 bridge FORWARDING vlan:30u pvid: 30
|
||||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
├ e6 bridge FORWARDING vlan:30u pvid: 30
|
||||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
├ e7 bridge FORWARDING vlan:40u pvid: 40
|
||||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
├ e8 bridge FORWARDING vlan:40u pvid: 40
|
||||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
├ e9 bridge FORWARDING vlan:50u pvid: 50
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
admin@example:/>
|
admin@example:/>
|
||||||
@@ -284,26 +284,26 @@ admin@example:/>
|
|||||||
Interface *vlan10* with an auto-configured IPv6 address should appear.
|
Interface *vlan10* with an auto-configured IPv6 address should appear.
|
||||||
|
|
||||||
```
|
```
|
||||||
admin@example:/> show interfaces
|
admin@example:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
br0 bridge vlan:10t
|
br0 bridge vlan:10t
|
||||||
│ ethernet UP 00:53:00:06:11:01
|
│ ethernet UP 00:53:00:06:11:01
|
||||||
├ e1 bridge FORWARDING vlan:10u pvid:10
|
├ e1 bridge FORWARDING vlan:10u pvid: 10
|
||||||
├ e2 bridge FORWARDING vlan:10u pvid:10
|
├ e2 bridge FORWARDING vlan:10u pvid: 10
|
||||||
├ e3 bridge FORWARDING vlan:20u pvid:20
|
├ e3 bridge FORWARDING vlan:20u pvid: 20
|
||||||
├ e4 bridge FORWARDING vlan:20u pvid:20
|
├ e4 bridge FORWARDING vlan:20u pvid: 20
|
||||||
├ e5 bridge FORWARDING vlan:30u pvid:30
|
├ e5 bridge FORWARDING vlan:30u pvid: 30
|
||||||
├ e6 bridge FORWARDING vlan:30u pvid:30
|
├ e6 bridge FORWARDING vlan:30u pvid: 30
|
||||||
├ e7 bridge FORWARDING vlan:40u pvid:40
|
├ e7 bridge FORWARDING vlan:40u pvid: 40
|
||||||
├ e8 bridge FORWARDING vlan:40u pvid:40
|
├ e8 bridge FORWARDING vlan:40u pvid: 40
|
||||||
├ e9 bridge FORWARDING vlan:50u pvid:50
|
├ e9 bridge FORWARDING vlan:50u pvid: 50
|
||||||
└ e10 bridge FORWARDING vlan:50u pvid:50
|
└ e10 bridge FORWARDING vlan:50u pvid: 50
|
||||||
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)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (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)
|
│ 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:/>
|
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:
|
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)
|
wg0 wireguard UP 2 peers (1 up)
|
||||||
ipv4 10.0.0.1/24 (static)
|
ipv4 10.0.0.1/24 (static)
|
||||||
ipv6 fd00::1/64 (static)
|
ipv6 fd00::1/64 (static)
|
||||||
|
|
||||||
admin@example:/> <b>show interfaces wg0</b>
|
admin@example:/> <b>show interface wg0</b>
|
||||||
name : wg0
|
name : wg0
|
||||||
type : wireguard
|
type : wireguard
|
||||||
index : 12
|
index : 12
|
||||||
operational status : up
|
operational status : up
|
||||||
peers : 2
|
peers : 2
|
||||||
|
|
||||||
Peer 1:
|
Peer 1:
|
||||||
status : UP
|
status : UP
|
||||||
|
|||||||
+23
-23
@@ -223,22 +223,22 @@ access-point).
|
|||||||
Use `show interface` to see discovered networks and their signal strength:
|
Use `show interface` to see discovered networks and their signal strength:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||||
name : wifi0
|
name : wifi0
|
||||||
type : wifi
|
type : wifi
|
||||||
index : 3
|
index : 3
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : enabled
|
ip forwarding : enabled
|
||||||
physical address : f0:09:0d:36:5f:86
|
physical address : f0:09:0d:36:5f:86
|
||||||
ipv4 addresses : 192.168.1.100/24 (dhcp)
|
ipv4 addresses : 192.168.1.100/24 (dhcp)
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 148388
|
in-octets : 148388
|
||||||
out-octets : 24555
|
out-octets : 24555
|
||||||
mode : station
|
mode : station
|
||||||
ssid : MyNetwork
|
ssid : MyNetwork
|
||||||
signal : -45 dBm (good)
|
signal : -45 dBm (good)
|
||||||
rx bitrate : 72.2 Mbps
|
rx bitrate : 72.2 Mbps
|
||||||
tx bitrate : 86.6 Mbps
|
tx bitrate : 86.6 Mbps
|
||||||
──────────────────────────────────────────────────────────────────────
|
──────────────────────────────────────────────────────────────────────
|
||||||
<span class="title">Available Networks</span>
|
<span class="title">Available Networks</span>
|
||||||
<span class="header">SSID BSSID SECURITY SIGNAL CHANNEL</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:
|
The connection attempt will start immediately. You can verify the connection status:
|
||||||
|
|
||||||
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
<pre class="cli"><code>admin@example:/> <b>show interface wifi0</b>
|
||||||
name : wifi0
|
name : wifi0
|
||||||
type : wifi
|
type : wifi
|
||||||
operational status : up
|
operational status : up
|
||||||
physical address : f0:09:0d:36:5f:86
|
physical address : f0:09:0d:36:5f:86
|
||||||
mode : station
|
mode : station
|
||||||
ssid : MyHomeNetwork
|
ssid : MyHomeNetwork
|
||||||
signal : -52 dBm (good)
|
signal : -52 dBm (good)
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
**Station configuration parameters:**
|
**Station configuration parameters:**
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ nav:
|
|||||||
- Bridging: bridging.md
|
- Bridging: bridging.md
|
||||||
- Link Aggregation: lag.md
|
- Link Aggregation: lag.md
|
||||||
- Ethernet Interfaces: ethernet.md
|
- Ethernet Interfaces: ethernet.md
|
||||||
|
- VLAN Interfaces: vlan.md
|
||||||
- IP Addressing: ip.md
|
- IP Addressing: ip.md
|
||||||
- Routing: routing.md
|
- Routing: routing.md
|
||||||
- Firewall Configuration: firewall.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)
|
static void sysrepo_print_error(sr_session_ctx_t *sess)
|
||||||
{
|
{
|
||||||
const sr_error_info_t *erri = NULL;
|
const sr_error_info_t *erri = NULL;
|
||||||
|
const char *msg;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!sess)
|
if (!sess)
|
||||||
@@ -292,7 +293,10 @@ static void sysrepo_print_error(sr_session_ctx_t *sess)
|
|||||||
if (err || !erri || !erri->err_count)
|
if (err || !erri || !erri->err_count)
|
||||||
return;
|
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 */
|
/* 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 '/'.")
|
print("Invalid XPATH. It must be a valid string starting with '/'.")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
try:
|
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
|
||||||
result = subprocess.run(["copy", datastore, "-x", shlex.quote(xpath)],
|
capture_output=True, text=True)
|
||||||
capture_output=True, text=True, check=True)
|
if result.returncode != 0:
|
||||||
if not result.stdout.strip():
|
# copy already wrote a 'failed retrieving …' message (and a
|
||||||
return {}
|
# sysrepo error line) to stderr; relay it verbatim.
|
||||||
json_data = json.loads(result.stdout)
|
if not quiet and result.stderr:
|
||||||
return json_data
|
print(result.stderr.rstrip())
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
if not quiet:
|
|
||||||
print(f"Error running copy: {e}")
|
|
||||||
return {}
|
return {}
|
||||||
|
if not result.stdout.strip():
|
||||||
|
return {}
|
||||||
|
try:
|
||||||
|
return json.loads(result.stdout)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print(f"Error parsing JSON output: {e}")
|
print(f"Error parsing JSON output: {e}")
|
||||||
@@ -40,15 +41,20 @@ def cli_pretty(json_data: dict, command: str, *args: str):
|
|||||||
return
|
return
|
||||||
|
|
||||||
safe_args = [shlex.quote(arg) for arg in args]
|
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:
|
# cli-pretty prints a user-facing message on stdout before any
|
||||||
json_input = json.dumps(json_data) # Keep as string, not bytes
|
# sys.exit(1) (e.g. 'Interface "w" not found'). Relay it regardless
|
||||||
result = subprocess.run([
|
# of the exit status, and only surface the generic exec error when
|
||||||
"/usr/libexec/statd/cli-pretty", command, *safe_args
|
# nothing useful was produced.
|
||||||
], input=json_input, capture_output=True, text=True, check=True)
|
if result.stdout:
|
||||||
print(result.stdout, end="")
|
print(result.stdout, end="")
|
||||||
except subprocess.CalledProcessError as e:
|
elif result.returncode != 0:
|
||||||
print(f"Error running cli-pretty: {e}")
|
msg = result.stderr.strip() or f"exit status {result.returncode}"
|
||||||
|
print(f"Error running cli-pretty: {msg}")
|
||||||
|
|
||||||
|
|
||||||
def dhcp(args: List[str]) -> None:
|
def dhcp(args: List[str]) -> None:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
# confd version is same as system YANG model version, step on breaking changes
|
# 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_INIT_AUTOMAKE(1.11 foreign subdir-objects)
|
||||||
AM_SILENT_RULES(yes)
|
AM_SILENT_RULES(yes)
|
||||||
|
|
||||||
@@ -22,6 +22,7 @@ AC_CONFIG_FILES([
|
|||||||
share/migrate/1.6/Makefile
|
share/migrate/1.6/Makefile
|
||||||
share/migrate/1.7/Makefile
|
share/migrate/1.7/Makefile
|
||||||
share/migrate/1.8/Makefile
|
share/migrate/1.8/Makefile
|
||||||
|
share/migrate/1.9/Makefile
|
||||||
yang/Makefile
|
yang/Makefile
|
||||||
yang/confd/Makefile
|
yang/confd/Makefile
|
||||||
yang/test-mode/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
|
migratedir = $(pkgdatadir)/migrate
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <linux/ethtool.h>
|
||||||
|
|
||||||
#include <srx/common.h>
|
#include <srx/common.h>
|
||||||
#include <srx/lyx.h>
|
#include <srx/lyx.h>
|
||||||
@@ -12,18 +15,96 @@
|
|||||||
|
|
||||||
#include "interfaces.h"
|
#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)
|
static bool iface_uses_autoneg(struct lyd_node *cif)
|
||||||
{
|
{
|
||||||
struct lyd_node *aneg = lydx_get_descendant(lyd_child(cif), "ethernet",
|
struct lyd_node *aneg = lydx_get_descendant(lyd_child(cif), "ethernet",
|
||||||
"auto-negotiation", NULL);
|
"auto-negotiation", NULL);
|
||||||
|
|
||||||
/* Because `ieee802-ethernet-interface` declares
|
/* `auto-negotiation` is a presence container; when absent the port
|
||||||
* `auto-negotiation` as a presence container, the `enabled`
|
* auto-negotiates (the modern default). When present, `enable`
|
||||||
* leaf, although `true` by default, is not set if the whole
|
* defaults to true and is materialised in the config tree, so
|
||||||
* container is absent. Since auto-negotiation is the expected
|
* lydx_get_bool() reads it correctly. */
|
||||||
* default behavior for most Ethernet links, we choose to
|
|
||||||
* enable it in these situations.
|
|
||||||
*/
|
|
||||||
return !aneg || lydx_get_bool(aneg, "enable");
|
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;
|
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)
|
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 *eth = lydx_get_child(cif, "ethernet");
|
||||||
|
struct lyd_node *aneg = lydx_get_child(eth, "auto-negotiation");
|
||||||
const char *ifname = lydx_get_cattr(cif, "name");
|
const char *ifname = lydx_get_cattr(cif, "name");
|
||||||
enum netdag_init phase = NETDAG_INIT_PHYS;
|
enum netdag_init phase = NETDAG_INIT_PHYS;
|
||||||
const char *speed, *duplex;
|
const char *duplex, *mdix, *unmapped = NULL;
|
||||||
int mbps, err = 0;
|
const char *mdix_arg = "";
|
||||||
|
uint64_t mask = 0;
|
||||||
|
int err = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if (iface_has_quirk(ifname, "broken-autoneg"))
|
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)
|
if (!fp)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supports-auto-negotiation\" == false)') ]] && exit 0\n", ifname);
|
||||||
|
|
||||||
if (iface_uses_autoneg(cif)) {
|
duplex = lydx_get_cattr(eth, "duplex");
|
||||||
fprintf(fp, "[[ -n $(ethtool --json %s | jq '.[] | select(.\"supports-auto-negotiation\" == false)') ]] && exit 0\n", ifname);
|
|
||||||
fprintf(fp, "ethtool --change %s autoneg on", ifname);
|
/* MDI/MDI-X pinout. The `mdi-x` boolean has no default, so an absent
|
||||||
} else {
|
* leaf (read as NULL here, hence lydx_get_cattr not lydx_get_bool) means
|
||||||
speed = lydx_get_cattr(eth, "speed");
|
* Auto-MDIX — emit nothing, leaving the PHY alone and not poking drivers
|
||||||
if (!speed) {
|
* that reject the `mdix` arg. ethtool's `mdix on` is MDI-X (crossover),
|
||||||
sr_session_set_error_message(net->session, "%s: "
|
* `off` is MDI. */
|
||||||
"\"speed\" must be specified "
|
mdix = lydx_get_cattr(eth, "mdi-x");
|
||||||
"when auto-negotiation is disabled", ifname);
|
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;
|
err = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mbps = (int)(atof(speed) * 1000.);
|
if (duplex)
|
||||||
if (!((mbps == 10) || (mbps == 100))) {
|
fixed_duplex = duplex;
|
||||||
sr_session_set_error_message(net->session, "%s: "
|
else if (forced->full_bit != NO_BIT)
|
||||||
"\"speed\" must be either 0.01 or 0.1 "
|
fixed_duplex = "full";
|
||||||
"when auto-negotiation is disabled", ifname);
|
else
|
||||||
err = -EINVAL;
|
fixed_duplex = "half";
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
duplex = lydx_get_cattr(eth, "duplex");
|
fprintf(fp, "ethtool --change %s autoneg off speed %d duplex %s%s\n",
|
||||||
if (!duplex || (strcmp(duplex, "full") && strcmp(duplex, "half"))) {
|
ifname, forced->speed_mbps, fixed_duplex, mdix_arg);
|
||||||
sr_session_set_error_message(net->session, "%s: "
|
goto out;
|
||||||
"\"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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
out:
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int netdag_gen_ethtool(struct dagger *net, struct lyd_node *cif, struct lyd_node *dif)
|
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;
|
return 0;
|
||||||
|
|
||||||
if (dagger_is_bootstrap(net) ||
|
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);
|
err = netdag_gen_ethtool_flow_control(net, cif);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dagger_is_bootstrap(net) ||
|
if (dagger_is_bootstrap(net) ||
|
||||||
lydx_get_descendant(lyd_child(eth), "auto-negotiation", "enable", NULL) ||
|
lydx_get_descendant(lyd_child(eth), "auto-negotiation", NULL) ||
|
||||||
lydx_get_child(eth, "speed") ||
|
lydx_get_child(eth, "duplex") ||
|
||||||
lydx_get_child(eth, "duplex")) {
|
lydx_get_child(eth, "mdi-x")) {
|
||||||
err = netdag_gen_ethtool_autoneg(net, cif);
|
err = netdag_gen_ethtool_autoneg(net, cif);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -44,10 +44,11 @@ MODULES=(
|
|||||||
"infix-meta@2025-12-10.yang"
|
"infix-meta@2025-12-10.yang"
|
||||||
"infix-system@2026-03-09.yang"
|
"infix-system@2026-03-09.yang"
|
||||||
"infix-services@2026-03-20.yang"
|
"infix-services@2026-03-20.yang"
|
||||||
"ieee802-ethernet-interface@2019-06-21.yang"
|
"ieee802-ethernet-interface@2025-09-10.yang"
|
||||||
"infix-ethernet-interface@2024-02-27.yang"
|
"ieee802-ethernet-phy-type@2025-09-10.yang"
|
||||||
|
"infix-ethernet-interface@2026-05-21.yang"
|
||||||
"infix-factory-default@2023-06-28.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"
|
"ietf-crypto-types -e cleartext-symmetric-keys"
|
||||||
"infix-crypto-types@2026-02-14.yang"
|
"infix-crypto-types@2026-02-14.yang"
|
||||||
"ietf-keystore -e symmetric-keys"
|
"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 {
|
import ieee802-ethernet-interface {
|
||||||
prefix eth;
|
prefix eth;
|
||||||
|
revision-date 2025-09-10;
|
||||||
|
}
|
||||||
|
import ieee802-ethernet-phy-type {
|
||||||
|
prefix ieee802-phy;
|
||||||
|
revision-date 2025-09-10;
|
||||||
}
|
}
|
||||||
import ietf-interfaces {
|
import ietf-interfaces {
|
||||||
prefix if;
|
prefix if;
|
||||||
}
|
}
|
||||||
|
import iana-if-type {
|
||||||
|
prefix ianaift;
|
||||||
|
}
|
||||||
import ietf-yang-types {
|
import ietf-yang-types {
|
||||||
prefix yang;
|
prefix yang;
|
||||||
reference "IETF RFC 6991";
|
reference "IETF RFC 6991";
|
||||||
@@ -18,6 +26,34 @@ module infix-ethernet-interface {
|
|||||||
contact "kernelkit@googlegroups.com";
|
contact "kernelkit@googlegroups.com";
|
||||||
description "Extensions and deviations to ieee802-ethernet-interface.yang";
|
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 {
|
revision 2024-02-27 {
|
||||||
description "Add augment for in-good-octets and out-good-octets";
|
description "Add augment for in-good-octets and out-good-octets";
|
||||||
reference "internal";
|
reference "internal";
|
||||||
@@ -36,6 +72,62 @@ module infix-ethernet-interface {
|
|||||||
/*
|
/*
|
||||||
* Data Nodes
|
* 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" {
|
augment "/if:interfaces/if:interface/eth:ethernet/eth:statistics/eth:frame" {
|
||||||
leaf out-good-octets {
|
leaf out-good-octets {
|
||||||
type yang:counter64;
|
type yang:counter64;
|
||||||
|
|||||||
@@ -41,6 +41,15 @@ module infix-interfaces {
|
|||||||
contact "kernelkit@googlegroups.com";
|
contact "kernelkit@googlegroups.com";
|
||||||
description "Linux bridge and lag extensions for ietf-interfaces.";
|
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 {
|
revision 2026-05-13 {
|
||||||
description "Add limitations on custom mac addresses on interfaces, now needs to be a correct unicast mac-address";
|
description "Add limitations on custom mac addresses on interfaces, now needs to be a correct unicast mac-address";
|
||||||
reference "internal";
|
reference "internal";
|
||||||
|
|||||||
@@ -737,15 +737,39 @@ echo "Public: $pub"
|
|||||||
</COMMAND>
|
</COMMAND>
|
||||||
|
|
||||||
<COMMAND name="factory-config" help="Show factory-config">
|
<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>
|
||||||
|
|
||||||
<COMMAND name="running-config" help="Show running-config">
|
<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>
|
||||||
|
|
||||||
<COMMAND name="startup-config" help="Show startup-config">
|
<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>
|
||||||
|
|
||||||
<COMMAND name="firewall" help="Show firewall status and configuration">
|
<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:/config/interface/eth0/> leave
|
||||||
admin@infix-12-34-56:/> show interfaces
|
admin@infix-12-34-56:/> show interface
|
||||||
INTERFACE PROTOCOL STATE DATA
|
INTERFACE PROTOCOL STATE DATA
|
||||||
eth0 ethernet UP 52:54:00:12:34:56
|
eth0 1000baseT UP duplex: full
|
||||||
ipv4 192.168.2.200/24 (static)
|
ethernet 52:54:00:12:34:56
|
||||||
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
ipv4 192.168.2.200/24 (static)
|
||||||
lo ethernet UP 00:00:00:00:00:00
|
ipv6 fe80::5054:ff:fe12:3456/64 (link-layer)
|
||||||
ipv4 127.0.0.1/8 (static)
|
lo loopback UP
|
||||||
ipv6 ::1/128 (static)
|
ipv4 127.0.0.1/8 (static)
|
||||||
|
ipv6 ::1/128 (static)
|
||||||
admin@infix-12-34-56:/> copy running-config startup-config</code></pre>
|
admin@infix-12-34-56:/> copy running-config startup-config</code></pre>
|
||||||
<a href="doc/cli/introduction.md">Click here</a> for more details.
|
<a href="doc/cli/introduction.md">Click here</a> for more details.
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ def compress_interface_list(interfaces):
|
|||||||
class Pad:
|
class Pad:
|
||||||
flags = 2
|
flags = 2
|
||||||
iface = 16
|
iface = 16
|
||||||
proto = 11
|
proto = 14
|
||||||
state = 12
|
state = 12
|
||||||
data = 41
|
data = 41
|
||||||
|
|
||||||
@@ -1042,7 +1042,15 @@ class Iface:
|
|||||||
self.autoneg = get_json_data('unknown', self.data, 'ieee802-ethernet-interface:ethernet',
|
self.autoneg = get_json_data('unknown', self.data, 'ieee802-ethernet-interface:ethernet',
|
||||||
'auto-negotiation', 'enable')
|
'auto-negotiation', 'enable')
|
||||||
self.duplex = get_json_data('', self.data,'ieee802-ethernet-interface:ethernet','duplex')
|
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.phys_address = data.get('phys-address', '')
|
||||||
|
|
||||||
self.br_mdb = get_json_data({}, self.data, 'infix-interfaces:bridge', 'multicast-filters')
|
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')
|
self.wireguard = self.data.get('infix-interfaces:wireguard')
|
||||||
|
|
||||||
if self.data.get('infix-interfaces:vlan'):
|
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:
|
else:
|
||||||
self.lower_if = ''
|
self.lower_if = ''
|
||||||
|
self.vid = None
|
||||||
|
|
||||||
def is_wifi(self):
|
def is_wifi(self):
|
||||||
return self.type == "infix-if-type:wifi"
|
return self.type == "infix-if-type:wifi"
|
||||||
@@ -1173,66 +1184,130 @@ class Iface:
|
|||||||
row += f"{'':<{Pad.state}}{addr['ip']}/{addr['prefix-length']} {origin}"
|
row += f"{'':<{Pad.state}}{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||||
print(row)
|
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 = ""
|
row = ""
|
||||||
if len(pipe) > 0:
|
if len(pipe) > 0:
|
||||||
row = f"{'':<{Pad.flags}}"
|
row = f"{'':<{Pad.flags}}"
|
||||||
row += f"{pipe:<{Pad.iface}}"
|
row += f"{pipe:<{Pad.iface}}"
|
||||||
|
|
||||||
row += f"{name:<{Pad.proto}}"
|
row += f"{name:<{Pad.proto}}"
|
||||||
dec = Decore.green if self.oper() == "up" else Decore.red
|
if show_state:
|
||||||
row += dec(f"{self.oper().upper():<{Pad.state}}")
|
dec = Decore.green if self.oper() == "up" else Decore.red
|
||||||
if phys_address:
|
row += dec(f"{self.oper().upper():<{Pad.state}}")
|
||||||
row += f"{self.phys_address:<{Pad.data}}"
|
else:
|
||||||
|
row += f"{'':<{Pad.state}}"
|
||||||
|
if data:
|
||||||
|
row += f"{data:<{Pad.data}}"
|
||||||
return row
|
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=''):
|
def pr_proto_eth(self, pipe=''):
|
||||||
row = self._pr_proto_common("ethernet", True, pipe);
|
print(self._pr_proto_common("ethernet", pipe, self.phys_address or ""))
|
||||||
print(row)
|
|
||||||
|
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=''):
|
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:
|
if self.lower_if:
|
||||||
row = f"{'':<{Pad.iface}}"
|
parts.append(f"peer: {self.lower_if}")
|
||||||
row += f"{'veth':<{Pad.proto}}"
|
print(self._pr_proto_common("veth", pipe, " ".join(parts)))
|
||||||
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)
|
|
||||||
|
|
||||||
def pr_proto_gre(self, pipe=''):
|
def pr_proto_gre(self, pipe=''):
|
||||||
row = self._pr_proto_common("gre", False, pipe);
|
data = ""
|
||||||
print(row)
|
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=''):
|
def pr_proto_vxlan(self, pipe=''):
|
||||||
row = self._pr_proto_common("vxlan", True, pipe);
|
parts = []
|
||||||
print(row)
|
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=''):
|
def pr_proto_wireguard(self, pipe=''):
|
||||||
row = self._pr_proto_common("wireguard", False, pipe)
|
data = ""
|
||||||
|
|
||||||
if self.wireguard:
|
if self.wireguard:
|
||||||
peer_status = self.wireguard.get('peer-status', {})
|
peer_status = self.wireguard.get('peer-status', {})
|
||||||
peers = peer_status.get('peer', [])
|
peers = peer_status.get('peer', [])
|
||||||
total_peers = len(peers)
|
total_peers = len(peers)
|
||||||
up_peers = sum(1 for p in peers if p.get('connection-status') == 'up')
|
up_peers = sum(1 for p in peers if p.get('connection-status') == 'up')
|
||||||
|
|
||||||
if total_peers > 0:
|
if total_peers > 0:
|
||||||
row += f"{total_peers} peer"
|
plural = "s" if total_peers != 1 else ""
|
||||||
if total_peers != 1:
|
data = f"{total_peers} peer{plural} ({up_peers} up)"
|
||||||
row += "s"
|
print(self._pr_proto_common("wireguard", pipe, data))
|
||||||
row += f" ({up_peers} up)"
|
|
||||||
|
|
||||||
print(row)
|
|
||||||
|
|
||||||
def pr_proto_loopack(self, pipe=''):
|
def pr_proto_loopack(self, pipe=''):
|
||||||
row = self._pr_proto_common("loopback", False, pipe);
|
print(self._pr_proto_common("loopback", pipe))
|
||||||
print(row)
|
|
||||||
|
|
||||||
def pr_wifi_ssids(self):
|
def pr_wifi_ssids(self):
|
||||||
width = 70
|
width = 70
|
||||||
@@ -1309,42 +1384,19 @@ class Iface:
|
|||||||
|
|
||||||
|
|
||||||
def pr_proto_wifi(self, pipe=''):
|
def pr_proto_wifi(self, pipe=''):
|
||||||
row = self._pr_proto_common("ethernet", True, pipe);
|
if self.wifi and (ap := self.wifi.get("access-point", {})):
|
||||||
print(row)
|
ssid = ap.get("ssid", "------")
|
||||||
ssid = None
|
stations = ap.get("stations", {}).get("station", [])
|
||||||
signal = None
|
data_str = f"access-point ssid: {ssid} stations: {len(stations)}"
|
||||||
mode = None
|
elif self.wifi and (station := self.wifi.get("station", {})):
|
||||||
|
ssid = station.get("ssid", "------")
|
||||||
if self.wifi:
|
data_str = f"station ssid: {ssid}"
|
||||||
# Detect mode: AP has "stations", Station has "signal-strength" or "scan-results"
|
if (signal := station.get("signal-strength")) is not None:
|
||||||
ap=self.wifi.get("access-point", {})
|
data_str += f" signal: {signal_to_status(signal)}"
|
||||||
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}"
|
|
||||||
else:
|
else:
|
||||||
data_str = "ssid: ------"
|
data_str = "ssid: ------"
|
||||||
|
|
||||||
row = f"{'':<{Pad.flags}}"
|
print(self._pr_proto_common("wifi", pipe, data_str))
|
||||||
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)
|
|
||||||
|
|
||||||
def pr_proto_br(self, br_vlans):
|
def pr_proto_br(self, br_vlans):
|
||||||
data_str = ""
|
data_str = ""
|
||||||
@@ -1357,23 +1409,18 @@ class Iface:
|
|||||||
else:
|
else:
|
||||||
row += Decore.red(f"{self.oper().upper():<{Pad.state}}")
|
row += Decore.red(f"{self.oper().upper():<{Pad.state}}")
|
||||||
|
|
||||||
|
vlans = []
|
||||||
for vlan in br_vlans:
|
for vlan in br_vlans:
|
||||||
if 'tagged' in vlan:
|
if 'tagged' in vlan and self.name in vlan['tagged']:
|
||||||
for tagged in vlan['tagged']:
|
vlans.append(f"{vlan['vid']}t")
|
||||||
if tagged == self.name:
|
if 'untagged' in vlan and self.name in vlan['untagged']:
|
||||||
if data_str:
|
vlans.append(f"{vlan['vid']}u")
|
||||||
data_str += f",{vlan['vid']}t"
|
tokens = []
|
||||||
else:
|
if vlans:
|
||||||
data_str += f"vlan:{vlan['vid']}t"
|
tokens.append(f"vlan: {','.join(vlans)}")
|
||||||
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 self.pvid:
|
if self.pvid:
|
||||||
data_str += f" pvid:{self.pvid}"
|
tokens.append(f"pvid: {self.pvid}")
|
||||||
|
data_str = " ".join(tokens)
|
||||||
|
|
||||||
if data_str:
|
if data_str:
|
||||||
row += f"{data_str:<{Pad.data}}"
|
row += f"{data_str:<{Pad.data}}"
|
||||||
@@ -1390,11 +1437,11 @@ class Iface:
|
|||||||
lowers.append(_iface)
|
lowers.append(_iface)
|
||||||
|
|
||||||
if lowers:
|
if lowers:
|
||||||
self.pr_proto_eth(pipe='│')
|
self.pr_proto_eth_subrow(pipe='│')
|
||||||
self.pr_proto_ipv4(pipe='│')
|
self.pr_proto_ipv4(pipe='│')
|
||||||
self.pr_proto_ipv6(pipe='│')
|
self.pr_proto_ipv6(pipe='│')
|
||||||
else:
|
else:
|
||||||
self.pr_proto_eth(pipe=' ')
|
self.pr_proto_eth_subrow()
|
||||||
self.pr_proto_ipv4()
|
self.pr_proto_ipv4()
|
||||||
self.pr_proto_ipv6()
|
self.pr_proto_ipv6()
|
||||||
|
|
||||||
@@ -1449,11 +1496,11 @@ class Iface:
|
|||||||
lowers.append(_iface)
|
lowers.append(_iface)
|
||||||
|
|
||||||
if lowers:
|
if lowers:
|
||||||
self.pr_proto_eth(pipe='│')
|
self.pr_proto_eth_subrow(pipe='│')
|
||||||
self.pr_proto_ipv4(pipe='│')
|
self.pr_proto_ipv4(pipe='│')
|
||||||
self.pr_proto_ipv6(pipe='│')
|
self.pr_proto_ipv6(pipe='│')
|
||||||
else:
|
else:
|
||||||
self.pr_proto_eth(pipe=' ')
|
self.pr_proto_eth_subrow()
|
||||||
self.pr_proto_ipv4()
|
self.pr_proto_ipv4()
|
||||||
self.pr_proto_ipv6()
|
self.pr_proto_ipv6()
|
||||||
|
|
||||||
@@ -1476,13 +1523,15 @@ class Iface:
|
|||||||
|
|
||||||
def pr_gretap(self):
|
def pr_gretap(self):
|
||||||
self.pr_name(pipe="")
|
self.pr_name(pipe="")
|
||||||
self.pr_proto_gretap()
|
self.pr_proto_gre()
|
||||||
|
self.pr_proto_eth_subrow()
|
||||||
self.pr_proto_ipv4()
|
self.pr_proto_ipv4()
|
||||||
self.pr_proto_ipv6()
|
self.pr_proto_ipv6()
|
||||||
|
|
||||||
def pr_vxlan(self):
|
def pr_vxlan(self):
|
||||||
self.pr_name(pipe="")
|
self.pr_name(pipe="")
|
||||||
self.pr_proto_vxlan()
|
self.pr_proto_vxlan()
|
||||||
|
self.pr_proto_eth_subrow()
|
||||||
self.pr_proto_ipv4()
|
self.pr_proto_ipv4()
|
||||||
self.pr_proto_ipv6()
|
self.pr_proto_ipv6()
|
||||||
|
|
||||||
@@ -1495,12 +1544,14 @@ class Iface:
|
|||||||
def pr_wifi(self):
|
def pr_wifi(self):
|
||||||
self.pr_name(pipe="")
|
self.pr_name(pipe="")
|
||||||
self.pr_proto_wifi()
|
self.pr_proto_wifi()
|
||||||
|
self.pr_proto_eth_subrow()
|
||||||
self.pr_proto_ipv4()
|
self.pr_proto_ipv4()
|
||||||
self.pr_proto_ipv6()
|
self.pr_proto_ipv6()
|
||||||
|
|
||||||
def pr_vlan(self, _ifaces):
|
def pr_vlan(self, _ifaces):
|
||||||
self.pr_name(pipe="")
|
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:
|
if self.lower_if:
|
||||||
self.pr_proto_ipv4(pipe='│')
|
self.pr_proto_ipv4(pipe='│')
|
||||||
@@ -1515,7 +1566,7 @@ class Iface:
|
|||||||
print(f"Error, didn't find parent interface for vlan {self.name}")
|
print(f"Error, didn't find parent interface for vlan {self.name}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
parent.pr_name(pipe='└ ')
|
parent.pr_name(pipe='└ ')
|
||||||
parent.pr_proto_eth()
|
print()
|
||||||
|
|
||||||
def pr_container(self):
|
def pr_container(self):
|
||||||
# Add ⇅ flag for interfaces with IP forwarding enabled
|
# Add ⇅ flag for interfaces with IP forwarding enabled
|
||||||
@@ -1532,92 +1583,85 @@ class Iface:
|
|||||||
|
|
||||||
def pr_iface(self):
|
def pr_iface(self):
|
||||||
if self.is_in_container():
|
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"{'name':<{19}}: {self.name}")
|
||||||
print(f"{'type':<{20}}: {self.type.split(':')[1]}")
|
print(f"{'type':<{19}}: {self.type.split(':')[1]}")
|
||||||
print(f"{'index':<{20}}: {self.index}")
|
print(f"{'index':<{19}}: {self.index}")
|
||||||
|
|
||||||
if self.mtu:
|
if self.mtu:
|
||||||
print(f"{'mtu':<{20}}: {self.mtu}")
|
print(f"{'mtu':<{19}}: {self.mtu}")
|
||||||
if self.oper():
|
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"
|
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:
|
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':
|
if self.autoneg != 'unknown':
|
||||||
val = "on" if self.autoneg else "off"
|
val = "on" if self.autoneg else "off"
|
||||||
print(f"{'auto-negotiation':<{20}}: {val}")
|
print(f"{'auto-negotiation':<{19}}: {val}")
|
||||||
|
|
||||||
if self.duplex:
|
if self.advertised:
|
||||||
print(f"{'duplex':<{20}}: {self.duplex}")
|
self._pr_label_list('advertised',
|
||||||
|
[self._pmd_label(pmd) for pmd in self.advertised])
|
||||||
|
|
||||||
if self.speed:
|
if self.supported:
|
||||||
mbs = float(self.speed) * 1000
|
self._pr_label_list('supported',
|
||||||
print(f"{'speed':<{20}}: {int(mbs)}")
|
[self._pmd_label(pmd) for pmd in self.supported])
|
||||||
|
|
||||||
if self.phys_address:
|
if self.phys_address:
|
||||||
print(f"{'physical address':<{20}}: {self.phys_address}")
|
print(f"{'physical address':<{19}}: {self.phys_address}")
|
||||||
|
|
||||||
if self.lag_mode:
|
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":
|
if self.lag_mode == "lacp":
|
||||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
print(f"{'lag hash':<{19}}: {self.lag_hash}")
|
||||||
print(f"{'lacp mode':<{20}}: {self.lacp_mode}")
|
print(f"{'lacp mode':<{19}}: {self.lacp_mode}")
|
||||||
print(f"{'lacp rate':<{20}}: {self.lacp_rate}")
|
print(f"{'lacp rate':<{19}}: {self.lacp_rate}")
|
||||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
print(f"{'lacp aggregate id':<{19}}: {self.lacp_id}")
|
||||||
print(f"{'lacp system priority':<{20}}: {self.lacp_sys_prio}")
|
print(f"{'lacp sys priority':<{19}}: {self.lacp_sys_prio}")
|
||||||
print(f"{'lacp actor key':<{20}}: {self.lacp_actor_key}")
|
print(f"{'lacp actor key':<{19}}: {self.lacp_actor_key}")
|
||||||
print(f"{'lacp partner key':<{20}}: {self.lacp_partner_key}")
|
print(f"{'lacp partner key':<{19}}: {self.lacp_partner_key}")
|
||||||
print(f"{'lacp partner mac':<{20}}: {self.lacp_partner_mac}")
|
print(f"{'lacp partner mac':<{19}}: {self.lacp_partner_mac}")
|
||||||
else:
|
else:
|
||||||
print(f"{'lag type':<{20}}: {self.lag_type}")
|
print(f"{'lag type':<{19}}: {self.lag_type}")
|
||||||
print(f"{'lag hash':<{20}}: {self.lag_hash}")
|
print(f"{'lag hash':<{19}}: {self.lag_hash}")
|
||||||
print(f"{'link debounce up':<{20}}: {self.link_updelay} msec")
|
print(f"{'link debounce up':<{19}}: {self.link_updelay} msec")
|
||||||
print(f"{'link debounce down':<{20}}: {self.link_downdelay} msec")
|
print(f"{'link debounce down':<{19}}: {self.link_downdelay} msec")
|
||||||
|
|
||||||
if self.lag:
|
if self.lag:
|
||||||
print(f"{'lag member':<{20}}: {self.lag}")
|
print(f"{'lag member':<{19}}: {self.lag}")
|
||||||
print(f"{'lag member state':<{20}}: {self.lag_state}")
|
print(f"{'lag member state':<{19}}: {self.lag_state}")
|
||||||
if self.lacp_state:
|
if self.lacp_state:
|
||||||
print(f"{'lacp aggregate id':<{20}}: {self.lacp_id}")
|
print(f"{'lacp aggregate id':<{19}}: {self.lacp_id}")
|
||||||
print(f"{'lacp actor state':<{20}}: {', '.join(self.lacp_state)}")
|
print(f"{'lacp actor state':<{19}}: {', '.join(self.lacp_state)}")
|
||||||
print(f"{'lacp partner state':<{20}}: {', '.join(self.lacp_pstate)}")
|
print(f"{'lacp partner state':<{19}}: {', '.join(self.lacp_pstate)}")
|
||||||
print(f"{'link failure count':<{20}}: {self.link_failures}")
|
print(f"{'link failure count':<{19}}: {self.link_failures}")
|
||||||
|
|
||||||
if self.ipv4_addr:
|
def _addr_lines(addrs):
|
||||||
first = True
|
for addr in addrs:
|
||||||
for addr in self.ipv4_addr:
|
|
||||||
origin = f"({addr['origin']})" if addr.get('origin') else ""
|
origin = f"({addr['origin']})" if addr.get('origin') else ""
|
||||||
key = 'ipv4 addresses' if first else ''
|
yield f"{addr['ip']}/{addr['prefix-length']} {origin}"
|
||||||
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}}:")
|
|
||||||
|
|
||||||
if self.ipv6_addr:
|
self._pr_label_list('ipv4 addresses', list(_addr_lines(self.ipv4_addr)))
|
||||||
first = True
|
self._pr_label_list('ipv6 addresses', list(_addr_lines(self.ipv6_addr)))
|
||||||
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}}:")
|
|
||||||
|
|
||||||
if self.in_octets and self.out_octets:
|
if self.in_octets and self.out_octets:
|
||||||
print(f"{'in-octets':<{20}}: {self.in_octets}")
|
print(f"{'in-octets':<{19}}: {self.in_octets}")
|
||||||
print(f"{'out-octets':<{20}}: {self.out_octets}")
|
print(f"{'out-octets':<{19}}: {self.out_octets}")
|
||||||
|
|
||||||
if self.wifi:
|
if self.wifi:
|
||||||
# Detect mode: AP has "stations", Station has "signal-strength" or "scan-results"
|
# Detect mode: AP has "stations", Station has "signal-strength" or "scan-results"
|
||||||
@@ -1627,43 +1671,43 @@ class Iface:
|
|||||||
ssid = ap.get('ssid', "----")
|
ssid = ap.get('ssid', "----")
|
||||||
stations_data = ap.get("stations", {})
|
stations_data = ap.get("stations", {})
|
||||||
stations = stations_data.get("station", [])
|
stations = stations_data.get("station", [])
|
||||||
print(f"{'mode':<{20}}: {mode}")
|
print(f"{'mode':<{19}}: {mode}")
|
||||||
print(f"{'ssid':<{20}}: {ssid}")
|
print(f"{'ssid':<{19}}: {ssid}")
|
||||||
print(f"{'connected stations':<{20}}: {len(stations)}")
|
print(f"{'connected stations':<{19}}: {len(stations)}")
|
||||||
self.pr_wifi_stations()
|
self.pr_wifi_stations()
|
||||||
else:
|
else:
|
||||||
mode = "station"
|
mode = "station"
|
||||||
station = self.wifi.get('station', {})
|
station = self.wifi.get('station', {})
|
||||||
signal = station.get('signal-strength')
|
signal = station.get('signal-strength')
|
||||||
ssid = station.get('ssid', "----")
|
ssid = station.get('ssid', "----")
|
||||||
print(f"{'mode':<{20}}: {mode}")
|
print(f"{'mode':<{19}}: {mode}")
|
||||||
print(f"{'ssid':<{20}}: {ssid}")
|
print(f"{'ssid':<{19}}: {ssid}")
|
||||||
if signal is not None:
|
if signal is not None:
|
||||||
signal_status = signal_to_status(signal)
|
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')
|
rx_speed = station.get('rx-speed')
|
||||||
tx_speed = station.get('tx-speed')
|
tx_speed = station.get('tx-speed')
|
||||||
if rx_speed is not None:
|
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:
|
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:
|
if "scan-results" in station:
|
||||||
self.pr_wifi_ssids()
|
self.pr_wifi_ssids()
|
||||||
|
|
||||||
if self.gre:
|
if self.gre:
|
||||||
print(f"{'local address':<{20}}: {self.gre['local']}")
|
print(f"{'local address':<{19}}: {self.gre['local']}")
|
||||||
print(f"{'remote address':<{20}}: {self.gre['remote']}")
|
print(f"{'remote address':<{19}}: {self.gre['remote']}")
|
||||||
|
|
||||||
if self.vxlan:
|
if self.vxlan:
|
||||||
print(f"{'local address':<{20}}: {self.vxlan['local']}")
|
print(f"{'local address':<{19}}: {self.vxlan['local']}")
|
||||||
print(f"{'remote address':<{20}}: {self.vxlan['remote']}")
|
print(f"{'remote address':<{19}}: {self.vxlan['remote']}")
|
||||||
print(f"{'VxLAN id':<{20}}: {self.vxlan['vni']}")
|
print(f"{'VxLAN id':<{19}}: {self.vxlan['vni']}")
|
||||||
|
|
||||||
if self.wireguard:
|
if self.wireguard:
|
||||||
peer_status = self.wireguard.get('peer-status', {})
|
peer_status = self.wireguard.get('peer-status', {})
|
||||||
peers = peer_status.get('peer', [])
|
peers = peer_status.get('peer', [])
|
||||||
if peers:
|
if peers:
|
||||||
print(f"{'peers':<{20}}: {len(peers)}")
|
print(f"{'peers':<{19}}: {len(peers)}")
|
||||||
for idx, peer in enumerate(peers, 1):
|
for idx, peer in enumerate(peers, 1):
|
||||||
print(f"\n Peer {idx}:")
|
print(f"\n Peer {idx}:")
|
||||||
|
|
||||||
@@ -1700,10 +1744,10 @@ class Iface:
|
|||||||
frame = get_json_data([], self.data,'ieee802-ethernet-interface:ethernet',
|
frame = get_json_data([], self.data,'ieee802-ethernet-interface:ethernet',
|
||||||
'statistics', 'frame')
|
'statistics', 'frame')
|
||||||
if frame:
|
if frame:
|
||||||
print("")
|
Decore.title("Ethernet Statistics")
|
||||||
for key, val in frame.items():
|
for key, val in frame.items():
|
||||||
key = remove_yang_prefix(key)
|
key = remove_yang_prefix(key)
|
||||||
print(f"eth-{key:<{25}}: {val}")
|
print(f"{key:<{25}}: {val}")
|
||||||
|
|
||||||
def pr_mdb(self, bridge):
|
def pr_mdb(self, bridge):
|
||||||
for group in self.br_mdb.get("multicast-filter", {}):
|
for group in self.br_mdb.get("multicast-filter", {}):
|
||||||
@@ -1804,7 +1848,10 @@ def brport_sort(iface):
|
|||||||
|
|
||||||
def print_interface(iface):
|
def print_interface(iface):
|
||||||
iface.pr_name()
|
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_ipv4()
|
||||||
iface.pr_proto_ipv6()
|
iface.pr_proto_ipv6()
|
||||||
|
|
||||||
|
|||||||
@@ -68,31 +68,172 @@ def statistics(ifname):
|
|||||||
|
|
||||||
return statistics
|
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):
|
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], {}):
|
if data := HOST.run_json(["ethtool", "--json", ifname], {}):
|
||||||
data = data[0]
|
data = data[0]
|
||||||
else:
|
else:
|
||||||
return None
|
return {}, None
|
||||||
|
|
||||||
eth = {}
|
eth = {"auto-negotiation": {"enable": data.get("auto-negotiation", False)}}
|
||||||
eth["auto-negotation"] = { "enable": data.get("auto-negotation", False) }
|
|
||||||
|
|
||||||
if data.get("speed"):
|
duplex = (data.get("duplex") or "").lower()
|
||||||
gbps = round((int(data["speed"]) / 1000), 3)
|
if duplex in ("full", "half"):
|
||||||
eth["speed"] = str(gbps)
|
eth["duplex"] = duplex
|
||||||
if data.get("duplex"):
|
|
||||||
eth["duplex"] = data["duplex"].lower()
|
# Expose what the kernel currently considers supported as a config-false
|
||||||
return eth
|
# 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):
|
def ethernet(iplink):
|
||||||
eth = link(iplink["ifname"])
|
"""Return (ethernet container, interface speed in bits/s or None)."""
|
||||||
|
eth, speed_bps = link(iplink["ifname"])
|
||||||
if eth is None:
|
|
||||||
eth = {}
|
|
||||||
|
|
||||||
if stats := statistics(iplink["ifname"]):
|
if stats := statistics(iplink["ifname"]):
|
||||||
eth["statistics"] = stats
|
eth["statistics"] = stats
|
||||||
|
|
||||||
return eth
|
return eth, speed_bps
|
||||||
|
|||||||
@@ -159,8 +159,11 @@ def interface(iplink, ipaddr, systemjson=None):
|
|||||||
if lg := lag.lag(iplink):
|
if lg := lag.lag(iplink):
|
||||||
interface["infix-interfaces:lag"] = lg
|
interface["infix-interfaces:lag"] = lg
|
||||||
case "infix-if-type:ethernet":
|
case "infix-if-type:ethernet":
|
||||||
if eth := ethernet.ethernet(iplink):
|
eth, speed_bps = ethernet.ethernet(iplink)
|
||||||
|
if eth:
|
||||||
interface["ieee802-ethernet-interface:ethernet"] = eth
|
interface["ieee802-ethernet-interface:ethernet"] = eth
|
||||||
|
if speed_bps:
|
||||||
|
interface["speed"] = str(speed_bps)
|
||||||
case "infix-if-type:vxlan":
|
case "infix-if-type:vxlan":
|
||||||
if vxlan := tun.vxlan(iplink):
|
if vxlan := tun.vxlan(iplink):
|
||||||
interface["infix-interfaces:vxlan"] = vxlan
|
interface["infix-interfaces:vxlan"] = vxlan
|
||||||
|
|||||||
@@ -4,11 +4,24 @@ ifdef::topdoc[:imagesdir: {topdoc}../../test/case/interfaces/speed_duplex_copper
|
|||||||
|
|
||||||
==== Description
|
==== 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
|
1. Single-mode advertise — host and target both advertise exactly
|
||||||
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
one PMD/duplex combination; the link comes up at that mode.
|
||||||
to the highest common speed/duplex.
|
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
|
==== Topology
|
||||||
|
|
||||||
@@ -18,16 +31,18 @@ image::topology.svg[Interface Speed Duplex (Copper) topology, align=center, scal
|
|||||||
|
|
||||||
. Set up topology and attach to target DUT
|
. Set up topology and attach to target DUT
|
||||||
. Enable target interface
|
. Enable target interface
|
||||||
. Verify fixed 10/full
|
. Advertise 10/full only on both peers
|
||||||
. Verify fixed 10/half
|
. Advertise 10/half only on both peers
|
||||||
. Verify fixed 100/full
|
. Advertise 100/full only on both peers
|
||||||
. Verify fixed 100/half
|
. Advertise 100/half only on both peers
|
||||||
. Switch to auto-negotiation mode for target and host
|
. Switch target back to advertising all supported modes
|
||||||
. Verify auto-negotiation to 10/Full only
|
. Host advertises 10/full only
|
||||||
. Verify auto-negotiation to 10/Half only
|
. Host advertises 10/half only
|
||||||
. Verify auto-negotiation to 100/Full only
|
. Host advertises 100/full only
|
||||||
. Verify auto-negotiation to 100/Half only
|
. Host advertises 100/half only
|
||||||
. Verify auto-negotiation to 10/half + 10/full + 100/half
|
. Host advertises 10/half + 10/full + 100/half
|
||||||
. Verify auto-negotiation to 10/half + 10/full + 100/half + 100/full + 1000/full
|
. 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)
|
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
|
1. Single-mode advertise — host and target both advertise exactly
|
||||||
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
one PMD/duplex combination; the link comes up at that mode.
|
||||||
to the highest common speed/duplex.
|
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
|
||||||
|
import infamy.iface as iface
|
||||||
import subprocess
|
import subprocess
|
||||||
from infamy.util import until
|
from infamy.util import until
|
||||||
|
|
||||||
ADVERTISE_MODES = {
|
ADVERTISE_MODES = {
|
||||||
# Values from ethtool's ETHTOOL_LINK_MODE bit positions
|
# Values from ethtool's ETHTOOL_LINK_MODE bit positions
|
||||||
# See: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ethtool.h
|
# See: https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ethtool.h
|
||||||
"10half": 0x0001,
|
"10half": 0x0001,
|
||||||
"10full": 0x0002,
|
"10full": 0x0002,
|
||||||
"100half": 0x0004,
|
"100half": 0x0004,
|
||||||
"100full": 0x0008,
|
"100full": 0x0008,
|
||||||
"1000full": 0x0020
|
"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):
|
def advertise_host_modes(interface, modes):
|
||||||
mask = 0
|
mask = 0
|
||||||
for mode in modes:
|
for mode in modes:
|
||||||
mask |= ADVERTISE_MODES[mode]
|
mask |= ADVERTISE_MODES[mode]
|
||||||
try:
|
try:
|
||||||
subprocess.run([
|
subprocess.run(["ethtool", "-s", interface, "advertise", hex(mask)],
|
||||||
"ethtool", "-s", interface,
|
check=True)
|
||||||
"advertise", hex(mask)
|
|
||||||
], check=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
raise RuntimeError(f"Failed to advertise modes via ethtool: {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):
|
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]
|
["interfaces"]["interface"][interface]
|
||||||
eth = data.get("ethernet", {})
|
eth = data.get("ethernet", {})
|
||||||
|
# Operational speed under ietf-interfaces:speed (bits/s, RFC 8343).
|
||||||
return eth.get("speed"), eth.get("duplex")
|
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({
|
target.put_config_dicts({
|
||||||
"ietf-interfaces": {
|
"ietf-interfaces": {
|
||||||
"interfaces": {
|
"interfaces": {
|
||||||
"interface": [{
|
"interface": [{"name": interface, "ethernet": eth}]
|
||||||
"name": interface,
|
|
||||||
"ethernet": {
|
|
||||||
"auto-negotiation": {
|
|
||||||
"enable": False
|
|
||||||
},
|
|
||||||
"speed": speed / 1000,
|
|
||||||
"duplex": duplex
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
})
|
||||||
|
|
||||||
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:
|
try:
|
||||||
subprocess.run([
|
clear_target_advertise(target, interface)
|
||||||
"ethtool", "-s", interface,
|
except Exception:
|
||||||
"speed", str(speed),
|
pass
|
||||||
"duplex", duplex,
|
target.put_config_dicts({
|
||||||
"autoneg", "off"
|
"ietf-interfaces": {
|
||||||
], check=True)
|
"interfaces": {
|
||||||
except subprocess.CalledProcessError as e:
|
"interface": [{
|
||||||
raise RuntimeError(f"Failed to set speed/duplex via ethtool: {e}")
|
"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))
|
def clear_target_advertise(target, interface):
|
||||||
act_speed, act_duplex = get_target_speed_duplex(target, interface)
|
"""Drop the entire ethernet sub-config on the target.
|
||||||
if act_speed is None or act_duplex is None:
|
|
||||||
print(f"Could not fetch speed or duplex from target for interface {interface}")
|
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()
|
test.fail()
|
||||||
|
|
||||||
exp_speed_gbps = exp_speed / 1000
|
act_mbps = int(speed_bps) // 1_000_000
|
||||||
if float(act_speed) != exp_speed_gbps:
|
if act_mbps != exp_mbps:
|
||||||
print(f"act_speed: {act_speed}, exp_speed: {exp_speed_gbps}")
|
print(f"act_mbps: {act_mbps}, exp_mbps: {exp_mbps}")
|
||||||
test.fail()
|
test.fail()
|
||||||
|
|
||||||
if act_duplex.lower() != exp_duplex.lower():
|
if duplex.lower() != exp_duplex.lower():
|
||||||
print(f"act_duplex: {act_duplex}, exp_duplex: {exp_duplex}")
|
print(f"act_duplex: {duplex}, exp_duplex: {exp_duplex}")
|
||||||
test.fail()
|
test.fail()
|
||||||
|
|
||||||
ns.must_reach("10.0.0.2")
|
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):
|
def _speed_duplex_present(target, interface):
|
||||||
speed, duplex = get_target_speed_duplex(target, interface)
|
speed_bps, duplex = get_target_speed_duplex(target, interface)
|
||||||
return speed is not None and duplex is not None
|
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):
|
def enable_target_interface(target, interface):
|
||||||
target.put_config_dicts({
|
target.put_config_dicts({
|
||||||
@@ -102,54 +237,26 @@ def enable_target_interface(target, interface):
|
|||||||
"interface": [{
|
"interface": [{
|
||||||
"name": interface,
|
"name": interface,
|
||||||
"enabled": True,
|
"enabled": True,
|
||||||
"ipv4": {
|
"ipv4": {"address": [{"ip": "10.0.0.2", "prefix-length": 24}]}
|
||||||
"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):
|
def cleanup(target, hdata, tdata):
|
||||||
"""
|
"""Restore both host and target to 'advertise everything supported'."""
|
||||||
Restore both host and target interfaces to autonegotiation mode
|
print("Restoring interfaces to default (advertise all)")
|
||||||
to ensure clean state for future tests.
|
|
||||||
"""
|
|
||||||
|
|
||||||
print("Restoring interfaces to default (autoneg on)")
|
|
||||||
try:
|
try:
|
||||||
enable_host_autoneg(hdata)
|
enable_host_autoneg_full(hdata)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Host autoneg restore failed: {e}")
|
print(f"Host restore failed: {e}")
|
||||||
try:
|
try:
|
||||||
enable_target_interface(target, tdata)
|
enable_target_interface(target, tdata)
|
||||||
enable_target_autoneg(target, tdata)
|
clear_target_advertise(target, tdata)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Target autoneg restore failed: {e}")
|
print(f"Target restore failed: {e}")
|
||||||
|
|
||||||
|
|
||||||
with infamy.Test() as test:
|
with infamy.Test() as test:
|
||||||
with test.step("Set up topology and attach to target DUT"):
|
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")
|
target = env.attach("target", "mgmt")
|
||||||
_, hdata = env.ltop.xlate("host", "data")
|
_, hdata = env.ltop.xlate("host", "data")
|
||||||
_, tdata = env.ltop.xlate("target", "data")
|
_, tdata = env.ltop.xlate("target", "data")
|
||||||
|
|
||||||
# Append a test cleanup function
|
|
||||||
test.push_test_cleanup(lambda: cleanup(target, hdata, tdata))
|
test.push_test_cleanup(lambda: cleanup(target, hdata, tdata))
|
||||||
|
|
||||||
with test.step("Enable target interface"):
|
with test.step("Enable target interface"):
|
||||||
enable_target_interface(target, tdata)
|
enable_target_interface(target, tdata)
|
||||||
|
|
||||||
with infamy.IsolatedMacVlan(hdata) as ns:
|
with infamy.IsolatedMacVlan(hdata) as ns:
|
||||||
ns.addip("10.0.0.1")
|
ns.addip("10.0.0.1")
|
||||||
|
|
||||||
# Fixed mode tests
|
# Pinned-mode tests: both peers advertise exactly one mode.
|
||||||
with test.step("Verify fixed 10/full"):
|
with test.step("Advertise 10/full only on both peers"):
|
||||||
set_host_speed_duplex(hdata, 10, "full")
|
advertise_host_modes(hdata, ["10full"])
|
||||||
set_target_speed_duplex(target, tdata, 10, "full")
|
set_target_advertise(target, tdata, ["10full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
verify_speed_duplex(target, ns, tdata, 10, "full")
|
||||||
|
|
||||||
with test.step("Verify fixed 10/half"):
|
with test.step("Advertise 10/half only on both peers"):
|
||||||
set_host_speed_duplex(hdata, 10, "half")
|
advertise_host_modes(hdata, ["10half"])
|
||||||
set_target_speed_duplex(target, tdata, 10, "half")
|
set_target_advertise(target, tdata, ["10half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
verify_speed_duplex(target, ns, tdata, 10, "half")
|
||||||
|
|
||||||
with test.step("Verify fixed 100/full"):
|
with test.step("Advertise 100/full only on both peers"):
|
||||||
set_host_speed_duplex(hdata, 100, "full")
|
advertise_host_modes(hdata, ["100full"])
|
||||||
set_target_speed_duplex(target, tdata, 100, "full")
|
set_target_advertise(target, tdata, ["100full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
verify_speed_duplex(target, ns, tdata, 100, "full")
|
||||||
|
|
||||||
with test.step("Verify fixed 100/half"):
|
with test.step("Advertise 100/half only on both peers"):
|
||||||
set_host_speed_duplex(hdata, 100, "half")
|
advertise_host_modes(hdata, ["100half"])
|
||||||
set_target_speed_duplex(target, tdata, 100, "half")
|
set_target_advertise(target, tdata, ["100half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||||
|
|
||||||
# Auto-negotiation tests: host advertises, Infix negotiates
|
# Multi-mode advertise tests: host restricted, target advertises all.
|
||||||
with test.step("Switch to auto-negotiation mode for target and host"):
|
with test.step("Switch target back to advertising all supported modes"):
|
||||||
enable_host_autoneg(hdata)
|
advertise_host_modes(hdata, ["100half"])
|
||||||
enable_target_autoneg(target, tdata)
|
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"])
|
advertise_host_modes(hdata, ["10full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
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"])
|
advertise_host_modes(hdata, ["10half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
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"])
|
advertise_host_modes(hdata, ["100full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
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"])
|
advertise_host_modes(hdata, ["100half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
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"])
|
advertise_host_modes(hdata, ["10half", "10full", "100half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
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"):
|
with test.step("Host advertises every mode up to 1G"):
|
||||||
advertise_host_modes(hdata, ["10half", "10full", "100half", "100full", "1000full"])
|
advertise_host_modes(hdata, ["10half", "10full", "100half",
|
||||||
|
"100full", "1000full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 1000, "full")
|
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": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -245,7 +245,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||||
lo loopback [32mUP [39m
|
lo loopback [32mUP [39m
|
||||||
ipv4 127.0.0.1/8 (static)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
br0 bridge [33m [39mvlan:1u pvid:1
|
br0 bridge [33m [39mvlan: 1u pvid: 1
|
||||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
│ ethernet 00:a0:85:00:03:00
|
||||||
│ ipv4 169.254.1.1/16 (random)
|
│ ipv4 169.254.1.1/16 (random)
|
||||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||||
├ e3 bridge [32mFORWARDING [39mvlan:1u pvid:1
|
├ e3 bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||||
├ e4 bridge [32mFORWARDING [39mvlan:1u pvid:1
|
├ e4 bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||||
├ veth0b bridge [32mFORWARDING [39mvlan:1u pvid:1
|
├ veth0b bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||||
└ veth2b bridge [32mFORWARDING [39mvlan:1u pvid:1
|
└ veth2b bridge [32mFORWARDING [39mvlan: 1u pvid: 1
|
||||||
br1 bridge [33m [39m
|
br1 bridge [33m [39m
|
||||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
│ ethernet 00:a0:85:00:03:00
|
||||||
├ veth1b bridge [32mFORWARDING [39mvlan:6u pvid:6
|
├ veth1b bridge [32mFORWARDING [39mvlan: 6u pvid: 6
|
||||||
└ veth3b bridge [32mFORWARDING [39m
|
└ veth3b bridge [32mFORWARDING [39m
|
||||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||||
e3.8 ethernet [32mUP [39m00:a0:85:00:03:03
|
e3.8 vlan [32mUP [39mvid: 8
|
||||||
│ ipv4 10.1.1.1/32 (static)
|
│ ipv4 10.1.1.1/32 (static)
|
||||||
└ e3 ethernet [32mUP [39m00:a0:85:00:03:03
|
└ e3
|
||||||
e4.8 ethernet [32mUP [39m00:a0:85:00:03:04
|
e4.8 vlan [32mUP [39mvid: 8
|
||||||
│ ipv4 10.1.1.1/32 (static)
|
│ ipv4 10.1.1.1/32 (static)
|
||||||
└ e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
└ e4
|
||||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||||
ipv4 10.1.1.101/24 (static)
|
ipv4 10.1.1.101/24 (static)
|
||||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||||
[100mveth0a container container-A [0m
|
[100mveth0a container container-A [0m
|
||||||
veth0b veth [32mUP [39me6:19:75:86:80:dd
|
veth0b veth [32mUP [39me6:19:75:86:80:dd
|
||||||
[100mveth1a container container-A [0m
|
[100mveth1a container container-A [0m
|
||||||
veth1b veth [32mUP [39m3e:67:0f:15:24:14
|
veth1b veth [32mUP [39m3e:67:0f:15:24:14
|
||||||
[100mveth2a container container-B [0m
|
[100mveth2a container container-B [0m
|
||||||
veth2b veth [32mUP [39mb2:fa:30:63:98:f0
|
veth2b veth [32mUP [39mb2:fa:30:63:98:f0
|
||||||
[100mveth3a container container-B [0m
|
[100mveth3a container container-B [0m
|
||||||
veth3b veth [32mUP [39mb2:1c:fa:a7:45:eb
|
veth3b veth [32mUP [39mb2:1c:fa:a7:45:eb
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -199,7 +199,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,51 +1,55 @@
|
|||||||
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
[7m⚑ INTERFACE PROTOCOL STATE DATA [0m
|
||||||
lo loopback [32mUP [39m
|
lo loopback [32mUP [39m
|
||||||
ipv4 127.0.0.1/8 (static)
|
ipv4 127.0.0.1/8 (static)
|
||||||
ipv6 ::1/128 (static)
|
ipv6 ::1/128 (static)
|
||||||
br-0 bridge [31mDOWN [39m
|
br-0 bridge [31mDOWN [39m
|
||||||
ethernet [31mDOWN [39m00:a0:85:00:03:00
|
ethernet 00:a0:85:00:03:00
|
||||||
br-D bridge [33m [39m
|
br-D bridge [33m [39m
|
||||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
│ ethernet 00:a0:85:00:03:00
|
||||||
│ ipv4 10.0.0.1/8 (static)
|
│ ipv4 10.0.0.1/8 (static)
|
||||||
│ ipv4 192.168.20.1/24 (static)
|
│ ipv4 192.168.20.1/24 (static)
|
||||||
│ ipv6 2001:db8::1/64 (static)
|
│ ipv6 2001:db8::1/64 (static)
|
||||||
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
│ ipv6 fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||||
└ veth0a.20 bridge [32mFORWARDING [39m
|
└ veth0a.20 bridge [32mFORWARDING [39m
|
||||||
br-Q bridge [33m [39mvlan:20u,30u,40t
|
br-Q bridge [33m [39mvlan: 20u,30u,40t
|
||||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
│ ethernet 00:a0:85:00:03:00
|
||||||
├ e3 bridge [32mFORWARDING [39mvlan:20t,30t,40t
|
├ e3 bridge [32mFORWARDING [39mvlan: 20t,30t,40t
|
||||||
└ veth0b 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.40 vlan [32mUP [39mvid: 40
|
||||||
└ br-Q ethernet [32mUP [39m00:a0:85:00:03:00
|
└ br-Q
|
||||||
br-X bridge [33m [39m
|
br-X bridge [33m [39m
|
||||||
│ ethernet [32mUP [39m00:a0:85:00:03:00
|
│ ethernet 00:a0:85:00:03:00
|
||||||
└ e2.30 bridge [32mFORWARDING [39m
|
└ e2.30 bridge [32mFORWARDING [39m
|
||||||
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
e1 ethernet [32mUP [39m00:a0:85:00:03:01
|
||||||
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:301/64 (link-layer)
|
||||||
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
||||||
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:302/64 (link-layer)
|
||||||
e2.30 ethernet [32mUP [39m00:a0:85:00:03:02
|
e2.30 vlan [32mUP [39mvid: 30
|
||||||
└ e2 ethernet [32mUP [39m00:a0:85:00:03:02
|
└ e2
|
||||||
e3.10 ethernet [32mUP [39m00:a0:85:00:03:03
|
e3.10 vlan [32mUP [39mvid: 10
|
||||||
└ e3 ethernet [32mUP [39m00:a0:85:00:03:03
|
└ e3
|
||||||
e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
e4 ethernet [32mUP [39m00:a0:85:00:03:04
|
||||||
ipv6 fe80::2a0:85ff:fe00:304/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:304/64 (link-layer)
|
||||||
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
e5 ethernet [32mUP [39m00:a0:85:00:03:05
|
||||||
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:305/64 (link-layer)
|
||||||
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
e6 ethernet [32mUP [39m00:a0:85:00:03:06
|
||||||
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:306/64 (link-layer)
|
||||||
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
e7 ethernet [32mUP [39m00:a0:85:00:03:07
|
||||||
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
ipv6 fe80::2a0:85ff:fe00:307/64 (link-layer)
|
||||||
gre-v4 gre [32mUP [39m
|
gre-v4 gre [32mUP [39mremote: 192.168.20.2
|
||||||
gre-v6 gre [32mUP [39m
|
gre-v6 gre [32mUP [39mremote: 2001:db8::2
|
||||||
ipv4 192.168.50.2/16 (static)
|
ipv4 192.168.50.2/16 (static)
|
||||||
gretap-v4 gretap [32mUP [39mf6:d4:96:d8:9f:96
|
gretap-v4 gre [32mUP [39mremote: 192.168.20.2
|
||||||
gretap-v6 gretap [32mUP [39m7a:46:13:bd:fa:e6
|
ethernet f6:d4:96:d8:9f:96
|
||||||
veth0a veth [32mUP [39m6e:d0:98:c4:e7:ef
|
gretap-v6 gre [32mUP [39mremote: 2001:db8::2
|
||||||
veth0a.20 ethernet [32mUP [39m6e:d0:98:c4:e7:ef
|
ethernet 7a:46:13:bd:fa:e6
|
||||||
└ veth0a ethernet [32mUP [39m6e:d0:98:c4:e7:ef
|
veth0a veth [32mUP [39m6e:d0:98:c4:e7:ef
|
||||||
veth0b veth [32mUP [39m36:da:80:06:7f:99
|
veth0a.20 vlan [32mUP [39mvid: 20
|
||||||
vxlan-v4 vxlan [32mUP [39m8a:ea:59:32:df:70
|
└ veth0a
|
||||||
ipv4 192.168.30.2/24 (static)
|
veth0b veth [32mUP [39m36:da:80:06:7f:99
|
||||||
vxlan-v6 vxlan [32mUP [39m3e:30:c6:a1:71:64
|
vxlan-v4 vxlan [32mUP [39mvni: 4 remote: 192.168.20.200
|
||||||
ipv4 192.168.40.2/24 (static)
|
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
|
name : br-0
|
||||||
type : bridge
|
type : bridge
|
||||||
index : 9
|
index : 9
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : down
|
operational status : down
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 00:a0:85:00:03:00
|
physical address : 00:a0:85:00:03:00
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name : br-D
|
name : br-D
|
||||||
type : bridge
|
type : bridge
|
||||||
index : 15
|
index : 15
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 00:a0:85:00:03:00
|
physical address : 00:a0:85:00:03:00
|
||||||
ipv4 addresses : 10.0.0.1/8 (static)
|
ipv4 addresses : 10.0.0.1/8 (static)
|
||||||
192.168.20.1/24 (static)
|
192.168.20.1/24 (static)
|
||||||
ipv6 addresses : 2001:db8::1/64 (static)
|
ipv6 addresses : 2001:db8::1/64 (static)
|
||||||
fe80::2a0:85ff:fe00:300/64 (link-layer)
|
fe80::2a0:85ff:fe00:300/64 (link-layer)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
name : br-Q
|
name : br-Q
|
||||||
type : bridge
|
type : bridge
|
||||||
index : 16
|
index : 16
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 00:a0:85:00:03:00
|
physical address : 00:a0:85:00:03:00
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
name : br-Q.40
|
name : br-Q.40
|
||||||
type : vlan
|
type : vlan
|
||||||
index : 17
|
index : 17
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
lower-layer-if : br-Q
|
lower-layer-if : br-Q
|
||||||
physical address : 00:a0:85:00:03:00
|
physical address : 00:a0:85:00:03:00
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
name : br-X
|
name : br-X
|
||||||
type : bridge
|
type : bridge
|
||||||
index : 11
|
index : 11
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 00:a0:85:00:03:00
|
physical address : 00:a0:85:00:03:00
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
name : gre-v4
|
name : gre-v4
|
||||||
type : gre
|
type : gre
|
||||||
index : 19
|
index : 19
|
||||||
mtu : 1476
|
mtu : 1476
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 192.168.20.1
|
local address : 192.168.20.1
|
||||||
remote address : 192.168.20.2
|
remote address : 192.168.20.2
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
name : gre-v6
|
name : gre-v6
|
||||||
type : gre
|
type : gre
|
||||||
index : 20
|
index : 20
|
||||||
mtu : 1448
|
mtu : 1448
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
ipv4 addresses : 192.168.50.2/16 (static)
|
ipv4 addresses : 192.168.50.2/16 (static)
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 2001:db8::1
|
local address : 2001:db8::1
|
||||||
remote address : 2001:db8::2
|
remote address : 2001:db8::2
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name : gretap-v4
|
name : gretap-v4
|
||||||
type : gretap
|
type : gretap
|
||||||
index : 21
|
index : 21
|
||||||
mtu : 1462
|
mtu : 1462
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : f6:d4:96:d8:9f:96
|
physical address : f6:d4:96:d8:9f:96
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 192.168.20.1
|
local address : 192.168.20.1
|
||||||
remote address : 192.168.20.2
|
remote address : 192.168.20.2
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name : gretap-v6
|
name : gretap-v6
|
||||||
type : gretap
|
type : gretap
|
||||||
index : 22
|
index : 22
|
||||||
mtu : 1434
|
mtu : 1434
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 7a:46:13:bd:fa:e6
|
physical address : 7a:46:13:bd:fa:e6
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 2001:db8::1
|
local address : 2001:db8::1
|
||||||
remote address : 2001:db8::2
|
remote address : 2001:db8::2
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name : veth0a
|
name : veth0a
|
||||||
type : veth
|
type : veth
|
||||||
index : 13
|
index : 13
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 6e:d0:98:c4:e7:ef
|
physical address : 6e:d0:98:c4:e7:ef
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 299
|
in-octets : 299
|
||||||
out-octets : 17190
|
out-octets : 17190
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
name : veth0a.20
|
name : veth0a.20
|
||||||
type : vlan
|
type : vlan
|
||||||
index : 14
|
index : 14
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
lower-layer-if : veth0a
|
lower-layer-if : veth0a
|
||||||
physical address : 6e:d0:98:c4:e7:ef
|
physical address : 6e:d0:98:c4:e7:ef
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
name : veth0b
|
name : veth0b
|
||||||
type : veth
|
type : veth
|
||||||
index : 12
|
index : 12
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 36:da:80:06:7f:99
|
physical address : 36:da:80:06:7f:99
|
||||||
ipv4 addresses :
|
ipv4 addresses :
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
in-octets : 17190
|
in-octets : 17190
|
||||||
out-octets : 299
|
out-octets : 299
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
name : vxlan-v4
|
name : vxlan-v4
|
||||||
type : vxlan
|
type : vxlan
|
||||||
index : 23
|
index : 23
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 8a:ea:59:32:df:70
|
physical address : 8a:ea:59:32:df:70
|
||||||
ipv4 addresses : 192.168.30.2/24 (static)
|
ipv4 addresses : 192.168.30.2/24 (static)
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 192.168.20.100
|
local address : 192.168.20.100
|
||||||
remote address : 192.168.20.200
|
remote address : 192.168.20.200
|
||||||
VxLAN id : 4
|
VxLAN id : 4
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
name : vxlan-v6
|
name : vxlan-v6
|
||||||
type : vxlan
|
type : vxlan
|
||||||
index : 24
|
index : 24
|
||||||
mtu : 1500
|
mtu : 1500
|
||||||
operational status : up
|
operational status : up
|
||||||
ip forwarding : disabled
|
ip forwarding : disabled
|
||||||
physical address : 3e:30:c6:a1:71:64
|
physical address : 3e:30:c6:a1:71:64
|
||||||
ipv4 addresses : 192.168.40.2/24 (static)
|
ipv4 addresses : 192.168.40.2/24 (static)
|
||||||
ipv6 addresses :
|
ipv6 addresses :
|
||||||
local address : 2001:db8::100
|
local address : 2001:db8::100
|
||||||
remote address : 2001:db8::200
|
remote address : 2001:db8::200
|
||||||
VxLAN id : 6
|
VxLAN id : 6
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
"mtu": 1500
|
"mtu": 1500
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
{
|
{
|
||||||
"admin-status": "up",
|
"admin-status": "up",
|
||||||
"ieee802-ethernet-interface:ethernet": {
|
"ieee802-ethernet-interface:ethernet": {
|
||||||
"auto-negotation": {
|
"auto-negotiation": {
|
||||||
"enable": false
|
"enable": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user