Ограничить пропускную способность для исходящих/входящих с задержкой для определенного порта с помощью TC

Мое личное мнение, основанное на реверс-инжиниринге, который я только что закончил на эту тему, заключается в том, что, при всем уважении, разработчики KDE устроили здесь большую неразбериху.

В порыве упрощения вариант, который вы упомянули, больше недоступен. Глобальное меню теперь включается автоматически, когда вы размещаете апплет глобального меню на панели или добавляете кнопку меню к оформлению окна на вкладке «Кнопки» модуля «Оформление окна».

В противном случае глобальное меню должно автоматически отключаться, а вместо него должна использоваться классическая строка меню «В приложении».

За некоторыми исключениями.

  1. KCalc, например, ведет себя как описано. Просто удалите любой апплет глобального меню и кнопку меню приложения из оформления окна, чтобы вернуть KCalc в меню приложения.
  2. Но другие приложения, такие как Ark, KMenuEdit, Muon, Okteta, KHelpCenter, и это лишь некоторые из них,при использовании кнопки меню приложения или апплета глобального меню хотя бы один раз оставайтесь в этом состоянии даже после удаления кнопки меню приложения или апплета глобального меню без доступа к меню вообще. Мне кажется баг. Для такого рода приложений вы должны вручную редактировать их файл конфигурации (, когда само приложение закрыто, конечно ). Вы найдете их в папке ~/.config. Поиск по названию приложения. Для Ark файл конфигурации:

    ~/.config/arkrc

Есть смена

MenuBar=Disabled

с

MenuBar=Enabled

Это восстанавливает меню "в приложении" (, но не забудьте перед этим удалить любой апплет глобального меню и кнопку меню приложения из оформления окна!)

  1. В дополнение к приведенным выше правилам, другие приложения реализуют дополнительный механизм для включения и выключения меню приложения "в приложении" с помощью горячей клавиши CTRL+M (при условии, что вы восстановили меню "в приложении" как описано в пункте 1 ). Например, Dolphin и Gwenview поддерживают CTRL+M, как описано. Кейт поддерживает CTRL+M, но любезно выдает предупреждение перед тем, как скрыть меню. Вместо этого терминал Konsole, который действует слишком круто для всех других приложений, требует CTRL+ SHIFT +M для включения и выключения меню. Выбранное состояние сохраняется после перезагрузки системы.

  2. И это еще не конец . Другие плазмоиды, разработанные как замена глобального меню приложений, такие как «Active Window Control », отключат ваше меню «в приложении», несмотря на любые другие противоположные директивы, которые вы могли установить. Итак, я предлагаю вам провести тесты в чистой плазменной среде KDE.

0
23.10.2020, 17:18
1 ответ

Вот сценарий, который я запускал пару лет назад, когда у моего провайдера возникли проблемы с переполнением буфера. Его нужно запускать как root- startи stop, но вы можете запустить statusбез root.

#!/bin/bash
# Traffic shaping script (AQM, fq_codel+tbf)
# Copyright 2018,2019 Mikko Rantalainen <mikko.rantalainen@gmail.com>
# License: MIT (X11)
# Usage:
#   21/0.8 Mbps connection (ADSL2): DOWNLINK_RATE=21.7Mbit UPLINK_RATE=0.8Mbit TBF_LATENCY=500ms DOWNLINK_BURST=1500 UPLINK_BURST=1500 bin/traffic-shaping start
#   100/100 Mbps connection:./traffic-shaping
#   1/1 GBps connection: DOWNLINK_RATE=1Gbit UPLINK_RATE=1Gbit TBF_LATENCY=15ms bin/traffic-shaping start
# Note that using low TBF_LATENCY will require powerful CPU.
#
# See also: https://www.bufferbloat.net/projects/codel/wiki/Best_practices_for_benchmarking_Codel_and_FQ_Codel/
# See also: http://www.jfcarter.net/~jimc/documents/voip-qos-1609.html
# TODO: man 7 tc-hfcs (instead of tbf)
# TODO: try to limit bandwidth using fq_codel only (get rid of tbf) - https://gist.github.com/eqhmcow/939373/8d2e8ad745a7e0a8ddb21abde42538034c2ea65b
#   
set -e # abort if a command returns non-zero status (failed)
#set -x # verbose execution

# Note: ip route sometimes outputs multiple lines with prefix "default", use the first one
DEV="${DEV:=$(ip route | grep "^default " | head -n1 | grep -Po "(?<=dev )[^ ]+")}"

# ingress:
DOWNLINK_RATE="${DOWNLINK_RATE:=103000kbit}" # or e.g. "21.5Mbit"
# egress:
UPLINK_RATE="${UPLINK_RATE:=102000kbit}"

CODEL_INTERVAL="${CODEL_INTERVAL:=100ms}" # usually 100ms, high speed links with low latency may need lower values
CODEL_TARGET="${CODEL_TARGET:=5ms}" # unit "us" is also available, usually 5%-10% of CODEL_INTERVAL
CODEL_LIMIT="${CODEL_LIMIT:=1001}" # decrease to reduce latency, too low values will limit throughput
CODEL_FLOWS="${CODEL_FLOWS:=1024}"

# set burst as high as possible without causing dropped packets at the start of the connections
DOWNLINK_BURST="${DOWNLINK_BURST:=8000}"
UPLINK_BURST="${UPLINK_BURST:=55000}"

TBF_LATENCY="${TBF_LATENCY:=10ms}" # set to lower latency to improve control over bandwidth limiting, UPLINK_BURST bytes must be able to be sent in this time


IFB="$DEV.in" # logically this should be $DEV.ingress but max limit might be exceeded (e.g. dev = enp0s29u1u6 -> enp0s29u1u6.ingress is too long

INITCWND="${INITCWND:=15}" # initial congestion window, decrease if packet loss is seen
INITRWND="${INITRWND:=30}" # initial receiving window (advertised from client to servers), can be safely pretty high if you have lots of bandwidth (Windows and OS X have this near 40)

# See also: https://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

# See also: https://www.acc.umu.se/~maswan/linux-netperf.txt

# See also: http://intronetworks.cs.luc.edu/1/html/newtcps.html

# See also: https://www.ietf.org/proceedings/84/slides/slides-84-iccrg-1.pdf

configure_shaping()
{
    # EGRESS (outgoing traffic, "uploads"):

    # setup bandwidth limiting:
    tc qdisc add dev "$DEV" root handle 1: tbf rate "$UPLINK_RATE" burst "$UPLINK_BURST" latency "$TBF_LATENCY"

    # setup fq_codel for bandwidth shaping
    tc qdisc add dev "$DEV" parent 1: fq_codel quantum 300 limit "$CODEL_LIMIT" target "$CODEL_TARGET" interval "$CODEL_INTERVAL" flows "$CODEL_FLOWS" noecn

    # INGRESS (incoming traffic, "downloads"):

    ip link show ifb0 >&/dev/null && HAD_IFB0=1 || HAD_IFB0=0
    ip link show ifb1 >&/dev/null && HAD_IFB1=1 || HAD_IFB1=0

    # setup bandwidth limiting (ingress limiting needs IFB or Intermediate Functional Block, see https://wiki.linuxfoundation.org/networking/ifb):
    tc qdisc add dev "$DEV" handle ffff: ingress
    ip link add name "$IFB" type ifb
    tc qdisc add dev "$IFB" root handle 1: tbf rate "$DOWNLINK_RATE" burst "$DOWNLINK_BURST" latency "$TBF_LATENCY"

    # setup fq_codel for bandwidth shaping
    tc qdisc add dev "$IFB" parent 1: fq_codel quantum 300 limit "$CODEL_LIMIT" target "$CODEL_TARGET" interval "$CODEL_INTERVAL" flows "$CODEL_FLOWS" ecn
    ip link set dev "$IFB" up

    # connect ingress filtering to actual WAN device
    tc filter add dev "$DEV" parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev "$IFB"

    # Configure initcwnd and initrwnd
    # Note that "ip route" sometimes emit multiple lines with prefix "default" - we'll use first one always
    ip route change $(ip route | grep ^default | head -n1) initcwnd "$INITCWND" initrwnd "$INITRWND"

    ## configure CDG congestion control algorithm
    ##modprobe tcp_cdg && echo cdg > /proc/sys/net/ipv4/tcp_congestion_control
    
    # cubic seems to be better overall with AQM, let's tune it
    echo cubic > /proc/sys/net/ipv4/tcp_congestion_control || true
    echo 13 > /sys/module/tcp_cubic/parameters/hystart_low_window

    echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle
    
    # TODO: try modprobe tcp_westwood
    
    # Remove any offloading that increases latency (Note that if you don't have enough CPU power, this may reduce max bandwith!)
    # Note that due ethtool braindamage, the names used here do not match with ethtool --show-offload, see 'man ethtool' for details!
    # ignore possible errors and keep going
    ethtool --offload "$DEV" gso off || true
    ethtool --offload "$DEV" gro off || true
    ethtool --offload "$DEV" tx off || true
    ethtool --offload "$DEV" rx off || true
    ethtool --offload "$DEV" rxvlan off || true
    ethtool --offload "$DEV" txvlan off || true
    
    # cleanup broken ip link add... type ifb sometimes creating extra ifb links (called "ifb0" and "ifb1")
    test "$HAD_IFB0" = "0" && ip link show ifb0 >&/dev/null && ip link del ifb0
    test "$HAD_IFB1" = "0" && ip link show ifb1 >&/dev/null && ip link del ifb1
}

remove_shaping()
{
#set -x
    tc qdisc list | grep -q "ingress" && tc qdisc del dev "$DEV" ingress || true
    # Note: we need to avoid removing root qdisc in case this kernel defaults to fq_codel, "qdisc list" will output "fq_codel 0:" for root qdisc so we look for something different
    tc qdisc list | grep -q "fq_codel [1-9]" && tc qdisc del dev "$DEV" root || true
    ip link show | grep -q "$IFB" && ip link del "$IFB" || true

    # configure CDG congestion control algorithm
    modprobe tcp_cdg && echo cdg > /proc/sys/net/ipv4/tcp_congestion_control || true
#set +x
}

status()
{
        echo "─── queue discipline configuration: ──────────────────"
        tc qdisc list
        echo "   TIP: use e.g. 'sudo tc qdisc del dev $DEV ingress' to remove ingress filtering"
        echo "   TIP: use e.g. 'sudo tc qdisc del dev $DEV root' to remove egress filtering"
        echo "─── ip link show: ────────────────────────────────────"
        ip link show
        echo "   TIP: use e.g. 'sudo ip link del $IFB' to remove ingress device"
}

color_status()
{
    status | grep --color=auto -E "^|$DEV|$IFB|rate [^ ]+"
}

# handle parameters

ACTION="$1"
shift || true

while [ ! -z "$1" ]
do
    case "$1" in
        -v|--verbose)
            echo "Device: $DEV"
            echo "Downlink rate (ingress): $DOWNLINK_RATE"
            echo "Uplink rate (egress): $UPLINK_RATE"
            set -x
            ;;
        *)
            if [ ! -z "$2" ]; then
                echo "Unknown parameter: '$2'" 1>&2
                exit 1
            fi
            ;;
    esac
    shift || true
done

case "$ACTION" in
    start)
        remove_shaping
        configure_shaping
        ;;
    stop)
        remove_shaping
        ;;
    status)
        color_status
        ;;
    restart)
        remove_shaping
        configure_shaping
        ;;
    *)
        echo "Unknown action: $1" 1>&2
        echo "Usage: $0 <start|stop|restart|status> [--verbose|-v]" 1>&2
        exit 1
esac

Способ использования этого скрипта состоит в том, чтобы сохранить его, например, как. traffic-shapingи запустите chmod a+x traffic-shaping, чтобы активировать бит выполнения. Затем вы можете либо изменить значения по умолчанию в файле, либо использовать переменные среды для настройки сценария. Например, если у вас соединение 100/100 Мбит/с, вы можете запустить

DOWNLINK_RATE=95Mbit UPLINK_RATE=95Mbit TBF_LATENCY=25ms./traffic-shaping start

как root. А для восстановления настроек по умолчанию запустите

./traffic-shaping stop

и для отображения текущего состояния запуска

./traffic-shaping stop

Обратите внимание, что приведенные выше настройки не являются постоянными, поэтому вам необходимо повторно запускать сценарий после каждой загрузки. Я использовал это с ядром Ubuntulow-latency(PREEMPT )Linux и TBF_LATENCY=10ms, поэтому я не знаю, какую задержку вы можете ожидать с ядром generic. Вам может понадобиться установить TBF_LATENCY=40ms, если вы запускаете его с ядром generic. Если вы запустите startбез каких-либо установленных переменных среды,вы получите мою собственную конфигурацию, которую я использовал для соединения FTTH со скоростью 100/100 Мбит/с с ядром low-latency. Если у вас соединение со скоростью менее 20 Мбит/с, вы, вероятно, захотите установить DOWNLINK_BURST=1500 UPLINK_BURST=1500, чтобы избежать коротких всплесков в начале новых соединений, которые могут привести к потере пакетов. Для медленного восходящего канала вам также может потребоваться уменьшитьINITCWND(этот сценарий по умолчанию до 15 ), если вы страдаете от потери пакетов / высокой задержки при запуске соединения с быстрыми серверами (, например. трафик веб-браузера ). Значения в диапазоне 7 -10 должны подойти для соединения со скоростью 1 Мбит/с.

0
05.09.2021, 11:49

Теги

Похожие вопросы