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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions osism/tasks/conductor/sonic/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@
# High speed ports that use 4x multiplier (lanes)
HIGH_SPEED_PORTS = {100000, 200000, 400000, 800000} # 100G, 200G, 400G, 800G in Mbps

# Supported four-subport breakout modes keyed by subport speed in Mbps
# (get_interface_speed normalizes explicit NetBox kbps speeds to Mbps).
# The SONiC EthernetX detection path filters breakout groups to <= 50G,
# so the 100G and 200G entries only match the NetBox EthX/Y/Z path;
# SONiC-format 4x100G is handled by the dedicated 400G branch.
BREAKOUT_MODE_BY_SPEED = {
10000: "4x10G",
25000: "4x25G",
50000: "4x50G",
100000: "4x100G",
200000: "4x200G",
}

# Path to SONiC port configuration files
PORT_CONFIG_PATH = "/etc/sonic/port_config"

Expand Down
33 changes: 15 additions & 18 deletions osism/tasks/conductor/sonic/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
import re
from loguru import logger

from .constants import PORT_TYPE_TO_SPEED_MAP, HIGH_SPEED_PORTS, PORT_CONFIG_PATH
from .constants import (
BREAKOUT_MODE_BY_SPEED,
HIGH_SPEED_PORTS,
PORT_CONFIG_PATH,
PORT_TYPE_TO_SPEED_MAP,
)
from .cache import get_cached_device_interfaces

# Global cache for port configurations to avoid repeated file reads
Expand Down Expand Up @@ -750,17 +755,10 @@ def detect_breakout_ports(device):
)

# Calculate breakout mode
if interface_speed == 10000 and num_subports == 4:
brkout_mode = "4x10G"
elif interface_speed == 25000 and num_subports == 4:
brkout_mode = "4x25G"
elif interface_speed == 50000 and num_subports == 4:
brkout_mode = "4x50G"
elif interface_speed == 100000 and num_subports == 4:
brkout_mode = "4x100G"
elif interface_speed == 200000 and num_subports == 4:
brkout_mode = "4x200G"
else:
brkout_mode = BREAKOUT_MODE_BY_SPEED.get(
interface_speed
)
if num_subports != 4 or not brkout_mode:
logger.debug(
f"Unsupported breakout configuration: {num_subports} ports at {interface_speed} Mbps"
)
Expand Down Expand Up @@ -917,14 +915,13 @@ def detect_breakout_ports(device):
if len(sonic_breakout_group) == 4:
master_port = f"Ethernet{base_port}"

# Determine breakout mode based on speed
# Determine breakout mode based on speed; the membership
# filter above (<= 50G) limits this path to 4x10G, 4x25G
# and 4x50G
interface_speed = get_interface_speed(sonic_breakout_group[0][1])

if interface_speed == 25000:
brkout_mode = "4x25G"
elif interface_speed == 50000:
brkout_mode = "4x50G"
else:
brkout_mode = BREAKOUT_MODE_BY_SPEED.get(interface_speed)
if not brkout_mode:
continue # Skip unsupported speeds

# Calculate physical port number (Ethernet0-3 -> port 1/1, Ethernet4-7 -> port 1/2, etc.)
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/tasks/conductor/sonic/test_breakout_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,9 @@ def test_detect_breakout_ports_sonic_400g_4_lane_master_falls_through(
@pytest.mark.parametrize(
"speed, expected_mode",
[
# Explicit speeds are kbps as NetBox stores them; detection
# normalizes them to Mbps before the breakout mode lookup.
(10_000_000, "4x10G"),
(25_000_000, "4x25G"),
(50_000_000, "4x50G"),
],
Expand Down