Skip to content

Commit f6bd256

Browse files
author
sweet.yangyz
committed
Support to set some attributes for latency, reorder, corrupt,etc...
1 parent 282983e commit f6bd256

File tree

6 files changed

+120
-91
lines changed

6 files changed

+120
-91
lines changed

api/http/server.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ func apiHandler(w http.ResponseWriter, r *http.Request) {
124124
v.Device = config.Device
125125
v.Latency = config.Latency
126126
v.LatencyJitter = config.LatencyJitter
127-
v.LatencyDistributionNormal = config.LatencyDistributionNormal
127+
v.LatencyCorrelation = config.LatencyCorrelation
128+
v.LatencyDistribution = config.LatencyDistribution
129+
v.LatencyReorder = config.LatencyReorder
130+
v.LatencyDuplicate = config.LatencyDuplicate
131+
v.LatencyCorrupt = config.LatencyCorrupt
128132
v.PacketLoss = config.PacketLoss
129133
v.TargetBandwidth = config.TargetBandwidth
130134
v.TargetPorts = config.TargetPorts
@@ -139,7 +143,11 @@ func apiHandler(w http.ResponseWriter, r *http.Request) {
139143
v.Config.Device = config.Device
140144
v.Config.Latency = config.Latency
141145
v.Config.LatencyJitter = config.LatencyJitter
142-
v.Config.LatencyDistributionNormal = config.LatencyDistributionNormal
146+
v.Config.LatencyCorrelation = config.LatencyCorrelation
147+
v.Config.LatencyDistribution = config.LatencyDistribution
148+
v.Config.LatencyReorder = config.LatencyReorder
149+
v.Config.LatencyDuplicate = config.LatencyDuplicate
150+
v.Config.LatencyCorrupt = config.LatencyCorrupt
143151
v.Config.PacketLoss = config.PacketLoss
144152
v.Config.TargetBandwidth = config.TargetBandwidth
145153
v.Config.TargetPorts = config.TargetPorts

examples/wonton/ubuntu/init.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ middleware:
1919
#
2020
- name: network_shape
2121
config:
22+
device: "ens33"
2223
latency: 0 # Latency to add in ms
2324
latency_jitter: 0
24-
latency_distribution_normal: false
25+
latency_correlation: 0
26+
latency_distribution: "normal" # uniform, normal, pareto, paretonormal
2527
latency_reorder: 0
2628
latency_duplicate: 0
2729
latency_corrupt: 0

examples/wonton/ubuntu/middleware.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ middleware:
1919
#
2020
- name: network_shape
2121
config:
22-
device: ens33
22+
device: "ens33"
2323
latency: 800 # Latency to add in ms
2424
target_bw: 3 # Bandwidth in kbits/s
2525
packet_loss: 30 # Packet loss, as a %

symptom/network_shape.go

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,24 @@ import (
1717
// NetworkShaperSymptom allows you to modify the network speed on a host
1818
// e.g. shape bandwidth to mobile, slower speeds
1919
type NetworkShaperSymptom struct {
20-
Config throttler.Config
21-
Device string
22-
Latency int `default:"-1"`
23-
TargetBandwidth int `mapstructure:"target_bw" default:"-1"`
24-
DefaultBandwidth int `mapstructure:"default_bw" default:"-1"`
25-
PacketLoss float64 `mapstructure:"packet_loss"`
26-
LatencyJitter float64 `mapstructure:"latency_jitter"`
27-
LatencyDistributionNormal bool `mapstructure:"latency_distribution_normal"`
28-
LatencyReorder float64 `mapstructure:"latency_reorder"`
29-
LatencyDuplicate float64 `mapstructure:"latency_duplicate"`
30-
LatencyCorrupt float64 `mapstructure:"latency_corrupt"`
31-
TargetIps []string `mapstructure:"target_ips"`
32-
TargetIps6 []string `mapstructure:"target_ips6"`
33-
TargetPorts []string `mapstructure:"target_ports"`
34-
TargetProtos []string `mapstructure:"target_protos" required:"true" default:"tcp,icmp,udp"`
35-
out io.Writer
36-
err io.Writer
20+
Config throttler.Config
21+
Device string
22+
Latency int `default:"-1"`
23+
TargetBandwidth int `mapstructure:"target_bw" default:"-1"`
24+
DefaultBandwidth int `mapstructure:"default_bw" default:"-1"`
25+
PacketLoss float64 `mapstructure:"packet_loss"`
26+
LatencyJitter float64 `mapstructure:"latency_jitter"`
27+
LatencyCorrelation float64 `mapstructure:"latency_correlation"`
28+
LatencyDistribution string `mapstructure:"latency_distribution"`
29+
LatencyReorder float64 `mapstructure:"latency_reorder"`
30+
LatencyDuplicate float64 `mapstructure:"latency_duplicate"`
31+
LatencyCorrupt float64 `mapstructure:"latency_corrupt"`
32+
TargetIps []string `mapstructure:"target_ips"`
33+
TargetIps6 []string `mapstructure:"target_ips6"`
34+
TargetPorts []string `mapstructure:"target_ports"`
35+
TargetProtos []string `mapstructure:"target_protos" required:"true" default:"tcp,icmp,udp"`
36+
out io.Writer
37+
err io.Writer
3738
}
3839

3940
func init() {
@@ -53,21 +54,22 @@ func (s *NetworkShaperSymptom) Setup() {
5354
log.Debug("NetworkShaperSymptom - \tIPv4 %s \tIPv6 %s")
5455

5556
s.Config = throttler.Config{
56-
Device: s.Device,
57-
Latency: s.Latency,
58-
TargetBandwidth: s.TargetBandwidth,
59-
DefaultBandwidth: s.DefaultBandwidth,
60-
PacketLoss: s.PacketLoss,
61-
LatencyJitter: s.LatencyJitter,
62-
LatencyDistributionNormal: s.LatencyDistributionNormal,
63-
LatencyReorder: s.LatencyReorder,
64-
LatencyDuplicate: s.LatencyDuplicate,
65-
LatencyCorrupt: s.LatencyCorrupt,
66-
TargetIps: targetIPv4,
67-
TargetIps6: targetIPv6,
68-
TargetPorts: ports,
69-
TargetProtos: s.TargetProtos,
70-
DryRun: false,
57+
Device: s.Device,
58+
Latency: s.Latency,
59+
TargetBandwidth: s.TargetBandwidth,
60+
DefaultBandwidth: s.DefaultBandwidth,
61+
PacketLoss: s.PacketLoss,
62+
LatencyJitter: s.LatencyJitter,
63+
LatencyCorrelation: s.LatencyCorrelation,
64+
LatencyDistribution: s.LatencyDistribution,
65+
LatencyReorder: s.LatencyReorder,
66+
LatencyDuplicate: s.LatencyDuplicate,
67+
LatencyCorrupt: s.LatencyCorrupt,
68+
TargetIps: targetIPv4,
69+
TargetIps6: targetIPv6,
70+
TargetPorts: ports,
71+
TargetProtos: s.TargetProtos,
72+
DryRun: false,
7173
}
7274

7375
executeThrottler(&s.Config)

throttler/tc.go

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,40 @@ import (
1010
)
1111

1212
const (
13-
tcRootQDisc = `dev %s handle 10: root`
14-
tcRootExtra = `default 1`
15-
tcDefaultClass = `dev %s parent 10: classid 10:1`
16-
tcTargetClass = `dev %s parent 10: classid 10:10`
17-
tcNetemRule = `dev %s parent 10:10 handle 100:`
18-
tcRate = `rate %vkbit`
19-
tcDelay = `delay %vms`
20-
tcLDelayistributionNormal = `distribution normal`
21-
tcLDelayJitter = `%vms`
22-
tcLoss = `loss %v%%`
23-
tcReorder = `reorder %f`
24-
tcDuplicate = `duplicate %f`
25-
tcCorrupt = `corrupt %f`
26-
tcAddClass = `sudo tc class add`
27-
tcDelClass = `sudo tc class del`
28-
tcAddQDisc = `sudo tc qdisc add`
29-
tcDelQDisc = `sudo tc qdisc del`
30-
iptAddTarget = `sudo %s -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
31-
iptDelTarget = `sudo %s -D POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
32-
iptDestIP = `-d %s`
33-
iptProto = `-p %s`
34-
iptDestPorts = `--match multiport --dports %s`
35-
iptDestPort = `--dport %s`
36-
iptSrcPorts = `--match multiport --sports %s`
37-
iptSrcPort = `--sport %s`
38-
iptDelSearch = `class 0010:0010`
39-
TcList = `sudo tc qdisc show`
40-
IptList = `sudo %s -S -t mangle`
41-
Ip4Tables = `iptables`
42-
Ip6Tables = `ip6tables`
43-
iptDel = `sudo %s -t mangle -D`
44-
tcExists = `sudo tc qdisc show | grep "netem"`
45-
tcCheck = `sudo tc -s qdisc`
13+
tcRootQDisc = `dev %s handle 10: root`
14+
tcRootExtra = `default 1`
15+
tcDefaultClass = `dev %s parent 10: classid 10:1`
16+
tcTargetClass = `dev %s parent 10: classid 10:10`
17+
tcNetemRule = `dev %s parent 10:10 handle 100:`
18+
tcRate = `rate %vkbit`
19+
tcDelay = `delay %vms`
20+
tcDelayistribution = `distribution %s`
21+
tcDelayJitter = `%vms`
22+
tcDelayCorrelation = `%v%%`
23+
tcLoss = `loss %v%% 25%%`
24+
tcReorder = `reorder %v%% gap 3`
25+
tcDuplicate = `duplicate %v%%`
26+
tcCorrupt = `corrupt %v%%`
27+
tcAddClass = `sudo tc class add`
28+
tcDelClass = `sudo tc class del`
29+
tcAddQDisc = `sudo tc qdisc add`
30+
tcDelQDisc = `sudo tc qdisc del`
31+
iptAddTarget = `sudo %s -A POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
32+
iptDelTarget = `sudo %s -D POSTROUTING -t mangle -j CLASSIFY --set-class 10:10`
33+
iptDestIP = `-d %s`
34+
iptProto = `-p %s`
35+
iptDestPorts = `--match multiport --dports %s`
36+
iptDestPort = `--dport %s`
37+
iptSrcPorts = `--match multiport --sports %s`
38+
iptSrcPort = `--sport %s`
39+
iptDelSearch = `class 0010:0010`
40+
TcList = `sudo tc qdisc show`
41+
IptList = `sudo %s -S -t mangle`
42+
Ip4Tables = `iptables`
43+
Ip6Tables = `ip6tables`
44+
iptDel = `sudo %s -t mangle -D`
45+
tcExists = `sudo tc qdisc show | grep "netem"`
46+
tcCheck = `sudo tc -s qdisc`
4647

4748
//tcCbq = `cbq avpkt 1000 bandwidth %vkbit`
4849
)
@@ -193,16 +194,31 @@ func addNetemRule(cfg *Config, c commander) error {
193194
strs = append(strs, fmt.Sprintf(tcDelay, cfg.Latency))
194195

195196
if cfg.LatencyJitter > 0 {
196-
strs = append(strs, fmt.Sprintf(tcLDelayJitter, cfg.LatencyJitter))
197+
strs = append(strs, fmt.Sprintf(tcDelayJitter, cfg.LatencyJitter))
197198

198-
if cfg.LatencyDistributionNormal {
199-
strs = append(strs, tcLDelayistributionNormal)
199+
if cfg.LatencyCorrelation > 0 {
200+
strs = append(strs, fmt.Sprintf(tcDelayCorrelation, cfg.LatencyCorrelation))
201+
}
202+
203+
if len(cfg.LatencyDistribution) > 0 {
204+
strs = append(strs, fmt.Sprintf(tcDelayistribution, cfg.LatencyDistribution))
200205
}
201206
}
202-
}
203207

204-
log.Debug("TargetBandwidth: %d", cfg.TargetBandwidth)
208+
if cfg.LatencyReorder > 0 {
209+
strs = append(strs, fmt.Sprintf(tcReorder, strconv.FormatFloat(cfg.LatencyReorder, 'f', 2, 64))) //"reorder 50% gap 3"
210+
}
211+
212+
if cfg.LatencyDuplicate > 0 {
213+
strs = append(strs, fmt.Sprintf(tcDuplicate, strconv.FormatFloat(cfg.LatencyDuplicate, 'f', 2, 64))) //"duplicate 50%"
214+
}
205215

216+
if cfg.LatencyCorrupt > 0 {
217+
strs = append(strs, fmt.Sprintf(tcCorrupt, strconv.FormatFloat(cfg.LatencyCorrupt, 'f', 2, 64))) //"corrupt 2%"
218+
}
219+
}
220+
221+
log.Debug("TargetBandwidth: %d, but if you used 'rate' in a netem command, you will received an error.", cfg.TargetBandwidth)
206222
if cfg.TargetBandwidth > -1 {
207223
// If you used 'rate' in netem, it will has an error.
208224
//strs = append(strs, fmt.Sprintf(tcRate, cfg.TargetBandwidth))
@@ -215,7 +231,7 @@ func addNetemRule(cfg *Config, c commander) error {
215231
cmd := strings.Join(strs, " ")
216232

217233
log.Debug("Adding a netem rule :")
218-
234+
log.Debug("%s", cmd)
219235
return c.execute(cmd)
220236
}
221237

throttler/throttler.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,23 @@ const (
2222

2323
// Config specifies options for configuring packet filter rules.
2424
type Config struct {
25-
Device string
26-
Stop bool
27-
Latency int
28-
TargetBandwidth int
29-
DefaultBandwidth int
30-
PacketLoss float64
31-
LatencyJitter float64
32-
LatencyDistributionNormal bool
33-
LatencyReorder float64
34-
LatencyDuplicate float64
35-
LatencyCorrupt float64
36-
TargetIps []string
37-
TargetIps6 []string
38-
TargetPorts []string
39-
TargetProtos []string
40-
DryRun bool
25+
Device string
26+
Stop bool
27+
Latency int
28+
TargetBandwidth int
29+
DefaultBandwidth int
30+
PacketLoss float64
31+
LatencyJitter float64
32+
LatencyCorrelation float64
33+
LatencyDistribution string
34+
LatencyReorder float64
35+
LatencyDuplicate float64
36+
LatencyCorrupt float64
37+
TargetIps []string
38+
TargetIps6 []string
39+
TargetPorts []string
40+
TargetProtos []string
41+
DryRun bool
4142
}
4243

4344
type throttler interface {

0 commit comments

Comments
 (0)