hellt / vrnetlab

Make VM-based Network OSes run in Containerlab
https://containerlab.dev
MIT License
129 stars 88 forks source link

Add interface aliases #200

Closed vista- closed 5 months ago

vista- commented 5 months ago

Interface aliases allow for the use of container interface names similar or matching those used by virtual appliances encapsulated in vrnetlab. This allows containerlab and any other projects that might use vrnetlab to better represent the internal network interface names of NOSes, and also allows for easier labbing and automatable lab generation based on existing topologies.

ethX based naming still works the same by design.

This PR adds interface aliases for most VM types, except for the following:

How does this work?

Containerlab creates interfaces within the container based on the Containerlab topology definition. vrnetlab expects these interfaces to be called ethX, corresponding to VM NIC interface X. eth0 is reserved for management purposes, and eth1 and up are data plane interfaces.

An important aspect of adding this feature is that backwards-compatibility needs to be preserved for vrnetlab naming rules (and by extension, for existing Containerlab topologies).

The implementation is based on the Linux Netlink feature called "altnames". When an interface has an altname set on it, Netlink-based tooling can transparently refer to this interface via its altname. Altnames were introduced in Linux kernel 5.5 and is a fairly mature feature.

The underlying vrnetlab interface handling logic, including the tc and vr-xcon connection modes, continues to rely on and use ethX-based interface naming. By adding appropriate ethX altnames to the container interfaces, virtual appliance-specific interface names can be used in topologies, while preserving correct container-to-VM interface naming.

Adding interface aliases to VM types

Developers working on existing or new VM types can add interface aliases by defining two new attributes on the VM class:

Additionally, the function for calculating aliased interface index offsets, calculate_interface_offset, can also be redefined inside the specific VM model. This is particularly useful for complex, LC-based virtual appliances, where additional calculation and information might be needed to correctly find the interface offset.

[!CAUTION] It's important that container interface names must NOT contain two characters that NOSes like to use: / and ` (whitespace). I would propose substituting the former with a-` and just removing the latter as a "good-enough" solution.

It is also important to note that Linux interface names must be at most 15 bytes long (16 bytes including null termination) -- some NOS's long interface names don't fit this limitation! These interface names need to be truncated or shortened by applications using vrnetlab containers.

Example usage

Say, we want to spin up a topology with the following kind of nodes:

and then connect them like so:

Using the ethX node names, one would have to create the following container interfaces and connect them up in the following manner (in this case, using the topology definition of Containerlab):

   links:
     - endpoints: ["vSRX:eth3", "vEOS:eth2"]
     - endpoints: ["CSR1000v:eth4", "vSRX:eth6"]
     - endpoints: ["vEOS:eth3", "CSR1000v:eth2"]

Note the three different kinds of offset used here on the three different types of VM images!

Using aliased interface names, the topology definition becomes more straightforward:

  links:
    - endpoints: ["vSRX:ge-0-0-2", "vEOS:Ethernet1-2"]
    - endpoints: ["CSR1000v:Gi5", "vSRX:ge-0-0-5"]
    - endpoints: ["vEOS:Ethernet1-3", "CSR1000v:Gi3"]

[!NOTE] Inside the vrnetlab containers, the following interfaces and altnames get created. This is done transparently to the user and to the application using vrnetlab. The calculations show the parsed port index, the alias offset and the starting ethX data interface index (currently supported aliases only derive this from the base VM subclass, where it's set to 1) respectively.

  • vSRX
    • ge-0-0-2 -> eth3 (2 - 0 + 1)
    • ge-0-0-5 -> eth6 (5 - 0 + 1)
  • vEOS
    • Ethernet1-2 -> eth2 (2 - 1 + 1)
    • Ethernet1-3 -> eth3 (3 - 1 + 1)
  • CSR1000v
    • Gi3 -> eth2 (2 - 2 + 1)
    • Gi5 -> eth4 (5 - 2 + 1)

What's next?

Testing for more "harder to acquire" VM types would be very welcome! Additional contributions for interface aliases, especially for SR OS, would be superb.

So far, these have been tested working with interface aliases, including discontinuous interface indexes in use, as well as legacy ethX-based interface naming:

After this PR is merged to vrnetlab, additional work is needed to add NOS-specific interface naming to Containerlab before this feature can be leveraged. This should be fairly straightforward by defining appropriate CheckInterfaceName functions for vrnetlab-based Kinds -- this function is already used to check NOS-specific interface names in containerised NOSes.

vista- commented 5 months ago

An interesting thing to note here is that some NOSes have interface names which don't fit Linux interface naming size constraints, such as IOS XR: GigabitEthernet-0-0-0-0 -> 23 chars (max 15)

or even shorter network interface names on C8000v and similar platforms: GigabitEthernet0 -> 16 chars

Does it make sense for the interface alias regexp even match on long interface names in this case?

hellt commented 5 months ago

@vista- we can use interface altname since altname can have more than 16 characters and then the original interface name can be in its original ethX value

vista- commented 5 months ago

That's true, but that would mean moving the functionality to containerlab, since that creates the container interfaces in the first place.

vista- commented 5 months ago

This PR's functionality is going to be moved to Containerlab, keep a lookout for a PR popping there in the near future.