Skip to content

Commit 134b828

Browse files
FloSch62hellt
andauthored
Add a reset command for network impairments in netem tool (srl-labs#2488)
* Add reset command for network impairments in netem tool * fix test * format --------- Co-authored-by: Roman Dodin <[email protected]>
1 parent b3a6850 commit 134b828

File tree

6 files changed

+168
-2
lines changed

6 files changed

+168
-2
lines changed

cmd/tools_netem.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ func init() {
6363
netemCmd.AddCommand(netemShowCmd)
6464
netemShowCmd.Flags().StringVarP(&netemNode, "node", "n", "", "node to apply impairment to")
6565
netemShowCmd.Flags().StringVarP(&netemFormat, "format", "f", "table", "output format (table, json)")
66+
67+
// Add reset command
68+
netemCmd.AddCommand(netemResetCmd)
69+
netemResetCmd.Flags().StringVarP(&netemNode, "node", "n", "", "node to reset impairment on")
70+
netemResetCmd.Flags().StringVarP(&netemInterface, "interface", "i", "", "interface to reset impairment on")
71+
netemResetCmd.MarkFlagRequired("node")
72+
netemResetCmd.MarkFlagRequired("interface")
6673
}
6774

6875
var netemCmd = &cobra.Command{
@@ -87,6 +94,14 @@ var netemShowCmd = &cobra.Command{
8794
RunE: netemShowFn,
8895
}
8996

97+
var netemResetCmd = &cobra.Command{
98+
Use: "reset",
99+
Short: "reset link impairments",
100+
Long: `Reset network impairments by deleting the netem qdisc from the specified interface.`,
101+
PreRunE: validateInputAndRoot,
102+
RunE: netemResetFn,
103+
}
104+
90105
func netemSetFn(_ *cobra.Command, _ []string) error {
91106
// Ensure that the sch_netem kernel module is loaded (for Fedora/RHEL compatibility)
92107
if err := exec.Command("modprobe", "sch_netem").Run(); err != nil {
@@ -384,3 +399,67 @@ func netemShowFn(_ *cobra.Command, _ []string) error {
384399

385400
return err
386401
}
402+
403+
func netemResetFn(_ *cobra.Command, _ []string) error {
404+
// Get the runtime initializer.
405+
_, rinit, err := clab.RuntimeInitializer(common.Runtime)
406+
if err != nil {
407+
return err
408+
}
409+
410+
// init the runtime
411+
rt := rinit()
412+
err = rt.Init(
413+
runtime.WithConfig(
414+
&runtime.RuntimeConfig{
415+
Timeout: common.Timeout,
416+
},
417+
),
418+
)
419+
if err != nil {
420+
return err
421+
}
422+
423+
ctx, cancel := context.WithCancel(context.Background())
424+
defer cancel()
425+
426+
// retrieve the container's NSPath
427+
nodeNsPath, err := rt.GetNSPath(ctx, netemNode)
428+
if err != nil {
429+
return err
430+
}
431+
432+
var nodeNs ns.NetNS
433+
if nodeNs, err = ns.GetNS(nodeNsPath); err != nil {
434+
return err
435+
}
436+
437+
tcnl, err := tc.NewTC(int(nodeNs.Fd()))
438+
if err != nil {
439+
return err
440+
}
441+
defer func() {
442+
if err := tcnl.Close(); err != nil {
443+
log.Errorf("could not close rtnetlink socket: %v\n", err)
444+
}
445+
}()
446+
447+
err = nodeNs.Do(func(_ ns.NetNS) error {
448+
netemIfLink, err := netlink.LinkByName(links.SanitiseInterfaceName(netemInterface))
449+
if err != nil {
450+
return err
451+
}
452+
// Retrieve the standard net.Interface from the netlink.Link name.
453+
netemIfIface, err := net.InterfaceByName(netemIfLink.Attrs().Name)
454+
if err != nil {
455+
return err
456+
}
457+
if err := tc.DeleteImpairments(tcnl, netemIfIface); err != nil {
458+
return err
459+
}
460+
fmt.Printf("Reset impairments on node %q, interface %q\n", netemNode, netemIfLink.Attrs().Name)
461+
return nil
462+
})
463+
464+
return err
465+
}

docs/cmd/tools/netem/reset.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Resetting Link Impairments
2+
3+
With the `containerlab tools netem reset` command users can remove (reset) all network impairments on a specified interface of a containerlab node. This command deletes the netem qdisc associated with the interface, restoring it to its default state. If no impairments are present, the command will complete successfully without error.
4+
5+
## Usage
6+
7+
```bash
8+
containerlab tools netem reset [local-flags]
9+
```
10+
11+
## Flags
12+
13+
### node
14+
15+
The mandatory `--node | -n` flag specifies the name of the containerlab node on which to reset link impairments.
16+
17+
### interface
18+
19+
The mandatory `--interface | -i` flag specifies the interface on which the netem impairments should be reset.
20+
21+
## Examples
22+
23+
### Resetting impairments on an interface
24+
25+
This example resets the impairments on the interface `eth1` of node `clab-netem-r1`:
26+
27+
```bash
28+
containerlab tools netem reset -n clab-netem-r1 -i eth1
29+
```
30+
31+
Output:
32+
33+
```bash
34+
Reset impairments on node "clab-netem-r1", interface "eth1"
35+
```
36+
37+
### Resetting impairments when none are set
38+
39+
If no impairments are configured on the specified interface, the command will complete without error:
40+
41+
```bash
42+
containerlab tools netem reset -n clab-netem-r1 -i eth0
43+
```
44+
45+
Output:
46+
47+
```bash
48+
Reset impairments on node "clab-netem-r1", interface "eth0"
49+
```

docs/manual/impairments.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ Labs are meant to be a reflection of real-world scenarios. To make simulated net
88

99
* [`tools netem set`](../cmd/tools/netem/set.md)
1010
* [`tools netem show`](../cmd/tools/netem/show.md)
11+
* [`tools netem reset`](../cmd/tools/netem/reset.md)
1112

12-
These commands allow users to set link impairments (delay, jitter, packet loss) on any link that belongs to a container node and create labs simulating real-world network conditions.
13+
These commands allow users to set, show and reset link impairments (delay, jitter, packet loss) on any link that belongs to a container node and create labs simulating real-world network conditions.
1314

1415
```bash title="setting packet loss at 10% rate on eth1 interface of clab-netem-r1 node"
1516
containerlab tools netem set -n clab-netem-r1 -i eth1 --loss 10

internal/tc/tc.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,24 @@ func SetImpairments(tcnl *tc.Tc, nodeName string, link *net.Interface, delay, ji
8484
return nil, fmt.Errorf("could not find qdisc for interface %q", link.Name)
8585
}
8686

87+
// DeleteImpairments deletes the netem impairments from the given interface.
88+
func DeleteImpairments(tcnl *tc.Tc, link *net.Interface) error {
89+
qdisc := tc.Object{
90+
Msg: tc.Msg{
91+
Family: unix.AF_UNSPEC,
92+
Ifindex: uint32(link.Index),
93+
Handle: core.BuildHandle(0x1, 0x0),
94+
Parent: tc.HandleRoot,
95+
Info: 0,
96+
},
97+
Attribute: tc.Attribute{
98+
Kind: "netem",
99+
Netem: &tc.Netem{},
100+
},
101+
}
102+
return tcnl.Qdisc().Delete(&qdisc)
103+
}
104+
87105
// setDelay sets delay and jitter to the qdisc.
88106
func setDelay(qdisc *tc.Object, delay, jitter time.Duration) error {
89107
delayTcTime, err := core.Duration2TcTime(delay)

links/link_macvlan.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ func (l *LinkMacVlan) Deploy(ctx context.Context, _ Endpoint) error {
156156
// enable promiscuous mode
157157
err = netlink.SetPromiscOn(mvInterface)
158158
if err != nil {
159-
return fmt.Errorf("failed setting promiscuous mode for interface %s (%s:%s): %v", l.NodeEndpoint.GetRandIfaceName(), l.NodeEndpoint.GetNode().GetShortName(), l.NodeEndpoint.GetIfaceName(), err)
159+
return fmt.Errorf("failed setting promiscuous mode for interface %s (%s:%s): %v",
160+
l.NodeEndpoint.GetRandIfaceName(), l.NodeEndpoint.GetNode().GetShortName(), l.NodeEndpoint.GetIfaceName(), err)
160161
}
161162

162163
// add the link to the Node Namespace

tests/01-smoke/08-tools-cmds.robot

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,21 @@ Show link impairments in JSON format
6767
Should Contain ${output} 10
6868
Should Contain ${output} 1000
6969
Should Contain ${output} 2
70+
71+
Reset link impairments
72+
${rc} ${output} = Run And Return Rc And Output
73+
... ${CLAB_BIN} --runtime ${runtime} tools netem reset -n clab-${lab-name}-l1 -i eth3
74+
Log ${output}
75+
Should Be Equal As Integers ${rc} 0
76+
Should Contain ${output} Reset impairments on node "clab-${lab-name}-l1", interface "eth3"
77+
78+
# Show impairments again to verify they have been reset.
79+
${rc} ${output} = Run And Return Rc And Output
80+
... ${CLAB_BIN} --runtime ${runtime} tools netem show -n clab-${lab-name}-l1
81+
Log ${output}
82+
Should Be Equal As Integers ${rc} 0
83+
# Verify that the previous impairment values are no longer present.
84+
Should Not Contain ${output} 100ms
85+
Should Not Contain ${output} 2ms
86+
Should Not Contain ${output} 10.00%
87+
Should Not Contain ${output} 1000

0 commit comments

Comments
 (0)