1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

[package] firewall:

- replace uci firewall with a modular dual stack implementation	developed by Malte S. Stretz
	- bump version to 2


git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21286 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
jow
2010-05-01 18:22:01 +00:00
parent 35989ffd58
commit e8be3016c9
15 changed files with 1023 additions and 544 deletions

View File

@@ -0,0 +1,97 @@
# Copyright (C) 2009-2010 OpenWrt.org
# Copyright (C) 2009 Malte S. Stretz <http://msquadrat.de>
#
# This is a temporary file, I hope to have some of this stuff merged into
# /lib/functions.sh (without the fw_ prefix of course) one day.
fw_config_append() { # <package>
CONFIG_APPEND=1 config_load "$@"
unset CONFIG_APPEND
}
fw_config_once() { # <function> <type>
local func=$1
local type=$2
shift 2
local config=cfg00nil
fw_config__once() {
config=$1
}
config_foreach fw_config__once "$type"
$func $config "$@"
}
fw_config_get_section() { # <config> <prefix> <type> <name> <default> ...
local config=$1
local prefix=$2
shift 2
[ -n "$config" ] || return 1
[ -n "$prefix" ] && {
prefix="${prefix}_"
export ${NO_EXPORT:+-n} -- "${prefix}NAME"="${config}"
config_get "${prefix}TYPE" "$config" TYPE
}
[ "$1" == '{' ] && shift
while [ $# -ge 3 ]; do
local type=$1
local name=$2
local dflt=$3
shift 3
# TODO: Move handling of defaults to /lib/functions.sh
# and get replace the case block with the following
# two lines:
# type=${type#string}
# config_get${type:+_${type}} "${prefix}${name}" "$config" "$name" "$dflt" || return
case "$type" in
string)
local tmp
config_get tmp "$config" "$name" || return
[ -z "$tmp" ] && tmp=$dflt
export ${NO_EXPORT:+-n} -- "${prefix}${name}=${tmp}"
continue
;;
boolean)
type=bool
;;
esac;
local cmd=${prefix}config_get_${type}
type $cmd > /dev/null || {
cmd=config_get_${type}
}
type $cmd > /dev/null || {
echo "config type $type (for $name) not supported" >&2
return 1
}
$cmd "${prefix}${name}" "$config" "$name" "$dflt" || return
done
}
config_get_ipaddr() {
local varn=$1
local conf=$2
local name=$3
local dflt=$4
local addr
config_get addr "$conf" "$name" || return
[ -n "$addr" ] || addr=$dflt
local mask=${addr#*/}
[ "$mask" != "$addr" ] || mask=
addr=${addr%/*}
local vers=
case "$addr" in
*.*) vers=4 ;;
*:*) vers=6 ;;
esac
export ${NO_EXPORT:+-n} -- "${varn}=${addr}"
export ${NO_EXPORT:+-n} -- "${varn}_prefixlen=${mask}"
export ${NO_EXPORT:+-n} -- "${varn}_version=${vers}"
}

View File

@@ -0,0 +1,136 @@
# Copyright (C) 2009-2010 OpenWrt.org
FW_LIBDIR=${FW_LIBDIR:-/lib/firewall}
. $FW_LIBDIR/fw.sh
include /lib/network
fw_start() {
fw_init
FW_DEFAULTS_APPLIED=
fw_is_loaded && {
echo "firewall already loaded" >&2
exit 1
}
uci_set_state firewall core "" firewall_state
fw_clear DROP
fw_callback pre core
echo "Loading defaults"
fw_config_once fw_load_defaults defaults
echo "Loading zones"
config_foreach fw_load_zone zone
echo "Loading forwardings"
config_foreach fw_load_forwarding forwarding
echo "Loading redirects"
config_foreach fw_load_redirect redirect
echo "Loading rules"
config_foreach fw_load_rule rule
echo "Loading includes"
config_foreach fw_load_include include
[ -n "$FW_NOTRACK_DISABLED" ] && {
echo "Optimizing conntrack"
config_foreach fw_load_notrack_zone zone
}
echo "Loading interfaces"
config_foreach fw_configure_interface interface add
fw_callback post core
uci_set_state firewall core loaded 1
}
fw_stop() {
fw_init
fw_callback pre stop
fw_clear ACCEPT
fw_callback post stop
uci_revert_state firewall
config_clear
unset FW_INITIALIZED
}
fw_restart() {
fw_stop
fw_start
}
fw_reload() {
fw_restart
}
fw_is_loaded() {
local bool
config_get_bool bool core loaded 0
return $((! $bool))
}
fw_die() {
echo "Error:" "$@" >&2
fw_log error "$@"
fw_stop
exit 1
}
fw_log() {
local level="$1"
[ -n "$2" ] || {
shift
level=notice
}
logger -t firewall -p user.$level "$@"
}
fw_init() {
[ -z "$FW_INITIALIZED" ] || return 0
. $FW_LIBDIR/config.sh
scan_interfaces
fw_config_append firewall
local hooks="core stop defaults zone notrack synflood"
local file lib hk pp
for file in $FW_LIBDIR/core_*.sh; do
. $file
hk=$(basename $file .sh)
hk=${hk#core_}
append hooks $hk
done
for file in $FW_LIBDIR/*.sh; do
lib=$(basename $file .sh)
lib=${lib##[0-9][0-9]_}
case $lib in
core*|fw|config|uci_firewall) continue ;;
esac
. $file
for hk in $hooks; do
for pp in pre post; do
type ${lib}_${pp}_${hk}_cb >/dev/null &&
append FW_CB_${pp}_${hk} ${lib}
done
done
done
fw_callback post init
FW_INITIALIZED=1
return 0
}

View File

@@ -0,0 +1,40 @@
# Copyright (C) 2009-2010 OpenWrt.org
fw_config_get_forwarding() {
[ "${forwarding_NAME}" != "$1" ] || return
fw_config_get_section "$1" forwarding { \
string _name "$1" \
string name "" \
string src "" \
string dest "" \
} || return
[ -n "$forwarding_name" ] || forwarding_name=$forwarding__name
}
fw_load_forwarding() {
fw_config_get_forwarding "$1"
fw_callback pre forwarding
local chain=forward
[ -n "$forwarding_src" ] && {
chain=zone_${forwarding_src}_forward
}
local target=ACCEPT
[ -n "$forwarding_dest" ] && {
target=zone_${forwarding_dest}_ACCEPT
}
fw add i f $chain $target ^
# propagate masq zone flag
[ -n "$forwarding_src" ] && list_contains CONNTRACK_ZONES $forwarding_src && {
append CONNTRACK_ZONES $forwarding_dest
}
[ -n "$forwarding_dest" ] && list_contains CONNTRACK_ZONES $forwarding_dest && {
append CONNTRACK_ZONES $forwarding_src
}
fw_callback post forwarding
}

View File

@@ -0,0 +1,258 @@
# Copyright (C) 2009-2010 OpenWrt.org
# Copyright (C) 2008 John Crispin <blogic@openwrt.org>
FW_INITIALIZED=
FW_ZONES=
FW_CONNTRACK_ZONES=
FW_NOTRACK_DISABLED=
FW_DEFAULTS_APPLIED=
FW_ADD_CUSTOM_CHAINS=
FW_ACCEPT_REDIRECTS=
FW_ACCEPT_SRC_ROUTE=
FW_DEFAULT_INPUT_POLICY=REJECT
FW_DEFAULT_OUTPUT_POLICY=REJECT
FW_DEFAULT_FORWARD_POLICY=REJECT
fw_load_defaults() {
fw_config_get_section "$1" defaults { \
string input $FW_DEFAULT_INPUT_POLICY \
string output $FW_DEFAULT_OUTPUT_POLICY \
string forward $FW_DEFAULT_FORWARD_POLICY \
boolean drop_invalid 0 \
boolean syn_flood 0 \
boolean synflood_protect 0 \
string synflood_rate 25 \
string synflood_burst 50 \
boolean tcp_syncookies 1 \
boolean tcp_ecn 0 \
boolean tcp_westwood 0 \
boolean tcp_window_scaling 1 \
boolean accept_redirects 0 \
boolean accept_source_route 0 \
boolean custom_chains 1 \
} || return
[ -n "$FW_DEFAULTS_APPLIED" ] && {
echo "Error: multiple defaults sections detected"
return 1
}
FW_DEFAULTS_APPLIED=1
FW_DEFAULT_INPUT_POLICY=$defaults_input
FW_DEFAULT_OUTPUT_POLICY=$defaults_output
FW_DEFAULT_FORWARD_POLICY=$defaults_forward
FW_ADD_CUSTOM_CHAINS=$defaults_custom_chains
FW_ACCEPT_REDIRECTS=$defaults_accept_redirects
FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route
fw_callback pre defaults
# Seems like there are only one sysctl for both IP versions.
for s in syncookies ecn westwood window_scaling; do
eval "sysctl -e -w net.ipv4.tcp_${s}=\$defaults_tcp_${s}" >/dev/null
done
fw_sysctl_interface all
[ $defaults_drop_invalid == 1 ] && {
fw add i f INPUT DROP { -m state --state INVALID }
fw add i f OUTPUT DROP { -m state --state INVALID }
fw add i f FORWARD DROP { -m state --state INVALID }
FW_NOTRACK_DISABLED=1
}
fw add i f INPUT ACCEPT { -m state --state RELATED,ESTABLISHED }
fw add i f OUTPUT ACCEPT { -m state --state RELATED,ESTABLISHED }
fw add i f FORWARD ACCEPT { -m state --state RELATED,ESTABLISHED }
fw add i f INPUT ACCEPT { -i lo }
fw add i f OUTPUT ACCEPT { -o lo }
# Compatibility to old 'syn_flood' parameter
[ $defaults_syn_flood == 1 ] && \
defaults_synflood_protect=1
[ $defaults_synflood_protect == 1 ] && {
echo "Loading synflood protection"
fw_callback pre synflood
fw add i f syn_flood
fw add i f syn_flood RETURN { \
-p tcp --syn \
-m limit --limit "${defaults_synflood_rate}/second" --limit-burst "${defaults_synflood_burst}" \
}
fw add i f syn_flood DROP
fw add i f INPUT syn_flood { -p tcp --syn }
fw_callback post synflood
}
[ $defaults_custom_chains == 1 ] && {
echo "Adding custom chains"
fw add i f input_rule
fw add i f output_rule
fw add i f forwarding_rule
fw add i n prerouting_rule
fw add i n postrouting_rule
fw add i f INPUT input_rule
fw add i f OUTPUT output_rule
fw add i f FORWARD forwarding_rule
fw add i n PREROUTING prerouting_rule
fw add i n POSTROUTING postrouting_rule
}
fw add i f input
fw add i f output
fw add i f forward
fw add i f INPUT input
fw add i f OUTPUT output
fw add i f FORWARD forward
fw add i f reject
fw add i f reject REJECT { --reject-with tcp-reset -p tcp }
fw add i f reject REJECT { --reject-with port-unreach }
fw_set_filter_policy
fw_callback post defaults
}
fw_config_get_zone() {
[ "${zone_NAME}" != "$1" ] || return
fw_config_get_section "$1" zone { \
string name "$1" \
string network "" \
string input "$FW_DEFAULT_INPUT_POLICY" \
string output "$FW_DEFAULT_OUTPUT_POLICY" \
string forward "$FW_DEFAULT_FORWARD_POLICY" \
boolean masq 0 \
boolean conntrack 0 \
boolean mtu_fix 0 \
boolean custom_chains "$FW_ADD_CUSTOM_CHAINS" \
} || return
[ -n "$zone_name" ] || zone_name=$zone_NAME
[ -n "$zone_network" ] || zone_network=$zone_name
}
fw_load_zone() {
fw_config_get_zone "$1"
list_contains FW_ZONES $zone_name && {
fw_die "zone ${zone_name}: duplicated zone"
}
append FW_ZONES $zone_name
fw_callback pre zone
[ $zone_conntrack = 1 -o $zone_masq = 1 ] && \
append FW_CONNTRACK_ZONES "$zone_NAME"
local chain=zone_${zone_name}
fw add i f ${chain}_ACCEPT
fw add i f ${chain}_DROP
fw add i f ${chain}_REJECT
fw add i f ${chain}_MSSFIX
# TODO: Rename to ${chain}_input
fw add i f ${chain}
fw add i f ${chain} ${chain}_${zone_input} $
fw add i f ${chain}_forward
fw add i f ${chain}_forward ${chain}_${zone_forward} $
# TODO: add ${chain}_output
fw add i f output ${chain}_${zone_output} $
# TODO: Rename to ${chain}_MASQUERADE
fw add i n ${chain}_nat
fw add i n ${chain}_prerouting
fw add i r ${chain}_notrack
[ $zone_masq == 1 ] && \
fw add i n POSTROUTING ${chain}_nat $
[ $zone_mtu_fix == 1 ] && \
fw add i f FORWARD ${chain}_MSSFIX ^
[ $zone_custom_chains == 1 ] && {
[ $FW_ADD_CUSTOM_CHAINS == 1 ] || \
fw_die "zone ${zone_name}: custom_chains globally disabled"
fw add i f input_${zone_name}
fw add i f ${chain} input_${zone_name} ^
fw add i f forwarding_${zone_name}
fw add i f ${chain}_forward forwarding_${zone_name} ^
fw add i n prerouting_${zone_name}
fw add i n ${chain}_prerouting prerouting_${zone_name} ^
}
fw_callback post zone
}
fw_load_notrack_zone() {
list_contains FW_CONNTRACK_ZONES "$1" && return
fw_config_get_zone "$1"
fw_callback pre notrack
fw add i f zone_${zone_name}_notrack NOTRACK $
fw_callback post notrack
}
fw_load_include() {
local name="$1"
local path; config_get path ${name} path
[ -e $path ] && . $path
}
fw_clear() {
local policy=$1
fw_set_filter_policy $policy
local tab
for tab in f n r; do
fw del i $tab
done
}
fw_set_filter_policy() {
local policy=$1
local chn tgt
for chn in INPUT OUTPUT FORWARD; do
eval "tgt=\${policy:-\${FW_DEFAULT_${chn}_POLICY}}"
[ $tgt == "REJECT" ] && tgt=reject
[ $tgt == "ACCEPT" -o $tgt == "DROP" ] || {
fw add i f $chn $tgt $
tgt=DROP
}
fw policy i f $chn $tgt
done
}
fw_callback() {
local pp=$1
local hk=$2
local libs lib
eval "libs=\$FW_CB_${pp}_${hk}"
[ -n "$libs" ] || return
for lib in $libs; do
${lib}_${pp}_${hk}_cb
done
}

View File

@@ -0,0 +1,86 @@
# Copyright (C) 2009-2010 OpenWrt.org
fw_configure_interface() {
local iface=$1
local action=$2
local ifname=$3
local status;
config_get_bool status "$iface" up "0"
[ "$status" == 1 ] || return 0
[ -n "$ifname" ] || {
config_get ifname "$iface" ifname
ifname=${ifname:-$iface}
}
[ "$ifname" == "lo" ] && return 0
fw_callback pre interface
fw__do_rules() {
local action=$1
local chain=$2
local ifname=$3
fw $action i f ${chain}_ACCEPT ACCEPT ^ { -o "$ifname" }
fw $action i f ${chain}_ACCEPT ACCEPT ^ { -i "$ifname" }
fw $action i f ${chain}_DROP DROP ^ { -o "$ifname" }
fw $action i f ${chain}_DROP DROP ^ { -i "$ifname" }
fw $action i f ${chain}_REJECT reject ^ { -o "$ifname" }
fw $action i f ${chain}_REJECT reject ^ { -i "$ifname" }
fw $action i n ${chain}_nat MASQUERADE ^ { -o "$ifname" }
fw $action i f ${chain}_MSSFIX TCPMSS ^ { -o "$ifname" -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu }
fw $action i f input ${chain} $ { -i "$ifname" }
fw $action i f forward ${chain}_forward $ { -i "$ifname" }
fw $action i n PREROUTING ${chain}_prerouting ^ { -i "$ifname" }
fw $action i r PREROUTING ${chain}_notrack ^ { -i "$ifname" }
}
local old_zones old_ifname
config_get old_zones core "${iface}_zone"
[ -n "$old_zones" ] && {
config_get old_ifname core "${iface}_ifname"
for z in $old_zones; do
fw_log info "removing $iface ($old_ifname) from zone $z"
fw__do_rules del zone_$z $old_ifname
ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
done
uci_revert_state firewall core "${iface}_zone"
uci_revert_state firewall core "${iface}_ifname"
}
[ "$action" == del ] && return
local new_zones
load_zone() {
fw_config_get_zone "$1"
list_contains zone_network "$iface" || return
fw_log info "adding $iface ($ifname) to zone $zone_name"
fw__do_rules add zone_${zone_name} "$ifname"
append new_zones $zone_name
ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall
}
config_foreach load_zone zone
uci_set_state firewall core "${iface}_zone" "$new_zones"
uci_set_state firewall core "${iface}_ifname" "$ifname"
fw_sysctl_interface $ifname
fw_callback post interface
}
fw_sysctl_interface() {
local ifname=$1
{
sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS
sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE
} >/dev/null 2>/dev/null
}

View File

@@ -0,0 +1,61 @@
# Copyright (C) 2009-2010 OpenWrt.org
fw_config_get_redirect() {
[ "${redirect_NAME}" != "$1" ] || return
fw_config_get_section "$1" redirect { \
string _name "$1" \
string name "" \
string src "" \
ipaddr src_ip "" \
ipaddr src_dip "" \
string src_mac "" \
string src_port "" \
string src_dport "" \
string dest "" \
ipaddr dest_ip "" \
string dest_mac "" \
string dest_port "" \
string proto "tcpudp" \
} || return
[ -n "$redirect_name" ] || redirect_name=$redirect__name
}
fw_load_redirect() {
fw_config_get_redirect "$1"
fw_callback pre redirect
[ -n "$redirect_src" -a -n "$redirect_dest_ip" ] || {
fw_die "redirect ${redirect_name}: needs src and dest_ip"
}
local nat_dest_port=$redirect_dest_port
redirect_dest_port=$(fw_get_port_range $redirect_dest_port)
redirect_src_port=$(fw_get_port_range $redirect_src_port)
redirect_src_dport=$(fw_get_port_range $redirect_src_dport)
local fwd_dest_port=${redirect_dest_port:-$redirect_src_dport}
[ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp"
for redirect_proto in $redirect_proto; do
fw add I n zone_${redirect_src}_prerouting DNAT $ { $redirect_src_ip $redirect_dest_ip } { \
${redirect_proto:+-p $redirect_proto} \
${redirect_src_ip:+-s $redirect_src_ip} \
${redirect_src_dip:+-d $redirect_src_dip} \
${redirect_src_port:+--sport $redirect_src_port} \
${redirect_src_dport:+--dport $redirect_src_dport} \
${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \
--to-destination ${redirect_dest_ip}${redirect_dest_port:+:$nat_dest_port} \
}
fw add I f zone_${redirect_src}_forward ACCEPT ^ { $redirect_src_ip $redirect_dest_ip } { \
-d $redirect_dest_ip \
${redirect_proto:+-p $redirect_proto} \
${redirect_src_ip:+-s $redirect_src_ip} \
${redirect_src_port:+--sport $redirect_src_port} \
${fwd_dest_port:+--dport $fwd_dest_port} \
${redirect_src_mac:+-m mac --mac-source $redirect_src_mac} \
}
done
fw_callback post redirect
}

View File

@@ -0,0 +1,66 @@
# Copyright (C) 2009-2010 OpenWrt.org
fw_config_get_rule() {
[ "${rule_NAME}" != "$1" ] || return
fw_config_get_section "$1" rule { \
string _name "$1" \
string name "" \
string src "" \
ipaddr src_ip "" \
string src_mac "" \
string src_port "" \
string dest "" \
ipaddr dest_ip "" \
string dest_mac "" \
string dest_port "" \
string icmp_type "" \
string proto "tcpudp" \
string target "" \
} || return
[ -n "$rule_name" ] || rule_name=$rule__name
[ "$rule_proto" == "icmp" ] || rule_icmp_type=
}
fw_load_rule() {
fw_config_get_rule "$1"
fw_callback pre rule
rule_src_port=$(fw_get_port_range $rule_src_port)
rule_dest_port=$(fw_get_port_range $rule_dest_port)
local chain=input
[ -n "$rule_src" ] && {
[ -z "$rule_dest" ] && {
chain=zone_${rule_src}
} || {
chain=zone_${rule_src}_forward
}
}
local target=$rule_target
[ -z "$target" ] && {
target=REJECT
}
[ -n "$dest" ] && {
target=zone_${rule_dest}_${target}
}
local rule_pos
eval 'rule_pos=$((++FW__RULE_COUNT_'$chain'))'
[ "$rule_proto" == "tcpudp" ] && rule_proto="tcp udp"
for rule_proto in $rule_proto; do
fw add I f $chain $target $rule_pos { $rule_src_ip $rule_dest_ip } { \
${rule_proto:+-p $rule_proto} \
${rule_src_ip:+-s $rule_src_ip} \
${rule_src_port:+--sport $rule_src_port} \
${rule_src_mac:+-m mac --mac-source $rule_src_mac} \
${rule_dest_ip:+-d $rule_dest_ip} \
${rule_dest_port:+--dport $rule_dest_port} \
${rule_icmp_type:+--icmp-type $rule_icmp_type} \
}
done
fw_callback post rule
}

View File

@@ -0,0 +1,182 @@
# Copyright (C) 2009-2010 OpenWrt.org
# Copyright (C) 2009 Malte S. Stretz
export FW_4_ERROR=0
export FW_6_ERROR=0
export FW_i_ERROR=0
export FW_e_ERROR=0
export FW_a_ERROR=0
#TODO: remove this
[ "${-#*x}" == "$-" ] && {
fw() {
fw__exec "$@"
}
} || {
fw() {
local os=$-
set +x
fw__exec "$@"
local rc=$?
set -$os
return $rc
}
}
fw__exec() { # <action> <family> <table> <chain> <target> <position> { <rules> }
local cmd fam tab chn tgt pos
local i
for i in cmd fam tab chn tgt pos; do
if [ "$1" -a "$1" != '{' ]; then
eval "$i='$1'"
shift
else
eval "$i=-"
fi
done
fw__rc() {
export FW_${fam}_ERROR=$1
return $1
}
fw__dualip() {
fw $cmd 4 $tab $chn $tgt $pos "$@"
fw $cmd 6 $tab $chn $tgt $pos "$@"
fw__rc $((FW_4_ERROR | FW_6_ERROR))
}
fw__autoip() {
local ip4 ip6
shift
while [ "$1" != '}' ]; do
case "$1" in
*.*.*.*) ip4=1 ;;
*:*) ip6=1 ;;
esac
shift
done
shift
if [ "${ip4:-4}" == "${ip6:-6}" ]; then
echo "fw: can't mix ip4 and ip6" >&2
return 1
fi
local ver=${ip4:+4}${ip6:+6}
fam=i
fw $cmd ${ver:-i} $tab $chn $tgt $pos "$@"
fw__rc $?
}
fw__has() {
local tab=${1:-$tab}
if [ $tab == '-' ]; then
type $app > /dev/null 2> /dev/null
fw__rc $(($? & 1))
return
fi
local mod
eval "mod=\$FW_${fam}_${tab}"
if [ "$mod" ]; then
fw__rc $mod
return
fi
case "$fam" in
4) mod=iptable_${tab} ;;
6) mod=ip6table_${tab} ;;
*) mod=. ;;
esac
grep "^${mod} " /proc/modules > /dev/null
mod=$?
export FW_${fam}_${tab}=$mod
fw__rc $mod
}
fw__err() {
local err
eval "err=\$FW_${fam}_ERROR"
fw__rc $err
}
local app=
local pol=
case "$fam" in
4) app=iptables ;;
6) app=ip6tables ;;
i) fw__dualip "$@"; return ;;
I) fw__autoip "$@"; return ;;
e) app=ebtables ;;
a) app=arptables ;;
-) fw $cmd i $tab $chn $tgt $pos "$@"; return ;;
*) return 254 ;;
esac
case "$tab" in
f) tab=filter ;;
m) tab=mangle ;;
n) tab=nat ;;
r) tab=raw ;;
-) tab=filter ;;
esac
case "$cmd:$chn:$tgt:$pos" in
add:*:-:*) cmd=new-chain ;;
add:*:*:-) cmd=append ;;
add:*:*:$) cmd=append ;;
add:*:*:*) cmd=insert ;;
del:-:*:*) cmd=delete-chain; fw flush $fam $tab ;;
del:*:-:*) cmd=delete-chain; fw flush $fam $tab $chn ;;
del:*:*:*) cmd=delete ;;
flush:*) ;;
policy:*) pol=$tgt; tgt=- ;;
has:*) fw__has; return ;;
err:*) fw__err; return ;;
list:*) cmd="numeric --verbose --$cmd" ;;
*) return 254 ;;
esac
case "$chn" in
-) chn= ;;
esac
case "$tgt" in
-) tgt= ;;
esac
case "$pos" in
^) pos=1 ;;
$) pos= ;;
-) pos= ;;
esac
if ! fw__has - family || ! fw__has $tab ; then
export FW_${fam}_ERROR=0
return 0
fi
if [ $# -gt 0 ]; then
shift
if [ $cmd == del ]; then
pos=-
fi
fi
while [ $# -gt 1 ]; do
echo -n "$1"
echo -ne "\0"
shift
done | xargs -0 ${FW_TRACE:+-t} \
$app --table ${tab} --${cmd} ${chn} ${pol} ${pos} ${tgt:+--jump "$tgt"}
fw__rc $?
}
fw_get_port_range() {
local ports=$1
local delim=${2:-:}
if [ "$3" ]; then
fw_get_port_range "${ports}-${3}" $delim
return
fi
local first=${ports%-*}
local last=${ports#*-}
if [ "$first" != "$last" ]; then
echo "$first$delim$last"
else
echo "$first"
fi
}

View File

@@ -0,0 +1,5 @@
# This file is here for backwards compatibility and to override the
# uci_firewall.sh from an earlier version.
type fw_is_loaded >/dev/null || {
. /lib/firewall/core.sh
}