Diff for /wikisrc/tutorials/altqd_traffic_shaping_example.mdwn between versions 1.2 and 1.3

version 1.2, 2012/02/05 07:14:36 version 1.3, 2019/04/09 09:53:27
Line 4 Line 4
   
 #   A simple example of ALTqd in action   #   A simple example of ALTqd in action 
   
 The problem was that I needed to make sure that all UDP traffic for my SIP VoIP phones was handled with a higher priority than all the normal low priority internet traffic such as web requests. Altq is a very powerful that can do this and a lot of other things. It was invented as part of the KAME project, and it's implementation is different across the BSD world. In OpenBSD for example, it's integrated with the packet filter (pf). On NetBSD it works by enabling it in the kernel and then running a user-space daemon to implement your shaping rules.   The problem was that I needed to make sure that all UDP traffic for my SIP VoIP phones was handled with a higher priority than all the normal low priority internet traffic such as web requests. Altq is a very powerful that can do this and a lot of other things. It was invented as part of the KAME project. On NetBSD it works by enabling it in the kernel and then running a user-space daemon to implement your shaping rules. 
   
       
   
   
 #   Getting the kernel ready to use Altqd   #   Getting the kernel ready to use Altqd 
   
 You'll need to make sure your kernel supports ALTQd. It almost certainly will not do so by default. The GENERIC kernel or any of it's variants like GENERIC.MP will not support altq out of the box. You'll need to create a new kernel with all the ALTQ features enabled. Recompiling your kernel is not really hard, but it's outside the scope of what I'm trying to explain here. You can find detailed descriptions of how to do it on this wiki or in the NetBSD guide. The way to enable ALTQ in your new kernel is to uncomment all the ALTQ lines you'll find a block there. Once you have installed the new kernel. Reboot your computer.   You'll need to make sure your kernel supports ALTQd. It almost certainly will not do so by default. The `GENERIC` kernel or any of it's variants like `GENERIC.MP` will not support altq out of the box. You'll need to create a new kernel with all the ALTQ features enabled. Recompiling your kernel is not really hard, but it's outside the scope of what I'm trying to explain here. You can find detailed descriptions of how to do it on this wiki or in the NetBSD guide. The way to enable ALTQ in your new kernel is to uncomment all the ALTQ lines you'll find a block there. Once you have installed the new kernel. Reboot your computer. 
   
       
   
   
 #   Enabling ALTQd   #   Enabling ALTQd 
   
 You'll need to create an empty /etc/altqd.conf file for starters, then edit your /etc/rc.conf and add a line at the bottom that says "altqd=yes". Reboot or run "/etc/rc.d/altqd start"   You'll need to create an empty `/etc/altqd.conf` file for starters, then edit your `/etc/rc.conf` and add a line at the bottom that says `altqd=yes`. Reboot or run `/etc/rc.d/altqd start` 
   
       
   
   
 #   Now configure it   #   Now configure it 
   
 You now want to setup your altqd classes and filters. The class tells altqd what kind of traffic shaping you want to do. There are about five different types and they all have their uses for various situations. In my case I knew that SIP traffic was all UDP, and since people are mostly too stupid these days to use FTP or other non-web services that also use UDP (after all "the web == internet" right?), I didn't bother with any kind of complex filters. I would notice that SIP audio quality would fall anytime people were really cranking on web pages and downloading stuff. So here is what I used in my /etc/altqd.conf   You now want to setup your altqd classes and filters. The class tells altqd what kind of traffic shaping you want to do. There are about five different types and they all have their uses for various situations. In my case I knew that SIP traffic was all UDP, and since people are mostly too stupid these days to use FTP or other non-web services that also use UDP (after all "the web == internet" right?), I didn't bother with any kind of complex filters. I would notice that SIP audio quality would fall anytime people were really cranking on web pages and downloading stuff. So here is what I used in my `/etc/altqd.conf`
   
       
   
Line 55  Okay, let's face it. The configuration i Line 55  Okay, let's face it. The configuration i
     interface bge0 bandwidth 5M priq      interface bge0 bandwidth 5M priq
           
   
 This line says that we intend on using a the first broadcom ethernet interaface as the outgoing WAN interface to shape the traffic on. In order for for ALTQ algorithms to work, most of them need to know how much bandwidth that line has. Even though that interface is capable of 1000mbit (it's a gigabit copper port) it's connected to a fiber optic media converter which is connected to my ISP. The ISP only gives me the capability to transmit at 5mbit. So, I don't want ALTQ to assume we are dealing with a gigabit link here. Otherwise, I suspect our shaping rules wouldn't work at all. Also, you'll notice that I keep talking about this being the WAN interface. Shaping traffic on the LAN interface of this firewall (it does NAT using IP filter) might work as well. However, I prefer to shape it at the last possible moment before it leaves my control. The authors of the altq.conf(4) man page seem to agree with this approach.   This line says that we intend on using a the first broadcom ethernet interaface as the outgoing WAN interface to shape the traffic on. In order for for ALTQ algorithms to work, most of them need to know how much bandwidth that line has. Even though that interface is capable of 1000mbit (it's a gigabit copper port) it's connected to a fiber optic media converter which is connected to my ISP. The ISP only gives me the capability to transmit at 5mbit. So, I don't want ALTQ to assume we are dealing with a gigabit link here. Otherwise, I suspect our shaping rules wouldn't work at all. Also, you'll notice that I keep talking about this being the WAN interface. Shaping traffic on the LAN interface of this firewall (it does NAT using IP filter) might work as well. However, I prefer to shape it at the last possible moment before it leaves my control. The authors of the [[!template id="man" name="altq.conf" section="5"]] man page seem to agree with this approach. 
           
     class priq bge0 high_class NULL priority 2      class priq bge0 high_class NULL priority 2
           
   
 This line says that we want to create a new parent-class for ALTQ. The parent class tells ALTQ what kind of shaping we'll be doing. In this case it's "priq" which is shorthand for priority queuing. This algorithm makes sure that network buffers with my chosen type of traffic will be separated out by using filters, and the ones with higher priorities will be emptied first. Moving on we see that the class applies to the interface "bge0" which is good since we just defined that above. Next is a simple user-defined label for this class. I chose the string "high_class" so it would be clear. You can call it anything you want. I could have chose "voip_class" or "udp_traffic". It doesn't matter. You'll notice the next item is "NULL". That's because this class _is_ a parent class and thus it has no parent class of it's own. The man-page was helpful enough to tell me what to use there. The last two items "priority 2" are pretty clear. I'm simply telling this class what priority it is. The higher the value, the more priority it has. In most cases I believe you can assign an integer value of 0-15 with 15 being the highest priority.   This line says that we want to create a new parent-class for ALTQ. The parent class tells ALTQ what kind of shaping we'll be doing. In this case it's `priq` which is shorthand for priority queuing. This algorithm makes sure that network buffers with my chosen type of traffic will be separated out by using filters, and the ones with higher priorities will be emptied first. Moving on we see that the class applies to the interface `bge0` which is good since we just defined that above. Next is a simple user-defined label for this class. I chose the string `high_class` so it would be clear. You can call it anything you want. I could have chose `voip_class` or `udp_traffic`. It doesn't matter. You'll notice the next item is `NULL`. That's because this class _is_ a parent class and thus it has no parent class of it's own. The man-page was helpful enough to tell me what to use there. The last two items `priority 2` are pretty clear. I'm simply telling this class what priority it is. The higher the value, the more priority it has. In most cases I believe you can assign an integer value of 0-15 with 15 being the highest priority. 
   
 Now, we need a way to add certain types of traffic into this class. We'll use the altq filter syntax to do this. That's where the next line comes in   Now, we need a way to add certain types of traffic into this class. We'll use the altq filter syntax to do this. That's where the next line comes in 
           
     filter bge0 high_class 0 0 0 0 17      filter bge0 high_class 0 0 0 0 17
           
   
 The first three items should be clear enough. We are writing a filter for interface bge0 and we want traffic that matches the filter to fall under the pervue of the "high_class" class. The integers that follow are the part were I wish the author would have been just a tad more IP-Filterish or PF-like. Here is the template for those from the altq.conf(4) man page:   The first three items should be clear enough. We are writing a filter for interface bge0 and we want traffic that matches the filter to fall under the pervue of the `high_class` class. The integers that follow are the part were I wish the author would have been just a tad more IP-Filterish or PF-like. Here is the template for those from the [[!template id="man" name="altq.c
   onf" section="5"]] man page: 
           
     dst_addr [netmask mask] dport src_addr [netmask mask] sport proto [tos value [tosmask value]] [gpi value      dst_addr [netmask mask] dport src_addr [netmask mask] sport proto [tos value [tosmask value]] [gpi value
           
   
 The value "0" means "any". All the stuff in square braces is optional and not used in my example. So I'm saying "from any host on any port to any host on any port using protocol UDP". What about that spurious 17 at the end you say? It's the protocol number for UDP. You can find all such numbers in your /etc/protocols file. Now let's move on to the last line:   The value "0" means "any". All the stuff in square braces is optional and not used in my example. So I'm saying "from any host on any port to any host on any port using protocol UDP". What about that spurious 17 at the end you say? It's the protocol number for UDP. You can find all such numbers in your `/etc/protocols` file. Now let's move on to the last line: 
           
     class priq bge0 low_class NULL priority 0 default      class priq bge0 low_class NULL priority 0 default
           
   
 With the 'priq' algorithm there must be a default class. This is because you aren't going to want to have a filter for every conceivable type of traffic. We assign this class a lower priority than the class we just made for UDP. Also note that you don't have to write a filter for the default class as that would kind of defeat the whole purpose of having a default class.   With the `priq` algorithm there must be a default class. This is because you aren't going to want to have a filter for every conceivable type of traffic. We assign this class a lower priority than the class we just made for UDP. Also note that you don't have to write a filter for the default class as that would kind of defeat the whole purpose of having a default class. 
   
 #   Monitoring Your ALTQ Classes in Realtime   #   Monitoring Your ALTQ Classes in Realtime 
   
 You can use the tool "altqstat" to see traffic flowing through your classes in realtime. I'd highly recommend doing so and testing to make sure things are getting filtered where you want them. Just kick off "altqstat" from the command line and let it run. The second time it spits out some data, it'll start giving you kb/s figures which are very useful. Here is an example from mine:   You can use the tool [[!template id="man" name="altqstat" section="1"]] to see traffic flowing through your classes in realtime. I'd highly recommend doing so and testing to make sure things are getting filtered where you want them. Just kick off [[!template id="man" name="altqstat" section="1"]] from the command line and let it run. The second time it spits out some data, it'll start giving you kb/s figures which are very useful. Here is an example from mine: 
   
       
   
Line 95  You can use the tool "altqstat" to see t Line 96  You can use the tool "altqstat" to see t
          packets:9110912 (3917080357 bytes) drops:1338           packets:9110912 (3917080357 bytes) drops:1338
           
   
 You can see that my phones are taking 32.45kbps and everything else is consuming 439.47kbps. Had I not setup altq with 'priq', my UDP phone traffic would be drowning in a sea of http request. Instead, my calls are getting their packets out the door precious fractions faster and that's making a big difference in my call quality. Yeah!   You can see that my phones are taking 32.45kbps and everything else is consuming 439.47kbps. Had I not setup `altq` with `priq`, my UDP phone traffic would be drowning in a sea of http request. Instead, my calls are getting their packets out the door precious fractions faster and that's making a big difference in my call quality. Yeah! 
   

Removed from v.1.2  
changed lines
  Added in v.1.3


CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb