# Mixing Different Shapers¶

## Goals¶

In this example we demonstrate how to use different traffic shapers in the same network interface.

INET version: 4.4

## The Model¶

There are three network nodes in the network. The client and the server are TsnDevice modules, and the switch is a TsnSwitch module. The links between them use 100 Mbps EthernetLink channels.

There are four applications in the network creating two independent data streams between the client and the server. The data rate of both streams are ~48 Mbps at the application level in the client.

# client applications
*.client.numApps = 2
*.client.app[*].typename = "UdpSourceApp"
*.client.app[0].display-name = "best effort"
*.client.app[1].display-name = "video"
*.client.app[0].io.destPort = 1000
*.client.app[1].io.destPort = 1001
*.client.app[*].source.packetLength = 1000B - 54B # 42B = 8B (UDP) + 20B (IP) + 14B (ETH MAC) + 4B (ETH FCS) + 8B (ETH PHY)
*.client.app[0].source.productionInterval = exponential(200us) # ~40Mbps
*.client.app[1].source.productionInterval = exponential(400us) # ~20Mbps

# server applications
*.server.numApps = 2
*.server.app[*].typename = "UdpSinkApp"
*.server.app[0].display-name = "best effort"
*.server.app[1].display-name = "video"
*.server.app[0].io.localPort = 1000
*.server.app[1].io.localPort = 1001


The two streams have two different traffic classes: best effort and video. The bridging layer identifies the outgoing packets by their UDP destination port. The client encodes and the switch decodes the streams using the IEEE 802.1Q PCP field.

# enable outgoing streams
*.client.hasOutgoingStreams = true

# client stream identification
*.client.bridging.streamIdentifier.identifier.mapping = [{stream: "best effort", packetFilter: expr(udp.destPort == 1000)},
{stream: "video", packetFilter: expr(udp.destPort == 1001)}]

# client stream encoding
*.client.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
{stream: "video", pcp: 4}]

# switch stream decoding
*.switch.bridging.streamCoder.decoder.mapping = [{pcp: 0, stream: "best effort"},
{pcp: 4, stream: "video"}]


The asynchronous traffic shaper requires the transmission eligibility time for each packet to be already calculated by the ingress per-stream filtering.

# enable ingress per-stream filtering
*.switch.hasIngressTrafficFiltering = true

# per-stream filtering for video stream
*.switch.bridging.streamFilter.ingress.typename = "SimpleIeee8021qFilter"
*.switch.bridging.streamFilter.ingress.numStreams = 1
*.switch.bridging.streamFilter.ingress.classifier.mapping = {video: 0}
*.switch.bridging.streamFilter.ingress.*[0].display-name = "video"
*.switch.bridging.streamFilter.ingress.meter[0].typename = "EligibilityTimeMeter"
*.switch.bridging.streamFilter.ingress.meter[0].committedInformationRate = 20Mbps
*.switch.bridging.streamFilter.ingress.meter[0].committedBurstSize = 10kB
*.switch.bridging.streamFilter.ingress.filter[0].typename = "EligibilityTimeFilter"


The traffic shaping takes place in the outgoing network interface of the switch where both streams pass through. The traffic shaper limits the data rate of the best effort stream to 40 Mbps and the data rate of the video stream to 20 Mbps. The excess traffic is stored in the MAC layer subqueues of the corresponding traffic class.

# enable egress traffic shaping
*.switch.hasEgressTrafficShaping = true

# credit-based and asynchronous traffic shaping
*.switch.eth[*].macLayer.queue.numTrafficClasses = 2
*.switch.eth[*].macLayer.queue.*[0].display-name = "best effort"
*.switch.eth[*].macLayer.queue.*[1].display-name = "video"
*.switch.eth[*].macLayer.queue.queue[1].typename = "EligibilityTimeQueue"
*.switch.eth[*].macLayer.queue.transmissionSelectionAlgorithm[0].typename = "Ieee8021qCreditBasedShaper"
*.switch.eth[*].macLayer.queue.transmissionSelectionAlgorithm[0].idleSlope = 40Mbps
*.switch.eth[*].macLayer.queue.transmissionSelectionAlgorithm[1].typename = "Ieee8021qAsynchronousShaper"


## Results¶

The first diagram shows the data rate of the application level outgoing traffic in the client. The data rate varies randomly over time but the averages are the same.

The next diagram shows the data rate of the incoming traffic of the traffic shapers of the outgoing network interface in the switch. This is different from the previous because the traffic is already in the switch and it is also measured at different protocol level.

The next diagram shows the data rate of the already shaped outgoing traffic of the outgoing network interface in the switch. The randomly varying data rate of the incoming traffic is transformed into a quite stable data rate for the outgoing traffic.

TODO

The next diagram shows the queue lengths of the traffic shapers in the outgoing network interface of the switch. The queue lengths increase over time because the data rate of the incoming traffic of the shapers is greater than the data rate of the outgoing traffic.

The next diagram shows the relationships between the number of credits, the gate state of the credit based transmission selection algorithm, and the transmitting state of the outgoing network interface for the best effort traffic class.

The next diagram shows the relationships between the number of credits, the gate state of the credit based transmission selection algorithm, and the transmitting state of the outgoing network interface for the video traffic class.

The last diagram shows the data rate of the application level incoming traffic in the server. The data rate is somewhat lower than the data rate of the outgoing traffic of the corresponding traffic shaper. The reason is that they are measured at different protocol layers.

Sources: omnetpp.ini

## Discussion¶

Use this page in the GitHub issue tracker for commenting on this showcase.