mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
86f6481e99
Temporary test data should all go somewhere under TEST_VAR_DIR instead of in the global /tmp. The existing mktemp could be changed so the data goes into the test directory but mktemp is overkill in this case. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
677 lines
15 KiB
Bash
Executable File
677 lines
15 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
promote_secondaries=true
|
|
|
|
not_implemented ()
|
|
{
|
|
echo "ip stub command: \"$1\" not implemented"
|
|
exit 127
|
|
}
|
|
|
|
######################################################################
|
|
|
|
ip_link ()
|
|
{
|
|
case "$1" in
|
|
set)
|
|
shift
|
|
# iface="$1"
|
|
case "$2" in
|
|
up) ip_link_set_up "$1" ;;
|
|
down) ip_link_down_up "$1" ;;
|
|
*) not_implemented "\"$2\" in \"$orig_args\"" ;;
|
|
esac
|
|
;;
|
|
show) shift ; ip_link_show "$@" ;;
|
|
add*) shift ; ip_link_add "$@" ;;
|
|
del*) shift ; ip_link_delete "$@" ;;
|
|
*) not_implemented "$*" ;;
|
|
esac
|
|
}
|
|
|
|
ip_link_add ()
|
|
{
|
|
_link=""
|
|
_name=""
|
|
_type=""
|
|
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
link)
|
|
_link="$2"
|
|
shift 2
|
|
;;
|
|
name)
|
|
_name="$2"
|
|
shift 2
|
|
;;
|
|
type)
|
|
if [ "$2" != "vlan" ] ; then
|
|
not_implemented "link type $1"
|
|
fi
|
|
_type="$2"
|
|
shift 2
|
|
;;
|
|
id) shift 2 ;;
|
|
*) not_implemented "$1" ;;
|
|
esac
|
|
done
|
|
|
|
case "$_type" in
|
|
vlan)
|
|
if [ -z "$_name" -o -z "$_link" ] ; then
|
|
not_implemented "ip link add with null name or link"
|
|
fi
|
|
|
|
mkdir -p "${FAKE_IP_STATE}/interfaces-vlan"
|
|
echo "$_link" >"${FAKE_IP_STATE}/interfaces-vlan/${_name}"
|
|
ip_link_set_down "$_name"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
ip_link_delete ()
|
|
{
|
|
mkdir -p "${FAKE_IP_STATE}/interfaces-deleted"
|
|
touch "${FAKE_IP_STATE}/interfaces-deleted/$1"
|
|
rm -f "${FAKE_IP_STATE}/interfaces-vlan/$1"
|
|
}
|
|
|
|
ip_link_set_up ()
|
|
{
|
|
rm -f "${FAKE_IP_STATE}/interfaces-down/$1"
|
|
rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1"
|
|
}
|
|
|
|
ip_link_set_down ()
|
|
{
|
|
rm -f "${FAKE_IP_STATE}/interfaces-deleted/$1"
|
|
mkdir -p "${FAKE_IP_STATE}/interfaces-down"
|
|
touch "${FAKE_IP_STATE}/interfaces-down/$1"
|
|
}
|
|
|
|
ip_link_show ()
|
|
{
|
|
dev="$1"
|
|
if [ "$dev" = "dev" -a -n "$2" ] ; then
|
|
dev="$2"
|
|
fi
|
|
|
|
if [ -e "${FAKE_IP_STATE}/interfaces-deleted/$dev" ] ; then
|
|
echo "Device \"${dev}\" does not exist." >&2
|
|
exit 255
|
|
fi
|
|
|
|
if [ -r "${FAKE_IP_STATE}/interfaces-vlan/${dev}" ] ; then
|
|
read _link <"${FAKE_IP_STATE}/interfaces-vlan/${dev}"
|
|
dev="${dev}@${_link}"
|
|
fi
|
|
|
|
_state="UP"
|
|
_flags=",UP,LOWER_UP"
|
|
if [ -e "${FAKE_IP_STATE}/interfaces-down/$dev" ] ; then
|
|
_state="DOWN"
|
|
_flags=""
|
|
fi
|
|
case "$dev" in
|
|
lo)
|
|
_mac="00:00:00:00:00:00"
|
|
_brd="00:00:00:00:00:00"
|
|
_type="loopback"
|
|
_opts="<LOOPBACK${_flags}> mtu 65536 qdisc noqueue state UNKNOWN"
|
|
;;
|
|
*)
|
|
_mac=$(echo $dev | md5sum | sed -r -e 's@(..)(..)(..)(..)(..)(..).*@\1:\2:\3:\4:\5:\6@')
|
|
_brd="ff:ff:ff:ff:ff:ff"
|
|
_type="ether"
|
|
_opts="<BROADCAST,MULTICAST${_flags}> mtu 1500 qdisc pfifo_fast state ${_state} qlen 1000"
|
|
esac
|
|
echo "${n:-42}: ${dev}: ${_opts}"
|
|
echo " link/${_type} ${_mac} brd ${_brd}"
|
|
}
|
|
|
|
# This is incomplete because it doesn't actually look up table ids in
|
|
# /etc/iproute2/rt_tables. The rules/routes are actually associated
|
|
# with the name instead of the number. However, we include a variable
|
|
# to fake a bad table id.
|
|
[ -n "$IP_ROUTE_BAD_TABLE_ID" ] || IP_ROUTE_BAD_TABLE_ID=false
|
|
|
|
ip_check_table ()
|
|
{
|
|
_cmd="$1"
|
|
|
|
if [ "$_cmd" = "route" -a -z "$_table" ] ;then
|
|
_table="main"
|
|
fi
|
|
|
|
[ -n "$_table" ] || not_implemented "ip rule/route without \"table\""
|
|
|
|
# Only allow tables names from 13.per_ip_routing and "main". This
|
|
# is a cheap way of avoiding implementing the default/local
|
|
# tables.
|
|
case "$_table" in
|
|
ctdb.*|main)
|
|
if $IP_ROUTE_BAD_TABLE_ID ; then
|
|
# Ouch. Simulate inconsistent errors from ip. :-(
|
|
case "$_cmd" in
|
|
route)
|
|
echo "Error: argument "${_table}" is wrong: table id value is invalid" >&2
|
|
|
|
;;
|
|
*)
|
|
echo "Error: argument "${_table}" is wrong: invalid table ID" >&2
|
|
esac
|
|
exit 255
|
|
fi
|
|
;;
|
|
*) not_implemented "table=${_table} ${orig_args}" ;;
|
|
esac
|
|
}
|
|
|
|
######################################################################
|
|
|
|
ip_addr ()
|
|
{
|
|
case "$1" in
|
|
show|list|"") shift ; ip_addr_show "$@" ;;
|
|
add*) shift ; ip_addr_add "$@" ;;
|
|
del*) shift ; ip_addr_del "$@" ;;
|
|
*) not_implemented "\"$1\" in \"$orig_args\"" ;;
|
|
esac
|
|
}
|
|
|
|
ip_addr_show ()
|
|
{
|
|
dev=""
|
|
primary=true
|
|
secondary=true
|
|
_to=""
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
dev)
|
|
dev="$2" ; shift 2
|
|
;;
|
|
# Do stupid things and stupid things will happen!
|
|
primary)
|
|
primary=true ; secondary=false ; shift
|
|
;;
|
|
secondary)
|
|
secondary=true ; primary=false ; shift
|
|
;;
|
|
to)
|
|
_to="$2" ; shift 2
|
|
;;
|
|
*)
|
|
# Assume an interface name
|
|
dev="$1" ; shift 1
|
|
esac
|
|
done
|
|
devices="$dev"
|
|
if [ -z "$devices" ] ; then
|
|
# No device specified? Get all the primaries...
|
|
devices=$(ls "${FAKE_IP_STATE}/addresses/"*-primary 2>/dev/null | \
|
|
sed -e 's@.*/@@' -e 's@-.*-primary$@@' | sort -u)
|
|
fi
|
|
calc_brd ()
|
|
{
|
|
case "${local#*/}" in
|
|
24) brd="${local%.*}.255" ;;
|
|
32) brd="" ;;
|
|
*) not_implemented "list ... fake bits other than 24/32: ${local#*/}"
|
|
esac
|
|
}
|
|
show_iface()
|
|
{
|
|
ip_link_show "$dev"
|
|
|
|
nets=$(ls "${FAKE_IP_STATE}/addresses/${dev}"-*-primary 2>/dev/null | \
|
|
sed -e 's@.*/@@' -e "s@${dev}-\(.*\)-primary\$@\1@")
|
|
|
|
for net in $nets ; do
|
|
pf="${FAKE_IP_STATE}/addresses/${dev}-${net}-primary"
|
|
sf="${FAKE_IP_STATE}/addresses/${dev}-${net}-secondary"
|
|
if $primary && [ -r "$pf" ] ; then
|
|
read local scope <"$pf"
|
|
if [ -z "$_to" -o "${_to%/*}" = "${local%/*}" ] ; then
|
|
calc_brd
|
|
echo " inet ${local} ${brd:+brd ${brd} }scope ${scope} ${dev}"
|
|
fi
|
|
fi
|
|
if $secondary && [ -r "$sf" ] ; then
|
|
while read local scope ; do
|
|
if [ -z "$_to" -o "${_to%/*}" = "${local%/*}" ] ; then
|
|
calc_brd
|
|
echo " inet ${local} ${brd:+brd }${brd} scope ${scope} secondary ${dev}"
|
|
fi
|
|
done <"$sf"
|
|
fi
|
|
if [ -z "$_to" ] ; then
|
|
echo " valid_lft forever preferred_lft forever"
|
|
fi
|
|
done
|
|
}
|
|
n=1
|
|
for dev in $devices ; do
|
|
if [ -z "$_to" ] || \
|
|
grep -F "${_to%/*}/" "${FAKE_IP_STATE}/addresses/${dev}-"* >/dev/null ; then
|
|
show_iface
|
|
fi
|
|
n=$(($n + 1))
|
|
done
|
|
}
|
|
|
|
# Copied from 13.per_ip_routing for now... so this is lazy testing :-(
|
|
ipv4_host_addr_to_net ()
|
|
{
|
|
_host="$1"
|
|
_maskbits="$2"
|
|
|
|
# Convert the host address to an unsigned long by splitting out
|
|
# the octets and doing the math.
|
|
_host_ul=0
|
|
for _o in $(export IFS="." ; echo $_host) ; do
|
|
_host_ul=$(( ($_host_ul << 8) + $_o)) # work around Emacs color bug
|
|
done
|
|
|
|
# Calculate the mask and apply it.
|
|
_mask_ul=$(( 0xffffffff << (32 - $_maskbits) ))
|
|
_net_ul=$(( $_host_ul & $_mask_ul ))
|
|
|
|
# Now convert to a network address one byte at a time.
|
|
_net=""
|
|
for _o in $(seq 1 4) ; do
|
|
_net="$(($_net_ul & 255))${_net:+.}${_net}"
|
|
_net_ul=$(($_net_ul >> 8))
|
|
done
|
|
|
|
echo "${_net}/${_maskbits}"
|
|
}
|
|
|
|
ip_addr_add ()
|
|
{
|
|
local=""
|
|
dev=""
|
|
brd=""
|
|
scope="global"
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
*.*.*.*/*)
|
|
local="$1" ; shift
|
|
;;
|
|
local)
|
|
local="$2" ; shift 2
|
|
;;
|
|
broadcast|brd)
|
|
# For now assume this is always '+'.
|
|
if [ "$2" != "+" ] ; then
|
|
not_implemented "addr add ... brd $2 ..."
|
|
fi
|
|
shift 2
|
|
;;
|
|
dev)
|
|
dev="$2" ; shift 2
|
|
;;
|
|
scope)
|
|
scope="$2" ; shift 2
|
|
;;
|
|
*)
|
|
not_implemented "$@"
|
|
esac
|
|
done
|
|
if [ -z "$dev" ] ; then
|
|
not_implemented "addr add (without dev)"
|
|
fi
|
|
mkdir -p "${FAKE_IP_STATE}/addresses"
|
|
net_str=$(ipv4_host_addr_to_net $(IFS="/" ; echo $local))
|
|
net_str=$(echo "$net_str" | sed -e 's@/@_@')
|
|
pf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-primary"
|
|
sf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-secondary"
|
|
# We could lock here... but we should be the only ones playing
|
|
# around here with these stubs.
|
|
if [ ! -f "$pf" ] ; then
|
|
echo "$local $scope" >"$pf"
|
|
elif grep -Fq "$local" "$pf" ; then
|
|
echo "RTNETLINK answers: File exists" >&2
|
|
exit 254
|
|
elif [ -f "$sf" ] && grep -Fq "$local" "$sf" ; then
|
|
echo "RTNETLINK answers: File exists" >&2
|
|
exit 254
|
|
else
|
|
echo "$local $scope" >>"$sf"
|
|
fi
|
|
}
|
|
|
|
ip_addr_del ()
|
|
{
|
|
local=""
|
|
dev=""
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
*.*.*.*/*)
|
|
local="$1" ; shift
|
|
;;
|
|
local)
|
|
local="$2" ; shift 2
|
|
;;
|
|
dev)
|
|
dev="$2" ; shift 2
|
|
;;
|
|
*)
|
|
not_implemented "addr del ... $1 ..."
|
|
esac
|
|
done
|
|
if [ -z "$dev" ] ; then
|
|
not_implemented "addr del (without dev)"
|
|
fi
|
|
mkdir -p "${FAKE_IP_STATE}/addresses"
|
|
net_str=$(ipv4_host_addr_to_net $(IFS="/" ; echo $local))
|
|
net_str=$(echo "$net_str" | sed -e 's@/@_@')
|
|
pf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-primary"
|
|
sf="${FAKE_IP_STATE}/addresses/${dev}-${net_str}-secondary"
|
|
# We could lock here... but we should be the only ones playing
|
|
# around here with these stubs.
|
|
if [ ! -f "$pf" ] ; then
|
|
echo "RTNETLINK answers: Cannot assign requested address" >&2
|
|
exit 254
|
|
elif grep -Fq "$local" "$pf" ; then
|
|
if $promote_secondaries && [ -s "$sf" ] ; then
|
|
head -n 1 "$sf" >"$pf"
|
|
sed -i -e '1d' "$sf"
|
|
else
|
|
# Remove primaries AND SECONDARIES.
|
|
rm -f "$pf" "$sf"
|
|
fi
|
|
elif [ -f "$sf" ] && grep -Fq "$local" "$sf" ; then
|
|
grep -Fv "$local" "$sf" >"${sf}.new"
|
|
mv "${sf}.new" "$sf"
|
|
else
|
|
echo "RTNETLINK answers: Cannot assign requested address" >&2
|
|
exit 254
|
|
fi
|
|
}
|
|
|
|
######################################################################
|
|
|
|
ip_rule ()
|
|
{
|
|
case "$1" in
|
|
show|list|"") shift ; ip_rule_show "$@" ;;
|
|
add) shift ; ip_rule_add "$@" ;;
|
|
del*) shift ; ip_rule_del "$@" ;;
|
|
*) not_implemented "$1 in \"$orig_args\"" ;;
|
|
esac
|
|
|
|
}
|
|
|
|
# All non-default rules are in $FAKE_IP_STATE_RULES/rules. As with
|
|
# the real version, rules can be repeated. Deleting just deletes the
|
|
# 1st match.
|
|
|
|
ip_rule_show ()
|
|
{
|
|
ip_rule_show_1 ()
|
|
{
|
|
_pre="$1"
|
|
_table="$2"
|
|
_selectors="$3"
|
|
# potentially more options
|
|
|
|
printf "%d:\t%s lookup %s \n" $_pre "$_selectors" "$_table"
|
|
}
|
|
|
|
ip_rule_show_some ()
|
|
{
|
|
_min="$1"
|
|
_max="$2"
|
|
|
|
[ -f "${FAKE_IP_STATE}/rules" ] || return
|
|
|
|
while read _pre _table _selectors ; do
|
|
# Only print those in range
|
|
[ $_min -le $_pre -a $_pre -le $_max ] || continue
|
|
|
|
ip_rule_show_1 $_pre "$_table" "$_selectors"
|
|
done <"${FAKE_IP_STATE}/rules"
|
|
}
|
|
|
|
ip_rule_show_1 0 "local" "from all"
|
|
|
|
ip_rule_show_some 1 32765
|
|
|
|
ip_rule_show_1 32766 "main" "from all"
|
|
ip_rule_show_1 32767 "default" "from all"
|
|
|
|
ip_rule_show_some 32768 2147483648
|
|
}
|
|
|
|
ip_rule_common ()
|
|
{
|
|
_from=""
|
|
_pre=""
|
|
_table=""
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
from) _from="$2" ; shift 2 ;;
|
|
pref) _pre="$2" ; shift 2 ;;
|
|
table) _table="$2" ; shift 2 ;;
|
|
*) not_implemented "$1 in \"$orig_args\"" ;;
|
|
esac
|
|
done
|
|
|
|
[ -n "$_pre" ] || not_implemented "ip rule without \"pref\""
|
|
ip_check_table "rule"
|
|
# Relax this if more selectors added later...
|
|
[ -n "$_from" ] || not_implemented "ip rule without \"from\""
|
|
}
|
|
|
|
ip_rule_add ()
|
|
{
|
|
ip_rule_common "$@"
|
|
|
|
_f="${FAKE_IP_STATE}/rules"
|
|
touch "$_f"
|
|
(
|
|
flock 0
|
|
# Filter order must be consistent with the comparison in ip_rule_del()
|
|
echo "$_pre $_table${_from:+ from }$_from" >>"$_f"
|
|
) <"$_f"
|
|
}
|
|
|
|
ip_rule_del ()
|
|
{
|
|
ip_rule_common "$@"
|
|
|
|
_f="${FAKE_IP_STATE}/rules"
|
|
touch "$_f"
|
|
(
|
|
flock 0
|
|
_tmp="${_f}.new"
|
|
: >"$_tmp"
|
|
_found=false
|
|
while read _p _t _s ; do
|
|
if ! $_found && \
|
|
[ "$_p" = "$_pre" -a "$_t" = "$_table" -a \
|
|
"$_s" = "${_from:+from }$_from" ] ; then
|
|
# Found. Skip this one but not future ones.
|
|
_found=true
|
|
else
|
|
echo "$_p $_t $_s" >>"$_tmp"
|
|
fi
|
|
done
|
|
if cmp -s "$_tmp" "$_f" ; then
|
|
# No changes, must not have found what we wanted to delete
|
|
echo "RTNETLINK answers: No such file or directory" >&2
|
|
rm -f "$_tmp"
|
|
exit 2
|
|
else
|
|
mv "$_tmp" "$_f"
|
|
fi
|
|
) <"$_f" || exit $?
|
|
}
|
|
|
|
######################################################################
|
|
|
|
ip_route ()
|
|
{
|
|
case "$1" in
|
|
show|list) shift ; ip_route_show "$@" ;;
|
|
flush) shift ; ip_route_flush "$@" ;;
|
|
add) shift ; ip_route_add "$@" ;;
|
|
del*) shift ; ip_route_del "$@" ;;
|
|
*) not_implemented "$1 in \"ip route\"" ;;
|
|
esac
|
|
}
|
|
|
|
ip_route_common ()
|
|
{
|
|
if [ "$1" = table ] ; then
|
|
_table="$2"
|
|
shift 2
|
|
fi
|
|
|
|
ip_check_table "route"
|
|
}
|
|
|
|
# Routes are in a file per table in the directory
|
|
# $FAKE_IP_STATE/routes. These routes just use the table ID
|
|
# that is passed and don't do any lookup. This could be "improved" if
|
|
# necessary.
|
|
|
|
ip_route_show ()
|
|
{
|
|
ip_route_common "$@"
|
|
|
|
# Missing file is just an empty table
|
|
sort "$FAKE_IP_STATE/routes/${_table}" 2>/dev/null || true
|
|
}
|
|
|
|
ip_route_flush ()
|
|
{
|
|
ip_route_common "$@"
|
|
|
|
rm -f "$FAKE_IP_STATE/routes/${_table}"
|
|
}
|
|
|
|
ip_route_add ()
|
|
{
|
|
_prefix=""
|
|
_dev=""
|
|
_gw=""
|
|
_table=""
|
|
_metric=""
|
|
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
*.*.*.*/*|*.*.*.*) _prefix="$1" ; shift 1 ;;
|
|
local) _prefix="$2" ; shift 2 ;;
|
|
dev) _dev="$2" ; shift 2 ;;
|
|
via) _gw="$2" ; shift 2 ;;
|
|
table) _table="$2" ; shift 2 ;;
|
|
metric) _metric="$2" ; shift 2 ;;
|
|
*) not_implemented "$1 in \"$orig_args\"" ;;
|
|
esac
|
|
done
|
|
|
|
ip_check_table "route"
|
|
[ -n "$_prefix" ] || not_implemented "ip route without inet prefix in \"$orig_args\""
|
|
# This can't be easily deduced, so print some garbage.
|
|
[ -n "$_dev" ] || _dev="ethXXX"
|
|
|
|
# Alias or add missing bits
|
|
case "$_prefix" in
|
|
0.0.0.0/0) _prefix="default" ;;
|
|
*/*) : ;;
|
|
*) _prefix="${_prefix}/32" ;;
|
|
esac
|
|
|
|
_f="$FAKE_IP_STATE/routes/${_table}"
|
|
mkdir -p "$FAKE_IP_STATE/routes"
|
|
touch "$_f"
|
|
|
|
# Check for duplicate
|
|
_prefix_regexp=$(echo "^${_prefix}" | sed -e 's@\.@\\.@g')
|
|
if [ -n "$_metric" ] ; then
|
|
_prefix_regexp="${_prefix_regexp} .*metric ${_metric} "
|
|
fi
|
|
if grep -q "$_prefix_regexp" "$_f" ; then
|
|
echo "RTNETLINK answers: File exists" >&2
|
|
exit 1
|
|
fi
|
|
|
|
(
|
|
flock 0
|
|
|
|
_out="${_prefix} "
|
|
[ -z "$_gw" ] || _out="${_out}via ${_gw} "
|
|
[ -z "$_dev" ] || _out="${_out}dev ${_dev} "
|
|
[ -n "$_gw" ] || _out="${_out} scope link "
|
|
[ -z "$_metric" ] || _out="${_out} metric ${_metric} "
|
|
echo "$_out" >>"$_f"
|
|
) <"$_f"
|
|
}
|
|
|
|
ip_route_del ()
|
|
{
|
|
_prefix=""
|
|
_dev=""
|
|
_gw=""
|
|
_table=""
|
|
_metric=""
|
|
|
|
while [ -n "$1" ] ; do
|
|
case "$1" in
|
|
*.*.*.*/*|*.*.*.*) _prefix="$1" ; shift 1 ;;
|
|
local) _prefix="$2" ; shift 2 ;;
|
|
dev) _dev="$2" ; shift 2 ;;
|
|
via) _gw="$2" ; shift 2 ;;
|
|
table) _table="$2" ; shift 2 ;;
|
|
metric) _metric="$2" ; shift 2 ;;
|
|
*) not_implemented "$1 in \"$orig_args\"" ;;
|
|
esac
|
|
done
|
|
|
|
ip_check_table "route"
|
|
[ -n "$_prefix" ] || not_implemented "ip route without inet prefix in \"$orig_args\""
|
|
# This can't be easily deduced, so print some garbage.
|
|
[ -n "$_dev" ] || _dev="ethXXX"
|
|
|
|
# Alias or add missing bits
|
|
case "$_prefix" in
|
|
0.0.0.0/0) _prefix="default" ;;
|
|
*/*) : ;;
|
|
*) _prefix="${_prefix}/32" ;;
|
|
esac
|
|
|
|
_f="$FAKE_IP_STATE/routes/${_table}"
|
|
mkdir -p "$FAKE_IP_STATE/routes"
|
|
touch "$_f"
|
|
|
|
(
|
|
flock 0
|
|
|
|
# Escape some dots
|
|
[ -z "$_gw" ] || _gw=$(echo "$_gw" | sed -e 's@\.@\\.@g')
|
|
_prefix=$(echo "$_prefix" | sed -e 's@\.@\\.@g' -e 's@/@\\/@')
|
|
|
|
_re="^${_prefix}\>.*"
|
|
[ -z "$_gw" ] || _re="${_re}\<via ${_gw}\>.*"
|
|
[ -z "$_dev" ] || _re="${_re}\<dev ${_dev}\>.*"
|
|
[ -z "$_metric" ] || _re="${_re}.*\<metric ${_metric}\>.*"
|
|
sed -i -e "/${_re}/d" "$_f"
|
|
) <"$_f"
|
|
}
|
|
|
|
######################################################################
|
|
|
|
orig_args="$*"
|
|
|
|
case "$1" in
|
|
link) shift ; ip_link "$@" ;;
|
|
addr*) shift ; ip_addr "$@" ;;
|
|
rule) shift ; ip_rule "$@" ;;
|
|
route) shift ; ip_route "$@" ;;
|
|
*) not_implemented "$1" ;;
|
|
esac
|
|
|
|
exit 0
|