Add dummynet AQM and scheduler configuration support to pfSense Limit… #3941
Conversation
…ers through the GUI. Only shaper.inc was changed. Presently, the traffic shaper is versatile however outbound shaping can be tricky. This patch aims to solve that, allowing not only outgoing shaping through dummynet pipes but also enabling users to attach configurable shaping to virtually any interface. Right now, altq does not support LAGG ifaces, ixgbe, among others. Additionally, this patch adds an extraordinary amount of configuration to PIE, RED, and CoDel. Saving a limiter will show a table with each configuration parameter. This patch also offers descriptive help for intermediate users like myself. For developers, this patch makes adding new scheds/aqms very easy; just update the huge array at the top of the file and everything will fall in place. Also, ipfw command formats are defined dynamically with %variables.
|
The construct $q =& new class() is not valid in PHP 7. |
|
All PHP code needs to be PHP 7 compliant since support for 5.6 ends this year. |
|
Thanks -- good catch. I based my shaper.inc on an earlier point in the branch. I've revised and made the requested changes. |
|
Just noticed a problem with this patch where if you select a scheduler or AQM which doesn't support ECN it still writes out EDIT: Fixed |
…AQM to work: noecn was appended in rules.limiter. - Made a change to an array reference that was breaking my test
|
Also,
My sysctl calls assume a unit in milliseconds. I need to factor for this. Will make another change. This would affect a few other params as well EDIT: Fixed. I also changed the way my parameters are formatted as commands, as well as made some slight changes to the sched config (assign to pipe explicitly by #) |
…ed in ms. they appear to be microseconds instead (thanks Harvy66) - Fix a problem where I was recursively assigning parameters in FormatParameters(), but that was not an ideal method (using vsprintf instead) - Fix scheduler configuration to better mirror pfSense forum's command syntax (configuring scheduler w/ pipe now with: 'sched 1 config pipe 1' instead of 'sched 1 config')
|
Hey all, Changes made as requested last week. Been using this patch on my system for the past week and observed no issues save those already addressed. Any chance this could get reviewed soon? Anything needed from me? |
|
Nothing further needed. Just requires testing |
|
what is status on this is there an easy way to help test this? |
|
I have a few questions and notes for things you may need/want to change. Nothing too major. It will still need testing afterward. |
| @@ -176,4 +176,4 @@ if ($config_parsed == true) { | |||
| } | |||
| } | |||
|
|
|||
| ?> | |||
| ?> | |||
jim-p
Jun 8, 2018
Contributor
Why is this file changed? It doesn't appear related
Why is this file changed? It doesn't appear related
| return array_column(array_map($f, array_keys($a), $a), 1, 0); | ||
| } | ||
| function build_queue_params($array, $selected, $params, $id) { | ||
| $form .= '<div id="params_' . gettext($id) . '">'; |
jim-p
Jun 8, 2018
Contributor
Why does this $id need run through gettext()? From the other uses of this function, that's always hardcoded to an internal-looking value.
Why does this $id need run through gettext()? From the other uses of this function, that's always hardcoded to an internal-looking value.
| $form .= "<td class=\"col-xs-4\">" . gettext($value["name"]) . "</td>"; | ||
| $form .= "<td class=\"col-xs-8\"><input class=\"form-control\" type=" . gettext($value["type"]) | ||
| . " name=\"param_" . gettext($selected) . "_" . gettext($key) . "\" placeholder=\"" . | ||
| gettext($value["default"]) . "\" value=\"" . gettext($currentValue) . "\"/></td>"; |
jim-p
Jun 8, 2018
Contributor
Since value will contain user input, it needs encoding. Change this to htmlspecialchars(gettext($currentValue)).
The other variables appear to be hardcoded values so they should be OK.
Since value will contain user input, it needs encoding. Change this to htmlspecialchars(gettext($currentValue)).
The other variables appear to be hardcoded values so they should be OK.
|
|
||
| $form .= '</div>'; | ||
| $form .= '<script type="text/javascript">'; | ||
| $form .= 'events.push(function() {$("#' . gettext($id) . '").change(function() {$("#params_' . |
jim-p
Jun 8, 2018
Contributor
Another instance of $id run through gettext() when it probably isn't necessary.
Another instance of $id run through gettext() when it probably isn't necessary.
| /* Limiter patch */ | ||
| $selectedScheduler = getSchedulers()[$data['sched']]; | ||
| if (!$selectedScheduler) | ||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); |
jim-p
Jun 8, 2018
Contributor
If they submitted a scheduler that isn't valid, they would have to have bypassed a drop-down and odds are it's not worth printing the resulting value. It would get encoded by the error display function later but it's better to leave it off anyhow.
If they submitted a scheduler that isn't valid, they would have to have bypassed a drop-down and odds are it's not worth printing the resulting value. It would get encoded by the error display function later but it's better to leave it off anyhow.
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); | ||
| $selectedAqm = getAQMs()[$data['aqm']]; | ||
| if (!$selectedAqm) | ||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); |
jim-p
Jun 8, 2018
Contributor
See above about printing this value, and should this not reference AQM and not Scheduler?
See above about printing this value, and should this not reference AQM and not Scheduler?
| if ($data['ecn'] && $data['ecn'] == 'on' && !$selectedScheduler["ecn"] && !$selectedAqm["ecn"]) { | ||
| $input_errors[] = gettext("Explicit Congestion Notification is selected, but neither " . $selectedAqm["name"] . " nor " . $selectedScheduler["name"] . " support it."); | ||
| } | ||
| /* End limiter patch */ |
jim-p
Jun 8, 2018
Contributor
Ideally you should also have input validation to ensure values are in the correct format (e.g. integers, etc) and are within supported ranges. That is not necessarily a blocker, though.
Ideally you should also have input validation to ensure values are in the correct format (e.g. integers, etc) and are within supported ranges. That is not necessarily a blocker, though.
| /* Limiter patch */ | ||
| $selectedAqm = getAQMs()[$data['aqm']]; | ||
| if (!$selectedAqm) | ||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); |
jim-p
Jun 8, 2018
Contributor
See previous comment about printing this value, and also the message says scheduler but it looks like it should be AQM
See previous comment about printing this value, and also the message says scheduler but it looks like it should be AQM
|
@grandrivers You can test it by using the System Patches package, add |
…me funny EOL stuff that happened. 2. Unwrapped gettext() 3. Agreed. Sanitized. 4. Unwrapped gettext() 5. Took out input_errors item 6. Took out input_errors item 7. I like the idea of this. I would love to add heavier validation; unless I just affix for datatype I would need to know the constraints on which the parameters live for the AQM/scheds. Maybe that's documented. I can revisit this. 8. Took out input_errors item
|
@jim-p ,
Thanks for taking a look, Jim! I appreciate the feedback. |
|
working great over vpn interface. One issue I had when I clicked save was the extra params showed up with bunch of php nonsense and it went away when I clicked apply. Edit: just noticed the params don't show up properly in ui. All I see is values where label for param is suppose to be. |
|
on 2.4.4 devel applied using url: https://github.com/pfsense/pfsense/pull/3941.diff This is what I see: |
|
@blackyellowred This was my fault; it should be fixed now :) |
|
Thanks its fixed now |
|
Updated shaper.inc and rebooted. Comes up with php warning warning error. Crash report begins. Anonymous machine information: amd64 Crash report details: PHP Errors: No FreeBSD crash data found. ie: foreach ($selectedParameters as $key => $value) { |
|
Hey @jsbsmd it's because I set the default scheduler to "FIFO" when it's defined as "fifo" in code, but PHP is case sensitive. I'm making a patch right now for everyone. EDIT: Should be fixed now. |
|
works perfect now. thanks. |
| @@ -3824,11 +3824,7 @@ class dnpipe_class extends dummynet_class { | |||
|
|
|||
| /* Limiter patch */ | |||
| $selectedScheduler = getSchedulers()[$data['sched']]; | |||
| if (!$selectedScheduler) | |||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); | |||
jim-p
Jul 2, 2018
Contributor
This should still be tested -- Keep the test but do not put the variable in the error message.
This should still be tested -- Keep the test but do not put the variable in the error message.
| $selectedAqm = getAQMs()[$data['aqm']]; | ||
| if (!$selectedAqm) | ||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); |
jim-p
Jul 2, 2018
Contributor
This should still be tested -- Keep the test but do not put the variable in the error message.
This should still be tested -- Keep the test but do not put the variable in the error message.
| @@ -4511,8 +4507,6 @@ class dnqueue_class extends dummynet_class { | |||
|
|
|||
| /* Limiter patch */ | |||
| $selectedAqm = getAQMs()[$data['aqm']]; | |||
| if (!$selectedAqm) | |||
| $input_errors[] = gettext("Selected scheduler not recognized: " . $data['sched'] . '.'); | |||
jim-p
Jul 2, 2018
Contributor
This should still be tested -- Keep the test but do not put the variable in the error message.
This should still be tested -- Keep the test but do not put the variable in the error message.
|
@jim-p, thanks again for taking a look -- I've made the requested changes. |
|
I just wanted to applaud y'all for getting fq_codel in there. Got any benchmarks? (rrul test from flent.org is good) |
|
That's quite an improvement. Welcome to the debloated internet club. :) I'm so glad pfsense got this code running and y'all can have way better internet. We have flent servers all over the world, if you would like to try a closer one (my guess is you are on the east coast?) - try flent-newark.bufferbloat.net. It would be interesting to get a docsis-pie result also (just shape the download), but at first eyeball I don't think pie is on. (one way to tell might be: flent -H flent-newark.bufferbloat.net tcp_upload) - pie ping latency on the upload would peak at ~20ms) "This is, of course, my home connection. I'm testing from a Debian VM hosted on a 2x X5650 server using an I350-T as the adapter in 2xGigE active load-balance LACP with the Modem. The pfSense VM is virtualized via Hyper-V on the same server, and I'm not using SR-IOV or vf's with the NIC. The Debian VM communicates with pfSense over a vSwitch on that host." As for this I can't help but laugh at how geeky we all are. Can you fix your parent's internet with something less extreme? Your neighbors? :) It's kind of weirdly wonderful that with all those layers you can still have reasonably accurate clock resolution. |
|
I'm also curious as to what happens with w/wo fq_codel, applied without a shaper, to the ethernet interface, over a 1gige or 100mbit local, native link. Linux regulates the local ring buffer with BQL (see https://lwn.net/Articles/454390/ ) which is necessary as they went hog-wild with offloads. |
|
@Manevolent Curious - how did you create those charts in #3941 (comment) above? |
|
@victorhooi that's a standard flent.org rrul plot. |
|
Oh - Flent looks very awesome! Just trying to find articles about it now: https://blog.tohojo.dk/2017/04/the-story-of-flent-the-flexible-network-tester.html iperf/netperf is for testing within the LAN however - so I'm curious what people are using as the remote endpoint to test for bufferbloat? Or do you setup your own netperf/iperf system on a cloud server somewhere nearby and try that? |
|
we have 6-7 public flent servers in the cloud at any given time. flent-fremont.bufferbloat.net (west coast) And the rest are in europe. We generally hope that folk will setup netserver and irtt ( https://github.com/heistp/irtt ) on their own clouds/servers... these are not good much past 5-600Mbit. if anyone wants to donate a server, that's nice too. :) |


Add dummynet AQM and scheduler configuration support to pfSense Limiters through the GUI. Only shaper.inc was changed.
Screenshot: https://i.imgur.com/N36gpXF.png
Related discussion: https://forum.pfsense.org/index.php?topic=126637
Highlights
Usage
Concept & Changes
I have added a new section ("Queue") to both Limiters and their child queues. Limiters have applicable several options:
NOTE: Limiters by default have an in-configurable (?) FIFO scheduler attached to the underlying pipe. So, you should not attach traffic to a limiter if you expect to schedule it with a different scheduler than FIFO. For this, you have to attach it to a child queue. See the related forum thread for details on this.
Limiter children have all of the same options, except do not define a scheduler. This is inherited from their configured parent's scheduler, and shared among the respective limiter's queues:
Generated ipfw commands (rules.limiter):