Modeling channelized subinterfaces as child interfaces #739

Open
opened 2026-04-05 17:22:23 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @jeremystretch on 12/12/2025

NetBox version

v4.4.8

Feature type

Data model extension

Proposed functionality

This FR aims to tackle the challenge of better modeling channelized subinterfaces in NetBox. It was prompted by work on FR NB-2037, but addresses a long-standing limitation in the data model. It is the solution for improved cable tracing provided under NB-2037 for the upcoming v4.5 release that unlocks this proposed work.

1. Add a channels integer field on the Interface model

This field will indicate the number of channels available on the parent interface. channels will be null for non-channelized interfaces.

Crucially, the cable tracing logic will need to be updated to reflect this new arrangement: A cable terminating to a channelized interface should effect path traces originating from and terminating at each of is channelized subinterfaces.

2. Add a channel_id integer field on the Interface model

In conjunction with the parent foreign key already present, this field will indicate the numeric channel on a parent interface to which a subinterface is bound.

Only one layer of channelization is to be permitted: An interface cannot have both channels and channel_id defined.

3. Introduce a "Channel" interface type (optional)

This new generic "channel" interface type may be introduced specifically to identify channelized subinterfaces. I believe this may be helpful as a guardrail to prevent errant configurations, as we can validate the assigned type of an interface against the channel_id field, and it avoids contention between the parent and child interface types.

However, if we find that there's sufficient value in retaining the explicit declaration of a subinterface's type (e.g. directly defining a 40GE channel as 10GBASE-SR) rather than inferring the type from a parent interface, we may opt to skip this element of the proposal. In this event, we would need to loosen the current restriction of assigning physical interface types to a parent, permitting it only where channelization is in use.

TBD

One potential issue for consideration is the handling of channelized interfaces which "consume" the parent interface. For instance, IIRC on some Junos platforms the original 40GE interface et-0/0/0 may be replaced in the configuration by four 10GE interfaces (xe-0/0/0 through xe-0/0/3). In this scenario, it's not clear how the parent interface would be accurately modeled.

Use case

As we've long held, a channelized interface is a physical subinterface which is dependent to some degree upon the characteristics of a parent interface. A very common example is a channelized 40GE interface which is broken out to 4x10GE channels, each terminating to an independent 10GE interface on the far end, with each channel utilizing a discrete fiber pair within e.g. an 8- or 12-strand MPO fiber cable. An example cable is show below.

!https://github.com/user-attachments/assets/459081d8-a1ce-4c66-a02d-99b5e36b7206

The subinterfaces manifest on the network device as either four independent 10GE interfaces (e.g. xe-0/0/0 through xe-0/0/3) or as four numbered channels on a common parent (e.g. Eth1/1:1 through Eth1/1:4). It's crucial to recognize that these are not virtual interfaces: Each subinterface is physically bound to an underlying medium, and the number of subinterfaces therefore is fixed.

The current recommended practice for modeling channelized subinterfaces is to simply model each interface independently, and create a separate cable termination for each. While this generally suffices, it presents two complications:

  1. It does not convey a dependency of the subinterface on its parent (which typically is not modeled).
  2. Showing multiple cable terminations (one per subinterface) is inaccurate (or at best confusing) as there is only a single connector shared by all the subinterfaces.

Database changes

Add nullable channels and channel_id PositiveSmallIntegerFields on dcim.Interface.

External dependencies

N/A

*Originally created by @jeremystretch on 12/12/2025* ### NetBox version v4.4.8 ### Feature type Data model extension ### Proposed functionality This FR aims to tackle the challenge of better modeling channelized subinterfaces in NetBox. It was prompted by work on FR [NB-2037](https://linear.app/netboxlabs/issue/NB-2037/cable-profiles-and-connectorposition-mapping), but addresses a long-standing limitation in the data model. It is the solution for improved cable tracing provided under [NB-2037](https://linear.app/netboxlabs/issue/NB-2037/cable-profiles-and-connectorposition-mapping) for the upcoming v4.5 release that unlocks this proposed work. #### 1\. Add a `channels` integer field on the Interface model This field will indicate the number of channels available on the parent interface. `channels` will be null for non-channelized interfaces. Crucially, the cable tracing logic will need to be updated to reflect this new arrangement: A cable terminating to a channelized interface should effect path traces originating from and terminating at each of is channelized subinterfaces. #### 2\. Add a `channel_id` integer field on the Interface model In conjunction with the `parent` foreign key already present, this field will indicate the numeric channel on a parent interface to which a subinterface is bound. Only one layer of channelization is to be permitted: An interface cannot have both `channels` and `channel_id` defined. #### 3\. Introduce a "Channel" interface type (optional) This new generic "channel" interface type may be introduced specifically to identify channelized subinterfaces. I believe this may be helpful as a guardrail to prevent errant configurations, as we can validate the assigned type of an interface against the `channel_id` field, and it avoids contention between the parent and child interface types. However, if we find that there's sufficient value in retaining the explicit declaration of a subinterface's type (e.g. directly defining a 40GE channel as 10GBASE-SR) rather than inferring the type from a parent interface, we may opt to skip this element of the proposal. In this event, we would need to loosen the current restriction of assigning physical interface types to a parent, permitting it only where channelization is in use. #### TBD One potential issue for consideration is the handling of channelized interfaces which "consume" the parent interface. For instance, IIRC on some Junos platforms the original 40GE interface `et-0/0/0` may be replaced in the configuration by four 10GE interfaces (`xe-0/0/0` through `xe-0/0/3`). In this scenario, it's not clear how the parent interface would be accurately modeled. ### Use case As we've long held, a channelized interface is a *physical* subinterface which is dependent to some degree upon the characteristics of a parent interface. A very common example is a channelized 40GE interface which is broken out to 4x10GE channels, each terminating to an independent 10GE interface on the far end, with each channel utilizing a discrete fiber pair within e.g. an 8- or 12-strand MPO fiber cable. An example cable is show below. !https://github.com/user-attachments/assets/459081d8-a1ce-4c66-a02d-99b5e36b7206 The subinterfaces manifest on the network device as either four independent 10GE interfaces (e.g. `xe-0/0/0` through `xe-0/0/3`) or as four numbered channels on a common parent (e.g. `Eth1/1:1` through `Eth1/1:4`). It's crucial to recognize that these are *not* virtual interfaces: Each subinterface is physically bound to an underlying medium, and the number of subinterfaces therefore is fixed. The current recommended practice for modeling channelized subinterfaces is to simply model each interface independently, and create a separate cable termination for each. While this generally suffices, it presents two complications: 1. It does not convey a dependency of the subinterface on its parent (which typically is not modeled). 2. Showing multiple cable terminations (one per subinterface) is inaccurate (or at best confusing) as there is only a single connector shared by all the subinterfaces. ### Database changes Add nullable `channels` and `channel_id` PositiveSmallIntegerFields on dcim.Interface. ### External dependencies N/A
MrUnknownDE added the status: under reviewnetboxcomplexity: mediumtype: featurestatus: under reviewstatus: under reviewstatus: under reviewstatus: under reviewstatus: under reviewnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumcomplexity: mediumtype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: featuretype: feature labels 2026-04-05 17:22:51 +02:00
Sign in to join this conversation.
No Label complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium complexity: medium netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox status: under review status: under review status: under review status: under review status: under review status: under review type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature type: feature
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#739