commit 2d46e1e4ca155541513f282c715fa36b683f17a8
Author: Jean Cyr <jcyr@dillobits.com>
Date:   Tue May 21 18:53:48 2013 -0400

    Allow IPV6 bandwidth limiter mask

diff --git a/etc/inc/shaper.inc b/etc/inc/shaper.inc
index fbb1200237..ed8a911da8 100644
--- a/etc/inc/shaper.inc
+++ b/etc/inc/shaper.inc
@@ -2781,8 +2781,25 @@ class dummynet_class {
         /* mask parameters */
         var $mask;
         var $noerror;
+        
+        var $ipv6allow;
+        
+        /* constructor */
+                
+        function __construct() {
+                global $config;
+                if (isset($config['system']['ipv6allow']))
+                        $this->ipv6allow = True;
+                else
+                        $this->ipv6allow = False;
+
+        }
 
         /* Accessor functions */
+        function IPV6Enabled() {
+                return $this->ipv6allow;
+        }
+        
         function SetLink($link) {
                 $this->link = $link;
         }
@@ -2859,18 +2876,24 @@ class dummynet_class {
         }
 
 	function build_javascript() {
-		$javascript .= "<script type=\"text/javascript\"> \n";
+		$javascript .= "<script type=\"text/javascript\">\n";
 		$javascript .= "//<![CDATA[\n";
-		$javascript .= "function enable_maskbits(enable_over) { \n";
-		$javascript .= "var e = document.getElementById(\"mask\"); \n";
-		$javascript .= "if ((e.options[e.selectedIndex].text == \"none\") || enable_over) { \n";
+		$javascript .= "function enable_maskbits(enable_over) {\n";
+		$javascript .= "var e = document.getElementById(\"mask\");\n";
+		$javascript .= "if ((e.options[e.selectedIndex].text == \"none\") || enable_over) {\n";
 		$javascript .= "document.iform.maskbits.disabled = 1;\n";
 		$javascript .= "document.iform.maskbits.value = \"\";\n";
-		$javascript .= "} else \n";
+                if ($this->IPV6Enabled()) {
+                        $javascript .= "document.iform.maskbitsv6.disabled = 1;\n";
+                        $javascript .= "document.iform.maskbitsv6.value = \"\";\n";
+                }
+		$javascript .= "} else {\n";
 		$javascript .= "document.iform.maskbits.disabled = 0;\n";
-		$javascript .= "} \n";
+                if ($this->IPV6Enabled())
+                        $javascript .= "document.iform.maskbitsv6.disabled = 0;\n";
+		$javascript .= "}}\n";
 		$javascript .= "//]]>\n";
-		$javascript .= "</script>";
+		$javascript .= "</script>\n";
 		return $javascript;
 	}
 
@@ -2896,11 +2919,52 @@ class dummynet_class {
 			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
         	if (!empty($data['name']) && !preg_match("/^[a-zA-Z0-9_-]+$/", $data['name']))
 			$input_errors[] = gettext("Queue names must be alphanumeric and _ or - only.");
-                if (isset($data['maskbits']) && ($data['maskbits'] <> "")) {
+                if (isset($data['maskbits']) && ($data['maskbits'] <> ""))
 			if ((!is_numeric($data['maskbits'])) || ($data['maskbits'] <= 0) || ($data['maskbits'] > 32))
-				$input_errors[] = gettext("Bit mask must be blank or numeric value between 1 and 32.");
-		}
+				$input_errors[] = gettext("IPV4 bit mask must be blank or numeric value between 1 and 32.");
+                if ($this->IPV6Enabled())
+                        if (isset($data['maskbitsv6']) && ($data['maskbitsv6'] <> "")) {
+				if ((!is_numeric($data['maskbitsv6'])) || ($data['maskbitsv6'] <= 0) || ($data['maskbitsv6'] > 128))
+					$input_errors[] = gettext("IPV6 bit mask must be blank or numeric value between 1 and 128.");
+			}
+	}
+	
+	function build_mask_rules(&$pfq_rule) {
+		$mask = $this->GetMask();
+		if (!empty($mask['type'])) {
+			if ($mask['type'] <> 'none')
+				$pfq_rule .= " mask";
+			switch ($mask['type']) {
+			case 'srcaddress':
+                                if ($this->IPV6Enabled()) {
+                                        if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> ""))
+                                                $pfq_rule .= " src-ip6 /" . $mask['bitsv6'];
+					else
+						$pfq_rule .= " src-ip6 /128";
+                                }
+                                if (!empty($mask['bits']) && ($mask['bits'] <> ""))
+                                        $pfq_rule .= sprintf(" src-ip 0x%x", gen_subnet_mask_long($mask['bits']));
+                                else
+					$pfq_rule .= " src-ip 0xffffffff";
+				break;
+			case 'dstaddress':
+                                if ($this->IPV6Enabled()) {
+                                        if (!empty($mask['bitsv6']) && ($mask['bitsv6'] <> ""))
+                                                $pfq_rule .= " dst-ip6 /" . $mask['bitsv6'];
+					else
+						$pfq_rule .= " dst-ip6 /128";
+                                }
+                                if (!empty($mask['bits']) && ($mask['bits'] <> ""))
+                                        $pfq_rule .= sprintf(" dst-ip 0x%x", gen_subnet_mask_long($mask['bits']));
+                                else
+					$pfq_rule .= " dst-ip 0xffffffff";
+				break;
+			default:
+				break;
+			}
+		}            
 	}
+        
 }
 
 class dnpipe_class extends dummynet_class {
@@ -3055,7 +3119,11 @@ class dnpipe_class extends dummynet_class {
 			$maskbits = $q['maskbits'];
 		else
 			$maskbits = "";
-		$this->SetMask(array("type" => $masktype, "bits" => $maskbits));
+		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "")
+			$maskbitsv6 = $q['maskbitsv6'];
+		else
+			$maskbitsv6 = "";
+		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
 		if (isset($q['buckets']) && $q['buckets'] <> "")
               		$this->SetBuckets($q['buckets']);
 		else
@@ -3138,28 +3206,8 @@ class dnpipe_class extends dummynet_class {
 			$pfq_rule .= " buckets " . $this->GetBuckets();
 		if ($this->GetDelay())
 			$pfq_rule .= " delay " . $this->GetDelay();
+		$this->build_mask_rules($pfq_rule);
 
-		$mask = $this->GetMask();
-		if (!empty($mask['type'])) {
-			switch ($mask['type']) {
-			case 'srcaddress':
-				$pfq_rule .= " mask src-ip 0x";
-				if (!empty($mask['bits']) && ($mask['bits'] <> ""))
-					$pfq_rule .= sprintf("%x", gen_subnet_mask_long($mask['bits']));
-				else
-					$pfq_rule .= "ffffffff";
-				break;
-			case 'dstaddress':
-				$pfq_rule .= " mask dst-ip 0x";
-				if (!empty($mask['bits']) && ($mask['bits'] <> ""))
-					$pfq_rule .= sprintf("%x", gen_subnet_mask_long($mask['bits']));
-				else
-					$pfq_rule .= "ffffffff";
-				break;
-			default:
-				break;
-			}
-    	}            
 		$pfq_rule .= "\n";
 
 		if (!empty($this->subqueues) && count($this->subqueues) > 0) {
@@ -3339,7 +3387,17 @@ EOD;
 		if ($mask['type'] == "none")
 			$form .= " disabled";
 		$form .= " />";
-		$form .= "&nbsp; mask bits (1-32)<br/>";
+		$form .= "&nbsp; IPV4 mask bits (1-32)<br/>";
+                if ($this->IPV6Enabled()) {
+                        $form .= "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/&nbsp;<input type=\"text\" class=\"formfld unknown\" size=\"2\" id=\"maskbitsv6\" name=\"maskbitsv6\" value=\"";
+                        if ($mask['type'] <> "none")
+                        $form .= $mask['bitsv6'];
+                        $form .= "\"";
+                        if ($mask['type'] == "none")
+                                $form .= " disabled";
+                        $form .= " />";
+                        $form .= "&nbsp; IPV6 mask bits (1-128)<br/>";
+                }
 		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
 		      .  "leaving the mask bits blank will create one pipe per host. Otherwise specify \n"
 		      .  "the number of 'one' bits in the subnet mask used to group multiple hosts \n"
@@ -3425,6 +3483,10 @@ EOD;
 		$mask = $this->GetMask();
 		$cflink['mask'] = $mask['type'];
 		$cflink['maskbits'] = $mask['bits'];
+                if ($this->IPV6Enabled())
+                        $cflink['maskbitsv6'] = $mask['bitsv6'];
+                else
+                        $cflink['maskbitsv6'] = "";
 		$cflink['delay'] = $this->GetDelay();
 	}
 
@@ -3505,7 +3567,11 @@ class dnqueue_class extends dummynet_class {
 			$maskbits = $q['maskbits'];
 		else
 			$maskbits = "";
-		$this->SetMask(array("type" => $masktype, "bits" => $maskbits));
+		if (isset($q['maskbitsv6']) && $q['maskbitsv6'] <> "")
+			$maskbitsv6 = $q['maskbitsv6'];
+		else
+			$maskbitsv6 = "";
+		$this->SetMask(array("type" => $masktype, "bits" => $maskbits, "bitsv6" => $maskbitsv6));
        		if (isset($q['weight']) && $q['weight'] <> "")
             		$this->SetWeight($q['weight']);
 		else
@@ -3538,27 +3604,7 @@ class dnqueue_class extends dummynet_class {
 			$pfq_rule .= " weight " . $this->GetWeight();
 		if ($this->GetBuckets())
 			$pfq_rule .= " buckets " . $this->GetBuckets();
-		$mask = $this->GetMask();
-		if (!empty($mask['type'])) {
-			switch ($mask['type']) {
-			case 'srcaddress':
-				$pfq_rule .= " mask src-ip 0x";
-				if (!empty($mask['bits']) && ($mask['bits'] <> ""))
-					$pfq_rule .= sprintf("%x", gen_subnet_mask_long($mask['bits']));
-				else
-					$pfq_rule .= "ffffffff";
-				break;
-			case 'dstaddress':
-				$pfq_rule .= " mask dst-ip 0x";
-				if (!empty($mask['bits']) && ($mask['bits'] <> ""))
-					$pfq_rule .= sprintf("%x", gen_subnet_mask_long($mask['bits']));
-				else
-					$pfq_rule .= "ffffffff";
-				break;
-			default:
-				break;
-			}
-		}
+		$this->build_mask_rules($pfq_rule);
 		$pfq_rule .= "\n";
 
 		return $pfq_rule;
@@ -3619,7 +3665,17 @@ class dnqueue_class extends dummynet_class {
 		if ($mask['type'] == "none")
 			$form .= " disabled";
 		$form .= " />";
-		$form .= "&nbsp; mask bits (1-32)<br/>";
+		$form .= "&nbsp; IPV4 mask bits (1-32)<br/>";
+                if ($this->IPV6Enabled()) {
+                        $form .= "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/&nbsp;<input type=\"text\" class=\"formfld unknown\" size=\"2\" id=\"maskbitsv6\" name=\"maskbitsv6\" value=\"";
+                        if ($mask['type'] <> "none")
+                        $form .= $mask['bitsv6'];
+                        $form .= "\"";
+                        if ($mask['type'] == "none")
+                                $form .= " disabled";
+                        $form .= " />";
+                        $form .= "&nbsp; IPV6 mask bits (1-128)<br/>";
+                }
 		$form .= "<span class=\"vexpl\">" . gettext("If 'source' or 'destination' slots is chosen, \n"
 		      .  "leaving the mask bits blank will create one pipe per host. Otherwise specify \n"
 		      .  "the number of 'one' bits in the subnet mask used to group multiple hosts \n"
@@ -3702,6 +3758,10 @@ class dnqueue_class extends dummynet_class {
 		$mask = $this->GetMask();
 		$cflink['mask'] = $mask['type'];
 		$cflink['maskbits'] = $mask['bits'];
+                if ($this->IPV6Enabled())
+                        $cflink['maskbitsv6'] = $mask['bitsv6'];
+                else
+                        $cflink['maskbitsv6'] = "";
 	}
 }
 
