+fw_do_interface_rules() {
+ local action=$1
+ local zone=$2
+ local chain=zone_${zone}
+ local ifname=$3
+ local subnet=$4
+ local extra_src="$5"
+ local extra_dest="$6"
+
+ local idev odev inet onet mode
+ fw_get_family_mode mode x $zone i
+
+ fw_get_negation idev '-i' "$ifname"
+ fw_get_negation odev '-o' "$ifname"
+
+ case "$mode/$subnet" in
+ # Zone supports v6 only or dual, need v6
+ G6/*:*|i/*:*)
+ fw_get_negation inet '-s' "$subnet"
+ fw_get_negation onet '-d' "$subnet"
+ mode=6
+ ;;
+
+ # Zone supports v4 only or dual, need v4
+ G4/*.*.*.*|i/*.*.*.*)
+ fw_get_negation inet '-s' "$subnet"
+ fw_get_negation onet '-d' "$subnet"
+ mode=4
+ ;;
+
+ # Need v6 while zone is v4
+ */*:*) fw_log info "zone $zone does not support IPv6 address family, skipping"; return ;;
+
+ # Need v4 while zone is v6
+ */*.*) fw_log info "zone $zone does not support IPv4 address family, skipping"; return ;;
+
+ # Strip prefix
+ *) mode="${mode#G}" ;;
+ esac
+
+ lock /var/run/firewall-interface.lock
+
+ fw $action $mode f ${chain}_dest_ACCEPT ACCEPT $ { $odev $onet $extra_dest }
+ fw $action $mode f ${chain}_src_ACCEPT ACCEPT $ { $idev $inet $extra_src }
+ fw $action $mode f ${chain}_dest_DROP DROP $ { $odev $onet $extra_dest }
+ fw $action $mode f ${chain}_src_DROP DROP $ { $idev $inet $extra_src }
+ fw $action $mode f ${chain}_dest_REJECT reject $ { $odev $onet $extra_dest }
+ fw $action $mode f ${chain}_src_REJECT reject $ { $idev $inet $extra_src }
+
+ [ "$(uci_get_state firewall core "${zone}_tcpmss")" == 1 ] && \
+ fw $action $mode m ${chain}_MSSFIX TCPMSS $ \
+ { $odev -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet $extra_dest }
+
+ fw $action $mode f delegate_input ${chain}_input $ { $idev $inet $extra_src }
+ fw $action $mode f delegate_forward ${chain}_forward $ { $idev $inet $extra_src }
+ fw $action $mode f delegate_output ${chain}_output $ { $odev $onet $extra_dest }
+
+ fw $action $mode n PREROUTING ${chain}_prerouting $ { $idev $inet $extra_src }
+ fw $action $mode r PREROUTING ${chain}_notrack $ { $idev $inet $extra_src }
+ fw $action $mode n POSTROUTING ${chain}_nat $ { $odev $onet $extra_dest }
+
+ # Flush conntrack table
+ echo f >/proc/net/nf_conntrack 2>/dev/null
+
+ lock -u /var/run/firewall-interface.lock
+}
+