Compare commits

...

2 Commits

Author SHA1 Message Date
Amit Kumar
dbee1f55e4 firewallmngr: Fix for new issue identified 2024-07-11 10:58:04 +05:30
Amit Kumar
dd58d0dcf9 firewallmngr: handling for firewallmngr module
* Added firewallmngr module with firewallmngr uci
* added compile time flag to include/exclude module
* script library to conver firewallmngr uci to firewall uci
* include files of some modules removed and handling added to
  add rule entry in uci file of firewallmngr
2024-07-10 10:35:18 +05:30
22 changed files with 4463 additions and 4 deletions

View File

@@ -8,5 +8,11 @@ config FIREWALLMNGR_PORT_TRIGGER
help
Set this option to include support for PortTrigger object.
config FIREWALLMNGR_BACKEND_FIREWALLMNGR
bool "Include Firewallmanager uci"
default n
help
Set this option to include support for firewallmngr uci.
endmenu
endif

View File

@@ -43,13 +43,17 @@ endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/firewallmngr/* $(PKG_BUILD_DIR)/
$(CP) -rf ./firewallmngr/* $(PKG_BUILD_DIR)/
endef
endif
ifeq ($(CONFIG_FIREWALLMNGR_PORT_TRIGGER),y)
TARGET_CFLAGS += -DINCLUDE_PORT_TRIGGER
endif
ifeq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
TARGET_CFLAGS += -DINCLUDE_BACKEND_FIREWALLMNGR
endif
define Package/firewallmngr/install
$(INSTALL_DIR) $(1)/etc/config
@@ -62,13 +66,32 @@ ifeq ($(CONFIG_FIREWALLMNGR_PORT_TRIGGER),y)
$(INSTALL_DATA) ./files/port-trigger/etc/config/port-trigger $(1)/etc/config/
$(INSTALL_DATA) ./files/port-trigger/lib/port-trigger/port_trigger.sh $(1)/lib/port-trigger/
endif
ifeq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/lib/fwmngr
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/firewallmngr_backend_firewallmngr/etc/uci-defaults/00-firewallmngr $(1)/etc/uci-defaults/00-firewallmngr
$(INSTALL_DATA) ./files/firewallmngr_backend_firewallmngr/etc/config/firewallmngr $(1)/etc/config/
$(INSTALL_BIN) ./files/firewallmngr_backend_firewallmngr/etc/init.d/firewallmngr $(1)/etc/init.d/
$(INSTALL_DATA) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/fwmngr.sh $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/fwmngr_functions.sh $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/uci_migration.sh $(1)/lib/fwmngr/
$(INSTALL_BIN) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/is_intf_bridge $(1)/lib/fwmngr/
$(INSTALL_BIN) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/firewallmngr_preconfig $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/firewallmngr_backend_firewallmngr/lib/fwmngr/fwmngr_twamp.sh $(1)/lib/fwmngr/
$(BBFDM_INSTALL_MS_DM) ./files/firewallmngr_backend_firewallmngr/etc/firewallmngr/firewallmngr.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/src/libfirewallmngr.so $(1) $(PKG_NAME)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/firewallmngr $(1)/usr/sbin
else
$(INSTALL_BIN) ./files/firewall.portmap $(1)/etc/
$(INSTALL_DATA) ./files/etc/uci-defaults/95-portmap-firewall $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/firewall.service $(1)/etc/
$(INSTALL_DATA) ./files/etc/uci-defaults/97-firewall-service $(1)/etc/uci-defaults/
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libfirewallmngr.so $(1) $(PKG_NAME)
endif
endef
$(eval $(call BuildPackage,firewallmngr))

View File

@@ -0,0 +1,18 @@
{
"daemon": {
"config": {
"loglevel": "4"
},
"input": {
"type": "JSON",
"name": "/etc/firewallmngr/firewallmngr.json",
"plugin_dir": "/etc/firewallmngr/plugins"
},
"output": {
"type": "UBUS",
"parent_dm": "Device.",
"root_obj": "bbfdm",
"multiple_objects": ["Firewall","NAT"]
}
}
}

View File

@@ -0,0 +1,160 @@
config firewall 'firewall'
option enable '1'
option config 'Advanced'
option advanced_level 'level1'
config level 'level1'
option name 'level1'
option chain 'chain1'
option port_mapping_enabled '1'
option default_policy 'reject'
option default_log_policy '0'
option enable '1'
config chain 'chain1'
option enable '1'
option name 'chain1'
config rule 'default_rule_0'
option chain 'chain1'
option enable '1'
option order '1'
option name 'Allow-DHCP-Renew'
option target 'Accept'
option src 'wan'
option family '4'
option proto '17'
option dest_port '68'
config rule 'default_rule_1'
option chain 'chain1'
option enable '1'
option order '2'
option name 'Allow-Ping'
option target 'Accept'
option src 'wan'
list icmp_type 'echo-request'
option family '4'
option proto '1'
config rule 'default_rule_2'
option chain 'chain1'
option enable '1'
option order '3'
option name 'Allow-IGMP'
option target 'Accept'
option src 'wan'
option family '4'
option proto '2'
config rule 'default_rule_3'
option chain 'chain1'
option enable '1'
option order '4'
option name 'Allow-DHCPv6'
option target 'Accept'
option src 'wan'
option family '6'
option proto '17'
option dest_port '546'
config rule 'default_rule_4'
option chain 'chain1'
option enable '1'
option order '5'
option name 'Allow-MLD'
option target 'Accept'
option src 'wan'
option family '6'
option src_ip 'fe80::'
option source_mask 'fe80::/10'
list icmp_type '130/0'
list icmp_type '131/0'
list icmp_type '132/0'
list icmp_type '143/0'
option proto '1'
config rule 'default_rule_5'
option chain 'chain1'
option enable '1'
option order '6'
option name 'Allow-ICMPv6-Input'
option target 'Accept'
option src 'wan'
option family '6'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
list icmp_type 'router-solicitation'
list icmp_type 'neighbour-solicitation'
list icmp_type 'router-advertisement'
list icmp_type 'neighbour-advertisement'
option limit '1000/sec'
option proto '1'
config rule 'default_rule_6'
option chain 'chain1'
option enable '1'
option order '7'
option name 'Allow-ICMPv6-Forward'
option target 'Accept'
option src 'wan'
option dest_all_interfaces '1'
option family '6'
list icmp_type 'echo-request'
list icmp_type 'echo-reply'
list icmp_type 'destination-unreachable'
list icmp_type 'packet-too-big'
list icmp_type 'time-exceeded'
list icmp_type 'bad-header'
list icmp_type 'unknown-header-type'
option limit '1000/sec'
option proto '1'
config rule 'default_rule_7'
option chain 'chain1'
option enable '1'
option order '8'
option name 'Allow-IPSec-ESP'
option target 'Accept'
option src 'wan'
option dest 'lan'
option proto '50'
config rule 'default_rule_8'
option chain 'chain1'
option enable '1'
option order '9'
option name 'Allow-ISAKMP'
option target 'Accept'
option src 'wan'
option dest 'lan'
option proto '17'
option dest_port '500'
config rule 'default_rule_9'
option chain 'chain1'
option enable '0'
option order '10'
option name 'Support-UDP-Traceroute'
option target 'Reject'
option src 'wan'
option family '4'
option proto '17'
option dest_port '33434'
option dest_port_range_max '33689'
config rule 'default_forward_rule'
option chain 'chain1'
option enable '1'
option order '65535'
option name 'forward-rule'
option src 'lan'
option dest 'wan'
option proto '-1'
option target 'Accept'

View File

@@ -0,0 +1,27 @@
#!/bin/sh /etc/rc.common
START=18
USE_PROCD=1
USE_PROCD=1
NAME=firewallmngr
PROG=/usr/sbin/firewallmngr
. /lib/fwmngr/fwmngr.sh
start_service() {
configure_firewall
procd_open_instance firewallmngr
procd_set_param command ${PROG}
procd_set_param respawn
procd_close_instance
}
boot() {
start
}
service_triggers() {
procd_add_reload_trigger firewallmngr
}

View File

@@ -0,0 +1,28 @@
#!/bin/sh
. /lib/fwmngr/fwmngr_functions.sh
. /lib/fwmngr/uci_migration.sh
rule_sec=$(uci show firewall | grep "=rule")
[ -z "$rule_sec" ] && return
rule_sec=$(echo $rule_sec | grep "fwmngr")
if [ -z "$rule_sec" ]; then
generate_firewallmngr_config
fi
if [ -f /etc/firewall.ddos ]; then
uci -q get firewall.ddos || {
uci -q set firewall.ddos=include
uci -q set firewall.ddos.path="/etc/firewall.ddos"
uci -q set firewall.ddos.reload=1
fi
if [ -f /etc/firewall.protect_port ]; then
uci -q get firewall.protect_port || {
uci -q set firewall.protect_port='include'
uci -q set firewall.protect_port.path='/etc/firewall.protect_port'
uci -q set firewall.protect_port.reload='1'
}
fi

View File

@@ -0,0 +1,76 @@
#!/bin/sh
. /lib/functions.sh
rule_max_order_val=0
config_load firewallmngr
firewallmngr_generate_nat_interface_setting() {
local intf="$1"
local is_bridge="false"
local masq="0"
local intf_dev
local type=""
local nat_intf_setting=""
type=$(uci -q get firewallmngr."$intf")
[ "$type" = "natif" ] && return
nat_intf_setting=$(uci add "firewallmngr" "natif")
uci set firewallmngr."$nat_intf_setting".interface="$intf"
if [ $(/lib/fwmngr/is_intf_bridge "$intf") -eq 1 ]; then
uci set firewallmngr."$nat_intf_setting".enabled="0"
else
uci set firewallmngr."$nat_intf_setting".enabled="1"
fi
uci rename firewallmngr."$nat_intf_setting"="$intf"
}
firewallmngr_process_rule_interface() {
local rule="$1"
local src_intf=""
local dest_intf=""
config_get src_intf "$rule" "src"
config_get dest_intf "$rule" "dest"
[ -z "$src_intf" ] || firewallmngr_generate_nat_interface_setting "$src_intf"
[ -z "$dest_intf" ] || firewallmngr_generate_nat_interface_setting "$dest_intf"
}
firewallmngr_process_rule_param() {
local order=""
config_get order "$1" order
if [ -z "$order" ] || [ "$order" = "65535" ]; then
return
fi
rule_max_order_val=$(( rule_max_order_val + 1 ))
if [ ${order} -gt ${rule_max_order_val} ]; then
uci -q set firewallmngr."$1".order="$rule_max_order_val"
uci -q reorder firewallmngr."$1"=${rule_max_order_val}
fi
firewallmngr_process_rule_interface "$1"
}
firewallmngr_set_rule_order() {
local order=""
config_get order "$1" order
if [ -n "$order" ]; then
uci -q reorder firewallmngr."$1"=${order}
return
fi
rule_max_order_val=$(( rule_max_order_val + 1 ))
uci -q set firewallmngr."$1".order="$rule_max_order_val"
uci -q reorder firewallmngr."$1"=${rule_max_order_val}
}
config_foreach firewallmngr_process_rule_param rule
config_foreach firewallmngr_set_rule_order rule
uci commit firewallmngr

View File

@@ -0,0 +1,195 @@
#!/bin/sh
#set -x
. /lib/functions.sh
. /lib/fwmngr/fwmngr_functions.sh
fw_rule_sections=""
fw_redirect_sections=""
fw_include_sections=""
clean_expiry() {
[ -f "/tmp/fw3.atjobs" ] || return
for job in $(cat /tmp/fw3.atjobs); do
atrm $job 2>/dev/null
done
rm -f /tmp/fw3.atjobs
}
schedule_expiry() {
[ -f "/usr/bin/at" ] || return
expire_at() {
local cfg=$1
local expiry atdate
config_get expiry $cfg expiry
[ -n "$expiry" ] || return
atdate="$(date +'%Y%m%d%H%M.%S' -d @$expiry)"
[ -n "$atdate" ] || return
sec=$(echo $atdate | cut -d. -f2)
at_date=$(echo $atdate | cut -d. -f1)
echo "sleep $sec && uci -q delete firewallmngr.$cfg; ubus call uci commit '{\"config\":\"firewallmngr\"}'" | \
at -t $at_date 2>&1 | grep job | awk '{print$2}' >> /tmp/fw3.atjobs
}
config_foreach expire_at rule
config_foreach expire_at redirect
}
firewall_cleanup() {
local count=1
list=$(uci show firewall)
section_list=$(echo "$list" | grep "fwmngr")
section_list=$(echo "$section_list" | awk -F. '{ print $2 }')
section_list=$(echo "$section_list" | awk -F= '{ print $1 }')
fw_rule_sections=$(echo "$list" | grep -v fwmngr | grep "=rule")
fw_rule_sections=$(echo "$fw_rule_sections" | awk -F= '{ print $1 }')
fw_rule_sections=$(echo "$fw_rule_sections" | awk -F. '{ print $2 }')
fw_redirect_sections=$(echo "$list" | grep -v fwmngr | grep "=redirect")
fw_redirect_sections=$(echo "$fw_redirect_sections" | awk -F= '{ print $1 }')
fw_redirect_sections=$(echo "$fw_redirect_sections" | awk -F. '{ print $2 }')
fw_include_sections=$(echo "$list" | grep -v fwmngr | grep "=include")
fw_include_sections=$(echo "$fw_include_sections" | awk -F= '{ print $1 }')
fw_include_sections=$(echo "$fw_include_sections" | awk -F. '{ print $2 }')
for sec in $section_list; do
uci -q delete firewall."$sec"
done
uci commit firewall
}
firewallmngr_preload() {
firewall_cleanup
/lib/fwmngr/firewallmngr_preconfig
}
firewall_handle_section_dmz() {
local dmz_cfg="$1"
local dest_uci="$2"
local dmz_sec=""
local enable=""
local origin=""
local description=""
local interface=""
local dest_ip=""
local source_prefix=""
config_get enable "$dmz_cfg" "enabled" 0
[ "$enable" = "1" ] || return
config_get dest_ip "$dmz_cfg" "dest_ip"
config_get interface "$dmz_cfg" "interface"
if [ -z "$dest_ip" ] || [ -z "$interface" ]; then
return
fi
config_get origin "$dmz_cfg" "origin"
config_get description "$dmz_cfg" "description"
config_get source_prefix "$dmz_cfg" "source_prefix"
if [ "$dest_uci" = "firewall" ]; then
zones=$(uci show firewall | grep "=zone")
for zn in zones; do
zn_arg=$(echo $zn | awk -F= '{ print $1 }')
if [ "$interface" = "$(uci -q get $zn_arg.network)" ]; then
zn_name=$(uci -q get "$zn_arg".name)
fi
done
fi
dmz_sec=$(uci add "$dest_uci" redirect)
uci set "$dest_uci"."$dmz_sec".src="$zn_name"
uci set "$dest_uci"."$dmz_sec".enabled="1"
uci set "$dest_uci"."$dmz_sec".dest_ip="$dest_ip"
uci set "$dest_uci"."$dmz_sec".origin="$origin"
uci set "$dest_uci"."$dmz_sec".src_ip="$source_prefix"
uci set "$dest_uci"."$dmz_sec".target="DNAT"
uci rename "$dest_uci"."$dmz_sec"="fwmngr_$dmz_cfg"
}
handle_section_nat_interface_setting() {
local nat_intf_cfg="$1"
local interface=""
local enable=""
config_get enable "$nat_intf_cfg" "enabled"
[ -z "$enable" ] && return
config_get interface "$nat_intf_cfg" "interface"
if [ -n "$interface" ]; then
create_firewall_zone_config "$interface" "$enable"
fi
}
generate_firewall_config() {
local minus_one
firewallmngr_preload
uci commit firewallmngr
fw_config="$(uci -q get firewallmngr.firewall.config)"
[ -z "$fw_config" ] && return
[ "$fw_config" = "Advanced" ] || return
#get active chain name
chain_name=$(firewallmngr_get_active_chain)
#configure firewall global config
global_exist=$(uci -q get firewall.globals)
if [ -z "$global_exist" ]; then
global_sec=$(uci add firewall globals)
uci set firewall."$global_sec".enabled="1"
uci rename firewall."$global_sec"="globals"
fi
#configure firewall default config
default_sec=$(uci add firewall defaults)
uci set firewall."$default_sec".syn_flood="1"
uci set firewall."$default_sec".input="$INPUT"
uci set firewall."$default_sec".output="$OUTPUT"
uci set firewall."$default_sec".forward="$FORWARD"
uci rename firewall."$default_sec"="fwmngr_default"
config_load firewallmngr
config_foreach handle_section_nat_interface_setting natif
uci commit firewall
#loop through rules in firewallmngr uci and write rule in firewall
config_foreach handle_section_firewall_rule rule "$chain_name" "firewall"
uci commit firewall
config_foreach handle_section_nat_port_mapping nat_portmapping "firewall"
config_foreach firewall_handle_section_dmz dmz "firewall"
config_foreach handle_section_service service "firewall"
#reorder sections to place rule created by user at the end
minus_one=$((2**16))
for sec in $fw_rule_sections; do
uci -q reorder firewall."$sec"=${minus_one}
done
for sec in $fw_redirect_sections; do
uci -q reorder firewall."$sec"=${minus_one}
done
for sec in $fw_include_sections; do
uci -q reorder firewall."$sec"=${minus_one}
done
ubus call uci commit '{"config":"firewall"}'
schedule_expiry
}
configure_firewall () {
if ! [ -f "/etc/config/firewall" ]; then
touch /etc/config/firewall
fi
generate_firewall_config
}

View File

@@ -0,0 +1,627 @@
#!/bin/sh
. /lib/functions.sh
INPUT="REJECT"
OUTPUT="ACCEPT"
FORWARD="REJECT"
firewallmngr_get_active_chain() {
local fw_level=""
local chain_name=""
local fw_level=""
local chain=""
fw_level="$(uci -q get firewallmngr.firewall.advanced_level)"
[ -z "$fw_level" ] && return
enabled="$(uci -q get firewallmngr."${fw_level}".enable)"
[ "$enabled" = "1" ] || exit
chain="$(uci -q get firewallmngr."${fw_level}".chain)"
[ -z "$chain" ] && exit
enabled="$(uci -q get firewallmngr."${chain}".enable)"
chain_name="$(uci -q get firewallmngr."${chain}".name)"
echo "$chain_name"
}
create_firewall_zone_config() {
local intf="$1"
local masq="$2"
local is_bridge="false"
local intf_dev=""
local ntwrk=""
local interface=$(echo "$intf" | awk -F" " '{ print $1 }')
type=$(uci -q get firewall."$interface")
[ "$type" = "zone" ] && return
zone_sec=$(uci add "firewall" "zone")
uci set firewall."$zone_sec".masq="$masq"
uci set firewall."$zone_sec".name="$interface"
uci set firewall."$zone_sec".output="$OUTPUT"
if [ $(/lib/fwmngr/is_intf_bridge "$interface") -eq 1 ]; then
uci set firewall."$zone_sec".input="ACCEPT"
uci set firewall."$zone_sec".forward="ACCEPT"
else
if [ "$(uci -q get firewallmngr.globals.enabled)" = "0" ]; then
uci set firewall."$zone_sec".input="ACCEPT"
else
uci set firewall."$zone_sec".input="REJECT"
fi
uci set firewall."$zone_sec".forward="REJECT"
fi
for ntwrk in $intf; do
uci add_list firewall."$zone_sec".network="$ntwrk"
done
uci rename firewall."$zone_sec"="$interface"
}
firewallmngr_set_ip() {
local rule_sec="$1"
local src_ip="$2"
local dest_ip="$3"
mask=$(echo "$src_ip"|grep "/")
if [ -z "$src_ip" ]; then
uci set firewallmngr."$rule_sec".src_ip="$src_ip"
else
ip=$(echo "$src_ip" | awk -F"/" '{ print $0 }')
mask=$(echo "$src_ip" | awk -F"/" '{ print $2 }')
uci set firewallmngr."$rule_sec".src_ip="$ip"
uci set firewallmngr."$rule_sec".source_mask="$mask"
fi
mask=$(echo "$src_ip"|grep "/")
if [ -z "$dest_ip" ]; then
uci set firewallmngr."$rule_sec".dest_ip="$dest_ip"
else
ip=$(echo "$dest_ip" | awk -F"/" '{ print $0 }')
mask=$(echo "$dest_ip" | awk -F"/" '{ print $2 }')
uci set firewallmngr."$rule_sec".dest_ip="$ip"
uci set firewallmngr."$rule_sec".dest_mask="$mask"
fi
}
firewall_set_ip() {
local rule_sec="$1"
local src_ip="$2"
local dest_ip="$3"
uci set firewall."$rule_sec".src_ip="$src_ip"
uci set firewall."$rule_sec".dest_ip="$dest_ip"
}
firewallmngr_set_port() {
local rule_sec="$1"
local src_port="$2"
local dest_port="$3"
local src_port_range_max="$4"
local dest_port_range_max="$5"
range=$(echo "$src_port" | grep ":")
if [ -z "$range" ]; then
uci set firewallmngr."$rule_sec".src_port="$src_port"
else
min_port=$(echo "$src_port" | awk -F":" '{ print $1 }')
max_port=$(echo "$src_port" | awk -F":" '{ print $2 }')
uci set firewallmngr."$rule_sec".src_port="$min_port"
uci set firewallmngr."$rule_sec".src_port_range_max="$max_port"
fi
range=$(echo "$dest_port" | grep ":")
if [ -z "$range" ]; then
uci set firewallmngr."$rule_sec".dest_port="$dest_port"
else
min_port=$(echo "$dest_port" | awk -F":" '{ print $1 }')
max_port=$(echo "$dest_port" | awk -F":" '{ print $2 }')
uci set firewallmngr."$rule_sec".dest_port="$min_port"
uci set firewallmngr."$rule_sec".dest_port_range_max="$max_port"
fi
}
firewall_set_port() {
local rule_sec="$1"
local src_port="$2"
local dest_port="$3"
local src_port_range_max="$4"
local dest_port_range_max="$5"
if [ -z "$dest_port_range_max" ] || [ "$dest_port_range_max" = "-1" ]; then
[ "$dest_port" == "-1" ] || uci set firewall."$rule_sec".dest_port="$dest_port"
else
uci set firewall."$rule_sec".dest_port="$dest_port:$dest_port_range_max"
fi
if [ -z "$src_port_range_max" ] || [ "$src_port_range_max" = "-1" ]; then
[ "$src_port" == "-1" ] || uci set firewall."$rule_sec".src_port="$src_port"
else
uci set firewall."$rule_sec".src_port="$src_port:$src_port_range_max"
fi
}
firewallmngr_set_interface() {
local rule_sec="$1"
local src_intf="$2"
local dest_intf="$3"
if [ "$src_intf" = "*" ]; then
uci set firewallmngr."$rule_sec".source_all_interfaces="1"
else
uci set firewallmngr."$rule_sec".source_all_interfaces="0"
uci set firewallmngr."$rule_sec".src="$src_intf"
fi
if [ "$dest_intf" = "*" ]; then
uci set firewallmngr."$rule_sec".dest_all_interfaces="1"
else
uci set firewallmngr."$rule_sec".dest_all_interfaces="0"
uci set firewallmngr."$rule_sec".dest="$dest_intf"
fi
}
firewall_set_interface() {
local rule_sec="$1"
local src_intf="$2"
local dest_intf="$3"
uci set firewall."$rule_sec".src="$src_intf"
uci set firewall."$rule_sec".dest="$dest_intf"
}
firewallmngr_get_rule_ip_family() {
local version="$1"
if [ "$version" == "ipv4" ]; then
echo "4"
elif [ "$version" == "ipv6" ]; then
echo "6"
else
echo "-1"
fi
}
firewall_get_rule_ip_family() {
local version="$1"
if [ "$version" == "4" ]; then
echo "ipv4"
elif [ "$version" == "6" ]; then
echo "ipv6"
else
echo "-1"
fi
}
firewallmngr_set_ip_family() {
local rule_sec="$1"
local ip_family="$2"
if [ -z "$ip_family" ]; then
uci set firewallmngr."$rule_sec".family="-1"
return
fi
uci set firewallmngr."$rule_sec".family="$ip_family"
}
firewall_set_ip_family() {
local rule_sec="$1"
local ip_family="$2"
[ "$ip_family" == "-1" ] || uci set firewall."$rule_sec".family="$ip_family"
}
firewallmngr_set_rule_target() {
local rule_sec="$1"
local target="$2"
local targetchain="$3"
local action
if [ "$target" = "MARK" ]; then
uci set firewallmngr."$rule_sec".target="Return"
elif [ "$target" = "TargetChain" ]; then
uci set firewallmngr."$rule_sec".target="$targetchain"
else
action=$(echo "$target" | awk '{for(i=1;i<=NF;i++){$i=toupper(substr($i,1,1)) substr($i,2)}} 1')
uci set firewallmngr."$rule_sec".target="$action"
fi
}
firewall_set_rule_target() {
local rule_sec="$1"
local target="$2"
local targetchain="$3"
target="$(echo $target | awk '{ print toupper($0) }')"
if [ "$target" = "ACCEPT" ] || [ "$target" = "REJECT" ] || [ "$target" = "DROP" ]; then
uci set firewall."$rule_sec".target="$(echo $target | awk '{ print toupper($0) }')"
elif [ "$target" = "Retrun" ]; then
uci set firewall."$rule_sec".target="MARK"
elif [ "$target" = "TargetChain" ]; then
uci set firewall."$rule_sec".target="$targetchain"
else
uci set firewall."$rule_sec".target="DROP"
fi
}
set_rule_protocol() {
local rule_sec="$1"
local protocol="$2"
local rule_rd="$3"
local dest_uci="$4"
set_icmp_type() {
uci add_list "$dest_uci"."$rule_sec".icmp_type="$1"
}
if [ -z "$protocol" ] || [ "$protocol" = "0" ] || [ "$protocol" = "all" ] || [ "$protocol" = "-1" ]; then
uci set "$dest_uci"."$rule_sec".proto="all"
return
fi
if [ "$dest_uci" = "firewallmngr" ]; then
protocol=$(grep -m 1 "$protocol" "/etc/protocols" | awk -F" " '{ print $2 }')
fi
uci set "$dest_uci"."$rule_sec".proto="$protocol"
if [ "$protocol" = "1" ] || [ "$protocol" = "icmp" ]; then
config_list_foreach "$rule_rd" "icmp_type" set_icmp_type
fi
}
handle_section_firewall_rule() {
local rule="$1"
local chain_name="$2"
local dest_uci="$3"
local chain=""
local is_enable=""
local src_intf=""
local ip_version=""
local ip_family=""
local protocol=""
local dest_intf=""
local target=""
local targetchain=""
local desc=""
local dest_port=""
local src_port=""
local src_port_range_max=""
local dest_port_range_max=""
local src_ip=""
local dest_ip=""
local source_mac=""
local source_all_interfaces=""
local dest_all_interfaces=""
local source_mask=""
local dest_mask=""
local limit=""
local expiry=""
local order=""
config_get is_enable "$rule" "enable" 1
[ "$is_enable" = "1" ] || return
if [ "$dest_uci" = "firewall" ]; then
config_get chain "$rule" "chain"
[ "$chain" = "$chain_name" ] || return
fi
config_get desc "$rule" "name"
config_get src_intf "$rule" "src"
config_get dest_intf "$rule" "dest"
config_get ip_version "$rule" "family"
function="$dest_uci"_get_rule_ip_family
ip_family="$($function $ip_version)"
config_get protocol "$rule" "proto"
config_get src_port "$rule" "src_port"
config_get dest_port "$rule" "dest_port"
config_get src_ip "$rule" "src_ip"
config_get source_mask "$rule" "source_mask"
[ -n "$source_mask" ] && src_ip="${src_ip}/$(echo $source_mask | awk -F/ '{ print $2 }')"
config_get dest_ip "$rule" "dest_ip"
config_get dest_mask "$rule" "dest_mask"
[ -n "$dest_mask" ] && dest_ip="${dest_ip}/$(echo $dest_mask | awk -F/ '{ print $2 }')"
config_get dest_port_range_max "$rule" "dest_port_range_max"
config_get src_port_range_max "$rule" "src_port_range_max"
config_get target "$rule" "target"
config_get targetchain "$rule" "targetchain"
config_get source_mac "$rule" "src_mac"
config_get order "$rule" "order"
config_get limit "$rule" "limit"
config_get expiry "$rule" "expiry"
config_get source_all_interfaces "$rule" "source_all_interfaces"
[ "$source_all_interfaces" = "1" ] && src_intf="*"
config_get dest_all_interfaces "$rule" "dest_all_interfaces"
[ "$dest_all_interfaces" = "1" ] && dest_intf="*"
rule_sec=$(uci add "$dest_uci" rule)
uci set "$dest_uci"."$rule_sec".chain="$chain_name"
uci set "$dest_uci"."$rule_sec".enabled="1"
uci set "$dest_uci"."$rule_sec".name="$desc"
"$dest_uci"_set_interface "$rule_sec" "$src_intf" "$dest_intf"
"$dest_uci"_set_ip_family "$rule_sec" "$ip_family"
"$dest_uci"_set_rule_target "$rule_sec" "$target" "$targetchain"
set_rule_protocol "$rule_sec" "$protocol" "$rule" "$dest_uci"
"$dest_uci"_set_port "$rule_sec" "$src_port" "$dest_port" "$src_port_range_max" "$dest_port_range_max"
"$dest_uci"_set_ip "$rule_sec" "$src_ip" "$dest_ip"
uci set "$dest_uci"."$rule_sec".src_mac="$source_mac"
uci set "$dest_uci"."$rule_sec".order="$order"
uci set "$dest_uci"."$rule_sec".limit="$limit"
uci set "$dest_uci"."$rule_sec".expiry="$expiry"
if [ "$dest_uci" = "firewall" ]; then
uci rename "$dest_uci"."$rule_sec"="fwmngr_$rule"
else
uci rename "$dest_uci"."$rule_sec"="$rule"
fi
}
firewallmngr_configure_service_rule() {
local interface="$1"
local dest_port="$2"
local ip_family="$3"
local protocol="$4"
local icmp_type="$5"
local source_prefix="$6"
local action="$7"
local service_cfg="$8"
local service_sec
service_sec_add_list_value() {
for value in $1; do
uci add_list firewallmngr."$service_sec"."$2"="$value"
done
}
service_sec=$(uci add firewall service)
uci set firewallmngr."$service_sec".enabled="1"
uci set firewallmngr."$service_sec".name="service rule"
uci set firewallmngr."$service_sec".src="$interface"
uci set firewallmngr."$service_sec".icmp_type="$icmp_type"
uci set firewallmngr."$service_sec".family=$(firewallmngr_get_rule_ip_family "$ip_family")
firewallmngr_set_rule_target "$service_sec" "$action" ""
service_sec_add_list_value "$dest_port" "dest_port"
service_sec_add_list_value "$protocol" "protocol"
service_sec_add_list_value "$source_prefix" "src_prefix"
uci rename firewallmngr."$service_sec"="${service_cfg}"
}
firewall_configure_service_rule() {
local interface="$1"
local dest_port="$2"
local ip_family="$3"
local protocol="$4"
local icmp_type="$5"
local source_prefix="$6"
local action="$7"
local service_cfg="$8"
local service_sec
service_sec=$(uci add firewall rule)
uci set firewall."$service_sec".enabled="1"
uci set firewall."$service_sec".name="service rule"
uci set firewall."$service_sec".src="$interface"
[ "$dest_port" == "-1" ] || uci set firewall."$service_sec".dest_port="$dest_port"
uci set firewall."$service_sec".family=$(firewall_get_rule_ip_family "$ip_family")
[ "$protocol" == "-1" ] || uci set firewall."$service_sec".proto="$protocol"
[ "$icmp_type" == "-1" ] || uci set firewall."$service_sec".icmp_type="$icmp_type"
uci set firewall."$service_sec".src_ip="$source_prefix"
firewall_set_rule_target "$service_sec" "$action" ""
[ -z "$service_cfg" ] || uci rename firewall."$service_sec"="fwmngr_${service_cfg}"
}
handle_section_service() {
local service_cfg="$1"
local dest_uci="$2"
local service_sec=""
local enable=""
local interface=""
local dest_port=""
local protocol=""
local icmp_type=""
local source_prefix=""
local action=""
local ip_family=""
get_service_proto_list() {
protocol="$protocol $1"
}
get_service_src_prefix_list() {
source_prefix="$source_prefix $1"
}
get_service_dest_port_list() {
dest_port="$dest_port $1"
}
config_get enable "$service_cfg" "enable" 0
[ "$enable" == "1" ] || return
config_get interface "$service_cfg" "interface"
[ -z "$interface" ] && return
config_get ip_family "$service_cfg" "family"
config_list_foreach "$service_cfg" "proto" get_service_proto_list
config_list_foreach "$service_cfg" "dest_port" get_service_dest_port_list
config_list_foreach "$service_cfg" "src_prefix" get_service_src_prefix_list
config_get icmp_type "$service_cfg" "icmp_type"
config_get action "$service_cfg" "target"
"$dest_uci"_configure_service_rule "$interface" "$dest_port" "$ip_family" "$protocol" "$icmp_type" "$source_prefix" "$action" "$service_cfg"
}
firewallmngr_set_all_intf_src_dip() {
local redirect_section="$1"
local zn_name="$2"
local all_interface="$3"
config_get src_dip "$redirect_section" "src_dip"
if [ "$src_dip" = "*" ]; then
uci set firewallmngr."$redirect_sec".all_interface="1"
else
uci set firewallmngr."$redirect_sec".all_interface="0"
fi
}
firewall_set_all_intf_src_dip() {
local redirect_section="$1"
local zn_name="$2"
local all_interface="$3"
if [ "$all_interface" = "1" ]; then
if [ -z "$zn_name" ]; then
uci set firewall."$redirect_sec".src="wan"
else
uci set firewall."$redirect_sec".src="$zn_name"
fi
uci set firewall."$redirect_sec".src_dip="*"
else
uci set firewall."$redirect_sec".src="$zn_name"
uci set firewall."$redirect_sec".src_dip=""
fi
}
firewallmngr_set_src_dport() {
local redirect_sec="$1"
lodcal external_port="$2"
local external_port_end="$3"
range=$(echo "$external_port" | grep "-")
if [ -z "$range" ]; then
uci set firewallmngr."$redirect_sec".src_dport="$external_port"
else
min_port=$(echo "$external_port" | awk -F"-" '{ print $1 }')
max_port=$(echo "$external_port" | awk -F"-" '{ print $2 }')
uci set firewallmngr."$redirect_sec".src_dport="$min_port"
uci set firewallmngr."$redirect_sec".src_dport_end="$max_port"
fi
}
firewall_set_src_dport() {
local redirect_sec="$1"
local external_port="$2"
local external_port_end="$3"
if [ "$external_port_end" = "0" ]; then
if ! [ "$external_port" = "0" ]; then
uci set firewall."$redirect_sec".src_dport="$external_port"
fi
else
uci set firewall."$redirect_sec".src_dport="$external_port-$external_port_end"
fi
}
# handling for firewallmngr to firewall
handle_section_nat_port_mapping() {
local nat_port_cfg="$1"
local dest_uci="$2"
local enable=""
local interface=""
local all_interface=""
local lease_duration=""
local remote_host=""
local external_port=""
local external_port_end=""
local internal_port=""
local protocol=""
local internal_client=""
local description=""
local redirect_sec=""
local epoch_sec=""
local stop_epoch=""
local stop_ymd=""
local stop_hms=""
local zn_name=""
config_get enable "$nat_port_cfg" "enabled"
config_get interface "$nat_port_cfg" "src"
if [ "$dest_uci" = "firewall" ]; then
zones=$(uci show firewall | grep "=zone")
for zn in zones; do
zn_arg=$(echo $zn | awk -F= '{ print $1 }')
if [ "$interface" = "$(uci -q get $zn_arg.network)" ]; then
zn_name=$(uci -q get "$zn_arg".name)
masq=$(uci -q get "$zn_arg".masq)
fi
done
if [ -z "$enable" ] && ! [ "$masq" = "1" ]; then
return
fi
fi
config_get internal_client "$nat_port_cfg" "dest_ip"
config_get all_interface "$nat_port_cfg" "all_interface"
config_get lease_duration "$nat_port_cfg" "lease_duration"
config_get remote_host "$nat_port_cfg" "src_ip"
config_get external_port "$nat_port_cfg" "src_dport" "0"
config_get external_port_end "$nat_port_cfg" "src_dport_end" "0"
config_get internal_port "$nat_port_cfg" "dest_port"
config_get protocol "$nat_port_cfg" "proto"
protocol=$(echo $protocol | awk '{ print tolower($0) }')
config_get description "$nat_port_cfg" "name"
redirect_sec=$(uci add "$dest_uci" redirect)
"dest_uci"_set_all_intf_src_dip "$redirect_sec" "$zn_name" "$all_interface"
if [ "$dest_uci" = "firewall" ]; then
if [ -n "$lease_duration" ] && ! [ "$lease_duration" == "0" ]; then
epoch_sec=$(date +%s)
stop_epoch=$(( epoch_sec + lease_duration ))
stop_ymd=$(date -d @${stop_epoh} +%Y-%m-%d)
stop_hms=$(date -d @${stop_epoch} +%H:%M:%S)
uci set "$dest_uci"."$redirect_sec".stop_date="$stop_ymd"
uci set "$dest_uci"."$redirect_sec".stop_time="$stop_hms"
fi
fi
"$dest_uci"_set_src_dport "$redirect_section" "$external_port" "$external_port_end"
uci set "$dest_uci"."$redirect_sec".enabled="1"
uci set "$dest_uci"."$redirect_sec".target="DNAT"
uci set "$dest_uci"."$redirect_sec".dest_ip="$internal_client"
[ -z "$protocol" ] || uci set "$dest_uci"."$redirect_sec".proto="$protocol"
[ -z "$remote_host" ] || uci set "$dest_uci"."$redirect_sec".src_ip="$remote_host"
[ -z "$internal_port" ] || uci set "$dest_uci"."$redirect_sec".dest_port="$internal_port"
[ -z "$description" ] || uci set "$dest_uci"."$redirect_sec".name="$description"
if [ "$dest_uci" = "firewall" ]; then
uci rename "$dest_uci"."$redirect_sec"="fwmngr_$nat_port_cfg"
else
uci rename "$dest_uci"."$redirect_sec"="$nat_port_cfg"
fi
}
handle_include_section() {
local include_sec="$1"
local dest_uci="$2"
config_get path "$include_sec" "path"
config_get reload "$include_sec" "reload"
config_get include_type "$include_sec" "type"
sec=$(uci add "$dest_uci" include)
[ -z "$path" ] || uci set "$dest_uci"."$sec".path="$path"
[ -z "$reload" ] || uci set "$dest_uci"."$sec".reload="$reload"
[ -z "$include_type" ] || uci set "$dest_uci"."$sec".type="$include_type"
if [ "$dest_uci" = "firewall" ]; then
uci rename "$dest_uci"."$sec"="fwmngr_$include_sec"
else
uci rename "$dest_uci"."$sec"="$include_sec"
fi
}

View File

@@ -0,0 +1,60 @@
#! /bin/sh
active_chain=""
remove_twamp_reflector_rules() {
config_get name "$1" name
if [ "$name" = "Twamp Reflector Rule" ]; then
uci delete firewallmngr."$1"
fi
}
handle_twamp_reflector_rules() {
local twamp_cfg="$1"
local sec_name=""
local action="Acept"
config_get enable "$twamp_cfg" enable "1"
config_get port "$twamp_cfg" port
config_get interface "$twamp_cfg" interface
if [ "${enable}" -eq 0 ] || [ -z "$port" ] || [ -z "$interface" ]; then
return
fi
sec_name="twamp_${interface}_${port}"
rule_twamp=$(uci add firewallmngr rule)
uci set firewallmngr."$rule_twamp".enable="1"
uci set firewallmngr."$rule_twamp".chain="$active_chain"
uci set firewallmngr."$rule_twamp".dest_port="$port"
uci set firewallmngr."$rule_twamp".name="Twamp Reflector Rule"
uci set firewallmngr."$rule_twamp".interface="$interface"
uci set firewallmngr."$rule_twamp".ip_version="4"
uci set firewallmngr."$rule_twamp".protocol="17"
uci set firewallmngr."$rule_twamp".target="$action"
uci rename firewallmngr."$rule_twamp"="fwmngr_$sec_name"
}
firewallmngr_get_active_chain() {
config_get creator "$1" creator
[ "$creator" = "PortMapping" ] && return
config_get enable "$1" enable
if [ -n "$enable" ] && [ "$enable" = "1" ]; then
config_get active_chain "$1" name
fi
}
handle_twamp_rules() {
twamp_enable=$(uci -q get twamp.twamp.enable)
config_load firewallmngr
config_foreach firewallmngr_get_active_chain chain
config_foreach remove_twamp_reflector_rules rule
config_load twamp
if [ -n "$twamp_enable" ] && [ "$twamp_enable" == "1" ]; then
config_foreach handle_twamp_reflector_rules twamp_reflector
fi
uci commit firewallmngr
}

View File

@@ -0,0 +1,23 @@
#!/bin/sh
. /lib/functions.sh
interface=$1
intf_dev=""
is_bridge=0
is_device_type_bridge() {
local dev
local dev_type
config_get dev "$1" "name"
config_get dev_type "$1" "type"
if [ "$dev" = "$intf_dev" ] && [ "$dev_type" = "bridge" ]; then
is_bridge=1
fi
}
intf_dev=$(uci -q get network."$interface".device)
config_load network
config_foreach is_device_type_bridge device
echo $is_bridge

View File

@@ -0,0 +1,158 @@
#!/bin/sh
. /lib/functions.sh
. /lib/fwmngr/fwmngr_functions.sh
uci_mig_include_sections=""
include_deprecated_list="hosts cwmp dmz mcast twamp portmap service"
final_include_cfg=""
firewallmngr_zone_to_nat_interface_setting() {
zone="$1"
config_get interface "$zone" "network"
[ -n "$interface" ] || return
config_get enable "$zone" "masq" "0"
nat_intf_setting=$(uci add "firewallmngr" "natif")
uci set firewallmngr."$nat_intf_setting".enabled="$enable"
uci set firewallmngr."$nat_intf_setting".interface="$interface"
uci rename firewallmngr."$nat_intf_setting"=$(echo "$interface" | awk -F" " '{ print $1 }')
}
handle_section_forwarding_rule() {
local fwd="$1"
local chain="$2"
config_get src_intf "$fwd" "src"
config_get dest_intf "$fwd" "dest"
rule_sec=$(uci add "firewallmngr" rule)
firewallmngr_set_interface "$rule_sec" "$src_intf" "$dest_intf"
uci set firewallmngr."$rule_sec".chain="$chain"
uci set firewallmngr."$rule_sec".name="$fwd"
uci set firewallmngr."$rule_sec".target="accept"
uci rename firewallmngr."$rule_sec"="fwmngr_$fwd"
}
firewallmngr_handle_section_dmz() {
local dmz_cfg="$1"
local dest_uci="$2"
local dmz_sec=""
local enabled=""
local origin=""
local description=""
local interface=""
local dest_ip=""
local source_prefix=""
config_get dest_ip "$dmz_cfg" "dest_ip"
config_get interface "$dmz_cfg" "interface"
config_get origin "$dmz_cfg" "origin"
config_get source_prefix "$dmz_cfg" "source_prefix"
config_get description "$dmz_cfg" "description"
config_get enabled "$dmz_cfg" "enabled"
dmz_sec=$(uci add firewallmngr dmz)
uci set firewallmngr."$dmz_sec".enabled="$enabled"
uci set firewallmngr."$dmz_sec".dest_ip="$dest_ip"
uci set firewallmngr."$dmz_sec".interface="$interface"
uci set firewallmngr."$dmz_sec".origin="$origin"
uci set firewallmngr."$dmz_sec".description="$description"
uci set firewallmngr."$dmz_sec".source_prefix="$source_prefix"
uci rename firewallmngr."$dmz_sec"="$dmz_cfg"
}
#This call must be triggered from procd boot function
cleanup_firewallmngr_rule_section() {
rule_sec=$(uci show firewallmngr | grep "=rule")
for sec in $rule_sec; do
rule=$(echo "$sec" | awk -F= '{ print $1 }')
uci delete "$rule"
done
uci commit firewallmngr
}
firewallmngr_delete_install_dmz_rule() {
local dmz_cfgs
dmz_cfgs=$(uci show firewall | grep "=dmz")
for dmz in $dmz_cfgs; do
dmz=$(echo $dmz | awk -F= '{ print $1 }')
uci del "$dmz"
done
uci commit firewall
}
firewall_delete_deprecated_include_section() {
new_inc_list=""
inc_list=$(uci show firewall | grep "=include")
for inc in $inc_list; do
inc=$(echo "$inc"| awk -F"=" '{ print $1 }')
inc_name=$(echo "$inc" | awk -F. '{ print $2 }')
inc_path=$(uci -q get "$inc".path | awk -F/ '{ print $NF }')
inc_file=$(echo "$inc_path" | awk -F. '{ print $2 }')
inc_ignore=$(echo "$include_deprecated_list"| grep -w "$inc_name")
if [ -z "$inc_ignore" ]; then
inc_ignore=$(echo "$include_deprecated_list"| grep -w "$inc_file")
fi
[ -z "$inc_ignore" ] || uci delete "$inc"
done
uci commit firewall
}
firewall_backup_include_section() {
list=$(uci show firewall)
uci_mig_include_sections=$(echo "$list" | grep "=include")
uci_mig_include_sections=$(echo "$fw_include_sections" | awk -F= '{ print $1 }')
uci_mig_include_sections=$(echo "$fw_include_sections" | awk -F. '{ print $2 }')
}
firewall_uci_cleanup() {
# cleanup all sections of firewall uci, firewall uci will be generated by firewallmngr init
section_cleanup () {
local sec="$1"
rule_sec=$(uci show firewall | grep "$sec")
for rule in $rule_sec; do
rule=$(echo "$rule" | awk -F= '{ print $1 }')
uci delete "$rule"
done
}
section_cleanup "=rule"
section_cleanup "=zone"
section_cleanup "=redirect"
section_cleanup "=dmz"
section_cleanup "=service"
section_cleanup "=forwarding"
section_cleanup "=defaults"
section_cleanup "=globals"
uci commit firewall
}
generate_firewallmngr_config() {
chain_name=$(firewallmngr_get_active_chain)
cleanup_firewallmngr_rule_section
config_load firewall
config_foreach handle_section_firewall_rule rule "$chain_name" "firewallmngr"
config_foreach firewallmngr_zone_to_nat_interface_setting zone
config_foreach handle_section_nat_port_mapping redirect "firewallmngr"
config_foreach firewallmngr_handle_section_dmz dmz "firewallmngr"
config_foreach handle_section_service service "firewallmngr"
config_foreach handle_section_forwarding_rule forwarding "$chain_name"
uci commit firewallmngr
firewall_uci_cleanup
firewall_delete_deprecated_include_section
}

View File

@@ -62,7 +62,11 @@ define Package/hostmngr/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/hostmngr $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/usr/share/hostmngr
ifneq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
$(INSTALL_DATA) ./files/scripts/hosts_acl.sh $(1)/usr/share/hostmngr/
else
$(INSTALL_DATA) ./files/scripts/hostmngr_backend_firewallmngr/hosts_acl.sh $(1)/usr/share/hostmngr/
endif
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/bbf_plugin/libhostmngr.so $(1) $(PKG_NAME)
endef

View File

@@ -0,0 +1,299 @@
#!/bin/sh
. /lib/functions.sh
day=""
next_days=""
prev_days=""
schedule_added=""
ACCESS_RULE=""
IP_RULE=""
IP_RULE1=""
get_next_day() {
local weekday="$1"
case "$weekday" in
"Mon"|"Monday") echo "Tuesday"
;;
"Tue"|"Tuesday") echo "Wednesday"
;;
"Wed"|"Wednesday") echo "Thursday"
;;
"Thu"|"Thursday") echo "Friday"
;;
"Fri"|"Friday") echo "Saturday"
;;
"Sat"|"Saturday") echo "Sunday"
;;
"Sun"|"Sunday") echo "Monday"
;;
esac
}
get_previous_day() {
local weekday="$1"
case "$weekday" in
"Mon"|"Monday") echo "Sunday"
;;
"Tue"|"Tuesday") echo "Monday"
;;
"Wed"|"Wednesday") echo "Tuesday"
;;
"Thu"|"Thursday") echo "Wednesday"
;;
"Fri"|"Friday") echo "Thursday"
;;
"Sat"|"Saturday") echo "Friday"
;;
"Sun"|"Sunday") echo "Saturday"
;;
esac
}
ip_rule_west_zone() {
local utc_start_t_h="$1"
local utc_stop_t_h="$2"
local local_start_t_h="$3"
local local_stop_t_h="$4"
local utc_start_time="$5"
local utc_stop_time="$6"
if [ "$utc_start_t_h" -lt "$local_start_t_h" ]; then
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
if [ -n "$next_days" ]; then
IP_RULE="$IP_RULE --weekdays $next_days"
fi
else
if [ "$utc_stop_t_h" -lt "$local_stop_t_h" ]; then
IP_RULE1="$IP_RULE"
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop 23:59"
IP_RULE1="$IP_RULE1 -m time --timestart 00:00 --timestop $utc_stop_time"
if [ -n "$next_days" ]; then
IP_RULE1="$IP_RULE1 --weekdays $next_days"
fi
else
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
fi
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
fi
fi
}
ip_rule_east_zone() {
local utc_start_t_h="$1"
local utc_stop_t_h="$2"
local local_start_t_h="$3"
local local_stop_t_h="$4"
local utc_start_time="$5"
local utc_stop_time="$6"
if [ "$utc_start_t_h" -lt "$local_start_t_h" ]; then
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
fi
else
if [ "$utc_stop_t_h" -lt "$local_stop_t_h" ]; then
IP_RULE1="$IP_RULE"
IP_RULE="$IP_RULE -m time --timestart 00:00 --timestop $utc_stop_time"
IP_RULE1="$IP_RULE1 -m time --timestart $utc_start_time --timestop 23:59"
if [ -n "$prev_days" ]; then
IP_RULE1="$IP_RULE1 --weekdays $prev_days"
fi
else
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
fi
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
fi
fi
}
add_access_rule() {
local rule="$1"
echo "iptables -w -A hosts_forward ${rule}" >> $ACL_FILE
echo "ip6tables -w -A hosts_forward ${rule}" >> $ACL_FILE
}
handle_day_list() {
local value=$1
val=$(echo $value | cut -c 1-3)
next_day_val=$(get_next_day $val)
prev_day_val=$(get_previous_day $val)
if [ -z $day ]; then
day="$val"
next_days="$next_day_val"
prev_days="$prev_day_val"
else
day="$day,$val"
next_days="$next_days,$next_day_val"
prev_days="$prev_days,$prev_day_val"
fi
}
handle_schedule() {
local schd_section="$1"
local ac_section="$2"
local acs_id
local start_time
local duration
IP_RULE="$ACCESS_RULE"
IP_RULE1=""
day=""
next_days=""
prev_days=""
config_get acs_id "$schd_section" "dm_parent"
if [ "$acs_id" != "$ac_section" ]; then
return # schedule not for this access control section
fi
local is_enabled
config_get is_enabled "$schd_section" "enable" 0
if [ "$is_enabled" == "0" ]; then
return
fi
local all_days="Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
local day_config
config_get day_config "$schd_section" "day" "$all_days"
IFS=" "
for d in $day_config; do
handle_day_list $d
done
config_get start_time "$schd_section" "start_time" "00:00"
config_get duration "$schd_section" "duration"
zone=$(date +%z | cut -c 1)
local_start_time=$start_time
hh=$(echo $local_start_time | awk -F: '{ print $1 }')
mm=$(echo $local_start_time | awk -F: '{ print $2 }')
hh_s=`expr $hh \* 3600`
mm_s=`expr $mm \* 60`
ss=$(( hh_s + mm_s ))
local_start_hh=$hh
if [ -n "$duration" ]; then
stop_ss=$(( ss + duration ))
hh=$(( stop_ss / 3600 ))
rem_ss=$(( stop_ss % 3600 ))
mm=$(( rem_ss / 60 ))
ss=$(( rem_ss % 60 ))
local_stop_time="$hh:$mm:$ss"
local_stop_hh=$hh
else
# if duartion is not specified, then apply rule to end of the day
local_stop_time="23:59:59"
local_stop_hh="23"
fi
utc_start_time=$(date -u -d @$(date "+%s" -d "$local_start_time") +%H:%M)
utc_stop_time=$(date -u -d @$(date "+%s" -d "$local_stop_time") +%H:%M)
utc_start_hh=$(echo $utc_start_time | awk -F: '{ print $1 }')
utc_stop_hh=$(echo $utc_stop_time | awk -F: '{ print $1 }')
if [ "$zone" == "-" ]; then
ip_rule_west_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time
else
ip_rule_east_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time
fi
IP_RULE="$IP_RULE -j ACCEPT"
if [ -n "$IP_RULE1" ]; then
IP_RULE1="$IP_RULE1 -j ACCEPT"
fi
add_access_rule "$IP_RULE"
if [ -n "$IP_RULE1" ]; then
add_access_rule "$IP_RULE1"
fi
# for access rules to be effective for a schedule, need to add DROP rule
# to block the access outside the defined schedule
if [ "$schedule_added" == "0" ]; then
schedule_added="1"
fi
}
handle_access_control() {
local ac_section="$1"
local is_enabled
# default value of Hosts.AccessControl.{i}.Enable is false,
# so, if not defined in uci as 1, assume 0
config_get is_enabled "$ac_section" "enable" 0
if [ "$is_enabled" == "0" ]; then
return
fi
local mac_addr
config_get mac_addr "$ac_section" "macaddr"
if [ -z "$mac_addr" ]; then
return
else
ACCESS_RULE="-m mac --mac-source $mac_addr"
fi
local access_policy
config_get access_policy "$ac_section" "access_policy"
if [ -z "$access_policy" ]; then
return # since system default is allow so no need to do anything
fi
# As per Data Model, if access policy is deny, then schedule is to be ignored
# and no access is to be provided for the device
if [ "$access_policy" == "Deny" ]; then
ACCESS_RULE="$ACCESS_RULE -j DROP"
add_access_rule "$ACCESS_RULE"
return # no need to parse schedule
fi
schedule_added="0"
# check if schedule is defined for this access_control instance
# and if yes, create rule accordingly
config_foreach handle_schedule ac_schedule "$ac_section"
# for access rule to work, need to have default drop rule as last rule
if [ "$schedule_added" == "1" ]; then
IP_RULE="$ACCESS_RULE -j DROP"
add_access_rule "$IP_RULE"
fi
}
ACL_FILE="/tmp/hosts_access_control/access_control.rules"
rm -f $ACL_FILE
mkdir -p /tmp/hosts_access_control/
touch $ACL_FILE
echo "iptables -w -F hosts_forward" >> $ACL_FILE
echo "ip6tables -w -F hosts_forward" >> $ACL_FILE
hosts_ipv4_forward=$(iptables -t filter --list -n | grep hosts_forward)
if [ -z "$hosts_ipv4_forward" ]; then
echo "iptables -w -t filter -N hosts_forward" >> $ACL_FILE
ret=$?
[ $ret -eq 0 ] && echo "iptables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
fi
hosts_ipv6_forward=$(ip6tables -t filter --list -n | grep hosts_forward)
if [ -z "$hosts_ipv6_forward" ]; then
echo "ip6tables -w -t filter -N hosts_forward" >> $ACL_FILE
ret=$?
[ $ret -eq 0 ] && echo "ip6tables -w -t filter -I FORWARD -j hosts_forward" >> $ACL_FILE
fi
# Load /etc/config/hosts UCI file
config_load hosts
config_foreach handle_access_control access_control
# apply the rules
sh $ACL_FILE

View File

@@ -50,10 +50,16 @@ define Package/icwmp/install
$(INSTALL_DIR) $(1)/etc/udhcpc.user.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/icwmpd $(1)/usr/sbin/icwmpd
$(INSTALL_DATA) ./files/etc/config/cwmp $(1)/etc/config/cwmp
ifneq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
$(INSTALL_BIN) ./files/etc/firewall.cwmp $(1)/etc/firewall.cwmp
$(INSTALL_BIN) ./files/etc/init.d/icwmpd $(1)/etc/init.d/icwmpd
$(INSTALL_BIN) ./files/etc/uci-defaults/85-cwmp-set-userid $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/90-cwmpfirewall $(1)/etc/uci-defaults/
else
$(INSTALL_DIR) $(1)/usr/share/icwmp
$(INSTALL_BIN) ./files/etc/init.d/icwmp_backend_firewallmngr/icwmpd $(1)/etc/init.d/icwmpd
$(INSTALL_BIN) ./files/script/icwmp_backend_firewallmngr/firewall_cwmp.sh $(1)/usr/share/icwmp/
endif
$(INSTALL_BIN) ./files/etc/uci-defaults/85-cwmp-set-userid $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/95-set-random-inform-time $(1)/etc/uci-defaults/
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/icwmp $(1)/lib/upgrade/keep.d/icwmp
$(INSTALL_BIN) ./files/etc/udhcpc.user.d/udhcpc_icwmp_opt125.user $(1)/etc/udhcpc.user.d/udhcpc_icwmp_opt125.user

View File

@@ -0,0 +1,589 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2015-2019 iopsys Software Solutions AB
START=99
STOP=00
USE_PROCD=1
PROG="/usr/sbin/icwmpd"
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
include /lib/network
log() {
echo "${@}"|logger -t cwmp.init -p info
}
regenerate_ssl_link() {
local cert_dir
cert_dir="${1%/}"
if [ -f "${cert_dir}" ]; then
return 0
fi
# do not generate the c_rehash if its system default cert path
# ca-certificate package already generates c_rehash on compilation
[ ! -d "${cert_dir}" ] || [ "${cert_dir}" = "/etc/ssl/certs" ] && return 0
generate_links() {
local file_type="$1"
local files="${cert_dir}"/*."${file_type}"
for cfile in ${files}; do
if [ -f "${cfile}" ]; then
rehash="$(openssl x509 -hash -noout -in "${cfile}")"
if [ ! -f "${cert_dir}/${rehash}.0" ]; then
log "Generating c_rehash for ${cfile}=>${rehash}.0"
ln -s "${cfile}" "${cert_dir}/${rehash}.0"
fi
fi
done
}
generate_links "pem"
}
enable_dhcp_option43() {
local wan="${1}"
### Ask for DHCP Option 43 only if CWMP is enabled ###
local reqopts="$(uci -q get network."${wan}".reqopts)"
local proto="$(uci -q get network."${wan}".proto)"
local newreqopts=""
local option43_present=0
for ropt in $reqopts; do
case $ropt in
43) option43_present=1 ;;
*) ;;
esac
done
if [ ${option43_present} -eq 1 ]; then
return;
fi
newreqopts="$reqopts 43"
if [ "${proto}" = "dhcp" ]; then
uci -q set network."${wan}".reqopts="$newreqopts"
uci commit network
ubus call network reload
fi
}
convert_to_hex() {
local val=""
local optval="${1}"
OPTIND=1
while getopts ":" opt "-$optval"
do
temp=$(printf "%02X" "'${OPTARG:-:}")
val="${val}:${temp}"
done
echo "${val}"
}
configure_send_op125() {
local sendopt="${1}"
local intf="${2}"
local uci="${3}"
local hex_oui=""
local hex_serial=""
local hex_class=""
local oui_len=0
local serial_len=0
local class_len=0
if [ "${uci}" = "network" ]; then
local opt125="125:00:00:0D:E9"
else
if [ -z "${sendopt}" ]; then
local opt125="125,00:00:0D:E9"
else
local opt125=":00:00:0D:E9"
fi
fi
config_get oui cpe manufacturer_oui ""
if [ -z "${oui}" ]; then
oui=$(db -q get device.deviceinfo.ManufacturerOUI)
fi
oui=$(echo "${oui}" | tr 'a-f' 'A-F')
config_get serial cpe serial_number ""
if [ -z "${serial}" ]; then
serial=$(db -q get device.deviceinfo.SerialNumber)
fi
config_get class cpe product_class ""
if [ -z "${class}" ]; then
class=$(db -q get device.deviceinfo.ProductClass)
fi
oui_len=$(echo -n "${oui}" | wc -m)
serial_len=$(echo -n "${serial}" | wc -m)
class_len=$(echo -n "${class}" | wc -m)
if [ "${oui_len}" -eq 0 ] || [ "${serial_len}" -eq 0 ]; then
return 0
fi
opt125_len=$((oui_len + serial_len + class_len))
if [ "${class_len}" -gt 0 ]; then
opt125_len=$((opt125_len + 6))
else
opt125_len=$((opt125_len + 4))
fi
hex_opt125_len=$(printf "%02X" "${opt125_len}")
opt125="${opt125}:${hex_opt125_len}"
hex_oui=$(convert_to_hex "${oui}")
if [ -z "${hex_oui}" ]; then
return 0
fi
hex_oui_len=$(printf "%02X" "${oui_len}")
if [ "${uci}" = "network" ]; then
opt125="${opt125}:01:${hex_oui_len}${hex_oui}"
else
opt125="${opt125}:04:${hex_oui_len}${hex_oui}"
fi
hex_serial=$(convert_to_hex "${serial}")
if [ -z "${hex_serial}" ]; then
return 0
fi
hex_serial_len=$(printf "%02X" "${serial_len}")
if [ "${uci}" = "network" ]; then
opt125="${opt125}:02:${hex_serial_len}${hex_serial}"
else
opt125="${opt125}:05:${hex_serial_len}${hex_serial}"
fi
if [ "${class_len}" -gt 0 ]; then
hex_class=$(convert_to_hex "${class}")
if [ -z "${hex_class}" ]; then
return 0
fi
hex_class_len=$(printf "%02X" "${class_len}")
if [ "${uci}" = "network" ]; then
opt125="${opt125}:03:${hex_class_len}${hex_class}"
else
opt125="${opt125}:06:${hex_class_len}${hex_class}"
fi
fi
if [ "${uci}" = "network" ]; then
new_send_opt="$sendopt $opt125"
uci -q set network."${intf}".sendopts="$new_send_opt"
else
new_send_opt="$sendopt$opt125"
uci -q add_list dhcp."${intf}".dhcp_option="$new_send_opt"
fi
}
check_for_suboptions() {
# Check if option 4 and 5 present inside enterprise id 3561
data=$(echo "${1}" | sed 's/://g')
len=$(printf "${data}"|wc -c)
rem_len="${len}"
while [ $rem_len -gt 8 ]; do
subopt_present=0
ent_id="${data:0:8}"
ent_id=$(printf "%d\n" "0x$ent_id")
if [ $ent_id -ne 3561 ]; then
len_val=${data:8:2}
data_len=$(printf "%d\n" "0x$len_val")
# add 4 byte for ent_id and 1 byte for len
data_len=$(( data_len * 2 + 10 ))
# move ahead data to next enterprise id
data=${data:"${data_len}":"${rem_len}"}
rem_len=$(( rem_len - data_len ))
continue
fi
# read the length of enterprise data
len_val=${data:8:2}
data_len=$(printf "%d\n" "0x$len_val")
# add 4 byte for ent_id and 1 byte for len
data_len=$(( data_len * 2 + 10 ))
len_val=${data:8:2}
opt_len=$(printf "%d\n" "0x$len_val")
if [ $opt_len -eq 0 ]; then
echo ${subopt_present}
return 0
fi
# populate the option data of enterprise id
sub_data_len=$(( opt_len * 2))
# starting 10 means ahead of length field
sub_data=${data:10:"${sub_data_len}"}
# parsing of suboption of option 125
while [ $sub_data_len -gt 0 ]; do
# get the suboption id
sub_opt_id=${sub_data:0:2}
sub_opt_id=$(printf "%d\n" "0x$sub_opt_id")
case "${sub_opt_id}" in
"4") subopt_present=1
;;
"5") subopt_present=1
;;
esac
if [ ${subopt_present} -eq 1 ]; then
break;
fi
# get the length of suboption
sub_opt_len=${sub_data:2:2}
sub_opt_len=$(printf "%d\n" "0x$sub_opt_len")
sub_opt_len=$(( sub_opt_len * 2 ))
# add 2 bytes for sub_opt id and sub_opt len field
sub_opt_end=$(( sub_opt_len + 4 ))
# update the remaining sub option hex string length
sub_data_len=$((sub_data_len - sub_opt_end))
# fetch next sub option hex string
sub_data=${sub_data:${sub_opt_end}:${sub_data_len}}
done
if [ ${subopt_present} -eq 1 ]; then
break;
else
# move ahead data to next enterprise id
rem_len=$(( rem_len - $data_len ))
data=${data:"${data_len}":"${rem_len}"}
fi
done
echo ${subopt_present}
}
enable_dnsmasq_option125() {
local lan="${1}"
local send125_present=0
local opt125="125,"
local proto="$(uci -q get dhcp."${lan}".dhcpv4)"
if [ "${proto}" = "server" ]; then
opt_list="$(uci -q get dhcp."${lan}".dhcp_option)"
base_opt=""
for sopt in $opt_list; do
if [[ "$sopt" == "$opt125"* ]]; then
send125_present=$(check_for_suboptions "${sopt:4}")
base_opt="${sopt}"
break
fi
done
if [ ${send125_present} -eq 0 ]; then
uci -q del_list dhcp."${lan}".dhcp_option="${base_opt}"
configure_send_op125 "${base_opt}" "${lan}" "dhcp"
ubus call uci commit '{"config":"dhcp"}'
fi
fi
}
set_vendor_id() {
local wan="${1}"
local proto="$(uci -q get network."${wan}".proto)"
if [ "${proto}" = "dhcp" ]; then
vendorid="$(uci -q get network."${wan}".vendorid)"
if [ -z "${vendorid}" ]; then
uci -q set network."${wan}".vendorid="dslforum.org"
ubus call uci commit '{"config":"network"}'
elif [[ $vendorid != *"dslforum.org"* ]]; then
uci -q set network."${wan}".vendorid="${vendorid},dslforum.org"
ubus call uci commit '{"config":"network"}'
fi
fi
}
enable_dhcp_option125() {
local wan="${1}"
local reqopts="$(uci -q get network."${wan}".reqopts)"
local sendopts="$(uci -q get network."${wan}".sendopts)"
local proto="$(uci -q get network."${wan}".proto)"
local newreqopts=""
local newsendopts=""
local req125_present=0
local send125_present=0
local network_uci_update=0
local opt125="125:"
for ropt in $reqopts; do
case $ropt in
125) req125_present=1 ;;
*) ;;
esac
done
for sopt in $sendopts; do
if [[ "$sopt" == "$opt125"* ]]; then
send125_present=1
break
fi
done
if [ "${proto}" = "dhcp" ]; then
if [ ${req125_present} -eq 0 ]; then
newreqopts="$reqopts 125"
uci -q set network."${wan}".reqopts="$newreqopts"
network_uci_update=1
fi
if [ ${send125_present} -eq 0 ]; then
configure_send_op125 "${sendopts}" "${wan}" "network"
network_uci_update=1
fi
fi
if [ ${network_uci_update} -eq 1 ]; then
uci commit network
ubus call network reload
fi
}
wait_for_resolvfile() {
local time=$1
local tm=1
local resolvfile="$(uci -q get dhcp.@dnsmasq[0].resolvfile)"
[ -n "$resolvfile" ] || return
while [ ! -f "$resolvfile" ]; do
sleep 1
[ "$tm" -ge "$time" ] && break
tm=$((tm+1))
done
}
copy_cwmp_etc_files_to_varstate() {
mkdir -p /var/run/icwmpd
if [ -f /etc/icwmpd/icwmpd_backup_session.xml ]; then
cp -f /etc/icwmpd/icwmpd_backup_session.xml /var/run/icwmpd/ 2>/dev/null
fi
if [ -f /etc/icwmpd/dm_enabled_notify.xml ]; then
cp -f /etc/icwmpd/dm_enabled_notify /var/run/icwmpd/ 2>/dev/null
fi
}
copy_cwmp_varstate_files_to_etc() {
if [ -f /var/run/icwmpd/icwmpd_backup_session.xml ]; then
cp -f /var/run/icwmpd/icwmpd_backup_session.xml /etc/icwmpd/ 2>/dev/null
fi
if [ -f /var/run/icwmpd/dm_enabled_notify.xml ]; then
cp -f /var/run/icwmpd/dm_enabled_notify /etc/icwmpd/ 2>/dev/null
fi
# move the successful custom notify import marker to persistent storage
if [ -f /var/run/icwmpd/icwmpd_notify_import_marker ]; then
cp -f /var/run/icwmpd/icwmpd_notify_import_marker /etc/icwmpd/
fi
}
validate_acs_section()
{
uci_validate_section cwmp acs "acs" \
'passwd:string' \
'periodic_inform_enable:bool' \
'periodic_inform_interval:uinteger' \
'periodic_inform_time:string' \
'url:string' \
'dhcp_discovery:string' \
'skip_dhcp_boot_options:bool:0' \
'dhcp_url:string' \
'compression:or("GZIP","Deflate","Disabled")' \
'retry_min_wait_interval:range(1, 65535)' \
'retry_interval_multiplier:range(1000, 65535)' \
'ssl_capath:string'
}
validate_cpe_section()
{
uci_validate_section cwmp cpe "cpe" \
'interface:string' \
'default_wan_interface:string' \
'log_to_console:or("enable","disable")' \
'log_to_file:or("enable","disable")' \
'log_severity:or("EMERG", "ALERT", "CRITIC" ,"ERROR", "WARNING", "NOTICE", "INFO", "DEBUG")' \
'log_file_name:string' \
'log_max_size:uinteger' \
'userid:string' \
'passwd:string' \
'port:uinteger' \
'provisioning_code:string:""' \
'amd_version:range(1, 6)' \
'instance_mode:or("InstanceNumber","InstanceAlias")' \
'session_timeout:uinteger' \
'notification:bool' \
'exec_download:bool' \
'periodic_notify_enable:bool' \
'enable:bool:1' \
'periodic_notify_interval:uinteger' \
'fw_upgrade_keep_settings:bool'
}
validate_defaults() {
local ssl_capath enable url dhcp_url
config_load cwmp
validate_acs_section || {
log "Validation of acs section failed"
return 1;
}
if [ -z "${url}" ] && [ -z "${dhcp_url}" ]; then
log "No ACS URL is configured"
return 1
fi
ssl_capath="${ssl_capath%/}"
# Put the cert pem file in keep list
if [ -d "${ssl_capath}" ] && [ "${ssl_capath}" != "/etc/ssl/certs" ]; then
if ! grep "*.pem\|*.crt" /lib/upgrade/keep.d/icwmp; then
echo "${ssl_capath}"'/*.pem' >> /lib/upgrade/keep.d/icwmp
echo "${ssl_capath}"'/*.crt' >> /lib/upgrade/keep.d/icwmp
fi
fi
validate_cpe_section || {
log "Validation of cpe section failed"
return 1;
}
if [ "$enable" = "0" ]; then
log "CWMP service disabled"
return 1
fi
return 0;
}
boot() {
local dhcp_discovery wan_interface skip_dhcp_boot_options disable_gatewayinfo
config_load cwmp
config_get wan_interface cpe default_wan_interface "wan"
config_get disable_gatewayinfo cpe disable_gatewayinfo "0"
config_get dhcp_discovery acs dhcp_discovery "0"
config_get dhcp_discovery acs dhcp_discovery "0"
config_get skip_dhcp_boot_options acs skip_dhcp_boot_options "0"
if [ "${dhcp_discovery}" = "enable" ] || [ "${dhcp_discovery}" = "1" ]; then
if [ "${skip_dhcp_boot_options}" -ne 1 ]; then
# Set dhcp option 43 if not already configured
enable_dhcp_option43 "${wan_interface}"
# Set dhcp option 60
set_vendor_id "${wan_interface}"
fi
fi
config_get lan_interface cpe default_lan_interface ""
if [ -n "${lan_interface}" ]; then
if [ "${disable_gatewayinfo}" -ne 1 ]; then
# Set dhcp_option 125 if not already configured
enable_dhcp_option125 "${wan_interface}"
enable_dnsmasq_option125 "${lan_interface}"
fi
fi
config_get ssl_capath acs ssl_capath
if [ -n "${ssl_capath}" ]; then
regenerate_ssl_link "${ssl_capath}"
fi
# Copy backup data so that if it restart latter on, it gets the info
copy_cwmp_etc_files_to_varstate
mkdir -p /var/run/icwmpd/
touch /var/run/icwmpd/cwmp
start
}
start_service() {
sh /usr/share/icwmp/firewall_cwmp.sh
procd_open_instance icwmp
validate_defaults || {
log "Validation of defaults failed"
procd_close_instance
return 1;
}
procd_set_param command "$PROG"
procd_append_param command -b
procd_set_param respawn \
"${respawn_threshold:-5}" \
"${respawn_timeout:-10}" "${respawn_retry:-3}"
procd_close_instance
}
stop_service()
{
copy_cwmp_varstate_files_to_etc
}
reload_service() {
local ret
log "Reload service $ret"
ret="0"
validate_defaults || {
stop
start
return 0;
}
ret=$(ubus call service list '{"name":"icwmpd"}' | jsonfilter -qe '@.icwmpd.instances.icwmp.running')
if [ "$ret" != "true" ]; then
log "Reloading cwmp service ..."
stop
start
return 0
fi
tr069_status="$(ubus -t 1 call tr069 status)"
ret="$?"
if [ "$ret" = "7" ]; then
# ubus timed out may be due to uloop is busy in some task so return
log "Skipping ubus reload due to ubus timeout"
return 0
fi
status="$(echo "${tr069_status}" | jsonfilter -qe '@.cwmp.status')"
if [ "$status" = "up" ]; then
ubus -t 1 call tr069 command '{"command":"reload"}'
fi
}
service_triggers() {
procd_add_reload_trigger "cwmp"
}

View File

@@ -0,0 +1,107 @@
#!/bin/sh
. /lib/functions.sh
order_offset=2
get_firewall_zone() {
zone="$(uci show firewall|grep network|grep ${1}|cut -d. -f 2)"
zone="${zone:-wan}" # defaults to wan zone
echo "$zone"
}
cleanup_rule_firewallmngr() {
local rule_sec="$1"
config_get description "$rule_sec" "name"
[ "$description" = "Open_ACS_port" ] || return
uci -q delete firewallmngr."$rule_sec"
order_offset=0
}
reorder_previous_rule() {
local rule_sec="$1"
local order
config_get order "$rule_sec" "order"
[ -n $order ] || return
uci set firewallmngr."$rule_sec".order=$(( order + order_offset ))
}
enable="$(uci -q get cwmp.cpe.enable)"
enable="${enable:-1}"
if [ "$enable" -eq 0 ]; then
exit 0;
fi
wan="$(uci -q get cwmp.cpe.default_wan_interface)"
wan="${wan:-wan}"
zone_name="$(get_firewall_zone $wan)"
active_level=$(uci -q get firewallmngr.firewall.advanced_level)
active_chain=$(uci -q get firewallmngr."$active_level".chain)
port=$(uci -q get cwmp.cpe.port)
port="${port:-7547}"
incoming_rule=$(uci -q get cwmp.cpe.incoming_rule|awk '{print tolower($0)}')
incoming_rule="${incoming_rule:-port_only}"
ipaddr=$(uci -c /var/state -q get icwmp.acs.ip)
ip6addr=$(uci -c /var/state -q get icwmp.acs.ip6)
config_load firewallmngr
config_foreach cleanup_rule_firewallmngr "rule"
config_foreach reorder_previous_rule "rule"
rule_sec=$(uci add firewallmngr rule)
rule1_sec=$(uci add firewallmngr rule)
uci set firewallmngr."$rule_sec".family="4"
uci set firewallmngr."$rule1_sec".family="6"
uci set firewallmngr."$rule_sec".src="$zone_name"
uci set firewallmngr."$rule1_sec".src="$zone_name"
uci set firewallmngr."$rule_sec".chain="$active_chain"
uci set firewallmngr."$rule1_sec".chain="$active_chain"
uci set firewallmngr."$rule_sec".proto="6"
uci set firewallmngr."$rule1_sec".proto="6"
uci set firewallmngr."$rule_sec".order="1"
uci set firewallmngr."$rule1_sec".order="2"
uci reorder firewallmngr."$rule_sec"=1
uci reorder firewallmngr."$rule1_sec"=2
# default incoming rule is Port only
if [ "${incoming_rule}" = "ip_only" ]; then
if [ -n "${ipaddr}" ]; then
uci -q set firewallmngr."$rule_sec".source_ip=${ipaddr}
fi
if [ -n "${ip6addr}" ]; then
uci -q set firewallmngr."$rule1_sec".source_ip=${ip6addr}
fi
elif [ "${incoming_rule}" = "port_only" ]; then
if [ -n "${port}" ]; then
uci -q set firewallmngr."$rule_sec".dest_port=${port}
uci -q set firewallmngr."$rule1_sec".dest_port=${port}
fi
else
if [ -n "${ipaddr}" ]; then
uci -q set firewallmngr."$rule_sec".source_ip=${ipaddr}
fi
if [ -n "${ip6addr}" ]; then
uci -q set firewallmngr."$rule1_sec".source_ip=${ip6addr}
fi
if [ -n "${port}" ]; then
uci -q set firewallmngr."$rule_sec".dest_port=${port}
uci -q set firewallmngr."$rule1_sec".dest_port=${port}
fi
fi
uci set firewallmngr."$rule_sec".name="Open_ACS_port"
uci set firewallmngr."$rule1_sec".name="Open_ACS_port"
uci set firewallmngr."$rule_sec".target="Accept"
uci set firewallmngr."$rule1_sec".target="Accept"
uci set firewallmngr."$rule_sec".enable="1"
uci set firewallmngr."$rule1_sec".enable="1"
ubus call uci commit '{"config":"firewallmngr"}'

View File

@@ -49,7 +49,21 @@ define Package/mcastmngr/install
ifneq ($(CONFIG_TARGET_brcmbca),)
$(CP) ./files/broadcom/* $(1)/
else
$(CP) ./files/linux/* $(1)/
$(INSTALL_DIR) $(1)/lib
$(INSTALL_DIR) $(1)/lib/mcast
$(INSTALL_DIR) $(1)/usr
$(INSTALL_DIR) $(1)/usr/libexec
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/linux/usr/libexec/rpcd/mcast $(1)/usr/libexec/rpcd/
$(INSTALL_BIN) ./files/linux/etc/uci-defaults/60-mcast_config_generate $(1)/etc/uci-defaults/
ifneq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
$(INSTALL_BIN) ./files/linux/etc/firewall.mcast $(1)/etc/
$(INSTALL_BIN) ./files/linux/lib/mcast/linux.sh $(1)/lib/mcast/
else
$(INSTALL_BIN) ./files/linux/lib/mcast/mcast_backend_firewallmngr/linux.sh $(1)/lib/mcast/
endif
endif
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/bbf_plugin/libmcast_bbf.so $(1) $(PKG_NAME)
endef

View File

@@ -0,0 +1,468 @@
#!/bin/sh
. /lib/mcast/common.sh
. /lib/functions/network.sh
include /lib/network
CONFFILE=
PROG_EXE=/usr/sbin/mcproxy
PROG_PARAMS=
PROG_PARAMS_SEPARATOR=:
snooping_bridges=
__device_is_bridge() {
local device="$2"
local devsec__="$(uci show network | grep -F ".name='$device'" | cut -d'.' -f2)"
local sectype="$(uci -q get network.$devsec__)"
local devtype="$(uci -q get network.$devsec__.type)"
[ "$sectype" != "device" -o "$devtype" != "bridge" ] && return 1
eval "$1=$devsec__"
}
device_is_bridge() {
local device="$1"
local devsec=
__device_is_bridge devsec "$device" || return 1
}
device_ports() {
local device="$1"
local devsec=
if __device_is_bridge devsec "$device"; then
echo "$(uci get network.$devsec.ports)"
else
echo "$device"
fi
}
device_has_ip() {
local protocol="$1"
local device="$2"
# Read the openwrt interface for the device.
# Device can have multiple logical interfaces like wan and wan6
# but same l3 device
local ifaces=$(ubus call network.interface dump | jsonfilter -e "@.interface[@.device='$device'].interface")
for iface in $ifaces; do
local ip=
case "$protocol" in
"igmp") network_get_ipaddr ip "$iface" ;;
"mld") network_get_ipaddr6 ip "$iface" ;;
esac
[ -n "$ip" ] && return
done
return 1
}
config_mcproxy_interfaces() {
local protocol="$1"
local upstreams="$2"
local downstreams="$3"
local exceptions="$4"
if [ -z "$upstreams" ] || [ -z "$downstreams" ]; then
return 1
fi
local str_up=""
for upstream in $upstreams; do
device_has_ip "$protocol" "$upstream" || continue
str_up="$str_up \"$upstream\""
done
[ -z "$str_up" ] && return 1
local str_down=""
for downstream in $downstreams; do
device_has_ip "$protocol" "$downstream" || continue
str_down="$str_down \"$downstream\""
done
[ -z "$str_down" ] && return 1
echo -e "pinstance main:$str_up ==>$str_down;\n" >> $CONFFILE
for excp in $exceptions; do
local filter=""
case $excp in
*/*)
ip_start="$(ipcalc.sh $excp | grep IP | awk '{print substr($0,4)}')"
ip_end="$(ipcalc.sh $excp | grep BROADCAST | awk '{print substr($0,11)}')"
filter="$filter ($ip_start - $ip_end | *)"
;;
*)
filter="$filter ($excp | *)"
;;
esac
for upstream in $str_up; do
echo "pinstance main upstream $upstream in blacklist table{$filter };" >> $CONFFILE
echo "pinstance main upstream $upstream out blacklist table{$filter };" >> $CONFFILE
done
for downstream in $str_down; do
echo "pinstance main downstream $downstream in blacklist table{$filter };" >> $CONFFILE
echo "pinstance main downstream $downstream out blacklist table{$filter };" >> $CONFFILE
done
done
}
config_sysfs_mcast_snooping() {
local downstreams="$1"
local snooping="$2"
for downstream in $downstreams; do
if device_is_bridge "$downstream"; then
echo 0 > /sys/class/net/$downstream/bridge/multicast_snooping
echo $snooping > /sys/class/net/$downstream/bridge/multicast_snooping
fi
done
}
config_sysfs_mcast_fastleave() {
local downstreams="$1"
local fastleave="$2"
local prt
for downstream in $downstreams; do
for prt in $(device_ports $downstream); do
if [ -f /sys/class/net/$prt/brport/multicast_fast_leave ]; then
echo $fastleave > /sys/class/net/$prt/brport/multicast_fast_leave
fi
done
done
}
config_sysfs_mcast_version() {
local protocol="$1"
local interfaces="$2"
local version="$3"
for iface in $interfaces; do
echo $version > /sys/class/net/$iface/bridge/multicast_"$protocol"_version
done
}
config_sysfs_mcast_robustness() {
local interfaces="$1"
local robustness="$2"
for iface in $interfaces; do
echo $robustness > /sys/class/net/$iface/bridge/multicast_last_member_count
done
}
config_sysfs_mcast_query_interval() {
local interfaces="$1"
local query_interval="$2"
for iface in $interfaces; do
echo $query_interval > /sys/class/net/$iface/bridge/multicast_query_interval
done
}
config_sysfs_mcast_q_resp_interval() {
local interfaces="$1"
local q_resp_interval="$2"
for iface in $interfaces; do
echo $q_resp_interval > /sys/class/net/$iface/bridge/multicast_query_response_interval
done
}
config_sysfs_mcast_last_mem_q_int() {
local interfaces="$1"
local last_mem_q_int="$2"
for iface in $interfaces; do
echo $last_mem_q_int > /sys/class/net/$iface/bridge/multicast_last_member_interval
done
}
config_sysfs_mcast_flood() {
local downstreams=$1
local mcast_mode=$2
local prt
local mcast_flood=
if [ $mcast_mode == "2" ]; then # disable mcast flood
mcast_flood=0
else
mcast_flood=1
fi
for downstream in $downstreams; do
for prt in $(device_ports $downstream); do
if [ -f /sys/class/net/$prt/brport/multicast_flood ]; then
echo $mcast_flood > /sys/class/net/$prt/brport/multicast_flood
fi
done
done
}
config_snooping_mode() {
local interfaces="$1"
local snooping="$2"
# snooping_mode:
# 0 - snooping is disabled
# 1 - multicast flood is enabled
# 2 - multicast flood is disabled
[ -z "$snooping_mode" ] && snooping_mode=2
if [ "$snooping_mode" == 0 ]; then
config_sysfs_mcast_snooping "$interfaces" 0
else
config_sysfs_mcast_snooping "$interfaces" 1
fi
config_sysfs_mcast_flood "$interfaces" "$snooping_mode"
}
config_mcproxy_instance() {
local protocol="$1"
local version="$2"
local robustness=
local query_interval=
local q_resp_interval=
local last_mem_q_int=
local fast_leave=0
local exceptions=
local upstreams=
local downstreams=
local mcast_mode=2 # default value 2 is for blocking mode
CONFFILE=/var/etc/mcproxy_"$protocol".conf
rm -f $CONFFILE
touch $CONFFILE
if [ "$protocol" == "igmp" ]; then
case "$version" in
[1-3])
echo -e "protocol IGMPv${version};\n" >> $CONFFILE
;;
*)
echo -e "protocol IGMPv2;\n" >> $CONFFILE
;;
esac
robustness=$igmp_p_robustness
query_interval=$igmp_query_interval
q_resp_interval=$igmp_q_resp_interval
last_mem_q_int=$igmp_last_mem_q_int
fast_leave=$igmp_fast_leave
exceptions=$igmp_p_exceptions
upstreams=$igmp_p_up_interfaces
downstreams=$igmp_p_down_interfaces
mcast_mode=$igmp_p_mode
elif [ "$protocol" == "mld" ]; then
case "$version" in
[1-2])
echo -e "protocol MLDv${version};\n" >> $CONFFILE
;;
*)
echo -e "protocol MLDv2;\n" >> $CONFFILE
;;
esac
robustness=$mld_p_robustness
query_interval=$mld_query_interval
q_resp_interval=$mld_q_resp_interval
last_mem_q_int=$mld_last_mem_q_int
fast_leave=$mld_fast_leave
exceptions=$mld_p_exceptions
upstreams=$mld_p_up_interfaces
downstreams=$mld_p_down_interfaces
mcast_mode=$mld_p_mode
fi
[ -n "$max_groups" ] && echo -e "max_groups $max_groups;" >> $CONFFILE
[ -n "$robustness" ] && echo -e "rv $robustness;" >> $CONFFILE
[ -n "$query_interval" ] && echo -e "qi $query_interval;" >> $CONFFILE
[ -n "$q_resp_interval" ] && echo -e "qri $q_resp_interval;" >> $CONFFILE
[ -n "$last_mem_q_int" ] && echo -e "lmqi $last_mem_q_int;" >> $CONFFILE
[ -n "$fast_leave" ] && echo -e "fastleave $fast_leave;\n" >> $CONFFILE
config_mcproxy_interfaces "$protocol" "$upstreams" "$downstreams" "$exceptions" || return
# for snooping to work we should enable it on the bridge, doing it from
# here instead of from inside network config
if [ "$downstreams" != "$snooping_bridges" ]; then
if [ "$mcast_mode" == "0" ]; then
config_sysfs_mcast_snooping "$downstreams" 0
else
config_sysfs_mcast_snooping "$downstreams" 1
fi
[ -n $fast_leave ] &&
config_sysfs_mcast_fastleave "$downstreams" "$fast_leave"
config_sysfs_mcast_flood "$downstreams" "$mcast_mode"
fi
PROG_PARAMS="${PROG_PARAMS} -f ${CONFFILE}${PROG_PARAMS_SEPARATOR}"
}
disable_snooping_iface() {
local iface="$(uci -q get network.$1.name)"
config_sysfs_mcast_snooping "$iface" 0
}
disable_snooping() {
config_load network
config_foreach disable_snooping_iface device
}
config_snooping() {
local protocol="$1"
local version=
local robustness=
local query_interval=
local q_resp_interval=
local last_mem_q_int=
local fast_leave=0
local snooping_mode=
local interfaces=
local HZ=100
local all_interfaces=
if [ "$protocol" == "igmp" ]; then
all_interfaces=$igmp_s_iface
elif [ "$protocol" == "mld" ]; then
all_interfaces=$mld_s_iface
fi
for iface in $all_interfaces; do
device_is_bridge "$iface" || continue
interfaces="$interfaces $iface"
done
[ -z "$interfaces" ] && return
snooping_bridges="$interfaces"
if [ "$protocol" == "igmp" ]; then
case "$igmp_s_version" in
[1-3])
version="$igmp_s_version"
;;
*)
version="2"
;;
esac
robustness=$igmp_s_robustness
query_interval=$(( igmp_s_query_interval * HZ ))
q_resp_interval=$(( igmp_s_q_resp_interval * HZ / 10 ))
last_mem_q_int=$(( igmp_s_last_mem_q_int * HZ / 10 ))
fast_leave=$igmp_s_fast_leave
snooping_mode=$igmp_s_mode
elif [ "$protocol" == "mld" ]; then
case "$mld_s_version" in
[1-2])
version="$mld_s_version"
;;
*)
version="2"
;;
esac
robustness=$mld_s_robustness
query_interval=$(( mld_s_query_interval * HZ ))
q_resp_interval=$(( mld_s_q_resp_interval * HZ / 10 ))
last_mem_q_int=$(( mld_s_last_mem_q_int * HZ / 10 ))
fast_leave=$mld_s_fast_leave
snooping_mode=$mld_s_mode
fi
config_snooping_mode "$interfaces" "$snooping_mode"
[ -n "$version" ] && config_sysfs_mcast_version "$protocol" "$interfaces" "$version"
[ -n "$robustness" ] && config_sysfs_mcast_robustness "$interfaces" "$robustness"
[ -n "$query_interval" ] && config_sysfs_mcast_query_interval "$interfaces" "$query_interval"
[ -n "$q_resp_interval" ] && config_sysfs_mcast_q_resp_interval "$interfaces" "$q_resp_interval"
[ -n "$last_mem_q_int" ] && config_sysfs_mcast_last_mem_q_int "$interfaces" "$last_mem_q_int"
[ -n "$fast_leave" ] && config_sysfs_mcast_fastleave "$interfaces" "$fast_leave"
}
config_mcproxy() {
disable_snooping
if [ "$igmp_p_enable" == "1" ]; then
config_mcproxy_instance igmp "$igmp_p_version"
elif [ "$igmp_s_enable" == "1" ]; then
config_snooping igmp "$igmp_s_version"
fi
if [ "$mld_p_enable" == "1" ]; then
config_mcproxy_instance mld "$mld_p_version"
elif [ "$mld_s_enable" == "1" ]; then
config_snooping mld "$mld_s_version"
fi
}
setup_mcast_mode() {
:
}
remove_mcast_rules() {
config_get name "$1" name
if [ "$name" = "Allow-Multicast-UDP" ]; then
uci delete firewallmngr."$1"
fi
}
create_mcast_firewallngr_rules() {
local src="wan"
local dst="lan"
local dest_ip="224.0.0.0/240.0.0.0"
local name="Allow-Multicast-UDP"
local target="accept"
local active_chain=""
firewallmngr_get_active_chain() {
config_get creator "$1" creator
[ "$creator" = "PortMapping" ] && return
config_get enable "$1" enable
if [ -n "$enable" ] && [ "$enable" = "1" ]; then
config_get active_chain "$1" name
fi
}
config_load firewallmngr
config_foreach remove_mcast_rules rule
sec=$(uci add firewallmngr rule)
uci set firewallmngr."$sec".enable="1"
uci set firewallmngr."$sec".chain="$active_chain"
uci set firewallmngr."$sec".name="$name"
uci set firewallmngr."$sec".src="$src"
uci set firewallmngr."$sec".dest="$dst"
uci set firewallmngr."$sec".dest_ip="$dest_ip"
uci set firewallmngr."$sec".family="4"
uci set firewallmngr."$sec".proto="17"
uci set firewallmngr."$sec".target="$target"
uci rename firewallmngr."$sec"="fwmngr_rule_mcast"
uci commit firewallmngr
}
configure_mcast() {
create_mcast_firewallngr_rules
config_global_params "set_max_groups_and_sources"
read_mcast_snooping_params
read_mcast_proxy_params
config_mcproxy
if [ -z "${PROG_PARAMS}" ]; then
exit 0
fi
}

View File

@@ -52,9 +52,13 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/twampd $(1)/usr/sbin/
$(INSTALL_DATA) ./files/etc/config/twamp $(1)/etc/config/twamp
ifneq ($(CONFIG_FIREWALLMNGR_BACKEND_FIREWALLMNGR),y)
$(INSTALL_BIN) ./files/etc/init.d/twampd $(1)/etc/init.d/twampd
$(INSTALL_BIN) ./files/etc/firewall.twamp $(1)/etc/firewall.twamp
$(INSTALL_BIN) ./files/etc/uci-defaults/92-twampfirewall $(1)/etc/uci-defaults/92-twampfirewall
else
$(INSTALL_BIN) ./files/etc/twamp_backend_firewallmngr/init.d/twampd $(1)/etc/init.d/twampd
endif
$(INSTALL_BIN) ./files/etc/uci-defaults/93-twamp_fix_reflector $(1)/etc/uci-defaults/93-twamp_fix_reflector
$(BBFDM_INSTALL_CORE_PLUGIN) $(PKG_BUILD_DIR)/libtwamp.so $(1)
endef

View File

@@ -0,0 +1,31 @@
#!/bin/sh /etc/rc.common
# TWAMP Reflector software
# Copyright (C) 2020-2022 IOPSYS Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
START=99
STOP=10
. /lib/fwmngr/fwmngr_twamp.sh
USE_PROCD=1
PROG="/usr/sbin/twampd"
start_service() {
local enable=$(uci -q get twamp.twamp.enable)
if [ "$enable" = "1" ]; then
procd_open_instance
procd_set_param command "$PROG"
procd_set_param respawn "3" "7" "0"
procd_close_instance
fi
handle_twamp_rules
}
reload_service() {
stop
start
}
service_triggers() {
procd_add_reload_trigger twamp
}