Project

General

Profile

« Previous | Next » 

Revision 25a0f534

Added by Marcos M 8 months ago

Decrease the number of config requests when deleting filter rules

View differences:

src/etc/inc/filter.inc
5032 5032
}
5033 5033

  
5034 5034
/**
5035
 * Get the first and last rule's index for an interface, and optionally the
5036
 * relative index of a rule within the interface.
5035
 * Get the first and last rule's index for an interface, and optionally
5036
 * a rule index relative to the number of rules on the interface.
5037 5037
 * 
5038
 * @param string $if The interface used to calculate the rule indices
5039
 * @param int $idx (optional) A rule index
5038
 * @param string $interface The interface used to find the rule indices
5039
 * @param int $rule_index (optional) A rule index
5040 5040
 * 
5041 5041
 * @return array Contains the matching interface's first and last rule's index,
5042 5042
 *               and the matching rule's relative index if found.
5043 5043
 */
5044
function get_interface_ruleindex(string $interface, ?int $rule_index = null): array {
5044
function get_interface_ruleindex(string $interface, ?int $rule_index = null, ?array $rules = null): array {
5045 5045
	if (isset($rule_index) && ($rule_index < 0)) {
5046 5046
		unset($rule_index);
5047 5047
	}
......
5054 5054
		return $interface_rule_index;
5055 5055
	}
5056 5056

  
5057
	$rules = $rules ?? config_get_path('filter/rule', []);
5057 5058
	$interface = strtolower($interface);
5058 5059
	$relative_index_count = -1; // a valid index count starts at 0
5059
	foreach (config_get_path('filter/rule',[]) as $idx => $rule) {
5060
	foreach ($rules as $idx => $rule) {
5060 5061
		// skip rules on unrelated interfaces
5061 5062
		if ((isset($rule['floating']) && ($interface != "floatingrules")) ||
5062 5063
		    (!isset($rule['floating']) && ($interface != strtolower($rule['interface'])))) {
src/usr/local/www/firewall_rules.php
125 125
	printf("%s/%s</a><br />", format_number($states), format_bytes($bytes));
126 126
}
127 127

  
128
function delete_nat_association($id) {
129
	$a_nat = config_get_path('nat/rule');
130
	if (!$id || !is_array($a_nat)) {
128
function delete_nat_association(array $associations_to_remove = []) {
129
	if (empty($associations_to_remove)) {
131 130
		return;
132 131
	}
133 132

  
134
	foreach ($a_nat as &$natent) {
135
		if ($natent['associated-rule-id'] == $id) {
133
	$nat_rules = config_get_path('nat/rule', []);
134
	if (empty($nat_rules)) {
135
		return;
136
	}
137

  
138
	$update_config = false;
139
	foreach ($nat_rules as &$natent) {
140
		if (in_array($natent['associated-rule-id'], $associations_to_remove)) {
136 141
			$natent['associated-rule-id'] = '';
142
			$update_config = true;
137 143
		}
138 144
	}
139
	config_set_path('nat/rule', $a_nat);
145

  
146
	if ($update_config) {
147
		config_set_path('nat/rule', $nat_rules);
148
	}
140 149
}
141 150

  
142 151
filter_rules_sort();
......
167 176
}
168 177

  
169 178
if ($_POST['act'] == "del") {
170
	if (config_get_path("filter/rule/{$_POST['id']}")) {
179
	$rule = is_numericint($_POST['id']) ? config_get_path("filter/rule/{$_POST['id']}") : null;
180
	if (isset($rule)) {
171 181
		// separators must be updated before the rule is removed
172 182
		$ridx = get_interface_ruleindex($if, $_POST['id']);
173 183
		$a_separators = config_get_path('filter/separator/' . strtolower($if), []);
174 184
		shift_separators($a_separators, $ridx['index'], true);
175 185
		config_set_path('filter/separator/' . strtolower($if), $a_separators);
176 186

  
177
		// remove the rule
178
		if (!empty(config_get_path("filter/rule/{$_POST['id']}/associated-rule-id"))) {
179
			delete_nat_association(config_get_path("filter/rule/{$_POST['id']}/associated-rule-id"));
187
		if (!empty($rule['associated-rule-id'])) {
188
			delete_nat_association([$rule['associated-rule-id']]);
180 189
		}
181 190
		config_del_path("filter/rule/{$_POST['id']}");
182 191

  
......
206 215
	if (is_array($_POST['rule']) && count($_POST['rule'])) {
207 216
		$removed = false;
208 217
		$a_separators = config_get_path('filter/separator/' . strtolower($if), []);
218
		$a_rules = config_get_path('filter/rule', []);
219
		$associations_to_remove = [];
209 220
		foreach ($_POST['rule'] as $rulei) {
221
			if (!isset($a_rules[$rulei])) {
222
				continue;
223
			}
224

  
210 225
			// separators must be updated before the rule is removed
211
			$ridx = get_interface_ruleindex($if, $rulei);
226
			$ridx = get_interface_ruleindex($if, $rulei, $a_rules);
212 227
			shift_separators($a_separators, $ridx['index'], true);
213 228

  
214
			// remove the rule
215
			delete_nat_association(config_get_path("filter/rule/{$rulei}/associated-rule-id"));
216
			config_del_path("filter/rule/{$rulei}");
229
			if (!empty($a_rules[$rulei]['associated-rule-id'])) {
230
				$associations_to_remove[] = $a_rules[$rulei]['associated-rule-id'];
231
			}
232

  
233
			unset($a_rules[$rulei]);
217 234
			$removed = true;
218 235
		}
219
		config_set_path('filter/separator/' . strtolower($if), $a_separators);
220 236

  
221 237
		if ($removed) {
238
			delete_nat_association($associations_to_remove);
239
			config_set_path('filter/separator/' . strtolower($if), $a_separators);
240
			config_set_path('filter/rule', $a_rules);
222 241
			if (write_config(gettext("Firewall: Rules - deleted selected firewall rules."))) {
223 242
				mark_subsystem_dirty('filter');
224 243
			}

Also available in: Unified diff