I always tried to make lab topologies as concise as I could, sometimes cheating using JSON-in-YAML syntax. For example, the topology describing three routers running OSPF could be as simple as this:
module: [ ospf ] nodes: [ r1, r2, r3 ] links: [ r1-r2, r2-r3, r3-r1 ]
Let’s unravel that:
- The module parameter is applied to all nodes in the topology unless specified within a single node or node group.
- While nodes is a dictionary of nodes, it can also be written as a list of node names which are automatically expanded into a dictionary.
- Individual links are dictionaries of nodes and link attributes1, but could be written as strings when you don’t need link attributes.
The above topology is thus expanded into:
module: [ ospf ] nodes: r1: r2: r3: links: - r1: r2: - r2: r3: - r3: r1:
I’m pretty sure you realized why I’m so proud of the concise syntax ;)
Unfortunately, you need link attributes to put links into VRFs. For example, if you want to build a topology with four hosts connected to two VRFs configured on a single router, you had to do it this way:
defaults.device: linux vrfs: red: blue: nodes: rtr: module: [ vrf ] device: eos h1: h2: h3: h4: links: - rtr: h1: vrf: red - rtr: h2: vrf: red - rtr: h3: vrf: blue - rtr: h4: vrf: blue
With the new VRF links functionality, you could list intra-VRF links in the links attribute of a global VRF definition, for example:
defaults.device: linux vrfs: red: links: [ rtr-h1, rtr-h2 ] blue: links: [ rtr-h3, rtr-h4 ] nodes: rtr: module: [ vrf ] device: eos h1: h2: h3: h4:
Like the global links, the links specified within a VRF definition are converted into standard link data structure. They get the vrf: name attribute, and the resulting data structure is appended to the global links list. You don’t even need the global links list if you have just the VRF links in your topology.
VLAN links are very similar to VRF links:
- They are listed in the links attribute of global VLAN definitions.
- They are appended to the global links list with vlan.access attribute set to the VLAN name.
For example, we could use them to simplify VXLAN bridging topology:
groups: hosts: members: [ h1, h2, h3, h4 ] device: linux switches: members: [ s1,s2 ] module: [ vlan,vxlan,ospf ] vlans: red: mode: bridge blue: mode: bridge nodes: [ h1, h2, h3, h4, s1, s2 ] links: - h1: s1: vlan.access: red - h2: s2: vlan.access: red - h3: s1: vlan.access: blue - h4: s2: vlan.access: blue - s1: s2:
Moving the VLAN access links into VLAN definitions results in a much cleaner lab description:
groups: hosts: members: [ h1, h2, h3, h4 ] device: linux switches: members: [ s1,s2 ] module: [ vlan,vxlan,ospf ] vlans: red: mode: bridge links: [ h1-s1, h2-s2 ] blue: mode: bridge links: [ h3-s1, h4-s2 ] nodes: [ h1, h2, h3, h4, s1, s2 ] links: [ s1-s2 ]
Both features were introduced in netlab release 1.5.1. To upgrade, execute
pip3 install --upgrade networklab.
The final data structure is a bit more complex and contains a list of interfaces attached to a link. The only reason to use that data structure in your lab topology are links connecting two interfaces of the same device. ↩︎