Skip to content
LinkState
Go back

Breakouts, subinterfaces, and LAGs as first-class data

Introduction to Interface Modeling

Overview of Interface Types

Modern network devices expose logical and physical constructs that automation must represent consistently:

These types can nest (e.g., a subinterface on a breakout lane that is a bundle member) and may share configuration dependencies. An interface model must capture inheritance, composition, and references without duplicating rules or hiding operational dependencies.

Importance of Accurate Interface Representation

Automation frameworks (Ansible, Terraform, custom controllers) rely on a canonical model to:

Duplicating inheritance rules (e.g., defining MTU on each subinterface and the parent) creates maintenance overhead and risk of inconsistency. Hiding dependencies (treating a bundle as an opaque block) blocks automation from verifying pre‑conditions such as member‑link state.

Interface Model Design

Breakout Ports

Definition and Purpose

A breakout port represents a single physical transceiver internally multiplexed into N independent logical lanes, enabling granular bandwidth without extra slots (e.g., 100 GbE → 4×25 GbE).

Configuration and Implementation

Breakout mode is set at the physical port; the device creates child interfaces using a vendor‑specific naming scheme (e.g., Eth1/1/1 on Cisco NX‑OS, et-0/0/0:0:3 on Juniper Junos). Child lanes inherit the parent’s physical‑layer attributes:

The model stores a parent‑child relationship where the parent holds the breakout mode and children inherit these attributes unless overridden (rarely allowed).

Subinterfaces

Definition and Purpose

A subinterface is a logical interface instantiated on a physical or breakout port to support multiple Layer‑2/Layer‑3 services over the same media, identified by an encapsulation tag (VLAN, QinQ, MPLS label, etc.).

Configuration and Implementation

Configuration selects the parent interface and specifies the encapsulation ID. Common per‑subinterface parameters:

The model captures that a subinterface depends on its parent’s operational state and physical attributes while allowing certain attributes to be locally configured. Inheritance is partial: some attributes are inherited by default, some are overridable, some are prohibited.

Logical Bundles

Definition and Purpose

A logical bundle (LAG, port‑channel, ethernet‑bundle) aggregates multiple member links to provide increased bandwidth, load‑sharing, and resilience, presenting a single interface to higher‑layer protocols.

Configuration and Implementation

Steps:

  1. Create the bundle interface (logical entity).
  2. Add member links (physical ports, breakout lanes, or subinterfaces).
  3. Optionally configure load‑balancing hash, LACP mode (active/passive/off), and minimum links for bundle‑up.

Attributes that must be homogeneous across members (or derived from them):

The model enforces homogeneity constraints, exposes the reference set of members, and supports dynamic membership (LACP) where members can be added/removed without recreating the bundle.

Cross‑Connects

Definition and Purpose

A cross‑connect (XC) is a deterministic mapping between an ingress termination point and an egress termination point, used in transport‑layer technologies (MPLS‑TP, OTN, pseudowire) to create a fixed path bypassing conventional routing/forwarding tables.

Configuration and Implementation

Configuration specifies:

The XC does not inherit routing attributes; it is a pure Layer‑1/Layer‑2 binding. The model must still track the operational state of the underlying termination points because an XC is usable only when both ends are up.

Implementing the Interface Model

Data Modeling Approach

Entity‑Relationship Diagram

[PhysicalPort] 1 --* [BreakoutLane]   (breakout_mode)
[PhysicalPort] 1 --* [Subinterface]   (encap_id)
[PhysicalPort] 1 --* [LogicalBundle]  (bundle_id)   <-- many‑to‑many via [BundleMember]
[LogicalBundle] * --* [BundleMember]   (member_id)   <-- [BundleMember] links to PhysicalPort/BreakoutLane/Subinterface
[Subinterface] 1 --* [CrossConnect]   (xc_ingress)
[Subinterface] 1 --* [CrossConnect]   (xc_egress)
[PhysicalPort] 1 --* [CrossConnect]   (xc_ingress)   (if XC terminates on raw port)
[PhysicalPort] 1 --* [CrossConnect]   (xc_egress)

Inheritance is modeled by storing attributes on the parent entity that child entities reference unless overridden. Reference sets (e.g., bundle members) are explicit many‑to‑many relationships, avoiding duplicated configuration rules. Cross‑connects are separate entities that reference termination points; they own no configuration attributes beyond the mapping.

Object‑Oriented Programming (Python‑like pseudocode)

class Interface:
    def __init__(self, name, mtu=1500, admin_state='up'):
        self.name = name
        self.mtu = mtu
        self.admin_state = admin_state
        self.oper_state = 'down'   # populated by hardware

class PhysicalPort(Interface):
    def __init__(self, name, media_type, fec_mode, breakout_mode=None):
        super().__init__(name)
        self.media_type = media_type
        self.fec_mode = fec_mode
        self.breakout_mode = breakout_mode   # None, '4x10G', '2x50G', etc.
        self.children = []   # holds BreakoutLane or Subinterface objects

class BreakoutLane(Interface):
    def __init__(self, parent: PhysicalPort, lane_index):
        super().__init__(name=f"{parent.name}:{lane_index}")
        # Inherit physical‑layer attributes unless overridden
        self.media_type = parent.media_type
        self.fec_mode = parent.fec_mode
        self.breakout_mode = None   # lanes themselves are not breakable further
        self.parent = parent

class Subinterface(Interface):
    def __init__(self, parent: Interface, encap_id):
        super().__init__(name=f"{parent.name}.{encap_id}")
        self.encap_id = encap_id
        self.parent = parent
        # Inherit MTU by default, but allow override
        self.mtu = parent.mtu

class LogicalBundle(Interface):
    def __init__(self, name):
        super().__init__(name)
        self.members = []   # list of Interface objects
        self.lacp_mode = 'off'
        self.min_links = 1

    def add_member(self, iface: Interface):
        # Enforce homogeneity checks
        if self.members and iface.mtu != self.mtu:
            raise ValueError("MTU mismatch")
        self.members.append(iface)
        iface.bundle = self

class CrossConnect:
    def __init__(self, xc_id, ingress: Interface, egress: Interface):
        self.xc_id = xc_id
        self.ingress = ingress
        self.egress = egress
        self.state = 'down'   # depends on ingress/egress oper_state

This design avoids duplicating inheritance rules: child classes reference parent attributes, and validation logic lives in the bundle’s add_member method.

Code Examples

Breakout Port Configuration

YANG (openconfig-interfaces)

container ethernet {
  leaf port-speed {
    type union {
      type eth-bandwidth;
      type enumeration {
        enum BREAKOUT_4X10G;
        enum BREAKOUT_2X25G;
        enum BREAKOUT_1X40G;
      }
    }
  }
  container breakout {
    if-feature "oc-if:breakout";
    leaf mode {
      type enumeration {
        enum NONE;
        enum FOUR_X_10G;
        enum TWO_X_25G;
        enum ONE_X_40G;
      }
    }
  }
}

CLI (Cisco IOS‑XR)

interface TenGigE0/0/0/0
  speed 100g
  breakout 4x10g
!
interface TenGigE0/0/0/0:0
  description Breakout lane 0
!
interface TenGigE0/0/0/0:1
  description Breakout lane 1
!

Subinterface Configuration

YANG (openconfig-if-ip)

container subinterfaces {
  list subinterface {
    key "index";
    leaf index { type uint32; }
    leaf encap {
      type encapsulation;   // includes VLAN, QinQ, etc.
    }
    container ipv4 {
      leaf address {
        type inet:ipv4-address;
      }
      leaf prefix-length { type uint8; }
    }
  }
}

CLI (Juniper Junos)

set interfaces xe-0/0/0 unit 100 vlan-id 100
set interfaces xe-0/0/0 unit 100 family inet address 10.0.0.1/24
set interfaces xe-0/0/0 unit 100 family mpls

Logical Bundle Configuration

YANG (openconfig-lag)

container lag {
  list interface {
    key "name";
    leaf name { type string; }
    container lag-attributes {
      leaf-list member { type if:interface-ref; }
      leaf lacp { type enumeration { enum ACTIVE; enum PASSIVE; enum OFF; } }
      leaf min-links { type uint16; }
    }
  }
}

CLI (Nokia SR OS)

configure
  lag 1

Share this post on:

Previous Post
Generating parsers from samples without blind trust
Next Post
When shared peer-group policy leaks into IX sessions