162 lines
6.1 KiB
Plaintext
162 lines
6.1 KiB
Plaintext
[[qos-dscp-pcp]]
|
|
== QoS, DSCP/TOS, Priority and IEEE 802.1q PCP
|
|
|
|
In many use cases operators want to apply different QoS classes for user plane
|
|
vs. control plane traffic. IP Routers, Ethernet switches and other network gear
|
|
can then perform intelligent queue management as required for the respective service.
|
|
|
|
For example, voice user plane frames need a rather stable and short latency,
|
|
while IP user plane and control plane traffic has less critical latency requirements.
|
|
|
|
=== IP Level (DSCP)
|
|
|
|
At IP level, different priorities / classes of traffic are expressed
|
|
in accordance to <<ietf-rfc2474>> by the DSCP (Differentiated Services Code
|
|
Point) field of the IP header. DSCP resembles the upper 6 bits of the
|
|
field formerly known as the TOS bits as per <<ietf-rfc791>>.
|
|
|
|
On Linux and other operating systems with BSD-style sockets API, the
|
|
applications can request a specific DSCP value to be used for packets
|
|
generated by those sockets.
|
|
|
|
Osmocom CNI software such as osmo-bts and osmo-mgw support setting the
|
|
DSCP value via VTY commands, see e.g. the `rtp ip-dscp` setting of the
|
|
`bts` node in osmo-bts.
|
|
|
|
|
|
=== Packet Priority
|
|
|
|
In the Linux network stack, every packet is represented by `struct
|
|
sk_buff`, which has an associated _priority_. Furthermore, every socket
|
|
through which applications send data have an associated _socket
|
|
priority_. Each time a packet is transmitted through a given socket,
|
|
the packet inherits the packet priority from the socket priority.
|
|
|
|
Furthermore, there is a mapping table that maps DSCP/TOS bits to
|
|
priority. The sixteen different TOS bit values are mapped to priority
|
|
values as follows:
|
|
|
|
.Linux kernel default DSCP/TOS -> priority mapping
|
|
[options="header",width="50%"]
|
|
|===
|
|
|TOS (binary)|DSCP (binary)|Priority (decimal)
|
|
|xxx0000x|xxx000|0
|
|
|xxx0001x|xxx000|0
|
|
|xxx0010x|xxx001|0
|
|
|xxx0011x|xxx001|0
|
|
|xxx0100x|xxx010|2
|
|
|xxx0101x|xxx010|2
|
|
|xxx0110x|xxx011|2
|
|
|xxx0111x|xxx011|2
|
|
|xxx1000x|xxx100|6
|
|
|xxx1001x|xxx100|6
|
|
|xxx1010x|xxx101|6
|
|
|xxx1011x|xxx101|6
|
|
|xxx1100x|xxx110|4
|
|
|xxx1101x|xxx110|4
|
|
|xxx1110x|xxx111|4
|
|
|xxx1111x|xxx111|4
|
|
|===
|
|
|
|
This table of default DSCP/TOS -> priority bit mappings cannot be
|
|
modified.
|
|
|
|
However, the per-packet _priority_ values can be set by various means
|
|
of network policy, including
|
|
|
|
* by packet filter rules (iptables, ip6tables, nftables)
|
|
** if you use `iptables`, using `CLASSIFY --set-class` in the `mangle` table
|
|
** if you use `nftables`, using `meta priority set` in the `mangle` table
|
|
* by the application using the SO_PRIORITY socket option (currently not yet supported by Osmocom CNI)
|
|
|
|
|
|
=== Ethernet Level (PCP)
|
|
|
|
At Ethernet level, different priorities / QoS classes are expressed by
|
|
the so-called PCP (Priority Code Point) field in the IEEE 802.1q (VLAN)
|
|
header.
|
|
|
|
NOTE:: This means that PCP functionality requires the use of IEEE 802.q
|
|
VLAN. You cannot use PCP without VLAN
|
|
|
|
The Linux kernel assigns IEEE 802.1q PCP bits based on a _mapping_
|
|
between the _priority_ and the PCP value. Each VLAN network device
|
|
maintains a separate map for both egress (transmit) and ingress
|
|
(receive) path.
|
|
|
|
The current priority mappings can be inspected via the `/proc`
|
|
filesystem. For example, if you have a VLAN device `eth0.9` for
|
|
VLAN ID 9 on the net-device `eth0`, you can use the following example:
|
|
|
|
.Example: Inspecting the current egress QoS map
|
|
----
|
|
$ sudo cat /proc/net/vlan/eth0.9<1>
|
|
eth0.9 VID: 9 REORDER_HDR: 1 dev->priv_flags: 1021
|
|
total frames received 123340
|
|
total bytes received 40668066
|
|
Broadcast/Multicast Rcvd 1106
|
|
|
|
total frames transmitted 10499
|
|
total bytes transmitted 1570809
|
|
Device: eth0
|
|
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 <2>
|
|
EGRESS priority mappings: <3>
|
|
----
|
|
<1> make sure to specify your specific VLAN interface name here instead of `eth0.9`
|
|
<2> ingress priority mappings (all PCP values mapped to priority 0)
|
|
<3> egress priority mappings (empty)
|
|
|
|
As we can see in the above example, there are no egress priority
|
|
mappings yet. Let's create three new mappings, mapping _priority_
|
|
value 1 to PCP 1, _priority_ 2 to PCP 2, and _priority_ 3 to PCP 3:
|
|
|
|
.Example: Creating three new egress QoS mappings
|
|
----
|
|
$ sudo ip link set dev eth0.9<1> type vlan egress-qos-map 1:1 2:2 3:3 <2>
|
|
$ sudo cat /proc/net/vlan/eth0.9 <3>
|
|
eth0.9 VID: 9 REORDER_HDR: 1 dev->priv_flags: 1021
|
|
total frames received 123898
|
|
total bytes received 40843611
|
|
Broadcast/Multicast Rcvd 1106
|
|
|
|
total frames transmitted 10517
|
|
total bytes transmitted 1574357
|
|
Device: eth0
|
|
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
|
|
EGRESS priority mappings: 1:1 2:2 3:3 <4>
|
|
----
|
|
<1> make sure to specify your specific VLAN interface name here instead of `eth0.9`
|
|
<2> command to define three new egress QoS maps
|
|
<3> command to re-display the current status
|
|
<4> three new egress mappings are shown as given in `ip` command
|
|
|
|
NOTE:: The settings of the `ip` command are volatile and only active until
|
|
the next reboot (or the network device or VLAN is removed). Please refer to
|
|
the documentation of your specific Linux distribution in order to find out how
|
|
to make such settings persistent by means of an `ifup` hook whenever the interface
|
|
comes up. For CentOS/RHEL 8 this can e.g. be achieved by means of an `/sbin/ifup-local
|
|
script` (when using `network-scripts` and not NetworkManager). For Debian or Ubuntu,
|
|
this typically involves adding `up` lines to `/etc/network/interfaces` or a `/etc/network/if-up.d`
|
|
script.
|
|
|
|
|
|
=== Putting things together
|
|
|
|
Assuming one needs to set both the DSCP bits as well as the PCP for
|
|
certain traffic, the above-mentioned mechanisms need to be combined as
|
|
follows:
|
|
|
|
. configure the osmocom program to set the DSCP value
|
|
. use the default DSCP -> priority mapping, if possible
|
|
. configure an egrees QoS map to map from priority to PCP
|
|
|
|
If the desired combination of DSCP + PCP cannot be achieved that way,
|
|
due to the rather static default kernel mapping table, one needs to go
|
|
one step further:
|
|
|
|
. configure the osmocom program to set the DSCP value
|
|
. use packet filter rules to set the priority based on DSCP
|
|
. configure an egrees QoS map to map from priority to PCP
|
|
|
|
include::{srcdir}/chapters/qos-example.adoc[]
|