Scenario: We needed an in-line, transparent traffic shaping solution. The solution we chose was pfsense due to it’s easy to use UI and effective QoS. The PfSense had to be placed in bridge mode, on a link that was carrying tagged traffic. It is important that the PfSense did not touch the vlan tagging, it was only to rate-limit the traffic.

The first step was to bridge the two interfaces. We first created allow rules on the firewall to allow all traffic to pass through the pfsense since filtering was not necessary. We then proceeded to bridge the interface via Interfaces > (assign) > bridges and creating a bridge interface containing the two interface in question. No further configuration was needed. PfSense retained the VLAN tagging so the L2 802.1q vlan tags were preserved across the bridge

An IP address was configured on one of the interfaces for management. Two points about configuring an IP address on the Pfsense:

It doesnt matter which interface you configure with the IP, the interfaces are bridged

The IP must be in the native vlan if you configure it on a physical pfsense interface

We next go on to defining queues for various traffic classes we needed. We decided not to use the wizard since that would introduce several feature we didnt need. The below is done via Firewall > Traffic Shaper.

Enable QoS on each interface by clicking on the interface on the left hand side and ticking “ Enable/disable discipline and its children “

“ Decide which scheduler type to use. We chose HFSC – this is the scheduler used by several industry firewalls such as Palo Alto.

Define the bandwidth available to the interface. In this case, since the firewall was internally placed, we set the bandwidth to 2GB/s

Proceed to define child queues by using the “Add new queue” button. How you place the queues (i.e. parent-child relationships) is highly dependent on what you want to achieve. In our case a single “layer” of queues was sufficient. we needed a queue for each customer and an “internal” queue which takes care of internal traffic – i.e. traffic not flowing out to the internet, which should not be rate limited. A couple of points about these queues: You need at least one default queue per interface. This will act as a catchall. A default queue is defined as any other queue, with the difference of selecting the “ default queue ” option in “scheduler options”



It’s always a good idea to enable random early detection in your queues in case they get over-subscribed





When dealing with high-bandwidth environments such as the one presented here (internal traffic on a gigabit network) you need to increase the queue limit (this option can be changed per queue). We found a value of 2000 to be sufficient. If left as per default, your queues will not provide the maximum bandwidth you configure for them

The most efficient QoS is applied to egress traffic. In order to visualize this, imagine you are the firewall… egress traffic on your WAN interface is what we generally call “uploading” to the internet. Similarly, egress traffic on the LAN is generally called “downloading” from the internet. Keep this in mind when defining queues. If you need to define the same queue on two interfaces (symmetric traffic shaping) simply add a new queue to the interface and ensure you name the queue in exactly the same way as you did on the other interface, for example:

Last, apply the queues you just defined. In our case, since we had symmetric traffic shaping we wanted the queues to apply in all directions, whether egressing from one interface or the other. So we defined floating rules via firewall > rules > floating tab.

The rules allow you to classify traffic as any other firewall rule does, so you can limit by subnet, IP, service, protocol, etc… simply define the rule, and under the advanced section make sure to select the correct queue (second fiel – the first field is used for ingress QoS which we didnt use)

The nice thing is that pfsense doesnt limit the maximum number of queues that you define – much better than some commercial solutions out there!!! 😉