-
Couldn't load subscription status.
- Fork 365
Cisco vIOS & vIOS-L2 #2902
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
Open
torbbang
wants to merge
3
commits into
srl-labs:main
Choose a base branch
from
torbbang:cisco-vios
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Cisco vIOS & vIOS-L2 #2902
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| --- | ||
| search: | ||
| boost: 4 | ||
| kind_code_name: cisco_vios | ||
| kind_display_name: Cisco vIOS | ||
| --- | ||
| # Cisco vIOS | ||
|
|
||
| Cisco vIOS virtualized router is identified with `-{{ kind_code_name }}-` kind in the [topology file](../topo-def-file.md). It is built using [vrnetlab](../vrnetlab.md) project and essentially is a Qemu VM packaged in a docker container format. | ||
|
|
||
| ## Managing Cisco vIOS nodes | ||
|
|
||
| Cisco vIOS node launched with containerlab can be managed via the following interfaces: | ||
|
|
||
| === "bash" | ||
| to connect to a `bash` shell of a running Cisco vIOS container: | ||
| ```bash | ||
| docker exec -it <container-name/id> bash | ||
| ``` | ||
| === "CLI" | ||
| to connect to the vIOS CLI | ||
| ```bash | ||
| ssh cisco@<container-name/id> | ||
| ``` | ||
|
|
||
| !!!info | ||
| Default user credentials: `cisco:cisco` | ||
|
|
||
| ## Interface naming | ||
|
|
||
| You can use [interfaces names](../topo-def-file.md#interface-naming) in the topology file like they appear in -{{ kind_display_name }}-. | ||
|
|
||
| The interface naming convention is: `GigabitEthernetX` (or `GiX`), where `X` is the port number. | ||
|
|
||
| With that naming convention in mind: | ||
|
|
||
| * `Gi0` - first data port available | ||
| * `Gi1` - second data port, and so on... | ||
|
|
||
| The example ports above would be mapped to the following Linux interfaces inside the container running the -{{ kind_display_name }}- VM: | ||
|
|
||
| * `eth0` - management interface connected to the containerlab management network (rendered as `GigabitEthernet0/0` in the CLI) | ||
| * `eth1` - first data interface, mapped to the first data port of the VM (rendered as `GigabitEthernet0`) | ||
| * `eth2+` - second and subsequent data interfaces, mapped to the second and subsequent data ports of the VM (rendered as `GigabitEthernet1` and so on) | ||
|
|
||
| When containerlab launches -{{ kind_display_name }}- node the management interface gets assigned an address from the containerlab management network. | ||
|
|
||
| Data interfaces `GigabitEthernet0+` need to be configured with IP addressing manually using CLI or other available management interfaces. | ||
|
|
||
| ## Features and options | ||
|
|
||
| ### Node configuration | ||
|
|
||
| Cisco vIOS nodes come up with a basic configuration where only `cisco` user and management interface are provisioned. | ||
|
|
||
| #### Startup configuration | ||
|
|
||
| It is possible to make vIOS nodes boot up with a user-defined startup-config instead of a built-in one. With a [`startup-config`](../nodes.md#startup-config) property of the node/kind user sets the path to the config file that will be mounted to a container and used as a startup-config: | ||
|
|
||
| ```yaml | ||
| topology: | ||
| nodes: | ||
| node: | ||
| kind: cisco_vios | ||
| startup-config: myconfig.txt | ||
| ``` | ||
|
|
||
| With this knob containerlab is instructed to take a file `myconfig.txt` from the directory that hosts the topology file, and copy it to the lab directory for that specific node under the `/config/startup-config.cfg` name. Then the directory that hosts the startup-config dir is mounted to the container. This will result in this config being applied at startup by the node. | ||
|
|
||
| Configuration is applied after the node is started, thus it can contain partial configuration snippets that you desire to add on top of the default config that a node boots up with. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| --- | ||
| search: | ||
| boost: 4 | ||
| kind_code_name: cisco_viosl2 | ||
| kind_display_name: Cisco vIOSL2 | ||
| --- | ||
| # Cisco vIOSL2 | ||
|
|
||
| Cisco vIOSL2 virtualized layer-2 switch is identified with `-{{ kind_code_name }}-` kind in the [topology file](../topo-def-file.md). It is built using [vrnetlab](../vrnetlab.md) project and essentially is a Qemu VM packaged in a docker container format. | ||
|
|
||
| ## Managing Cisco vIOSL2 nodes | ||
|
|
||
| Cisco vIOSL2 node launched with containerlab can be managed via the following interfaces: | ||
|
|
||
| === "bash" | ||
| to connect to a `bash` shell of a running Cisco vIOSL2 container: | ||
| ```bash | ||
| docker exec -it <container-name/id> bash | ||
| ``` | ||
| === "CLI" | ||
| to connect to the vIOSL2 CLI | ||
| ```bash | ||
| ssh cisco@<container-name/id> | ||
| ``` | ||
|
|
||
| !!!info | ||
| Default user credentials: `cisco:cisco` | ||
|
|
||
| ## Interface naming | ||
|
|
||
| You can use [interfaces names](../topo-def-file.md#interface-naming) in the topology file like they appear in -{{ kind_display_name }}-. | ||
|
|
||
| The interface naming convention is: `GigabitEthernetX` (or `GiX`), where `X` is the port number. | ||
|
|
||
| With that naming convention in mind: | ||
|
|
||
| * `Gi0` - first data port available | ||
| * `Gi1` - second data port, and so on... | ||
|
|
||
| The example ports above would be mapped to the following Linux interfaces inside the container running the -{{ kind_display_name }}- VM: | ||
|
|
||
| * `eth0` - management interface connected to the containerlab management network (rendered as `GigabitEthernet0/0` in the CLI) | ||
| * `eth1` - first data interface, mapped to the first data port of the VM (rendered as `GigabitEthernet0`) | ||
| * `eth2+` - second and subsequent data interfaces, mapped to the second and subsequent data ports of the VM (rendered as `GigabitEthernet1` and so on) | ||
|
|
||
| When containerlab launches -{{ kind_display_name }}- node the management interface gets assigned an address from the containerlab management network. | ||
|
|
||
| Data interfaces `GigabitEthernet0+` need to be configured with IP addressing manually using CLI or other available management interfaces. | ||
|
|
||
| ## Features and options | ||
|
|
||
| ### Node configuration | ||
|
|
||
| Cisco vIOSL2 nodes come up with a basic configuration where only `cisco` user and management interface are provisioned. | ||
|
|
||
| #### Startup configuration | ||
|
|
||
| It is possible to make vIOSL2 nodes boot up with a user-defined startup-config instead of a built-in one. With a [`startup-config`](../nodes.md#startup-config) property of the node/kind user sets the path to the config file that will be mounted to a container and used as a startup-config: | ||
|
|
||
| ```yaml | ||
| topology: | ||
| nodes: | ||
| node: | ||
| kind: cisco_viosl2 | ||
| startup-config: myconfig.txt | ||
| ``` | ||
|
|
||
| With this knob containerlab is instructed to take a file `myconfig.txt` from the directory that hosts the topology file, and copy it to the lab directory for that specific node under the `/config/startup-config.cfg` name. Then the directory that hosts the startup-config dir is mounted to the container. This will result in this config being applied at startup by the node. | ||
|
|
||
| Configuration is applied after the node is started, thus it can contain partial configuration snippets that you desire to add on top of the default config that a node boots up with. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| // Copyright 2020 Nokia | ||
| // Licensed under the BSD 3-Clause License. | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
|
|
||
| package vr_vios | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "path" | ||
| "regexp" | ||
|
|
||
| clabnodes "github.com/srl-labs/containerlab/nodes" | ||
| clabtypes "github.com/srl-labs/containerlab/types" | ||
| clabutils "github.com/srl-labs/containerlab/utils" | ||
| ) | ||
|
|
||
| var ( | ||
| kindnames = []string{"cisco_vios", "vr-vios", "vr-cisco_vios"} | ||
| defaultCredentials = clabnodes.NewCredentials("cisco", "cisco") | ||
|
|
||
| InterfaceRegexp = regexp.MustCompile(`(?:Gi|GigabitEthernet)\s?(?P<port>\d+)$`) | ||
| InterfaceOffset = 0 | ||
| InterfaceHelp = "GiX or GigabitEthernetX (where X >= 0) or ethX (where X >= 1)" | ||
| ) | ||
|
|
||
| const ( | ||
| scrapliPlatformName = "cisco_ios" | ||
| ) | ||
|
|
||
| // Register registers the node in the NodeRegistry. | ||
| func Register(r *clabnodes.NodeRegistry) { | ||
| platformAttrs := &clabnodes.PlatformAttrs{ | ||
| ScrapliPlatformName: scrapliPlatformName, | ||
| } | ||
|
|
||
| nrea := clabnodes.NewNodeRegistryEntryAttributes(defaultCredentials, nil, platformAttrs) | ||
|
|
||
| r.Register(kindnames, func() clabnodes.Node { | ||
| return new(vrVios) | ||
| }, nrea) | ||
| } | ||
|
|
||
| type vrVios struct { | ||
| clabnodes.VRNode | ||
| } | ||
|
|
||
| func (n *vrVios) Init(cfg *clabtypes.NodeConfig, opts ...clabnodes.NodeOption) error { | ||
| // Init VRNode | ||
| n.VRNode = *clabnodes.NewVRNode(n, defaultCredentials, scrapliPlatformName) | ||
| // set virtualization requirement | ||
| n.HostRequirements.VirtRequired = true | ||
|
|
||
| n.Cfg = cfg | ||
| for _, o := range opts { | ||
| o(n) | ||
| } | ||
| // env vars are used to set launch.py arguments in vrnetlab container | ||
| defEnv := map[string]string{ | ||
| "CONNECTION_MODE": clabnodes.VrDefConnMode, | ||
| "USERNAME": defaultCredentials.GetUsername(), | ||
| "PASSWORD": defaultCredentials.GetPassword(), | ||
| "DOCKER_NET_V4_ADDR": n.Mgmt.IPv4Subnet, | ||
| "DOCKER_NET_V6_ADDR": n.Mgmt.IPv6Subnet, | ||
| } | ||
| n.Cfg.Env = clabutils.MergeStringMaps(defEnv, n.Cfg.Env) | ||
|
|
||
| // mount config dir to support startup-config functionality | ||
| n.Cfg.Binds = append( | ||
| n.Cfg.Binds, | ||
| fmt.Sprint(path.Join(n.Cfg.LabDir, n.ConfigDirName), ":/config"), | ||
| ) | ||
|
|
||
| if n.Cfg.Env["CONNECTION_MODE"] == "macvtap" { | ||
| // mount dev dir to enable macvtap | ||
| n.Cfg.Binds = append(n.Cfg.Binds, "/dev:/dev") | ||
| } | ||
|
|
||
| n.Cfg.Cmd = fmt.Sprintf( | ||
| "--username %s --password %s --hostname %s --connection-mode %s --trace", | ||
| n.Cfg.Env["USERNAME"], | ||
| n.Cfg.Env["PASSWORD"], | ||
| n.Cfg.ShortName, | ||
| n.Cfg.Env["CONNECTION_MODE"], | ||
| ) | ||
|
|
||
| n.InterfaceRegexp = InterfaceRegexp | ||
| n.InterfaceOffset = InterfaceOffset | ||
| n.InterfaceHelp = InterfaceHelp | ||
|
|
||
| return nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| package vr_vios | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| clablinks "github.com/srl-labs/containerlab/links" | ||
| clabnodes "github.com/srl-labs/containerlab/nodes" | ||
| clabtypes "github.com/srl-labs/containerlab/types" | ||
| ) | ||
|
|
||
| func TestVIOSInterfaceParsing(t *testing.T) { | ||
| tests := map[string]struct { | ||
| endpoints []*clablinks.EndpointVeth | ||
| node *vrVios | ||
| resultEps []string | ||
| }{ | ||
| "alias-parse": { | ||
| endpoints: []*clablinks.EndpointVeth{ | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "Gi0", | ||
| }, | ||
| }, | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "GigabitEthernet1", | ||
| }, | ||
| }, | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "GigabitEthernet 2", | ||
| }, | ||
| }, | ||
| }, | ||
| node: &vrVios{ | ||
| VRNode: clabnodes.VRNode{ | ||
| DefaultNode: clabnodes.DefaultNode{ | ||
| Cfg: &clabtypes.NodeConfig{ | ||
| ShortName: "vios", | ||
| }, | ||
| InterfaceRegexp: InterfaceRegexp, | ||
| InterfaceOffset: InterfaceOffset, | ||
| }, | ||
| }, | ||
| }, | ||
| resultEps: []string{ | ||
| "eth1", "eth2", "eth3", | ||
| }, | ||
| }, | ||
| "original-parse": { | ||
| endpoints: []*clablinks.EndpointVeth{ | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "eth1", | ||
| }, | ||
| }, | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "eth2", | ||
| }, | ||
| }, | ||
| { | ||
| EndpointGeneric: clablinks.EndpointGeneric{ | ||
| IfaceName: "eth3", | ||
| }, | ||
| }, | ||
| }, | ||
| node: &vrVios{ | ||
| VRNode: clabnodes.VRNode{ | ||
| DefaultNode: clabnodes.DefaultNode{ | ||
| Cfg: &clabtypes.NodeConfig{ | ||
| ShortName: "vios", | ||
| }, | ||
| InterfaceRegexp: InterfaceRegexp, | ||
| InterfaceOffset: InterfaceOffset, | ||
| }, | ||
| }, | ||
| }, | ||
| resultEps: []string{ | ||
| "eth1", "eth2", "eth3", | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| for name, tc := range tests { | ||
| t.Run(name, func(tt *testing.T) { | ||
| foundError := false | ||
| tc.node.OverwriteNode = tc.node | ||
| tc.node.InterfaceMappedPrefix = "eth" | ||
| tc.node.FirstDataIfIndex = 1 | ||
| for _, ep := range tc.endpoints { | ||
| gotEndpointErr := tc.node.AddEndpoint(ep) | ||
| if gotEndpointErr != nil { | ||
| foundError = true | ||
| t.Errorf("got error for endpoint %+v", gotEndpointErr) | ||
| } | ||
| } | ||
|
|
||
| if !foundError { | ||
| gotCheckErr := tc.node.CheckInterfaceName() | ||
| if gotCheckErr != nil { | ||
| foundError = true | ||
| t.Errorf("got error for check %+v", gotCheckErr) | ||
| } | ||
|
|
||
| if !foundError { | ||
| for idx, ep := range tc.node.Endpoints { | ||
| if ep.GetIfaceName() != tc.resultEps[idx] { | ||
| t.Errorf("got wrong mapped endpoint %q (%q), want %q", | ||
| ep.GetIfaceName(), ep.GetIfaceAlias(), tc.resultEps[idx]) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.