mirror of
https://github.com/brenozd/tc-easy.git
synced 2025-12-05 20:39:37 -03:00
Add route subcommand (#1)
Add route subcommand with incremental class handle --------- Co-authored-by: Breno Detomini <brenozd@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6fd015de99
commit
da51cf0e1d
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.txt
|
||||
399
tc-easy.sh
399
tc-easy.sh
@@ -3,8 +3,70 @@
|
||||
# set -e
|
||||
# set -x
|
||||
|
||||
# Global Variables
|
||||
__g_force_cmd=0
|
||||
|
||||
# Global return variables
|
||||
__g_ip_string=""
|
||||
__g_ip_hex=""
|
||||
__g_dev_qdisc=""
|
||||
|
||||
_log() {
|
||||
echo "$@"
|
||||
case $1 in
|
||||
error)
|
||||
__tag="ERROR"
|
||||
__redirect="2"
|
||||
;;
|
||||
warn)
|
||||
__tag="WARN"
|
||||
__redirect="2"
|
||||
;;
|
||||
info)
|
||||
__tag="INFO"
|
||||
__redirect="1"
|
||||
;;
|
||||
debug)
|
||||
__tag="DEBUG"
|
||||
__redirect="1"
|
||||
;;
|
||||
esac
|
||||
|
||||
printf '%s - [%s] - %s\n' "$(date)" "$__tag" "$2"
|
||||
}
|
||||
|
||||
# Convert an formated IPv4 string to hexadecimal. Return value is variable __g_ip_hex
|
||||
_ip_string_to_hex() {
|
||||
__s2h_ip="$1"
|
||||
__g_ip_hex=""
|
||||
__s2h_old_IFS="$IFS"
|
||||
IFS="."
|
||||
for num in $__s2h_ip; do
|
||||
__g_ip_hex="$__g_ip_hex$(printf "%02x" "$num")"
|
||||
done
|
||||
IFS=$__s2h_old_IFS
|
||||
}
|
||||
|
||||
# Convert an hexadecimal IPv4 to a formatted string. Return value is variable __g_ip_string
|
||||
_ip_hex_to_string() {
|
||||
__h2s_hex=$(echo "$1" | sed 's/.\{2\}/& /g')
|
||||
__g_ip_string=""
|
||||
|
||||
_ip_h2s_old_IFS=$IFS
|
||||
IFS=" "
|
||||
for hex in $__h2s_hex; do
|
||||
__g_ip_string="$__g_ip_string$(printf "%d" "0x$hex")."
|
||||
done
|
||||
IFS=$_ip_h2s_old_IFS
|
||||
__g_ip_string=$(echo "$__g_ip_string" | cut -d'.' -f 1,2,3,4)
|
||||
}
|
||||
|
||||
# Check if a given IP is a valid IPv4 construction (do not check if values are greater than 255 tho)
|
||||
_is_ipv4_valid() {
|
||||
__is_ipv4_valid_ip=$(echo "$1" | sed -n -e 's/^\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}$/\0/p')
|
||||
if [ -z "$__is_ipv4_valid_ip" ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Utilizar modprobe para habilitar os módulos utilizados
|
||||
@@ -30,35 +92,24 @@ _check_if_interface_exists() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Gets the current qdisc associated with dev at classid. Return value is variable __g_dev_qdisc
|
||||
_get_dev_qdisc() {
|
||||
__dev="$1"
|
||||
__classid="$2"
|
||||
__qdisc=$(tc qdisc show dev "$__dev" "$__classid")
|
||||
if [ -z "$__qdisc" ]; then
|
||||
__get_dev_qdisc_dev="$1"
|
||||
__get_dev_qdisc_classid="$2"
|
||||
__get_dev_qdisc_root_qdisc=$(tc qdisc show dev "$__get_dev_qdisc_dev" "$__get_dev_qdisc_classid")
|
||||
if [ -z "$__get_dev_qdisc_root_qdisc" ]; then
|
||||
return 1
|
||||
fi
|
||||
echo "$__qdisc" | awk '{print $2}'
|
||||
__g_dev_qdisc=$(echo "$__get_dev_qdisc_root_qdisc" | awk '{print $2}')
|
||||
return 0
|
||||
}
|
||||
|
||||
_show_help_add() {
|
||||
echo "Usage: tc-easy add dev <interface> from <ip> to <ip> OPTIONS"
|
||||
printf "Options:\n\t--latency=<value>\n\t--packetloss=<value>\n\t--jitter=<value> (only used if --latency is passed)\n\t--download=<value>\n\t--upload=<value>\n"
|
||||
printf "Options:\n\t--latency=<value>\n\t--loss=<value>\n\t--jitter=<value> (only used if --latency is passed)\n\t--download=<value>\n\t--upload=<value>\n"
|
||||
}
|
||||
|
||||
_add_route_shaping() {
|
||||
__dev=""
|
||||
__src_ip=""
|
||||
__dst_ip=""
|
||||
__latency=""
|
||||
__jitter=""
|
||||
__packet_loss=""
|
||||
__reorder=""
|
||||
__duplication=""
|
||||
__corruption=""
|
||||
__bandwidth_download="1000"
|
||||
__bandwidth_upload="1000"
|
||||
|
||||
_parse_args_add() {
|
||||
while :; do
|
||||
case $1 in
|
||||
-h|-\?|--help) # Call a "show_help" function to display a synopsis, then exit.
|
||||
@@ -68,17 +119,21 @@ _add_route_shaping() {
|
||||
dev)
|
||||
shift
|
||||
_check_if_interface_exists "$1" || return
|
||||
__dev="$1"
|
||||
__args_add_dev="$1"
|
||||
shift
|
||||
;;
|
||||
from)
|
||||
shift
|
||||
__src_ip="$1"
|
||||
__args_add_src_ip="$1"
|
||||
shift
|
||||
;;
|
||||
to)
|
||||
shift
|
||||
__dst_ip="$1"
|
||||
__args_add_dst_ip="$1"
|
||||
shift
|
||||
;;
|
||||
-f|--froce)
|
||||
__g_force_cmd=1
|
||||
shift
|
||||
;;
|
||||
--latency|-l)
|
||||
@@ -91,7 +146,7 @@ _add_route_shaping() {
|
||||
__jitter="$1"
|
||||
shift
|
||||
;;
|
||||
--packetloss|-p)
|
||||
--loss|-p)
|
||||
shift
|
||||
__packet_loss="$1"
|
||||
shift
|
||||
@@ -124,97 +179,158 @@ _add_route_shaping() {
|
||||
-?*)
|
||||
printf 'WARN: Unknown add option: %s\n' "$1" >&2
|
||||
_show_help_add
|
||||
return
|
||||
;;
|
||||
*)
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$__dev" ] || [ -z "$__src_ip" ] || [ -z "$__dst_ip" ]; then
|
||||
printf 'Missing arguments\n'
|
||||
# TODO: Antes de fazer qualquer coisa checar se há banda disponível no TC
|
||||
if [ -z "$__args_add_dev" ] || [ -z "$__args_add_src_ip" ] || [ -z "$__args_add_dst_ip" ]; then
|
||||
_show_help_add
|
||||
return
|
||||
fi
|
||||
|
||||
__dev_qdisc=$(_get_dev_qdisc "$__dev" "root")
|
||||
if [ "$__dev_qdisc" != "htb" ]; then
|
||||
echo "Interface $__dev has qdisc $__dev_qdisc associated with it" >&2
|
||||
echo "Do you want to continue? All qdisc from interface $__dev will be deleted [y|n]"
|
||||
read -r __continue
|
||||
if [ "$__continue" != "y" ]; then
|
||||
echo "Aborting tc-easy"
|
||||
if ! _is_ipv4_valid "$__args_add_src_ip" || ! _is_ipv4_valid "$__args_add_dst_ip"; then
|
||||
_log "error" "Either source or destination IP is no a valid IPv4"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if route already exists
|
||||
__args_add_interface_routes=$(tc filter show dev "$__args_add_dev")
|
||||
__args_add_flow_handle=""
|
||||
__args_add_old_IFS=$IFS
|
||||
IFS="
|
||||
"
|
||||
for line in $__args_add_interface_routes; do
|
||||
case $line in
|
||||
# If line is a filter definition, get handle
|
||||
"filter"*)
|
||||
__args_add_flow_handle=$(echo "$line" | sed -n -e 's/^.*\([0-9]\+:[0-9]\+\).*/\1/p')
|
||||
__args_add_src_ip_filter=""
|
||||
__args_add_dst_ip_filter=""
|
||||
;;
|
||||
*"match"*"at 12")
|
||||
# TODO: checar o que é o argumento depois do / no IP
|
||||
__args_add_src_ip_filter=$(echo "$line" | sed -e 's/^.*\([abcdef0-9]\{8\}\/[abcdef0-9]\{8\}\).*/\1/p' | cut -d'/' -f1)
|
||||
;;
|
||||
*"match"*"at 16")
|
||||
__args_add_dst_ip_filter=$(echo "$line" | sed -e 's/^.*\([abcdef0-9]\{8\}\/[abcdef0-9]\{8\}\).*/\1/p' | cut -d'/' -f1)
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$__args_add_flow_handle" ] && [ -n "$__args_add_src_ip_filter" ] && [ -n "$__args_add_dst_ip_filter" ]; then
|
||||
_ip_hex_to_string $__args_add_src_ip_filter
|
||||
__args_add_src_ip_filter="$__g_ip_string"
|
||||
|
||||
_ip_hex_to_string $__args_add_dst_ip_filter
|
||||
__args_add_dst_ip_filter="$__g_ip_string"
|
||||
|
||||
# TODO: Ao invés de abortar, perguntar ao usuário se deseja alterar a rota
|
||||
# TODO: Imprimir informações da rota
|
||||
if [ "$__args_add_src_ip" = "$__args_add_src_ip_filter" ] && [ "$__args_add_dst_ip" = "$__args_add_dst_ip_filter" ]; then
|
||||
_log "warn" "Route from $__args_add_src_ip_filter to $__args_add_dst_ip_filter already exists (flowid $__args_add_flow_handle), aborting!\n"
|
||||
exit 10
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
IFS=$__args_add_old_IFS
|
||||
|
||||
__netem_params=""
|
||||
if [ -n "$__latency" ]; then
|
||||
__netem_params="$__netem_params delay ${__latency}ms"
|
||||
# TODO: Checar se setando o jitter > latencia o TC buga
|
||||
if [ -n "$__jitter" ]; then
|
||||
__netem_params="$__netem_params ${__jitter}ms distribution normal"
|
||||
fi
|
||||
__ifb_dev="ifb_$__args_add_dev"
|
||||
if ! _check_if_interface_exists "$__ifb_dev"; then
|
||||
ip link add name "$__ifb_dev" type ifb
|
||||
fi
|
||||
|
||||
if [ -n "$__packet_loss" ]; then
|
||||
__netem_params="$__netem_params loss ${__packet_loss}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__reorder" ]; then
|
||||
__netem_params="$__netem_params reorder ${__reorder}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__duplication" ]; then
|
||||
__netem_params="$__netem_params reorder ${__duplication}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__corruption" ]; then
|
||||
__netem_params="$__netem_params corrupt ${__corruption}%"
|
||||
fi
|
||||
|
||||
__ifb_dev="ifb_$__dev"
|
||||
if _check_if_interface_exists "$__ifb_dev"; then
|
||||
ip link delete "$__ifb_dev"
|
||||
fi
|
||||
|
||||
ip link add name "$__ifb_dev" type ifb
|
||||
ip link set dev "$__ifb_dev" up
|
||||
|
||||
_add_route "$__args_add_dev" "$__args_add_src_ip" "$__args_add_dst_ip" "$__latency" "$__jitter" "$__packet_loss" "$__reorder" "$__duplication" "$__corruption" "$__bandwidth_download"
|
||||
_add_route "$__ifb_dev" "$__args_add_src_ip" "$__args_add_dst_ip" "$__latency" "$__jitter" "$__packet_loss" "$__reorder" "$__duplication" "$__corruption" "$__bandwidth_upload"
|
||||
|
||||
tc qdisc del dev "$__ifb_dev" root >/dev/null 2>&1
|
||||
tc qdisc del dev "$__dev" root >/dev/null 2>&1
|
||||
if _get_dev_qdisc "$__args_add_dev" "ingress"; then
|
||||
tc qdisc del dev "$__args_add_dev" ingress
|
||||
fi
|
||||
|
||||
# TODO: Arrumar os handles do qdisc, começando em 0
|
||||
# TODO: Adicionar fifo_fast como classe default do htb
|
||||
# TODO: Se houver outro qdisc como root, perguntar para o usuario o que fazer
|
||||
# TODO: Limitar a banda do root como a
|
||||
tc qdisc add dev "$__args_add_dev" ingress
|
||||
tc filter add dev "$__args_add_dev" ingress matchall action mirred egress redirect dev "$__ifb_dev"
|
||||
|
||||
__interface_speed=$(cat /sys/class/net/"$__dev"/speed)
|
||||
tc qdisc add dev "$__dev" root handle 1: htb default 1
|
||||
tc qdisc add dev "$__ifb_dev" root handle 1: htb default 1
|
||||
_log "info" "Added route from $__args_add_src_ip to $__args_add_dst_ip via $__args_add_dev"
|
||||
}
|
||||
|
||||
_add_route() {
|
||||
__add_route_dev="$1"
|
||||
__add_route_src_ip="$2"
|
||||
__add_route_dst_ip="$3"
|
||||
__add_route_latency="$4"
|
||||
__add_route_jitter="$5"
|
||||
__add_route_packet_loss="$6"
|
||||
__add_route_reorder="$7"
|
||||
__add_route_duplication="$8"
|
||||
__add_route_corruption="$9"
|
||||
__add_route_bandwidth="${10}"
|
||||
|
||||
|
||||
if _get_dev_qdisc "$__add_route_dev" "root" && [ "$__g_dev_qdisc" != "htb" ]; then
|
||||
if [ $__g_force_cmd -ne 1 ] && [ "$__continue" != "y" ]; then
|
||||
_log warn "Interface $__add_route_dev has qdisc $__g_dev_qdisc associated with it"
|
||||
echo "Do you want to continue? All qdisc from interface $__add_route_dev will be deleted [y|n]"
|
||||
read -r __continue
|
||||
if [ "$__continue" != "y" ]; then
|
||||
echo "Aborting tc-easy"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
tc qdisc del dev "$__add_route_dev" root >/dev/null 2>&1
|
||||
tc qdisc add dev "$__add_route_dev" root handle 1: htb
|
||||
# TODO: A banda máxima de download/upload deve ser sempre simétrica?
|
||||
# TODO: Adicionar fifo_fast como classe default do htb
|
||||
__add_route_dev_speed=$(cat /sys/class/net/"$__add_route_dev"/speed >/dev/null 2>&1)
|
||||
if [ -z "$__add_route_dev_speed" ] || [ "$__add_route_dev_speed" -lt 0 ]; then
|
||||
_log "warn" "Cannot get $__add_route_dev speed, assuming 1000mbps"
|
||||
__add_route_dev_speed="1000"
|
||||
fi
|
||||
tc class add dev "$__add_route_dev" parent 1: classid 1:1 htb rate "$__add_route_dev_speed"mbit ceil "$__add_route_dev_speed"mbit
|
||||
fi
|
||||
|
||||
# TODO: Os parâmetros do NetEm devem ser mirrored?
|
||||
# Quero dizer: se temos 10 de latência, seriam 5ms outgoing e 5ms incoming, totalizando 10ms
|
||||
# Ou 10ms outgoing e 10ms incoming, totalizando 20ms
|
||||
__add_route_netem_params=""
|
||||
if [ -n "$__add_route_latency" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params delay ${__add_route_latency}ms"
|
||||
if [ -n "$__add_route_jitter" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params ${__add_route_jitter}ms distribution normal"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$__add_route_packet_loss" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params loss ${__add_route_packet_loss}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__add_route_reorder" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params reorder ${__add_route_reorder}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__add_route_duplication" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params reorder ${__add_route_duplication}%"
|
||||
fi
|
||||
|
||||
if [ -n "$__add_route_corruption" ]; then
|
||||
__add_route_netem_params="$__add_route_netem_params corrupt ${__add_route_corruption}%"
|
||||
fi
|
||||
|
||||
# TODO: checar se há banda disponível para a classe
|
||||
tc class add dev "$__dev" parent 1: classid 1:2 htb rate "$__bandwidth_upload"mbps ceil "$__bandwidth_upload"mbps prio 2
|
||||
tc class add dev "$__ifb_dev" parent 1: classid 1:1 htb rate "$__bandwidth_upload"mbps ceil "$__bandwidth_upload"mbps prio 2
|
||||
__add_route_new_handle=$(tc class show dev "$__add_route_dev" | grep htb | awk '{print $3}' | sort | tail -n1 | awk -F ':' '{print $2+1}')
|
||||
__add_route_bandwidth=${__add_route_bandwidth:-"50"}
|
||||
# Se não houver banda disponível, perguntar quando alocar e checar se o valor fornecido é menor que o máximo disponível (speed da interface - soma de todas as rates dos HTBs)
|
||||
tc class add dev "$__add_route_dev" parent 1:1 classid 1:"$__add_route_new_handle" htb rate "$__add_route_bandwidth"mbit ceil "$__add_route_bandwidth"mbit prio 2
|
||||
|
||||
if [ -n "$__netem_params" ]; then
|
||||
# Remove trailing whitespaces, otherwhise TC does not accept __netem_params
|
||||
__netem_params=$(echo "$__netem_params" | cut -f 2- -d ' ')
|
||||
tc qdisc add dev "$__dev" parent 1:2 handle 10:0 netem $__netem_params
|
||||
tc qdisc add dev "$__ifb_dev" parent 1:1 handle 10:0 netem $__netem_params
|
||||
if [ -n "$__add_route_netem_params" ]; then
|
||||
# Remove trailing whitespaces, otherwhise TC does not accept __add_route_netem_params
|
||||
__add_route_netem_params=$(echo "$__add_route_netem_params" | cut -f 2- -d ' ')
|
||||
tc qdisc add dev "$__add_route_dev" parent 1:"$__add_route_new_handle" handle "$__add_route_new_handle":1 netem $__add_route_netem_params
|
||||
fi
|
||||
|
||||
tc filter add dev "$__dev" protocol ip parent 1:0 prio 2 u32 match ip src "$__src_ip" match ip dst "$__dst_ip" flowid 1:2
|
||||
tc filter add dev "$__ifb_dev" protocol ip parent 1:0 prio 2 u32 match ip src "$__src_ip" match ip dst "$__dst_ip" flowid 1:2
|
||||
|
||||
if _get_dev_qdisc "$__dev" "ingress"; then
|
||||
tc qdisc del dev "$__dev" ingress
|
||||
fi
|
||||
|
||||
tc qdisc add dev "$__dev" ingress
|
||||
tc filter add dev "$__dev" ingress matchall action mirred egress redirect dev "$__ifb_dev"
|
||||
|
||||
printf 'Added route from %s to %s via %s\n' "$__src_ip" "$__dst_ip" "$__dev"
|
||||
|
||||
tc filter add dev "$__add_route_dev" protocol ip parent 1: prio 2 u32 match ip src "$__add_route_src_ip" match ip dst "$__add_route_dst_ip" flowid 1:"$__add_route_new_handle"
|
||||
}
|
||||
|
||||
_parse_args_rm() {
|
||||
@@ -263,12 +379,65 @@ _parse_args_rm() {
|
||||
ip link delete "$__ifb_dev"
|
||||
fi
|
||||
|
||||
printf 'Removed route from %s to %s via %s\n' "$__src_ip" "$__dst_ip" "$__dev"
|
||||
_log info "Removed route from $__src_ip to $__dst_ip via $__dev"
|
||||
|
||||
}
|
||||
|
||||
_show_help_ls() {
|
||||
printf "Usage: tc-easy ls dev <interface>\n"
|
||||
printf "Optional: from <ip>, to <ip>\n"
|
||||
}
|
||||
|
||||
_parse_args_ls() {
|
||||
echo "Not implemented yet"
|
||||
while :; do
|
||||
case $1 in
|
||||
-h|-\?|--help) # Call a "show_help" function to display a synopsis, then exit.
|
||||
_show_help_ls
|
||||
exit
|
||||
;;
|
||||
dev)
|
||||
shift
|
||||
_check_if_interface_exists "$1" || return
|
||||
__dev="$1"
|
||||
shift
|
||||
;;
|
||||
from)
|
||||
shift
|
||||
__src_ip="$1"
|
||||
shift
|
||||
;;
|
||||
to)
|
||||
shift
|
||||
__dst_ip="$1"
|
||||
shift
|
||||
;;
|
||||
-?*)
|
||||
printf 'WARN: Unknown add option: %s\n' "$1" >&2
|
||||
_show_help_add
|
||||
;;
|
||||
*)
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$__dev" ]; then
|
||||
_show_help_ls
|
||||
return
|
||||
fi
|
||||
|
||||
_list_routes "$__dev"
|
||||
}
|
||||
|
||||
_list_routes() {
|
||||
__list_route_dev="$1"
|
||||
__list_route_src_ip="$2"
|
||||
__list_route_dst_ip="$3"
|
||||
__list_routes_dev_qdiscs=$(tc qdisc show dev "$__list_route_dev")
|
||||
__list_routes_dev_classes=$(tc class show dev "$__list_route_dev")
|
||||
__list_routes_dev_filters=$(tc filter show dev "$__list_route_dev")
|
||||
|
||||
|
||||
printf "%s\n" "$__list_routes_dev_qdiscs"
|
||||
}
|
||||
|
||||
_show_help_global() {
|
||||
@@ -285,7 +454,7 @@ _parse_args_global() {
|
||||
;;
|
||||
add)
|
||||
shift
|
||||
_add_route_shaping "$@"
|
||||
_parse_args_add "$@"
|
||||
;;
|
||||
rm)
|
||||
shift
|
||||
@@ -296,7 +465,7 @@ _parse_args_global() {
|
||||
_parse_args_ls "$@"
|
||||
;;
|
||||
-?*)
|
||||
printf 'WARN: Unknown subcommand: %s, avaible subcommands are: add, rm and ls\n' "$1" >&2
|
||||
_log 'warn' "Unknown subcommand: $1, avaible subcommands are: add, rm and ls"
|
||||
_show_help_global
|
||||
;;
|
||||
*)
|
||||
@@ -330,13 +499,43 @@ fi
|
||||
|
||||
#check if ifb and tc are enabled
|
||||
if ! _check_kmod_enabled "ifb"; then
|
||||
_log "IFB kernel module is deactivated, consider enabling it"
|
||||
exit 3
|
||||
_log "IFB kernel module is deactivated, try to activate it? [y|n]"
|
||||
read -r __continue
|
||||
if [ "$__continue" = "y" ]; then
|
||||
if ! modprobe ifb; then
|
||||
_log "error" "Failed to activate module IFB"
|
||||
exit 3
|
||||
fi
|
||||
else
|
||||
exit 4
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if ! _check_kmod_enabled "htb"; then
|
||||
_log "HTB kernel module is deactivated, try to activate it? [y|n]"
|
||||
read -r __continue
|
||||
if [ "$__continue" = "y" ]; then
|
||||
if ! modprobe sch_netem; then
|
||||
_log "error" "Failed to activate module NetEm"
|
||||
exit 3
|
||||
fi
|
||||
else
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! _check_kmod_enabled "netem"; then
|
||||
_log "NetEm kernel module is deactivated, consider enabling it"
|
||||
exit 4
|
||||
_log "NetEm kernel module is deactivated, try to activate it? [y|n]"
|
||||
read -r __continue
|
||||
if [ "$__continue" = "y" ]; then
|
||||
if ! modprobe sch_netem; then
|
||||
_log "error" "Failed to activate module NetEm"
|
||||
exit 3
|
||||
fi
|
||||
else
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
|
||||
_parse_args_global "$@"
|
||||
Reference in New Issue
Block a user