freebsd-dev/libexec/rc/rc.d/ipfw
Eugene Grosbein f5b5de1a32 ipfw: reload sysctl.conf variables if needed
Currently ipfw has multiple components that are not parts
of GENERIC kernel like dummynet etc. They can bring in important
sysctls if enabled with rc.conf(5) and loaded with ipfw startup script
by means of "required_modules" after initial consult
with /etc/sysctl.conf at boot time. Here is an example of one
increasing limit for dummynet hold queues that defaults to 100:

net.inet.ip.dummynet.pipe_slot_limit=1000

This makes it possible to use ipfw/dummynet rules such as:

ipfw pipe 1 config bw 50Mbit/s queue 1000

Such rule is rejected unless above sysctl is applied.
Another example is a group of net.inet.ip.alias.* sysctls
created after libalias.ko loaded as dependency of ipfw_nat.

This is not a problem if corresponding code compiled in custom kernel
so sysctls exist when sysctl.conf is read early or kernel modules
loaded with a loader. This change makes it work also for GENERIC
and modules loaded by means of rc.conf(5) settings.

MFC after:	1 month
2021-05-18 04:03:15 +07:00

168 lines
3.4 KiB
Bash
Executable File

#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: ipfw
# REQUIRE: ppp
# KEYWORD: nojailvnet
. /etc/rc.subr
. /etc/network.subr
name="ipfw"
desc="Firewall, traffic shaper, packet scheduler, in-kernel NAT"
rcvar="firewall_enable"
start_cmd="ipfw_start"
start_precmd="ipfw_prestart"
start_postcmd="ipfw_poststart"
stop_cmd="ipfw_stop"
status_cmd="ipfw_status"
required_modules="ipfw"
extra_commands="status"
set_rcvar_obsolete ipv6_firewall_enable
ipfw_prestart()
{
if checkyesno dummynet_enable; then
required_modules="$required_modules dummynet"
fi
if checkyesno natd_enable; then
required_modules="$required_modules ipdivert"
fi
if checkyesno firewall_nat_enable; then
required_modules="$required_modules ipfw_nat"
fi
if checkyesno firewall_nat64_enable; then
required_modules="$required_modules ipfw_nat64"
fi
if checkyesno firewall_nptv6_enable; then
required_modules="$required_modules ipfw_nptv6"
fi
if checkyesno firewall_pmod_enable; then
required_modules="$required_modules ipfw_pmod"
fi
}
ipfw_start()
{
local _firewall_type _module _sysctl_reload
if [ -n "${1}" ]; then
_firewall_type=$1
else
_firewall_type=${firewall_type}
fi
_sysctl_reload=no
for _module in ${required_modules}
do
if kldstat -qn ${_module}; then
_sysctl_reload=yes
break
fi
done
if [ ${_sysctl_reload} = yes ]; then
/etc/rc.d/sysctl reload
fi
# set the firewall rules script if none was specified
[ -z "${firewall_script}" ] && firewall_script=/etc/rc.firewall
if [ -r "${firewall_script}" ]; then
/bin/sh "${firewall_script}" "${_firewall_type}"
echo 'Firewall rules loaded.'
elif [ "`ipfw list 65535`" = "65535 deny ip from any to any" ]; then
echo 'Warning: kernel has firewall functionality, but' \
'firewall rules are not enabled.'
echo ' All ip services are disabled.'
fi
# Firewall logging
#
if checkyesno firewall_logging; then
echo 'Firewall logging enabled.'
${SYSCTL} net.inet.ip.fw.verbose=1 >/dev/null
fi
if checkyesno firewall_logif; then
if ! ifconfig ipfw0 >/dev/null 2>&1; then
ifconfig ipfw0 create
echo 'Firewall logging pseudo-interface (ipfw0)' \
'created.'
else
echo 'Firewall logging pseudo-interface (ipfw0)' \
'already created.'
fi
fi
}
ipfw_poststart()
{
local _coscript
# Start firewall coscripts
#
for _coscript in ${firewall_coscripts} ; do
if [ -f "${_coscript}" ]; then
${_coscript} quietstart
fi
done
# Enable the firewall
#
if ! ${SYSCTL} net.inet.ip.fw.enable=1 >/dev/null 2>&1; then
warn "failed to enable IPv4 firewall"
fi
if afexists inet6; then
if ! ${SYSCTL} net.inet6.ip6.fw.enable=1 >/dev/null 2>&1
then
warn "failed to enable IPv6 firewall"
fi
fi
}
ipfw_stop()
{
local _coscript
# Disable the firewall
#
${SYSCTL} net.inet.ip.fw.enable=0 >/dev/null
if afexists inet6; then
${SYSCTL} net.inet6.ip6.fw.enable=0 >/dev/null
fi
# Stop firewall coscripts
#
for _coscript in `reverse_list ${firewall_coscripts}` ; do
if [ -f "${_coscript}" ]; then
${_coscript} quietstop
fi
done
}
ipfw_status()
{
status=$(sysctl -i -n net.inet.ip.fw.enable)
: ${status:=0}
if afexists inet6; then
status6=$(sysctl -i -n net.inet6.ip6.fw.enable)
: ${status6:=0}
status=$((${status} + ${status6}))
fi
if [ ${status} -eq 0 ]; then
echo "ipfw is not enabled"
exit 1
else
echo "ipfw is enabled"
exit 0
fi
}
load_rc_config $name
firewall_coscripts="/etc/rc.d/natd ${firewall_coscripts}"
run_rc_command $*