Skip to content

Commit f6637b4

Browse files
Added dnpipe, pdnpipe, defaultqueue and ackqueue fields to firewall rule endpoints, prevented shapers from being deleted while in use, updated unit tests
1 parent c3f4a26 commit f6637b4

13 files changed

Lines changed: 690 additions & 33 deletions

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,10 @@ URL: https://{{$hostname}}/api/v1/firewall/rule
18011801
| dstport | string or integer | Set the TCP and/or UDP destination port or port alias of the firewall rule. This is only necessary if you have specified the `protocol` to `tcp`, `udp`, `tcp/udp` |
18021802
| gateway | string | Set the routing gateway traffic will take upon match (optional) |
18031803
| sched | string | Set a firewall schedule to apply to this rule. This must be an existing firewall schedule name. (optional) |
1804+
| dnpipe | string | Specify a traffic shaper limiter (in) queue for this rule. This must be an existing traffic shaper limiter or queue. This field is required if a `pdnpipe` value is provided.Ioptional) |
1805+
| pdnpipe | string | Specify a traffic shaper limiter (out) queue for this rule. This must be an existing traffic shaper limiter or queue. This value cannot match the `dnpipe` value and must be a child queue if `dnpipe` is a child queue, or a parent limiiter if `dnpipe` is a parent limiter. (optional) |
1806+
| defaultqueue | string | Specify a default traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue name. This field is required when an `ackqueue` value is provided. (optional) |
1807+
| ackqueue | string | Specify an acknowledge traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue and cannot match the `defaultqueue` value. (optional) |
18041808
| disabled | boolean | Disable the rule upon creation (optional) |
18051809
| descr | string | Set a description for the rule (optional) |
18061810
| log | boolean | Enabling rule matched logging (optional) |
@@ -1929,6 +1933,10 @@ URL: https://{{$hostname}}/api/v1/firewall/rule
19291933
| dstport | string or integer | Update the TCP and/or UDP destination port or port alias of the firewall rule. This is only necessary if you have specified the `protocol` to `tcp`, `udp`, `tcp/udp` |
19301934
| gateway | string | Update the routing gateway traffic will take upon match (optional) |
19311935
| sched | string | Update the firewall schedule to apply to this rule. This must be an existing firewall schedule name. Provide an empty string to remove the configured schedule from the rule. (optional) |
1936+
| dnpipe | string | Update the traffic shaper limiter (in) queue for this rule. This must be an existing traffic shaper limiter or queue. This field is required if a `pdnpipe` value is provided. To unset this value, pass in an empty string. This will also unset the existing `pdnpipe` value. (optional) |
1937+
| pdnpipe | string | Update the traffic shaper limiter (out) queue for this rule. This must be an existing traffic shaper limiter or queue. This value cannot match the `dnpipe` value and must be a child queue if `dnpipe` is a child queue, or a parent limiiter if `dnpipe` is a parent limiter. To unset this value, pass in an empty string. (optional) |
1938+
| defaultqueue | string | Update the default traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue name. This field is required when an `ackqueue` value is provided. To unset this field, pass in an empty string. This will also unset the existing `ackqueue` value. (optional) |
1939+
| ackqueue | string | Update acknowledge traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue and cannot match the `defaultqueue` value. To unset this field, pass in an empty string. (optional) |
19321940
| disabled | boolean | Disable the rule upon modification (optional) |
19331941
| descr | string | Update the description of the rule (optional) |
19341942
| log | boolean | Enable rule matched logging (optional) |

docs/documentation.json

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,7 @@
22202220
}
22212221
},
22222222
"url": {
2223-
"raw": "https://{{$hostname}}/api/v1/firewall/rule?type=string&interface=string&ipprotocol=string&protocol=string&icmptype=string or array&src=string&dst=string&srcport=string or integer&dstport=string or integer&gateway=string&sched=string&disabled=boolean&descr=string&log=boolean&top=boolean&apply=boolean",
2223+
"raw": "https://{{$hostname}}/api/v1/firewall/rule?type=string&interface=string&ipprotocol=string&protocol=string&icmptype=string or array&src=string&dst=string&srcport=string or integer&dstport=string or integer&gateway=string&sched=string&dnpipe=string&pdnpipe=string&defaultqueue=string&ackqueue=string&disabled=boolean&descr=string&log=boolean&top=boolean&apply=boolean",
22242224
"protocol": "https",
22252225
"host": [
22262226
"{{$hostname}}"
@@ -2287,6 +2287,26 @@
22872287
"value": "string",
22882288
"description": "Set a firewall schedule to apply to this rule. This must be an existing firewall schedule name. (optional)"
22892289
},
2290+
{
2291+
"key": "dnpipe",
2292+
"value": "string",
2293+
"description": "Specify a traffic shaper limiter (in) queue for this rule. This must be an existing traffic shaper limiter or queue. This field is required if a `pdnpipe` value is provided.Ioptional)"
2294+
},
2295+
{
2296+
"key": "pdnpipe",
2297+
"value": "string",
2298+
"description": "Specify a traffic shaper limiter (out) queue for this rule. This must be an existing traffic shaper limiter or queue. This value cannot match the `dnpipe` value and must be a child queue if `dnpipe` is a child queue, or a parent limiiter if `dnpipe` is a parent limiter. (optional)"
2299+
},
2300+
{
2301+
"key": "defaultqueue",
2302+
"value": "string",
2303+
"description": "Specify a default traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue name. This field is required when an `ackqueue` value is provided. (optional)"
2304+
},
2305+
{
2306+
"key": "ackqueue",
2307+
"value": "string",
2308+
"description": "Specify an acknowledge traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue and cannot match the `defaultqueue` value. (optional)"
2309+
},
22902310
{
22912311
"key": "disabled",
22922312
"value": "boolean",
@@ -2333,7 +2353,7 @@
23332353
}
23342354
},
23352355
"url": {
2336-
"raw": "https://{{$hostname}}/api/v1/firewall/rule?tracker=string or Integer&type=string&interface=string&ipprotocol=string&protocol=string&icmptype=string or array&src=string&dst=string&srcport=string or integer&dstport=string or integer&gateway=string&sched=string&disabled=boolean&descr=string&log=boolean&top=boolean&apply=boolean",
2356+
"raw": "https://{{$hostname}}/api/v1/firewall/rule?tracker=string or Integer&type=string&interface=string&ipprotocol=string&protocol=string&icmptype=string or array&src=string&dst=string&srcport=string or integer&dstport=string or integer&gateway=string&sched=string&dnpipe=string&pdnpipe=string&defaultqueue=string&ackqueue=string&disabled=boolean&descr=string&log=boolean&top=boolean&apply=boolean",
23372357
"protocol": "https",
23382358
"host": [
23392359
"{{$hostname}}"
@@ -2405,6 +2425,26 @@
24052425
"value": "string",
24062426
"description": "Update the firewall schedule to apply to this rule. This must be an existing firewall schedule name. Provide an empty string to remove the configured schedule from the rule. (optional)"
24072427
},
2428+
{
2429+
"key": "dnpipe",
2430+
"value": "string",
2431+
"description": "Update the traffic shaper limiter (in) queue for this rule. This must be an existing traffic shaper limiter or queue. This field is required if a `pdnpipe` value is provided. To unset this value, pass in an empty string. This will also unset the existing `pdnpipe` value. (optional)"
2432+
},
2433+
{
2434+
"key": "pdnpipe",
2435+
"value": "string",
2436+
"description": "Update the traffic shaper limiter (out) queue for this rule. This must be an existing traffic shaper limiter or queue. This value cannot match the `dnpipe` value and must be a child queue if `dnpipe` is a child queue, or a parent limiiter if `dnpipe` is a parent limiter. To unset this value, pass in an empty string. (optional)"
2437+
},
2438+
{
2439+
"key": "defaultqueue",
2440+
"value": "string",
2441+
"description": "Update the default traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue name. This field is required when an `ackqueue` value is provided. To unset this field, pass in an empty string. This will also unset the existing `ackqueue` value. (optional)"
2442+
},
2443+
{
2444+
"key": "ackqueue",
2445+
"value": "string",
2446+
"description": "Update acknowledge traffic shaper queue to apply to this rule. This must be an existing traffic shaper queue and cannot match the `defaultqueue` value. To unset this field, pass in an empty string. (optional)"
2447+
},
24082448
{
24092449
"key": "disabled",
24102450
"value": "boolean",

pfSense-pkg-API/files/etc/inc/api/framework/APIResponse.inc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,6 +2312,60 @@ function get($id, $data=[], $all=false) {
23122312
"return" => $id,
23132313
"message" => "Firewall traffic shaper limiter queue name does not exist"
23142314
],
2315+
4222 => [
2316+
"status" => "bad request",
2317+
"code" => 400,
2318+
"return" => $id,
2319+
"message" => "Unknown firewall rule dnpipe or pdnpipe"
2320+
],
2321+
4223 => [
2322+
"status" => "bad request",
2323+
"code" => 400,
2324+
"return" => $id,
2325+
"message" => "Firewall rule dnpipe is required for pdnpipe"
2326+
],
2327+
4224 => [
2328+
"status" => "bad request",
2329+
"code" => 400,
2330+
"return" => $id,
2331+
"message" => "Firewall rule dnpipe and pdnpipe queues cannot be the same"
2332+
],
2333+
4225 => [
2334+
"status" => "bad request",
2335+
"code" => 400,
2336+
"return" => $id,
2337+
"message" => "Firewall rule dnpipe and pdnpip queue and a virtual interface cannot be selected"
2338+
],
2339+
4226 => [
2340+
"status" => "bad request",
2341+
"code" => 400,
2342+
"return" => $id,
2343+
"message" => "Unknown firewall rule default queue"
2344+
],
2345+
4227 => [
2346+
"status" => "bad request",
2347+
"code" => 400,
2348+
"return" => $id,
2349+
"message" => "Firewall rule default queue required for ackqueue"
2350+
],
2351+
4228 => [
2352+
"status" => "bad request",
2353+
"code" => 400,
2354+
"return" => $id,
2355+
"message" => "Unknown firewall rule ackqueue"
2356+
],
2357+
4229 => [
2358+
"status" => "bad request",
2359+
"code" => 400,
2360+
"return" => $id,
2361+
"message" => "Firewall rule default queue and ackqueue cannot be the same"
2362+
],
2363+
4230 => [
2364+
"status" => "bad request",
2365+
"code" => 400,
2366+
"return" => $id,
2367+
"message" => "Firewall traffic shaper child queue cannot be deleted while in use"
2368+
],
23152369

23162370
//5000-5999 reserved for /users API calls
23172371
5000 => [

pfSense-pkg-API/files/etc/inc/api/models/APIFirewallRuleCreate.inc

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,91 @@ class APIFirewallRuleCreate extends APIModel {
223223
}
224224
}
225225

226+
private function __validate_dnpipe() {
227+
# Check for our optional 'dnpipe' payload value
228+
if (isset($this->initial_data["dnpipe"])) {
229+
# Load our dummynet config and fetch configured queues
230+
read_dummynet_config();
231+
$dnqueues = get_unique_dnqueue_list();
232+
233+
# Ensure this is a valid queue
234+
if (array_key_exists($this->initial_data["dnpipe"], $dnqueues)) {
235+
$this->validated_data["dnpipe"] = $this->initial_data["dnpipe"];
236+
} else {
237+
$this->errors[] = APIResponse\get(4222);
238+
}
239+
}
240+
}
241+
242+
private function __validate_pdnpipe() {
243+
# Check for our optional 'pdnpipe' payload value
244+
if (isset($this->initial_data["pdnpipe"])) {
245+
# Load our dummynet config and fetch configured queues
246+
read_dummynet_config();
247+
$dnqueues = get_unique_dnqueue_list();
248+
249+
# Only allow this setting if a dnpipe was set
250+
if (isset($this->validated_data["dnpipe"])) {
251+
# Ensure this is a valid queue
252+
if (array_key_exists($this->initial_data["pdnpipe"], $dnqueues)) {
253+
# Ensure the dnpipe does not match the pdn pipe
254+
if ($this->initial_data["pdnpipe"] !== $this->validated_data["dnpipe"]) {
255+
# Determine pipe types
256+
$dnpipe_type = $dnqueues[$this->validated_data['dnpipe']][0];
257+
$pdnpipe_type = $dnqueues[$_POST['pdnpipe']][0];
258+
259+
# Ensure the dnpipe and pdnpipe types do not match
260+
if (($dnpipe_type === "?" and $pdnpipe_type !== "?") or ($pdnpipe_type === "?" and $dnpipe_type !== "?")) {
261+
$this->validated_data["pdnpipe"] = $this->initial_data["pdnpipe"];
262+
} else {
263+
$this->errors[] = APIResponse\get(4225);
264+
}
265+
} else {
266+
$this->errors[] = APIResponse\get(4224);
267+
}
268+
} else {
269+
$this->errors[] = APIResponse\get(4222);
270+
}
271+
} else {
272+
$this->errors[] = APIResponse\get(4223);
273+
}
274+
}
275+
}
276+
277+
private function __validate_defaultqueue() {
278+
# Validate our optional 'defaultqueue' payload value
279+
if (isset($this->initial_data["defaultqueue"])) {
280+
# Require the value to be a known altq (traffic shaper) queue
281+
if ($this->is_altq_queue($this->initial_data["defaultqueue"])) {
282+
$this->validated_data["defaultqueue"] = $this->initial_data["defaultqueue"];
283+
} else {
284+
$this->errors[] = APIResponse\get(4226);
285+
}
286+
}
287+
}
288+
289+
private function __validate_ackqueue() {
290+
# Validate our optional 'ackqueue' payload value
291+
if (isset($this->initial_data["ackqueue"])) {
292+
# Only allow this field if a default queue was provided
293+
if (isset($this->validated_data["defaultqueue"])) {
294+
# Require the value to be a known altq (traffic shaper) queue
295+
if ($this->is_altq_queue($this->initial_data["ackqueue"])) {
296+
# Ackqueue cannot match default queue
297+
if ($this->initial_data["ackqueue"] !== $this->validated_data["defaultqueue"]) {
298+
$this->validated_data["ackqueue"] = $this->initial_data["ackqueue"];
299+
} else {
300+
$this->errors[] = APIResponse\get(4229);
301+
}
302+
} else {
303+
$this->errors[] = APIResponse\get(4228);
304+
}
305+
} else {
306+
$this->errors[] = APIResponse\get(4227);
307+
}
308+
}
309+
}
310+
226311
private function __validate_disabled() {
227312
# Check for our optional 'disabled' payload value
228313
if ($this->initial_data['disabled'] === true) {
@@ -263,6 +348,10 @@ class APIFirewallRuleCreate extends APIModel {
263348
$this->__validate_dstport();
264349
$this->__validate_gateway();
265350
$this->__validate_sched();
351+
$this->__validate_dnpipe();
352+
$this->__validate_pdnpipe();
353+
$this->__validate_defaultqueue();
354+
$this->__validate_ackqueue();
266355
$this->__validate_disabled();
267356
$this->__validate_descr();
268357
$this->__validate_log();
@@ -283,6 +372,24 @@ class APIFirewallRuleCreate extends APIModel {
283372
$this->validated_data["updated"] = $this->validated_data["created"];
284373
}
285374

375+
public function is_altq_queue($name) {
376+
# Local variables
377+
read_altq_config();
378+
$qlist = get_unique_queue_list();
379+
$iflist = get_configured_interface_with_descr();
380+
$list = [];
381+
382+
# Format interface queues
383+
foreach ($qlist as $q => $qkey) {
384+
if (isset($ifdisp[$q])) {
385+
$list[$q] = $iflist[$q];
386+
} else {
387+
$list[$q] = $q;
388+
}
389+
}
390+
return array_key_exists($name, $list);
391+
}
392+
286393
public function apply() {
287394
# Mark the firewall subsystem as changed, this will be cleared if applied
288395
mark_subsystem_dirty('filter');
@@ -293,4 +400,4 @@ class APIFirewallRuleCreate extends APIModel {
293400
clear_subsystem_dirty('filter');
294401
}
295402
}
296-
}
403+
}

0 commit comments

Comments
 (0)