(posting from tech@xxxxxxxxxxx taken here for discussion in wider audience) Dear all, There may be opportunity for improvement of ssh(1) and sshd(8)'s default QoS markers for better integration in environments that can offer either layer-2 or layer-3 prioritisation profiles. Currently ssh(1) and sshd(8) set obsoleted values 'lowdelay' for interactive sessions and 'throughput' for non-interactive sessions. TL;DR: I propose to update the defaults to use DSCP "AF21" (Low Latency Data) for interactive session traffic, and CS1 ("Lower Effort") for non-interactive traffic. This applies to both IPv4 and IPv6. The openbsd 'lowdelay' value translates to IP TOS '0x10', and 'throughput' translates to IP TOS 0x08'. The IP TOS field is 8 bits, and was defined in RFC 1349 (1992 A.D.). IP TOS was deprecated in RFC 2474 (1998 A.D.) with the introduction of "Differentiated Services Field" aka DSCP. When the world transitioned from TOS to DSCP, the IP TOS field was chopped up into two parts: the 6 most significant bits became the DSField (which contains a DSCP), and the 2 least significant bits became a place for ECN experimentation. (Similarly in IPv6, the 'Traffic Class' became the DSField). To convert the IP TOS value to a DSCP value you shift the value 2 bits to the right: 'lowdelay' = DSCP 0x04 and 'throughput' = DSCP 0x02. It should be noted that DSCP 0x04 and DSCP 0x02 have no meaning. Both 0x02 and 0x04 map to Precedence "routine", which is the /least/ important Precedence. Using IP TOS values is problematic because network operators can't match on TOS values on today's equipment. We looked at Cisco IOS XR, Juniper Junos, and Nokia SR-OS - and there aren't classifiers to match on TOS values. Instead, the systems I mentioned allow you to match on DSCP value (and perhaps IPv4 precedence). The ability to correctly match QoS markers of this nature is important in controlled environments, you'll generally see that the DSCP values are fully trusted, or not honored at all (such as when crossing Internet boundaries). An example would be how traffic from VOIP phones/apps are treated in enterprise office networks, perhaps even in the entire branch network. The industry practise is that iff QoS markers are honored, they are translated 1:1 - so AF21 goes into AF21 (or equivalent). I selected AF21 as this is the highest priority within the low-latency service class (and it is higher than what we have today). SSH is elastic and time-sensitive data, where a user is waiting for a response via the network in order to continue with a task at hand. As such, these flows should be considered foreground traffic, with delays or drops to such traffic directly impacting user-productivity. You may ask, "why not EF?" - the risk with EF is that you can easily end up in a tiny policer queue, as an example some CPEs by default only allow up to 100Kbps of EF traffic. EF is meant for inelastic traffic, where for instance the codec sends packets at the rate the codec produces them, regardless of availability of capacity. For bulk SSH traffic, the "Lower Effort" marker was chosen to enable networks implementing a scavanger/lower-than-best effort class to discriminate scp(1) below normal activities, such as web surfing. In general this type of bulk SSH traffic is a background activity. Today this traffic would go into 'best effort', potentially drowning out other traffic on wireless links, so kicking this into 'background' may improve the user experience. An advantage of using "AF21" for interactive SSH and "CS1" for bulk SSH is that they are recognisable values on all common platforms (IANA https://www.iana.org/assignments/dscp-registry/dscp-registry.xml ), and for AF21 specifically a rigorous definition of the intended behavior exists https://tools.ietf.org/html/rfc4594#section-4.7 in addition to the definition of the Assured Forwarding PHB group https://tools.ietf.org/html/rfc2597, and for CS1 (Lower Effort) there is https://tools.ietf.org/html/rfc3662 - finally this document is also a recommened reading: https://tools.ietf.org/html/rfc8325 Another advantage is that the first three bits of "AF21" map to the equivalent IEEEE 802.1D PCP, IEEE 802.11e, MPLS EXP/Cos and IP Precedence value of 2 (also known as "Immediate", or "AC_BE"), and CS1's first 3 bits map to IEEEE 802.1D PCP, IEEE 802.11e, MPLS/Cos and IP Precedence value 1 ("Background" or "AC_BK"). The below patch ensures that in environments where people are using QoS, the openssh defaults can easily matched both for interactive and bulk SSH traffic in all layers of the transport stack (wired/wirless Ethernet, MPLS, IP) and priortize accordingly. Kind regards, Job The below patch should be portable, but I've only tested it on my own openbsd machines. usr.bin/ssh/readconf.c | 4 ++-- usr.bin/ssh/servconf.c | 4 ++-- usr.bin/ssh/ssh_config.5 | 6 ++++-- usr.bin/ssh/sshd_config.5 | 6 ++++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git usr.bin/ssh/readconf.c usr.bin/ssh/readconf.c index 5d17b725600..d3a121373d8 100644 --- usr.bin/ssh/readconf.c +++ usr.bin/ssh/readconf.c @@ -1981,9 +1981,9 @@ fill_default_options(Options * options) if (options->visual_host_key == -1) options->visual_host_key = 0; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_LOWDELAY; + options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_THROUGHPUT; + options->ip_qos_bulk = IPTOS_DSCP_CS1; if (options->request_tty == -1) options->request_tty = REQUEST_TTY_AUTO; if (options->proxy_use_fdpass == -1) diff --git usr.bin/ssh/servconf.c usr.bin/ssh/servconf.c index 69c17907317..48354fda822 100644 --- usr.bin/ssh/servconf.c +++ usr.bin/ssh/servconf.c @@ -351,9 +351,9 @@ fill_default_server_options(ServerOptions *options) if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; if (options->ip_qos_interactive == -1) - options->ip_qos_interactive = IPTOS_LOWDELAY; + options->ip_qos_interactive = IPTOS_DSCP_AF21; if (options->ip_qos_bulk == -1) - options->ip_qos_bulk = IPTOS_THROUGHPUT; + options->ip_qos_bulk = IPTOS_DSCP_CS1; if (options->version_addendum == NULL) options->version_addendum = xstrdup(""); if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) diff --git usr.bin/ssh/ssh_config.5 usr.bin/ssh/ssh_config.5 index 71705cabdda..8989675d512 100644 --- usr.bin/ssh/ssh_config.5 +++ usr.bin/ssh/ssh_config.5 @@ -984,9 +984,11 @@ If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is -.Cm lowdelay +.Cm af21 +.Ar (Low-Latency Data) for interactive sessions and -.Cm throughput +.Cm CS1 +.Ar (Lower Effort) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. diff --git usr.bin/ssh/sshd_config.5 usr.bin/ssh/sshd_config.5 index e051df91254..ebf6f0c0c74 100644 --- usr.bin/ssh/sshd_config.5 +++ usr.bin/ssh/sshd_config.5 @@ -817,9 +817,11 @@ If one argument is specified, it is used as the packet class unconditionally. If two values are specified, the first is automatically selected for interactive sessions and the second for non-interactive sessions. The default is -.Cm lowdelay +.Cm af21 +.Ar (Low-Latency Data) for interactive sessions and -.Cm throughput +.Cm CS1 +.Ar (Lower Effort) for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev