Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add interfaces layer property to openconfig-interfaces model #1083

Closed
wants to merge 3 commits into from

Conversation

mikewiebe
Copy link
Contributor

@mikewiebe mikewiebe commented Apr 3, 2024

Change Scope

The proposal is to add an additional "layer" leaf to interface
This is to explicitly specify the interface layer.

interfaces
   +-- interface[name]
           +-- config
           +     +-- name
           +     +-- type
           |     +-- layer <<< new leaf
           +-- state
                 +-- layer
  • The layer can by Layer2 or Layer3
  • This change is backward compatible
    When the 'layer" is not specified, the behavior is the same as if the "layer" is not defined in the previous model.

pyang tree output

module: openconfig-interfaces
  +--rw interfaces
     +--rw interface* [name]
        +--rw name                  -> ../config/name
        +--rw config
        |  +--rw name?            string
        |  +--rw type             identityref
        |  +--rw mtu?             uint16
        |  +--rw loopback-mode?   oc-opt-types:loopback-mode-type
        |  +--rw description?     string
        |  +--rw enabled?         boolean
        |  +--rw layer?           identityref
        +--ro state
        |  +--ro name?            string
        |  +--ro type             identityref
        |  +--ro mtu?             uint16
        |  +--ro loopback-mode?   oc-opt-types:loopback-mode-type
        |  +--ro description?     string
        |  +--ro enabled?         boolean
        |  +--ro layer?           identityref
        |  +--ro ifindex?         uint32
        |  +--ro admin-status     enumeration
        |  +--ro oper-status      enumeration
        |  +--ro last-change?     oc-types:timeticks64
        |  +--ro logical?         boolean
        |  +--ro management?      boolean
        |  +--ro cpu?             boolean

Rationale

Currently in openconfig-interface, there is no “layer” information for an interface,
while L2 (switching) / L3 (routing) child configs are all mixed across the interface model.

  • Example L2 config : switch-vlan, dot1x, etc
  • Example L3 config : proxy-arp, ip addressed, dhcp, etc

Since the interface can mix and match both L2 and L3 config, the model user could have the impression that any given interface can operate concurrently in both the switching and routing mode. This is not true across vendors. Commonly an interface either operates in L2 or L3 mode, and it requires explicit configuration to toggle the interface layer.

The lack of the “layer” affects both the model user and the target device :

  • Currently the model user would need to infer the interface layer.

    • Via the interface "name"
      The interface name may suggest its operating layer.
      For example, when the interface name is like vl12, Vlan12, lo100,
      the user can infer these interfaces are logical, and thus are used for routing.
      But such naming semantics is rather vendor specific

    • Via the interface "type"
      Some specific interface types could also suggest its operarting layer.
      For example, the type "iana:softwareLoopback" is a lookback, and thus deemed for routing.
      Though commonly, the interface type refers more to the underlying medium/technology.
      For example, the type "iana:ethernetCsmacd" only means the inteface is an ethernet link,
      it does not tell whether such ethernet interface serves for switching or routing.

  • Oppositely, the target device also needs to infer the model user’s intent.
    Take the above ethernet interface as example. The interface may support either L2 or L3 functionality.
    . If the user ever touches the L3-ish config, like ip (or dhcp, etc), then toggle the interface to L3
    . If the user ever touches the L2-ish config, like vlan (or dot1q, etc), then toggle the interface to L2.

These guess works are not straight-forward nor unreliable.
Thus the proposal is to add a new config leaf “interfaces/interface/config/layer” to eliminate such uncertainty/ambiguity.
Though to emphasize again, the new "layer" config is optional. If the "layer" is not specified, the behavior remains the same as the current behavior.

Platform Implementations

@mikewiebe mikewiebe requested a review from a team as a code owner April 3, 2024 16:48
@wenovus
Copy link
Contributor

wenovus commented Apr 3, 2024

/gcbrun

@OpenConfigBot
Copy link

OpenConfigBot commented Apr 3, 2024

No major YANG version changes in commit 709071e

@wenovus
Copy link
Contributor

wenovus commented Apr 3, 2024

/gcbrun

Copy link
Contributor

@rolandphung rolandphung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very useful and welcomed change. Thanks for getting this up :-)

description
"Types associated with a interface";

oc-ext:openconfig-version "3.7.1";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is not a submodule, we can start with 1.0.0

@dplore
Copy link
Member

dplore commented Apr 4, 2024

Thanks Mike, please provide some explicit examples where there is a problem without this leaf and using the new leaf solves the issue. Consider that subinterfaces is where OC defines properties for logical and layer 3 interfaces.

@mikewiebe
Copy link
Contributor Author

mikewiebe commented Apr 9, 2024

Thanks Mike, please provide some explicit examples where there is a problem without this leaf and using the new leaf solves the issue. Consider that subinterfaces is where OC defines properties for logical and layer 3 interfaces.

Here is the additional information:

Problem Statement:

Take an ethernet port ‘eth1/1’ as example.
This is an ethernet port which can run either in L2 or L3 layer based on the ‘switchport’ config.
The layer then dictates the valid child config under the interface, ie, L2 and L3 configs are mutual exclusive.

  • When the interface is in L2 mode,
    it can only config the L2-ish config, like the below trunk config
      interface Ethernet1/3
        switchport
        switchport mode trunk
        switchport trunk native vlan 100

The trunk config is equivalent to the below opeconfig path.

      interfaces/interface[name=eth1/3]/ethernet/switched-vlan/interface-mode  = TRUNK
                                                               native-vlan     = 100
  • When the interface is in L3 mode.
    it can only config the L3-ish config, like the below ip config
      interface Ethernet1/3
        no switchport
        ip address 1.1.1.1/24
        ipv6 address 1::1/24

The ip/ipv6 config is equivalent to the below opeconfig path.

      interfaces/interface[name=eth1/3]/subinterfaces/subinterface/ipv4/addresses/address/ip = 1.1.1.1
                                                                   ipv6/addresses/address/ip = 1::1

Now, for an openconfig user, the existing ‘name=eth1/3” and “type=ethernetCsmacd” could not differentiate the interface layer,so user cannot change the L2-ish / L3-ish freely.
If e1/3 is currently in the L2, then the user cannot config any L3-ish config via openconfig.
Vice-versa for e1/2 in L3.

There exist two current workarounds:

  • Mixed model workaround
    The user needs to defer to the proprietary way to toggle e1/3, through vendor specific cli or device yang.
    Only then the user can proceed the change at the openconfig side.

  • Inference workaround
    The target device needs to infer the user intent based on some heuristics like

    • if the request config the L2-ish path (ex interfaces/.../switched-vlan/...) then silently change the interface to L2.
    • if the request unconfig the L2-ish path, then revert the interface to L3.
      … etc
      However, this is pretty error-prone.
      As a single openconfig request can always mix all various L2 and L3 config.
      Netconf is even worse as it allows both config / unconfig to mix in a single payload.

These two workaround are far less than ideal for the usability perspective.
Thus we need the change.

Subinterfaces

This proposed “layer” property does NOT change sub-interfaces behavior.

Take the same ethernet 1/3 as the example.
In NXOS, only L3 interface can support sub-interface.
In the below example, we have the “parent physical e1/3” and “logical sub-interface e1/3.100”,
Both interfaces can have their own L3 config

interface Ethernet1/3
  no switchport
  ip address 1.1.1.1/24
 
interface Ethernet1/3.100
  ip address 4.4.4.4/24

The equivalent openconfig representation is as the following.

interfaces/interface[name=eth1/3]/subinterfaces/subinterface[0]/ipv4/addresses/address/ip = 1.1.1.1
                                  subinterfaces/subinterface[100]/ipv4/addresses/address/ip = 4.4.4.4

If e1/3 is in the L2 layer, then sub-interfaces is not even supported.
Today, without the “layer” property, the user needs to first use CLI or device YANG to change e1/3 to L3, then the user can config sub-interfaces.
This is already the existing behavior with or without the “layer” property anyway.

Granted that for other vendor devices, they may support sub-interfaces under both physical L2 and L3 parent interfaces.
Though it is still irrelevant to this change, as in this proposal, we deliberately do not include any restriction with the new “layer” property.
Image if the change has included the following to restrict the sub-interfaces node, then we indeed have compatibility concern.
But given that this change does not impose any of such new restrictions, it does not introduce behavior changes.

    list interface {
       ...
       uses subinterfaces-top {
+++      when "oc-if:config/oc-if:layer = 'oc-if-type:L3'" {
         ...
       }
    }

@LimeHat
Copy link

LimeHat commented Apr 9, 2024

      interface Ethernet1/3
        no switchport
        ip address 1.1.1.1/24
        ipv6 address 1::1/24

Note that in OC, IP addresses always belong to subinterfaces (which is not the case in this cli example).

If e1/3 is in the L2 layer, then sub-interfaces is not even supported.

In a specific implementation, perhaps.

In OC, subinterfaces can be used with L2 network instances.

I understand that the idea is to introduce "switchport/no switchport" equivalent to OC, but I'm not convinced it fits well into the overall architecture. There's a bit more basis for that for legacy-ish l2 switching that does not use subifs, but then there's already interface-mode that is related to this use case and covers this scenario to a certain extent.

leaf interface-mode {
type oc-vlan-types:vlan-mode-type;
description
"Set the interface to access or trunk mode for
VLANs";
}

@robshakir any thoughts?

@jorabada
Copy link

I agree with @LimeHat with all his comments. Another question would be: if an implementation needs this, can the interface type not be used? in the referred implementations it seems pointless to have type ethernetCsmacd and other types like l2vlan or l3ipvlan may provide the required distinction..

@earies
Copy link
Contributor

earies commented Apr 12, 2024

A few comments:

Consider that subinterfaces is where OC defines properties for logical and layer 3 interfaces
...
Note that in OC, IP addresses always belong to subinterfaces (which is not the case in this cli example).

Not entirely true - see: #781

Since this is not a submodule, we can start with 1.0.0

Any new model that has been introduced to date should have carried 0.1.0 and at some point of adoption/stabilization move to 1.0.0

in the referred implementations it seems pointless to have type ethernetCsmacd

Agreed - how many implementations do you have to dictate an ethernet interface to be ethernet? Then validate to ensure the dictated type actually corresponds to the actual underlying physical hardware? Or drop on the floor, do nothing with it but merely reflect it back... For logical interfaces where you can dictate various encapsulations sure - also see: #780

As an implementor (and cross referencing other implementations), this type has < 3% usage of the model identities defined so an implementation must go through an extra effort for true validations that fall outside of what can be expressed in the YANG language today in 1.0/1.1

Today, without the “layer” property, the user needs to first use CLI or device YANG to change e1/3 to L3, then he/she can config sub-interfaces.

Not necessarily however this is also not a unique problem when translating between alien schemas and native constructs that mismatch in implementation behavior. Translation logic could handle this but it comes at a cost - this is what happens when trying to normalize things that may vary greatly underneath - the 1:many and many:1 translation w/ additional checks then occurs which is derived off the intended payload. Part of this is also that the model does not provide some of the guardrails in that a client can generate a schema compliant configuration that would ultimately fail on the device when applied. This again is a common problem statement in all of this which also applies to the underlying native implementation as well.

I understand that the idea is to introduce "switchport/no switchport" equivalent to OC, but I'm not convinced it fits well into the overall architecture.

And seems along the same lines as classical ip routing enablement...

We (Juniper) don't have this explicit concept but rather take paths based on "families" - essentially no precursor step necessary to dictate the mode

@dplore
Copy link
Member

dplore commented Jul 2, 2024

Hi there, I am not seeing an operational use case for this change. Can you provide some specific examples of configuration that is needed operationally and cannot be done without this change? The two examples seem relatively straight forward for the NOS to understand if layer 2 switching or layer 3 routing is requested by the user:

      interfaces/interface[name=eth1/3]/ethernet/switched-vlan/interface-mode  = TRUNK
                                                               native-vlan     = 100
      interfaces/interface[name=eth1/3]/subinterfaces/subinterface/ipv4/addresses/address/ip = 1.1.1.1
                                                                   ipv6/addresses/address/ip = 1::1

The NOS should enforce that the interface in question cannot be configured with both of these snippets at the same time.

@github-actions github-actions bot added the Stale label Dec 30, 2024
@github-actions github-actions bot closed this Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waiting for author
Development

Successfully merging this pull request may close these issues.

8 participants