Compare commits

...

5 Commits

Author SHA1 Message Date
Amit Kumar
67310d7017 firewallmngr: handled upgrade scenario 2024-05-10 18:07:27 +05:30
Amit Kumar
bcecfab3e5 firewallmngr: firewall config handling on upgrade 2024-05-06 10:38:26 +05:30
Amit Kumar
54f950fed8 firewallmngr: default forwarding rule handled 2024-04-19 11:47:55 +05:30
Amit Kumar
084ea36a62 firewallmngr: logical name to default rule section 2024-04-18 10:31:07 +05:30
Rahul Thakur
a04c53b03e firewallmngr: handling for firewallmngr
Default config for firewall manager, this config is in sync
with the default firewall uci config of iowrt.
Added library function that read teh uci file of firewallmngr.
convert it to generate firewall uci file.
added bbf code for Device.Firewall. as microservice
handling for Device.NAT object
concept to add porttrigger in firewallmngr
firewall include section handling
2024-04-17 11:08:25 +05:30
26 changed files with 4559 additions and 135 deletions

69
firewallmngr/Makefile Normal file
View File

@@ -0,0 +1,69 @@
#
# Copyright (C) 2022-2024 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=firewallmngr
PKG_VERSION:=1.0.0
#LOCAL_DEV:=1
#ifneq ($(LOCAL_DEV),1)
#PKG_SOURCE_PROTO:=git
#PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/firewallmngr.git
#PKG_SOURCE_VERSION:=4f429e25c6e7a69c5171186731bc560befa5a660
#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
#PKG_MIRROR_HASH:=skip
#endif
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include ../bbfdm/bbfdm.mk
#MAKE_PATH:=src
define Package/firewallmngr
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=TRx69
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +firewall
TITLE:=Package to add Device.Firewall data model support.
endef
define Package/firewallmngr/description
Package to add Device.Firewall data model support.
endef
#ifeq ($(LOCAL_DEV),0)
#define Build/Prepare
# $(CP) -rf ./src/* $(PKG_BUILD_DIR)/
#endef
#endif
define Package/firewallmngr/install
$(INSTALL_DIR) $(1)/etc/firewallmngr
$(INSTALL_DIR) $(1)/etc/firewallmngr/plugins
$(INSTALL_DIR) $(1)/etc/config
$(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/etc/uci-defaults/00-firewallmngr $(1)/etc/uci-defaults/00-firewallmngr
$(INSTALL_DATA) ./files/etc/config/firewallmngr $(1)/etc/config/
$(INSTALL_BIN) ./files/etc/init.d/firewallmngr $(1)/etc/init.d/
$(INSTALL_DATA) ./files/lib/fwmngr/fwmngr.sh $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/lib/fwmngr/fwmngr_functions.sh $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/lib/fwmngr/uci_migration.sh $(1)/lib/fwmngr/
$(INSTALL_BIN) ./files/lib/fwmngr/is_intf_bridge $(1)/lib/fwmngr/
$(INSTALL_BIN) ./files/lib/fwmngr/firewallmngr_preconfig $(1)/lib/fwmngr/
$(INSTALL_DATA) ./files/lib/fwmngr/fwmngr_twamp.sh $(1)/lib/fwmngr/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/firewallmngr $(1)/usr/sbin
$(call BbfdmInstallPluginInMicroservice, $(1)/etc/firewallmngr,./files/etc/firewallmngr/firewallmngr.json)
$(call BbfdmInstallPluginInMicroservice, $(1)/etc/firewallmngr/plugins,$(PKG_BUILD_DIR)/libbbffirewall.so)
$(call BbfdmInstallMicroServiceInputFile,$(1),./files/etc/bbfdm/micro_services/firewallmngr.json)
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_interface '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 '1'
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'

File diff suppressed because it is too large Load Diff

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,71 @@
#!/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
[ -z "$order" ] && return
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
[ -n "$order" ] && return
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,265 @@
#!/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"
}
configure_cwmp_rule_option() {
# default incoming rule is Port only
local rule_sec="$1"
local enabled="$2"
local incoming_rule="$3"
local ipaddr="$4"
local family="$5"
local port="$6"
local zone_name="$7"
uci set firewall."$rule_sec".enabled="$enabled"
uci set firewall."$rule_sec".src="$zone_name"
if [ "$incoming_rule" == "ip_only" ]; then
uci set firewall."$rule_sec".family="$family"
uci set firewall."$rule_sec".src_ip="$ipaddr"
elif [ "$incoming_rule" == "port_only" ]; then
if [ -n "${port}" ]; then
uci set firewall."$rule_sec".dest_port="$port"
fi
else
uci set firewall."$rule_sec".family="$family"
uci set firewall."$rule_sec".src_ip="$ipaddr"
if [ -n "${port}" ]; then
uci set firewall."$rule_sec".dest_port="$port"
fi
fi
uci set firewall."$rule_sec".name="Open_ACS_port"
uci set firewall."$rule_sec".target="ACCEPT"
}
handle_cwmp_rules() {
get_firewall_zone() {
zone="$(uci show firewall|grep network|grep ${1}|cut -d. -f 2)"
zone="${zone:-wan}" # defaults to wan zone
echo "$zone"
}
enable="$(uci -q get cwmp.cpe.enable)"
enable="${enable:-1}"
if [ "$enable" -eq 0 ]; then
return
fi
wan="$(uci -q get cwmp.cpe.default_wan_interface)"
wan="${wan:-wan}"
zone_name="$(get_firewall_zone $wan)"
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)
rule_sec=$(uci add "firewall" "rule")
configure_cwmp_rule_option "$rule_Sec" "$enable" "$incoming_rule" "$ipaddr" "ipv4" "$port" "$zone_name"
uci -q reorder firewall."$rule_sec"=0
rule_sec=$(uci add "firewall" "rule")
configure_cwmp_rule_option "$rule_Sec" "$enable" "$incoming_rule" "$ip6addr" "ipv6" "$port" "$zone_name"
uci -q reorder firewall."$rule_sec"=1
}
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
touch /tmp/amit_debug
generate_firewall_config
}

View File

@@ -0,0 +1,625 @@
#!/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".enabled="$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"
if [ "$target" = "Accept" ] || [ "$target" = "accept" ] || [ "$target" = "Reject" ] || [ "$target" = "reject" ] || [ "$target" = "Drop" ] || [ "$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}/$source_mask"
config_get dest_ip "$rule" "dest_ip"
config_get dest_mask "$rule" "dest_mask"
[ -n "$dest_mask" ] && dest_ip="${dest_ip}/$dest_mask"
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
}

34
firewallmngr/src/Makefile Normal file
View File

@@ -0,0 +1,34 @@
CC=gcc
PROG = firewallmngr
LIB_BBF = libbbffirewall.so
SRC_DIR = .
OBJS = $(addprefix $(SRC_DIR)/, firewallmngr.o)
LIB_OBJS = ./bbf_plugin/firewall.o
DIAG_CFLAGS = -Wall -Wshadow -Wdouble-promotion -Wformat=2 -Wundef -fno-common -Wstrict-prototypes -Wno-declaration-after-statement
PROG_CFLAGS = $(CFLAGS) $(DIAG_CFLAGS) -Werror -fstrict-aliasing -fPIC
# MUSL has the following issue in snprintf, so it is ignored:
PROG_CFLAGS += -Wno-format-nonliteral
PROG_LDFLAGS = $(LDFLAGS)
PROG_LIBS += -luci -lubus -lubox -ljson-c -lblobmsg_json
%.o: %.c
$(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $<
.PHONY: all clean
all: $(PROG) $(LIB_BBF)
$(PROG): $(OBJS)
$(CC) $(PROG_LDFLAGS) -o $@ $^ $(PROG_LIBS)
$(LIB_BBF): $(LIB_OBJS)
$(CC) $(PROG_LDFLAGS) -shared -o $@ $^
clean:
rm -f *.o $(PROG)
make -C bbf_plugin clean
.PHONY: clean

View File

@@ -0,0 +1,21 @@
LIB_FIREWALL := libfirewallrule.so
OBJS := firewall.o
LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fstrict-aliasing
LIB_LDFLAGS = $(LDFLAGS)
FPIC := -fPIC
.PHONY: all
%.o: %.c
$(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $<
all: $(LIB_FIREWALL)
$(LIB_FIREWALL): $(OBJS)
$(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^
clean:
rm -f *.o $(LIB_FIREWALL)

View File

@@ -0,0 +1,820 @@
/*
* Copyright (C) 2023 iopsys Software Solutions AB
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation
*
* Author: Husaam Mehdi <husaam.mehdi@iopsys.eu>
*/
#include <libbbfdm-api/dmcommon.h>
#include <libbbfdm_api.h>
/*************************************************************
* UTILITY METHODS
**************************************************************/
static int browseFirewallChainRuleInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
{
struct dm_data *p = NULL;
LIST_HEAD(dup_list);
char *inst = NULL;
char *parent_chain = NULL;
if (!(((struct dm_data *)prev_data)->config_section)) {
return 0;
}
bbf_uci_get_value_by_section(((struct dm_data *)prev_data)->config_section, "name", &parent_chain);
if (!parent_chain) {
return 0;
}
synchronize_specific_config_sections_with_dmmap("firewallmngr", "rule", "dmmap_firewallmngr", &dup_list);
list_for_each_entry(p, &dup_list, list) {
char *current_chain = NULL;
bbf_uci_get_value_by_section(p->config_section, "chain", &current_chain);
if (!current_chain) {
continue;
}
if (DM_STRCMP(current_chain, parent_chain)) {
continue;
}
inst = handle_instance(dmctx, parent_node, p->dmmap_section, "firewall_rule_instance", "firewall_rule_alias");
if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p, inst) == DM_STOP)
break;
}
free_dmmap_config_dup_list(&dup_list);
return 0;
}
/*************************************************************
* ADD & DEL OBJ
**************************************************************/
static int addObjFirewallChainRule(char *refparam, struct dmctx *ctx, void *data, char **instance)
{
struct uci_section *s = NULL;
struct uci_section *dmmap_firewall_rule = NULL;
char creation_date[32] = {0};
char rule_name[32] = {0};
char *parent_chain = NULL;
time_t now = time(NULL);
if (!((struct dm_data *)data)->config_section)
return 0;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "name", &parent_chain);
if (!parent_chain || !DM_STRLEN(parent_chain))
return 0;
snprintf(rule_name, sizeof(rule_name), "%s_rule_%s", section_name(((struct dm_data *)data)->config_section), *instance);
// Add rule section
dmuci_add_section("firewallmngr", "rule", &s);
dmuci_rename_section_by_section(s, rule_name);
dmuci_set_value_by_section(s, "name", rule_name);
dmuci_set_value_by_section(s, "chain", parent_chain);
dmuci_set_value_by_section(s, "target", "0");
dmuci_set_value_by_section(s, "enable", "0");
dmuci_set_value_by_section(s, "proto", "0");
// Add rule section in dmmap_firewallmngr file
dmuci_add_section_bbfdm("dmmap_firewallmngr", "rule", &dmmap_firewall_rule);
dmuci_set_value_by_section(dmmap_firewall_rule, "section_name", rule_name);
dmuci_set_value_by_section(dmmap_firewall_rule, "firewall_rule_instance", *instance);
strftime(creation_date, sizeof(creation_date), "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
dmuci_set_value_by_section(dmmap_firewall_rule, "creation_date", creation_date);
return 0;
}
static int delObjFirewallChainRule(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)
{
switch (del_action) {
case DEL_INST:
char buf[32] = {0};
char *rule_name = NULL;
char *rule_order = NULL;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "order", &rule_order);
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "name", &rule_name);
snprintf(buf, sizeof(buf), "%lu", DM_STRTOUL(rule_order) + 1);
// Remove section
dmuci_delete_by_section(((struct dm_data *)data)->config_section, NULL, NULL);
// Remove section in dmmap file
dmuci_delete_by_section(((struct dm_data *)data)->dmmap_section, NULL, NULL);
break;
case DEL_ALL:
//TODO
break;
}
return 0;
}
/*************************************************************
* GET & SET PARAM
**************************************************************/
static int get_FirewallChain_RuleNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
int cnt = get_number_of_entries(ctx, data, instance, browseFirewallChainRuleInst);
dmasprintf(value, "%d", cnt);
return 0;
}
static int get_FirewallChainRule_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "enable", "0");
return 0;
}
static int set_FirewallChainRule_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
break;
case VALUESET:
bool b = true;
string_to_bool(value, &b);
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "enable", value);
break;
}
return 0;
}
static int get_FirewallChainRule_Status(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "status", "Enabled");
return 0;
}
static int get_FirewallChainRule_Order(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "order", "");
return 0;
}
static int set_FirewallChainRule_Order(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1",NULL}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "order", value);
break;
}
return 0;
}
static int get_FirewallChainRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
return bbf_get_alias(ctx, ((struct dm_data *)data)->dmmap_section, "firewall_rule_alias", instance, value);
}
static int set_FirewallChainRule_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, "firewall_rule_alias", instance, value);
}
static int get_FirewallChainRule_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "name", "");
return 0;
}
static int set_FirewallChainRule_Description(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 256, NULL, NULL))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "name", value);
break;
}
return 0;
}
static int get_FirewallChainRule_Target(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *target_arr[] = {"Drop", "Accept", "Reject", "Return", "TargetChain", NULL};
char *target = NULL;
target = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "target", "0");
if (target) {
int c = atoi(target);
if (c >=0 && c < 5)
*value = target_arr[c];
else
*value = "Drop";//TODO verify default behaviour
}
return 0;
}
static int set_FirewallChainRule_Target(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *target_arr[] = {"Drop", "Accept", "Reject", "Return", "TargetChain", NULL};
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, -1, target_arr, NULL))
return FAULT_9007;
break;
case VALUESET:
int i = 0;
bool found = false;
for (i = 0; i < 5; i++) {
if (!DM_STRCMP(value, target_arr[i])) {
found = true;
break;
}
}
if (found) {
char str[2] = {0};
snprintf(str, 2, "%d", i);
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "target", str);
} else {
// TODO correct default behaviour?
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "target", "DROP");
}
break;
}
return 0;
}
static int get_FirewallChainRule_Log(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "log", "0");
return 0;
}
static int set_FirewallChainRule_Log(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
break;
case VALUESET:
bool b = false;
string_to_bool(value, &b);
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "log", b ? "1" : "0");
break;
}
return 0;
}
static int get_FirewallChainRule_CreationDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "creation_date", "0001-01-01T00:00:00Z");
return 0;
}
static int get_FirewallChainRule_ExpiryDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *expiry_date = NULL;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "expiry", &expiry_date);
if (expiry_date && DM_STRLEN(expiry_date) != 0 && DM_STRTOL(expiry_date) > 0) {
char expiry[sizeof "AAAA-MM-JJTHH:MM:SSZ"];
time_t time_value = DM_STRTOL(expiry_date);
strftime(expiry, sizeof expiry, "%Y-%m-%dT%H:%M:%SZ", gmtime(&time_value));
*value = dmstrdup(expiry);
} else {
*value = "9999-12-31T23:59:59Z";
}
return 0;
}
static int set_FirewallChainRule_ExpiryDate(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char expiry_date[16];
struct tm tm;
switch (action) {
case VALUECHECK:
if (bbfdm_validate_dateTime(ctx, value))
return FAULT_9007;
break;
case VALUESET:
strptime(value, "%Y-%m-%dT%H:%M:%SZ", &tm);
snprintf(expiry_date, sizeof(expiry_date), "%lld", (long long)timegm(&tm));
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "expiry", expiry_date);
break;
}
return 0;
}
static int get_FirewallChainRule_SourceInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *linker = NULL;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "src", &linker);
bbf_get_reference_param("Device.IP.Interface.", "Name", linker, value);
return 0;
}
static int set_FirewallChainRule_SourceInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *allowed_objects[] = {"Device.IP.Interface.", NULL};
struct dm_reference reference = {0};
bbf_get_reference_args(value, &reference);
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL)) {
return FAULT_9007;
}
if (dm_validate_allowed_objects(ctx, &reference, allowed_objects))
return FAULT_9007;
break;
case VALUESET:
if (DM_STRLEN(reference.value)) {
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src", reference.value);
}
break;
}
return 0;
}
static int get_FirewallChainRule_SourceAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_all_interfaces", "0");
return 0;
}
static int set_FirewallChainRule_SourceAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
break;
case VALUESET:
bool b = false;
string_to_bool(value, &b);
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_all_interfaces", b ? "1" : "0");
break;
}
return 0;
}
static int get_FirewallChainRule_DestInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *linker = NULL;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "dest", &linker);
bbf_get_reference_param("Device.IP.Interface.", "Name", linker, value);
return 0;
}
static int set_FirewallChainRule_DestInterface(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char *allowed_objects[] = {"Device.IP.Interface.", NULL};
struct dm_reference reference = {0};
bbf_get_reference_args(value, &reference);
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, reference.path, -1, 256, NULL, NULL)) {
return FAULT_9007;
}
if (dm_validate_allowed_objects(ctx, &reference, allowed_objects))
return FAULT_9007;
break;
case VALUESET:
if (DM_STRLEN(reference.value)) {
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest", reference.value);
}
break;
}
return 0;
}
static int get_FirewallChainRule_DestAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_all_interfaces", "0");
return 0;
}
static int set_FirewallChainRule_DestAllInterfaces(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
break;
case VALUESET:
bool b = false;
string_to_bool(value, &b);
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_all_interfaces", b ? "1" : "0");
break;
}
return 0;
}
static int get_FirewallChainRule_IPVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *ipversion = NULL;
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "family", &ipversion);
if (!ipversion) {
*value = "-1";
return 0;
}
if (strcasecmp(ipversion, "ipv4") == 0) {
*value = "4";
} else if (strcasecmp(ipversion, "ipv6") == 0) {
*value = "6";
} else {
*value = "-1";
}
return 0;
}
static int set_FirewallChainRule_IPVersion(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","15"}}, 1))
return FAULT_9007;
break;
case VALUESET:
if (DM_LSTRCMP(value, "4") == 0)
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", "ipv4");
else if (DM_LSTRCMP(value, "6") == 0)
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", "ipv6");
else if (DM_LSTRCMP(value, "-1") == 0)
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "family", "");
break;
}
return 0;
}
static int get_FirewallChainRule_DestIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_ip", "");
return 0;
}
static int set_FirewallChainRule_DestIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 45, NULL, IPAddress))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_ip", value);
break;
}
return 0;
}
static int get_FirewallChainRule_DestMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_mask", "");
return 0;
}
static int set_FirewallChainRule_DestMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 49, NULL, IPPrefix))
return FAULT_9007;
break;
case VALUESET:
char *pch = NULL;
pch = DM_STRCHR(value, '/');
if (pch == NULL)
return 0;
pch++;
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_mask", pch);
break;
}
return 0;
}
static int get_FirewallChainRule_SourceIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "src_ip", "");
return 0;
}
static int set_FirewallChainRule_SourceIP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 45, NULL, IPAddress))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src_ip", value);
break;
}
return 0;
}
static int get_FirewallChainRule_SourceMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_mask", "");
return 0;
}
static int set_FirewallChainRule_SourceMask(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 49, NULL, IPPrefix))
return FAULT_9007;
break;
case VALUESET:
char *pch = NULL;
pch = DM_STRCHR(value, '/');
if (pch == NULL)
return 0;
pch++;
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_mask", pch);
break;
}
return 0;
}
static int get_FirewallChainRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *proto = NULL, buf[256], protocol[32], protocol_nbr[16];
bbf_uci_get_value_by_section(((struct dm_data *)data)->config_section, "proto", &proto);
if (!proto || DM_STRLEN(proto) == 0 || strchr(proto, ' ')) {
*value = "255";
return 0;
}
if (*proto == '0' || strcmp(proto, "all") == 0) {
*value = "-1";
return 0;
}
if (isdigit_str(proto)) {
*value = proto;
return 0;
}
FILE *fp = fopen("/etc/protocols", "r");
if (fp == NULL)
return 0;
while (fgets (buf , 256 , fp) != NULL) {
sscanf(buf, "%31s %15s", protocol, protocol_nbr);
if (DM_STRCASECMP(protocol, proto) == 0) {
*value = dmstrdup(protocol_nbr);
fclose(fp);
return 0;
}
}
fclose(fp);
return 0;
}
static int set_FirewallChainRule_Protocol(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","255"}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "proto", (*value == '-') ? "0" : value);
break;
}
return 0;
}
static int get_FirewallChainRule_DestPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_port", "-1");
return 0;
}
static int set_FirewallChainRule_DestPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_port", value);
break;
}
return 0;
}
static int get_FirewallChainRule_DestPortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "dest_port_range_max", "-1");
return 0;
}
static int set_FirewallChainRule_DestPortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "dest_port_range_max", value);
break;
}
return 0;
}
static int get_FirewallChainRule_SourcePort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_port", "-1");
return 0;
}
static int set_FirewallChainRule_SourcePort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_port", value);
break;
}
return 0;
}
static int get_FirewallChainRule_SourcePortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "source_port_range_max", "-1");
return 0;
}
static int set_FirewallChainRule_SourcePortRangeMax(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_int(ctx, value, RANGE_ARGS{{"-1","65535"}}, 1))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "source_port_range_max", value);
break;
}
return 0;
}
static int get_FirewallChainRule_SourceMAC(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = bbf_uci_get_value_by_section_fallback_def(((struct dm_data *)data)->config_section, "src_mac", "");
return 0;
}
static int set_FirewallChainRule_SourceMAC(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
switch (action) {
case VALUECHECK:
if (bbfdm_validate_string(ctx, value, -1, 17, NULL, MACAddress))
return FAULT_9007;
break;
case VALUESET:
bbf_uci_set_value_by_section(((struct dm_data *)data)->config_section, "src_mac", value);
break;
}
return 0;
}
/**********************************************************************************************************************************
* OBJ & PARAM DEFINITION
***********************************************************************************************************************************/
/* *** Device.Firewall.Chain.{i}.Rule.{i}. *** */
DMLEAF tFirewallChainRuleParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
{"Enable", &DMWRITE, DMT_BOOL, get_FirewallChainRule_Enable, set_FirewallChainRule_Enable, BBFDM_BOTH},
{"Status", &DMREAD, DMT_STRING, get_FirewallChainRule_Status, NULL, BBFDM_BOTH},
{"Order", &DMWRITE, DMT_STRING, get_FirewallChainRule_Order, set_FirewallChainRule_Order, BBFDM_BOTH},
{"Alias", &DMWRITE, DMT_STRING, get_FirewallChainRule_Alias, set_FirewallChainRule_Alias, BBFDM_BOTH},
{"Description", &DMWRITE, DMT_STRING, get_FirewallChainRule_Description, set_FirewallChainRule_Description, BBFDM_BOTH},
{"Target", &DMWRITE, DMT_STRING, get_FirewallChainRule_Target, set_FirewallChainRule_Target, BBFDM_BOTH},
/*{"TargetChain", &DMWRITE, DMT_STRING, get_FirewallChainRule_TargetChain, set_FirewallChainRule_TargetChain, BBFDM_BOTH, DM_FLAG_REFERENCE},*/
{"Log", &DMWRITE, DMT_BOOL, get_FirewallChainRule_Log, set_FirewallChainRule_Log, BBFDM_BOTH},
{"CreationDate", &DMREAD, DMT_TIME, get_FirewallChainRule_CreationDate, NULL, BBFDM_BOTH},
{"ExpiryDate", &DMWRITE, DMT_TIME, get_FirewallChainRule_ExpiryDate, set_FirewallChainRule_ExpiryDate, BBFDM_BOTH},
{"SourceInterface", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceInterface, set_FirewallChainRule_SourceInterface, BBFDM_BOTH, DM_FLAG_REFERENCE},
/*{"SourceInterfaceExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceInterfaceExclude, set_FirewallChainRule_SourceInterfaceExclude, BBFDM_BOTH},*/
{"SourceAllInterfaces", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceAllInterfaces, set_FirewallChainRule_SourceAllInterfaces, BBFDM_BOTH},
{"DestInterface", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestInterface, set_FirewallChainRule_DestInterface, BBFDM_BOTH, DM_FLAG_REFERENCE},
/*{"DestInterfaceExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestInterfaceExclude, set_FirewallChainRule_DestInterfaceExclude, BBFDM_BOTH},*/
{"DestAllInterfaces", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestAllInterfaces, set_FirewallChainRule_DestAllInterfaces, BBFDM_BOTH},
{"IPVersion", &DMWRITE, DMT_INT, get_FirewallChainRule_IPVersion, set_FirewallChainRule_IPVersion, BBFDM_BOTH},
{"DestIP", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestIP, set_FirewallChainRule_DestIP, BBFDM_BOTH},
{"DestMask", &DMWRITE, DMT_STRING, get_FirewallChainRule_DestMask, set_FirewallChainRule_DestMask, BBFDM_BOTH},
/*{"DestIPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestIPExclude, set_FirewallChainRule_DestIPExclude, BBFDM_BOTH},*/
{"SourceIP", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceIP, set_FirewallChainRule_SourceIP, BBFDM_BOTH},
{"SourceMask", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceMask, set_FirewallChainRule_SourceMask, BBFDM_BOTH},
/*{"SourceIPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceIPExclude, set_FirewallChainRule_SourceIPExclude, BBFDM_BOTH},*/
{"Protocol", &DMWRITE, DMT_INT, get_FirewallChainRule_Protocol, set_FirewallChainRule_Protocol, BBFDM_BOTH},
/*{"ProtocolExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_ProtocolExclude, set_FirewallChainRule_ProtocolExclude, BBFDM_BOTH},*/
{"DestPort", &DMWRITE, DMT_INT, get_FirewallChainRule_DestPort, set_FirewallChainRule_DestPort, BBFDM_BOTH},
{"DestPortRangeMax", &DMWRITE, DMT_INT, get_FirewallChainRule_DestPortRangeMax, set_FirewallChainRule_DestPortRangeMax, BBFDM_BOTH},
/*{"DestPortExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DestPortExclude, set_FirewallChainRule_DestPortExclude, BBFDM_BOTH},*/
{"SourcePort", &DMWRITE, DMT_INT, get_FirewallChainRule_SourcePort, set_FirewallChainRule_SourcePort, BBFDM_BOTH},
{"SourcePortRangeMax", &DMWRITE, DMT_INT, get_FirewallChainRule_SourcePortRangeMax, set_FirewallChainRule_SourcePortRangeMax, BBFDM_BOTH},
/*{"SourcePortExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourcePortExclude, set_FirewallChainRule_SourcePortExclude, BBFDM_BOTH},*/
/*{"DSCP", &DMWRITE, DMT_INT, get_FirewallChainRule_DSCP, set_FirewallChainRule_DSCP, BBFDM_BOTH},*/
/*{"DSCPExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_DSCPExclude, set_FirewallChainRule_DSCPExclude, BBFDM_BOTH},*/
/*{"ConnectionState", &DMWRITE, DMT_STRING, get_FirewallChainRule_ConnectionState, set_FirewallChainRule_ConnectionState, BBFDM_BOTH},*/
{"SourceMAC", &DMWRITE, DMT_STRING, get_FirewallChainRule_SourceMAC, set_FirewallChainRule_SourceMAC, BBFDM_BOTH},
/*{"SourceMACExclude", &DMWRITE, DMT_BOOL, get_FirewallChainRule_SourceMACExclude, set_FirewallChainRule_SourceMACExclude, BBFDM_BOTH},*/
{0}
};
DMLEAF tDeviceFirewallChainRuleParam[] = {
{"RuleNumberOfEntries", &DMREAD, DMT_UNINT, get_FirewallChain_RuleNumberOfEntries, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.Firewall.Chain.{i}. *** */
DMOBJ tDeviceFirewallChainRuleObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */
{"Rule", &DMWRITE, addObjFirewallChainRule, delObjFirewallChainRule, NULL, browseFirewallChainRuleInst, NULL, NULL, NULL, tFirewallChainRuleParams, NULL, BBFDM_BOTH, NULL},
{0}
};
/* ********** DynamicObj ********** */
DM_MAP_OBJ tDynamicObj[] = {
/* parentobj, nextobject, parameter */
{"Device.Firewall.Chain.", tDeviceFirewallChainRuleObj, tDeviceFirewallChainRuleParam},
{0}
};

View File

@@ -0,0 +1,394 @@
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <libubox/blobmsg_json.h>
#include <libubus.h>
#include <uci.h>
#include <json-c/json.h>
int nat_get_status(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
int firewallmngr_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg);
const char *ubus_socket;
struct ubus_context *ctx = NULL;
enum {
STATUS_POLICY_INSTANCE,
STATUS_POLICY_MAX
};
static const struct blobmsg_policy status_policy[STATUS_POLICY_MAX] = {
[STATUS_POLICY_INSTANCE] = { .name = "instance", .type = BLOBMSG_TYPE_STRING },
};
static const struct ubus_method nat_methods[] = {
UBUS_METHOD("status", nat_get_status, status_policy),
};
static struct ubus_object_type nat_object_type =
UBUS_OBJECT_TYPE("nat", nat_methods);
static struct ubus_object nat_object = {
.name = "nat",
.type = &nat_object_type,
.methods = nat_methods,
.n_methods = ARRAY_SIZE(nat_methods),
};
static const struct ubus_method firewallmngr_methods[] = {
{ .name = "status", .handler = firewallmngr_get_status },
};
static struct ubus_object_type firewallmngr_object_type =
UBUS_OBJECT_TYPE("firewallmngr", firewallmngr_methods);
static struct ubus_object firewallmngr_object = {
.name = "firewallmngr",
.type = &firewallmngr_object_type,
.methods = firewallmngr_methods,
.n_methods = ARRAY_SIZE(firewallmngr_methods),
};
/**
* To expose the firewallmngr object on ubus i.e., firewallmngr or nat with method status
* @param context input parameter pointer to ubus context
* retrun integer value 0 on success and -1 on failure
*/
static int firewallmngr_publish_object(struct ubus_context *context, struct ubus_object *obj)
{
int ret;
ret = ubus_add_object(context, obj);
if (ret) {
syslog(LOG_ERR, "Failed to add firewallmngr ubus object: %s\n",
ubus_strerror(ret));
}
return ret;
}
static void nat_get_interfacesetting_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg)
{
char *status = "Disabled";
struct uci_element *uci_elmnt = NULL;
struct blob_attr *tb[STATUS_POLICY_MAX];
char instance[20] = {0};
blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg));
if (!tb[STATUS_POLICY_INSTANCE])
return;
strncpy(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1);
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec && !strcmp(uci_sec->type, "zone")) {
struct uci_element *e = NULL;
if (strcmp(instance, uci_sec->e.name))
continue;
blobmsg_add_string(buf, "name", uci_sec->e.name);
uci_foreach_element(&uci_sec->options, e) {
struct uci_option *uci_opn = uci_to_option(e);
syslog(LOG_INFO,"%s %d \n", __FUNCTION__, __LINE__);
if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) {
status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled";
break;
}
}
blobmsg_add_string(buf, "Status", status);
}
}
}
static void nat_get_portmapping_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg)
{
char *status = "Disabled";
struct uci_element *uci_elmnt = NULL;
struct blob_attr *tb[STATUS_POLICY_MAX];
char instance[20] = {0};
blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg));
if (!tb[STATUS_POLICY_INSTANCE])
return;
strncpy(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1);
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec && !strcmp(uci_sec->type, "redirect")) {
struct uci_element *e = NULL;
if (strcmp(instance, uci_sec->e.name))
continue;
blobmsg_add_string(buf, "name", uci_sec->e.name);
uci_foreach_element(&uci_sec->options, e) {
struct uci_option *uci_opn = uci_to_option(e);
if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) {
status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled";
break;
}
}
blobmsg_add_string(buf, "Status", status);
}
}
}
/**
* nat_get_status function callback on ubus method nat_status
* @param ctx input parameter pointer to ubus context
* @param obj input parameter pointer to ubus object in out case nat
* @param req input parameter pointer to ubus requested data
* @param method input parameter pointer to char method i.e., nat_status
* @param msg input parameter pointer containing
* retrun integer value 0 on success and -1 on failure
*/
int nat_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret = 0;
struct blob_buf b = {0};
struct uci_package *uci_pkg = NULL;
struct uci_context *uci_ctx = uci_alloc_context();
uci_load(uci_ctx, "firewall", &uci_pkg);
if (!uci_pkg) {
syslog(LOG_ERR, "nat Failed to load configuration\n");
goto done;
}
blob_buf_init(&b, 0);
nat_get_interfacesetting_status(&b, uci_pkg, msg);
nat_get_portmapping_status(&b, uci_pkg, msg);
ubus_send_reply(ctx_arg, req, b.head);
blob_buf_free(&b);
uci_unload(uci_ctx, uci_pkg);
done:
uci_free_context(uci_ctx);
return ret;
}
static void firewallmngr_get_service_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg)
{
char *status = "Disabled";
struct uci_element *uci_elmnt = NULL;
struct blob_attr *tb[STATUS_POLICY_MAX];
char instance[30] = {0};
blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg));
if (!tb[STATUS_POLICY_INSTANCE])
return;
strcpy(instance,"fwmngr_");
strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1);
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec && !strcmp(uci_sec->type, "service")) {
struct uci_element *e = NULL;
if (strcmp(instance, uci_sec->e.name))
continue;
blobmsg_add_string(buf, "name", uci_sec->e.name);
uci_foreach_element(&uci_sec->options, e) {
struct uci_option *uci_opn = uci_to_option(e);
if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) {
status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled";
break;
}
}
blobmsg_add_string(buf, "Status", status);
}
}
}
static void firewallmngr_get_dmz_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg)
{
char *status = "Disabled";
struct uci_element *uci_elmnt = NULL;
struct blob_attr *tb[STATUS_POLICY_MAX];
char instance[30] = {0};
blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg));
if (!tb[STATUS_POLICY_INSTANCE])
return;
strcpy(instance,"fwmngr_");
strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1);
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec && !strcmp(uci_sec->type, "redirect")) {
struct uci_element *e = NULL;
if (strcmp(instance, uci_sec->e.name))
continue;
blobmsg_add_string(buf, "name", uci_sec->e.name);
uci_foreach_element(&uci_sec->options, e) {
struct uci_option *uci_opn = uci_to_option(e);
if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) {
status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled";
break;
}
}
blobmsg_add_string(buf, "Status", status);
}
}
}
static void firewallmngr_get_rule_status(struct blob_buf *buf, struct uci_package *uci_pkg, struct blob_attr *msg)
{
char *status = "Disabled";
struct uci_element *uci_elmnt = NULL;
struct blob_attr *tb[STATUS_POLICY_MAX];
char instance[30] = {0};
blobmsg_parse(status_policy, STATUS_POLICY_MAX, tb, blob_data(msg), (unsigned int)blob_len(msg));
if (!tb[STATUS_POLICY_INSTANCE])
return;
strcpy(instance,"fwmngr_");
strncat(instance, blobmsg_data(tb[STATUS_POLICY_INSTANCE]), sizeof(instance)-1);
uci_foreach_element(&uci_pkg->sections, uci_elmnt) {
struct uci_section *uci_sec = uci_to_section(uci_elmnt);
if (uci_sec && !strcmp(uci_sec->type, "rule")) {
struct uci_element *e = NULL;
if (strcmp(instance, uci_sec->e.name))
continue;
blobmsg_add_string(buf, "name", uci_sec->e.name);
uci_foreach_element(&uci_sec->options, e) {
struct uci_option *uci_opn = uci_to_option(e);
if (uci_opn && !strcmp(uci_opn->e.name, "enabled")) {
status = (*(uci_opn->v.string) == 'n' || *(uci_opn->v.string) == '0' ) ? "Disabled" : "Enabled";
break;
}
}
blobmsg_add_string(buf, "Status", status);
}
}
}
/**
* firewallmngr_get_status function callback on ubus method firewallmngr_status
* @param ctx input parameter pointer to ubus context
* @param obj input parameter pointer to ubus object in out case firewallmngr
* @param req input parameter pointer to ubus requested data
* @param method input parameter pointer to char method i.e., firewallmngr_status
* @param msg input parameter pointer containing
* retrun integer value 0 on success and -1 on failure
*/
int firewallmngr_get_status(struct ubus_context *ctx_arg, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret = 0;
struct blob_buf b = {0};
struct uci_package *uci_pkg = NULL;
struct uci_context *uci_ctx = uci_alloc_context();
blob_buf_init(&b, 0);
uci_load(uci_ctx, "firewall", &uci_pkg);
if (!uci_pkg) {
syslog(LOG_ERR, "firewallmngr Failed to load configuration\n");
uci_free_context(uci_ctx);
return ret;
}
firewallmngr_get_rule_status(&b, uci_pkg, msg);
firewallmngr_get_dmz_status(&b, uci_pkg, msg);
firewallmngr_get_service_status(&b, uci_pkg, msg);
ubus_send_reply(ctx_arg, req, b.head);
blob_buf_free(&b);
uci_unload(uci_ctx, uci_pkg);
uci_free_context(uci_ctx);
return ret;
}
/**
* Main function for firewallmngr, everything starts here
* @param argc input number of input arguments
* @param argv input double pointer array of optional command line arguments
* retrun integer value 0 on success and -1 on failure
*/
int main(int argc, char **argv)
{
int ret;
int ch;
while ((ch = getopt(argc, argv, "s:e:")) != -1) {
switch (ch) {
case 's':
ubus_socket = optarg;
break;
default:
break;
}
}
argc -= optind;
argv += optind;
uloop_init();
ctx = ubus_connect(ubus_socket);
if (!ctx) {
syslog(LOG_ERR, "nat Failed to connect to ubus\n");
return -1;
}
ubus_add_uloop(ctx);
ret = firewallmngr_publish_object(ctx, &nat_object);
if (ret)
goto out;
ret = firewallmngr_publish_object(ctx, &firewallmngr_object);
if (ret)
goto out;
/* Main loop of firewallmngr */
uloop_run();
out:
ubus_free(ctx);
uloop_done();
return 0;
}

View File

@@ -7,9 +7,9 @@ next_days=""
prev_days=""
schedule_added=""
ACCESS_RULE=""
IP_RULE=""
IP_RULE1=""
rule1_needed="0"
active_chain=""
rule_count=1
get_next_day() {
local weekday="$1"
@@ -58,25 +58,32 @@ ip_rule_west_zone() {
local local_stop_t_h="$4"
local utc_start_time="$5"
local utc_stop_time="$6"
local rule_sec="$7"
local rule1_sec="$8"
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"
uci set firewallmngr."$rule_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule_sec".stop_time="$utc_stop_time"
if [ -n "$next_days" ]; then
IP_RULE="$IP_RULE --weekdays $next_days"
uci set firewallmngr."$rule_sec".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"
rule1_needed="1"
uci set firewallmngr."$rule_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule_sec".stop_time="23:59"
uci set firewallmngr."$rule1_sec".start_time="00:00"
uci set firewallmngr."$rule1_sec".stop_time="$utc_stop_time"
if [ -n "$next_days" ]; then
IP_RULE1="$IP_RULE1 --weekdays $next_days"
uci set firewallmngr."$rule1_sec".weekdays="$next_days"
fi
else
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
uci set firewallmngr."$rule_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule_sec".stop_time="$utc_stop_time"
fi
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
uci set firewallmngr."$rule_sec".weekdays="$days"
fi
fi
}
@@ -88,36 +95,35 @@ ip_rule_east_zone() {
local local_stop_t_h="$4"
local utc_start_time="$5"
local utc_stop_time="$6"
local rule_sec="$7"
local rule1_sec="$8"
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"
uci set firewallmngr."$rule_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule_sec".stop_time="$utc_stop_time"
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
uci set firewallmngr."$rule_sec".weekdays="$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 00:00 --timestop $utc_stop_time"
IP_RULE1="$IP_RULE1 -m time --timestart $utc_start_time --timestop 23:59"
rule1_needed="1"
uci set firewallmngr."$rule_sec".start_time="00:00"
uci set firewallmngr."$rule_sec".stop_time="$utc_stop_time"
uci set firewallmngr."$rule1_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule1_sec".stop_time="23:59"
if [ -n "$prev_days" ]; then
IP_RULE1="$IP_RULE1 --weekdays $prev_days"
uci set firewallmngr."$rule1_sec".weekdays="$prev_days"
fi
else
IP_RULE="$IP_RULE -m time --timestart $utc_start_time --timestop $utc_stop_time"
uci set firewallmngr."$rule_sec".start_time="$utc_start_time"
uci set firewallmngr."$rule_sec".stop_time="$utc_stop_time"
fi
if [ -n "$day" ]; then
IP_RULE="$IP_RULE --weekdays $day"
uci set firewallmngr."$rule_sec".weekdays="$days"
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
@@ -138,12 +144,12 @@ handle_day_list() {
handle_schedule() {
local schd_section="$1"
local ac_section="$2"
local rule_sec
local rule1_sec
local acs_id
local start_time
local duration
IP_RULE="$ACCESS_RULE"
IP_RULE1=""
day=""
next_days=""
prev_days=""
@@ -199,24 +205,42 @@ handle_schedule() {
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 }')
rule_sec=$(uci add "firewallmngr" "rule")
rule1_sec=$(uci add "firewallmngr" "rule")
uci set firewallmngr."$rule_sec".enable="1"
uci set firewallmngr."$rule_sec".chain="$active_chain"
uci set firewallmngr."$rule_sec".creator="host_acl"
uci set firewallmngr."$rule_sec".source_interface="*"
uci set firewallmngr."$rule_sec".dest_interface="*"
uci set firewallmngr."$rule_sec".source_mac="$mac_addr"
uci set firewallmngr."$rule1_sec".enable="1"
uci set firewallmngr."$rule1_sec".chain="$active_chain"
uci set firewallmngr."$rule_sec".creator="host_acl"
uci set firewallmngr."$rule1_sec".source_interface="*"
uci set firewallmngr."$rule1_sec".dest_interface="*"
uci set firewallmngr."$rule1_sec".source_mac="$mac_addr"
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
ip_rule_west_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time "$rule_sec" "$rule1_sec"
else
ip_rule_east_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time
ip_rule_east_zone $utc_start_hh $utc_stop_hh $local_start_hh $local_stop_hh $utc_start_time $utc_stop_time "$rule_sec" "$rule1_sec"
fi
IP_RULE="$IP_RULE -j ACCEPT"
if [ -n "$IP_RULE1" ]; then
IP_RULE1="$IP_RULE1 -j ACCEPT"
uci set firewallmngr.$rule_sec.target="ACCEPT"
uci rename firewallmngr."$rule_sec"="fwmngr_host_acl_${rule_count}"
rule_count=$(( rule_count + 1 ))
if [ "$rule1_needed" == "1" ]; then
uci set firewallmngr."$rule1_sec".target="ACCEPT"
uci rename firewallmngr."$rule1_sec"="fwmngr_host_acl_${rule_count}"
rule_count=$(( rule_count + 1 ))
else
uci delete firewallmngr."$rule1_sec"
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
# to block the access outside the defined schedule
if [ "$schedule_added" == "0" ]; then
schedule_added="1"
fi
@@ -225,6 +249,9 @@ handle_schedule() {
handle_access_control() {
local ac_section="$1"
local is_enabled
local rule_sec
local rule1_sec
local rule2_sec
# default value of Hosts.AccessControl.{i}.Enable is false,
# so, if not defined in uci as 1, assume 0
@@ -237,8 +264,6 @@ handle_access_control() {
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
@@ -250,46 +275,61 @@ handle_access_control() {
# 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"
rule_sec=$(uci add "firewallmngr" "rule")
uci set firewallmngr."$rule_sec".enable="1"
uci set firewallmngr."$rule_sec".chain="$active_chain"
uci set firewallmngr."$rule_sec".creator="host_acl"
uci set firewallmngr."$rule_sec".source_interface="*"
uci set firewallmngr."$rule_sec".dest_interface="*"
uci set firewallmngr."$rule_sec".source_mac="$mac_addr"
uci set firewallmngr."$rule_sec".target="DROP"
uci rename firewallmngr."$rule_sec"="fwmngr_host_acl_${rule_count}"
rule_count=$(( rule_count + 1 ))
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"
config_foreach handle_schedule ac_schedule "$ac_section" "$mac_addr"
# 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"
rule2_sec=$(uci add "firewallmngr" "rule")
uci set firewallmngr."$rule2_sec".enable="1"
uci set firewallmngr."$rule2_sec".chain="$active_chain"
uci set firewallmngr."$rule_sec".creator="host_acl"
uci set firewallmngr."$rule2_sec".source_interface="*"
uci set firewallmngr."$rule2_sec".dest_interface="*"
uci set firewallmngr."$rule_sec".source_mac="$mac_addr"
uci set firewallmngr."$rule2_sec".target="DROP"
uci rename firewallmngr."$rule1_sec"="fwmngr_host_acl_${rule_count}"
rule_count=$(( rule_count + 1 ))
fi
}
ACL_FILE="/tmp/hosts_access_control/access_control.rules"
firewallmngr_get_active_chain() {
config_get creator "$1" creator
[ "$creator" = "PortMapping" ] && return
rm -f $ACL_FILE
config_get enable "$1" enable
if [ -n "$enable" ] && [ "$enable" = "1" ]; then
config_get active_chain "$1" name
fi
}
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_forward=$(iptables -t filter --list | grep hosts_forward)
if [ -z "$hosts_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
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
remove_firewallmngr_host_acl_rule() {
config_get creator "$1" creator
[ "$creator" = "host_acl" ] || return
uci delete firewallmngr."$1"
}
# Load /etc/config/hosts UCI file
config_load firewallmngr
config_foreach firewallmngr_get_active_chain chain
config_foreach remove_firewallmngr_host_acl_rule rule
config_load hosts
config_foreach handle_access_control access_control
# apply the rules
sh $ACL_FILE
uci commit firewallmngr

View File

@@ -51,10 +51,9 @@ define Package/icwmp/install
$(INSTALL_DIR) $(1)/etc/icwmpd/plugins
$(INSTALL_BIN) $(PKG_BUILD_DIR)/icwmpd $(1)/usr/sbin/icwmpd
$(INSTALL_DATA) ./files/etc/config/cwmp $(1)/etc/config/cwmp
$(INSTALL_BIN) ./files/etc/firewall.cwmp $(1)/etc/firewall.cwmp
$(INSTALL_BIN) ./files/etc/firewall_cwmp.sh $(1)/etc/firewall_cwmp.sh
$(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/
$(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,91 @@
#!/bin/sh
. /lib/functions.sh
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" "description"
[ "$description" = "Open_ACS_port" ] || return
uci -q delete firewallmngr."$rule_sec"
}
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"
rule_sec=$(uci add firewallmngr rule)
rule1_sec=$(uci add firewallmngr rule)
uci set firewallmngr."$rule_sec".ip_version="4"
uci set firewallmngr."$rule1_sec".ip_version="6"
uci set firewallmngr."$rule_sec".source_interface="$zone_name"
uci set firewallmngr."$rule1_sec".source_interface="$zone_name"
uci set firewallmngr."$rule_sec".dm_parent="$active_chain"
uci set firewallmngr."$rule1_sec".dm_parent="$active_chain"
uci reorder firewallmngr."$rule_sec"=1
uci reorder firewallmngr."$rule1_sec"=1
# 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".description="Open_ACS_port"
uci set firewallmngr."$rule1_sec".description="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"
uci commit firewallmngr

View File

@@ -532,6 +532,7 @@ start_service() {
"${respawn_timeout:-10}" "${respawn_retry:-3}"
procd_close_instance
sh /etc/firewall_cwmp.sh
}
stop_service()

View File

@@ -413,7 +413,52 @@ 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".active_chain="$active_chain"
uci set firewallmngr."$sec".name="$name"
uci set firewallmngr."$sec".source_interface="$src"
uci set firewallmngr."$sec".dest_interface="$dst"
uci set firewallmngr."$sec".dest_ip="$dest_ip"
uci set firewallmngr."$sec".ip_version="4"
uci set firewallmngr."$sec".protocol="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

View File

@@ -26,7 +26,7 @@ define Package/port-trigger
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Port Trigger Daemon
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +kmod-ipt-trigger +kmod-ip6t-trigger +iptables-mod-nfqueue
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +kmod-ipt-trigger +kmod-ip6t-trigger +iptables-mod-nfqueue +firewallmngr
endef
define Package/port-trigger/description
@@ -44,12 +44,12 @@ define Package/port-trigger/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/lib/port-trigger
$(CP) ./files/* $(1)/
$(INSTALL_DIR) $(1)/etc/firewallmngr/plugins
$(INSTALL_BIN) ./files/etc/init.d/port-trigger $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/port-trigger $(1)/etc/config/
$(INSTALL_DATA) ./files/lib/port-trigger/port_trigger.sh $(1)/lib/port-trigger/
$(call BbfdmInstallPluginInMicroservice, $(1)/etc/port-trigger,$(PKG_BUILD_DIR)/bbf_plugin/libporttrigger.so)
$(call BbfdmInstallMicroServiceInputFile,$(1),./files/etc/bbfdm/micro_services/port-trigger.json)
$(INSTALL_DATA) $(PKG_BUILD_DIR)/bbf_plugin/libporttrigger.so $(1)/etc/firewallmngr/plugins/
endef
$(eval $(call BuildPackage,port-trigger))

View File

@@ -53,8 +53,6 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) $(PKG_BUILD_DIR)/twampd $(1)/usr/sbin/
$(INSTALL_DATA) ./files/etc/config/twamp $(1)/etc/config/twamp
$(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
$(INSTALL_BIN) ./files/etc/uci-defaults/93-twamp_fix_reflector $(1)/etc/uci-defaults/93-twamp_fix_reflector
$(call BbfdmInstallPlugin,$(1),$(PKG_BUILD_DIR)/libtwamp.so)
endef

View File

@@ -1,48 +0,0 @@
#!/bin/sh
. /lib/functions.sh
#created by the icwmp package
log() {
echo "${@}"|logger -t firewall.twamp -p info
}
if [ ! -f "/etc/config/twamp" ]; then
exit 0;
fi
configure_firewall() {
local enable port interface
config_get enable "${1}" enable "1"
config_get port "${1}" port
config_get interface "${1}" interface
if [ "$enable" -eq 0 ] || [ -z "${port}" ] || [ -z "${interface}" ]; then
return 0;
fi
iptables -w 1 -nL zone_"${interface}"_input 2>/dev/null 1>&2
if [ "$?" -eq 0 ]; then
iptables -w 1 -I zone_"${interface}"_input -p udp --dport "${port}" -j ACCEPT -m comment --comment "TWAMP reflector port"
fi
}
delete_rule() {
while iptables -w 1 -nL zone_"${1}"_input --line-numbers 2>/dev/null | grep "TWAMP reflector port"; do
rule_num="$(iptables -w 1 -nL zone_"${1}"_input --line-numbers | grep "TWAMP reflector port" | head -1|awk '{print $1}')"
if [ -n "${rule_num}" ]; then
iptables -w 1 -D zone_"${1}"_input "${rule_num}";
fi
done
}
# Loop through all interfaces and delete the twamp reflector rule from interface's input chain
config_load network
config_foreach delete_rule interface
config_load twamp
config_get twamp_enable twamp enable "0"
if [ "${twamp_enable}" -eq "0" ]; then
exit 0;
fi
config_foreach configure_firewall twamp_reflector

View File

@@ -6,6 +6,8 @@
START=99
STOP=10
. /lib/fwmngr/fwmngr_twamp.sh
USE_PROCD=1
PROG="/usr/sbin/twampd"
@@ -17,16 +19,15 @@ start_service() {
procd_set_param respawn "3" "7" "0"
procd_close_instance
fi
handle_twamp_rules
}
reload_service() {
stop
start
[ -f /etc/firewall.twamp ] && {
sh /etc/firewall.twamp
}
}
service_triggers() {
procd_add_reload_trigger twamp
procd_add_reload_trigger firewallmngr
}

View File

@@ -1,12 +0,0 @@
#!/bin/sh
uci -q batch <<-EOT
delete firewall.twamp
set firewall.twamp=include
set firewall.twamp.path=/etc/firewall.twamp
set firewall.twamp.reload=1
commit firewall
EOT
exit 0