diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc
index 52667c97c6735a0bd9ae682138e1c4efffb7c3f3..b8a34322b158af5ae0db4e4ea93573ce066cd7b4 100644
--- a/src/etc/inc/filter.inc
+++ b/src/etc/inc/filter.inc
@@ -2165,6 +2165,7 @@ function filter_nat_rules_generate() {
 			if (isset($rule['disabled'])) {
 				continue;
 			}
+			$rule['ipprotocol'] = 'inet6';
 
 			if (!$rule['interface']) {
 				$natif = "wan";
diff --git a/src/usr/local/pfSense/include/www/firewall_nat_npt.inc b/src/usr/local/pfSense/include/www/firewall_nat_npt.inc
index 6edc06389014c42783e9829410b7d35499ac3957..802d267ecc234525ba14a2ca758a5f8e4ba2ac85 100644
--- a/src/usr/local/pfSense/include/www/firewall_nat_npt.inc
+++ b/src/usr/local/pfSense/include/www/firewall_nat_npt.inc
@@ -47,8 +47,10 @@ function savenptNATrule($post, $id, $json = false) {
 	$reqdfieldsn = array(gettext("Interface"));
 	$reqdfields[] = "src";
 	$reqdfieldsn[] = gettext("Source prefix");
-	$reqdfields[] = "dst";
-	$reqdfieldsn[] = gettext("Destination prefix");
+	if (!is_specialnet($post['dsttype'])) {
+		$reqdfields[] = "dst";
+		$reqdfieldsn[] = gettext("Destination prefix");
+	}
 
 	if (!$json) {
 		do_input_validation($post, $reqdfields, $reqdfieldsn, $input_errors);
@@ -57,13 +59,20 @@ function savenptNATrule($post, $id, $json = false) {
 	if (!is_ipaddrv6(trim($post['src']))) {
 		$input_errors[] = gettext("The specified source address is not a valid IPv6 prefix");
 	}
-	if (!is_ipaddrv6(trim($post['dst']))) {
+	if (!is_ipaddrv6(trim($post['dst'])) && !is_specialnet(trim($post['dsttype']))) {
 		$input_errors[] = gettext("The specified destination address is not a valid IPv6 prefix");
 	}
 	if (check_subnetsv6_overlap(get_interface_ipv6($post['interface']), 128, trim($post['dst']), $post['dstmask']) &&
 	    !$post['dstnot']) {
 		$input_errors[] = gettext("The specified destination address and interface IPv6 address cannot overlap");
 	}
+	if (is_specialnet($post['dsttype'])) {
+		$track6ip = get_interface_track6ip($post['dsttype']);
+		$post['dstmask'] = $track6ip[1];
+	}
+	if (!empty($post['dstmask']) && ($post['srcmask'] != $post['dstmask'])) {
+		$input_errors[] = gettext("The specified source prefix size must be equal to the destination prefix size.");
+	}
 
 	if (!$input_errors) {
 		$natent = array();
@@ -75,7 +84,10 @@ function savenptNATrule($post, $id, $json = false) {
 		if ($post['src']) {
 			$post['src'] = trim($post['src']);
 		}
-		if ($post['dst']) {
+		if (is_specialnet($post['dsttype'])) {
+			$post['dst'] = $post['dsttype'];
+			$post['dstmask'] = 0;
+		} elseif ($post['dst']) {
 			$post['dst'] = trim($post['dst']);
 		}
 
@@ -240,4 +252,4 @@ function applynptNATrules() {
 	return $retval;
 }
 
-?>
\ No newline at end of file
+?>
diff --git a/src/usr/local/www/firewall_nat_npt.php b/src/usr/local/www/firewall_nat_npt.php
index 432da1dc428474ae8fccdd1dfe48a663ab3b728d..f773c9591440a2047d1becc2e9af428db4363de0 100644
--- a/src/usr/local/www/firewall_nat_npt.php
+++ b/src/usr/local/www/firewall_nat_npt.php
@@ -140,7 +140,15 @@ display_top_tabs($tab_array);
 						</td>
 						<td>
 <?php
-	echo $textss . pprint_address($natent['destination']) . $textse;
+		if (is_array($config['interfaces'][$natent['destination']['network']]) &&
+		    ($config['interfaces'][$natent['destination']['network']]['ipaddrv6'] == 'track6')) {
+			$track6ip = get_interface_track6ip($natent['destination']['network']);
+			$pdsubnet = gen_subnetv6($track6ip[0], $track6ip[1]);
+			$dst = "{$config['interfaces'][$natent['destination']['network']]['descr']} ({$pdsubnet}/{$track6ip[1]})";
+		} else {
+			$dst = pprint_address($natent['destination']);
+		}
+		echo $textss . $dst . $textse;
 ?>
 						</td>
 						<td>
diff --git a/src/usr/local/www/firewall_nat_npt_edit.php b/src/usr/local/www/firewall_nat_npt_edit.php
index 929b619cd411ef07a3ef51c49fded94dd3b45d88..150b9bdc35dce2269e93984951a510f57576790f 100644
--- a/src/usr/local/www/firewall_nat_npt_edit.php
+++ b/src/usr/local/www/firewall_nat_npt_edit.php
@@ -80,6 +80,42 @@ $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("NPt"), gettext("E
 $pglinks = array("", "firewall_nat.php", "firewall_nat_npt.php", "@self");
 include("head.inc");
 
+function dsttype_selected() {
+	global $pconfig;
+
+	if ($pconfig['dsttype']) {
+		// The rule type came from the $_POST array, after input errors, so keep it.
+		return $pconfig['dsttype'];
+	}
+
+	$sel = is_specialnet($pconfig['dst']);
+
+	if (!$sel) {
+		return('network');
+	}
+
+	return($pconfig['dst']);
+}
+
+function build_dsttype_list() {
+	global $pconfig, $config;
+
+	$sel = is_specialnet($pconfig['dst']);
+	$list = array('network' => gettext('Prefix'));
+
+	foreach (get_configured_interface_with_descr() as $if => $ifdesc) {
+		if (($config['interfaces'][$if]['ipaddrv6'] == 'track6') && 
+		    get_interface_track6ip($if)) {
+			$track6ip = get_interface_track6ip($if);
+			$pdsubnet = gen_subnetv6($track6ip[0], $track6ip[1]);
+			$sntext .= " ({$pdsubnet}/{$track6ip[1]})";
+			$list[$if] = $ifdesc . $sntext;
+		}
+	}
+
+	return($list);
+}
+
 if ($input_errors) {
 	print_input_errors($input_errors);
 }
@@ -103,34 +139,58 @@ $section->addInput(new Form_Select(
 ))->setHelp('Choose which interface this rule applies to.%s' .
 			'Hint: Typically the "WAN" is used here.', '<br />');
 
-$section->addInput(new Form_Checkbox(
+$group = new Form_Group('*Source IPv6 prefix');
+
+$group->add(new Form_Checkbox(
 	'srcnot',
 	'Internal IPv6 prefix',
 	'Not',
 	$pconfig['srcnot']
-))->setHelp('Use this option to invert the sense of the match. ');
+))->setHelp('Invert the sense of the match.')->setWidth(2);
+
+$group->add(new Form_StaticText(
+	null,
+	null
+))->setWidth(3);
 
-$section->addInput(new Form_IpAddress(
+$group->add(new Form_IpAddress(
 	'src',
-	'*Address',
+	'*Source prefix',
 	$pconfig['src'],
 	'V6'
-))->addMask('srcmask', $pconfig['srcmask'])->setHelp('Internal (LAN) ULA IPv6 Prefix for the Network Prefix translation. ' .
-													 'The prefix size specified for the internal IPv6 prefix will be applied to the external prefix.');
+))->addMask('srcmask', $pconfig['srcmask'], 128, 1, false);
 
-$section->addInput(new Form_Checkbox(
+$group->setHelp('Internal (LAN) ULA IPv6 Prefix for the Network Prefix translation. ' .
+		'The prefix size specified for the internal IPv6 prefix will be applied to the external prefix.');
+
+$section->add($group);
+
+$group = new Form_Group('*Destination IPv6 prefix');
+
+$group->add(new Form_Checkbox(
 	'dstnot',
-	'Destination IPv6 prefix',
+	null,
 	'Not',
 	$pconfig['dstnot']
-))->setHelp('Use this option to invert the sense of the match. ');
+))->setHelp('Invert the sense of the match.')->setWidth(2);
 
-$section->addInput(new Form_IpAddress(
+$group->add(new Form_Select(
+	'dsttype',
+	null,
+	dsttype_selected(),
+	build_dsttype_list()
+))->setHelp('Type')->setWidth(3);
+
+$group->add(new Form_IpAddress(
 	'dst',
-	'*Address',
+	'*Destination prefix',
 	$pconfig['dst'],
 	'V6'
-))->addMask('dstmask', $pconfig['dstmask'])->setHelp('Global Unicast routable IPv6 prefix');
+))->addMask('dstmask', $pconfig['dstmask'], 128, 1, false);
+
+$group->setHelp('Global Unicast routable IPv6 prefix');
+
+$section->add($group);
 
 $section->addInput(new Form_Input(
 	'descr',
@@ -150,5 +210,39 @@ if (isset($id) && $a_npt[$id]) {
 
 $form->add($section);
 print($form);
+?>
+
+<script type="text/javascript">
+//<![CDATA[
+events.push(function() {
+
+	function typesel_change() {
+		switch ($('#dsttype').find(":selected").index()) {
+			case 0: // prefix
+				disableInput('dst', false);
+				disableInput('dstmask', false);
+				break;
+			default:
+				$('#dst').val('');
+				disableInput('dst', true);
+				$('#dstmask').val('');
+				disableInput('dstmask', true);
+				break;
+		}
+	}
+
+	// ---------- Click checkbox handlers ---------------------------------------------------------
+
+	$('#dsttype').change(function () {
+		typesel_change();
+	});
+
+	// ---------- On initial page load ------------------------------------------------------------
+
+	typesel_change();
+
+});
+//]]>
+</script>
 
-include("foot.inc");
+<?php include("foot.inc");
