commit 1b8b0963fc2d11e479e128a6443e531c8fa71460
Author: Marcos Mendoza <mmendoza@netgate.com>
Date:   Thu Aug 10 16:53:54 2023 -0600

    Revert "Refactor outbound NAT target config field"
    
    This reverts commit 5557bc594916a5a6ff51ac8ed319a6ad436d3475.

diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc
index a2e4632e4d..1354ab19c8 100644
--- a/src/etc/inc/filter.inc
+++ b/src/etc/inc/filter.inc
@@ -1990,7 +1990,7 @@ function filter_nat_rules_outbound_automatic($src) {
 		$natent['interface'] = $if;
 		$natent['source']['network'] = $src;
 		$natent['dstport'] = "500";
-		$natent['target'] = "";
+		$natent['target_type'] = "";
 		$natent['destination']['any'] = true;
 		$natent['staticnatport'] = true;
 		$natent['descr'] = gettext('Auto created rule for ISAKMP');
@@ -2000,7 +2000,7 @@ function filter_nat_rules_outbound_automatic($src) {
 		$natent['interface'] = $if;
 		$natent['source']['network'] = $src;
 		$natent['sourceport'] = "";
-		$natent['target'] = "";
+		$natent['target_type'] = "";
 		$natent['destination']['any'] = true;
 		$natent['natport'] = "";
 		$natent['descr'] = gettext('Auto created rule');
@@ -2439,7 +2439,7 @@ function filter_nat_rules_generate() {
 				continue;
 			}
 
-			$obtarget = $obent['target'] . (!is_alias($obent['target'] && !empty($obent['target_subnet'])) ? '/' . $obent['target_subnet'] : '');
+			$obtarget = ($obent['target_type'] == "network") ? $obent['target'] . '/' . $obent['target_subnet']: $obent['target_type'];
 			$poolopts = (is_subnet($obtarget) || is_alias($obtarget)) ? $obent['poolopts'] : "";
 
 			/* pool option source-hash allows specification of an optional source-hash key */
@@ -2500,7 +2500,7 @@ function filter_nat_rules_generate() {
 					$a_out['sourceport'],
 					$a_out['destination']['address'],
 					$a_out['dstport'],
-					$a_out['target'],
+					$a_out['target_type'],
 					$a_out['natport'],
 					isset($a_out['nonat']),
 					isset($a_out['staticnatport']));
diff --git a/src/etc/inc/upgrade_config.inc b/src/etc/inc/upgrade_config.inc
index 72dec94364..df72314fe5 100644
--- a/src/etc/inc/upgrade_config.inc
+++ b/src/etc/inc/upgrade_config.inc
@@ -6791,14 +6791,27 @@ function upgrade_229_to_230() {
 	foreach ($obn_rules as & $obent) {
 		if (empty($obent['target'])) {
 			// migrate interface address selection
-			$obent['target'] = $obent['interface'] . 'ip';
+			$obent['target_type'] = $obent['interface'] . 'ip';
+			$obent['target'] = '';
+			$obent['target_subnet'] = '';
+		} elseif (str_contains($obent['target'], ':') ||
+		          str_contains($obent['target'], '.')) {
+			// migrate VIPs
+			if (get_specialnet($obent['target'])) {
+				$obent['target_type'] = $obent['target'];
+				$obent['target'] = '';
+			} else {
+				$obent['target_type'] = '';
+			}
 			$obent['target_subnet'] = '';
 		} elseif ($obent['target'] == 'other-subnet') {
 			// migrate custom subnets
+			$obent['target_type'] = 'network';
 			$obent['target'] = $obent['targetip'];
 			$obent['target_subnet'] = $obent['targetip_subnet'];
 		} else {
-			// migrate VIPs and aliases
+			// migrate aliases
+			$obent['target_type'] = 'network';
 			$obent['target_subnet'] = '';
 		}
 		foreach (['targetip', 'targetip_subnet'] as $old) {
diff --git a/src/usr/local/pfSense/include/www/firewall_nat_out.inc b/src/usr/local/pfSense/include/www/firewall_nat_out.inc
index 311767673f..4d03ae8285 100644
--- a/src/usr/local/pfSense/include/www/firewall_nat_out.inc
+++ b/src/usr/local/pfSense/include/www/firewall_nat_out.inc
@@ -73,7 +73,7 @@ function saveNAToutMode($post, $json = false) {
 					if ($rule['interface'] == $natent['interface'] &&
 					    $rule['source']['network'] == $natent['source']['network'] &&
 					    $rule['dstport'] == $natent['dstport'] &&
-					    $rule['target'] == $natent['target'] &&
+					    $rule['target_type'] == $natent['target_type'] &&
 					    $rule['descr'] == $natent['descr']) {
 						$found = true;
 						break;
@@ -285,13 +285,8 @@ function saveoutNATrule($post, $id, $json = false) {
 		$natent['source']['network'] = $osn;
 		$natent['sourceport'] = ($protocol_uses_ports) ? $post['sourceport'] : "";
 		$natent['descr'] = $post['descr'];
-		if (isset($post['nonat'])) {
-			$natent['target'] = '';
-		} elseif ($post['target_type'] == 'network') {
-			$natent['target'] = $post['target'];
-		} else {
-			$natent['target'] = $post['target_type'];
-		}
+		$natent['target_type'] = (!isset($post['nonat'])) ? $post['target_type'] : "";
+		$natent['target'] = (!isset($post['nonat'])) ? $post['target'] : "";
 		$natent['target_subnet'] = (!isset($post['nonat'])) ? $post['target_subnet'] : "";
 		$natent['interface'] = $post['interface'];
 		$natent['poolopts'] = $poolopts;
@@ -407,35 +402,18 @@ function getoutNATrule($id, $json = false) {
 	
 		$pconfig['ipprotocol'] = $a_out[$id]['ipprotocol'];
 		$pconfig['protocol'] = $a_out[$id]['protocol'];
-
-		$pconfig['source_type'] = 'any';
-		$pconfig['source'] = '';
-		$pconfig['source_subnet'] = '';
-		if (!empty($a_out[$id]['source']['network'])) {
-			if (get_specialnet($a_out[$id]['source']['network'])) {
-				$pconfig['source_type'] = $pconfig['source'];
-			} else {
-				$pconfig['source_type'] = 'network';
-				list($pconfig['source'], $pconfig['source_subnet']) = explode('/', $a_out[$id]['source']['network']);
-			}
+		list($pconfig['source'], $pconfig['source_subnet']) = explode('/', $a_out[$id]['source']['network']);
+		if (!is_numeric($pconfig['source_subnet'])) {
+			$pconfig['source_subnet'] = 32;
 		}
 		$pconfig['sourceport'] = $a_out[$id]['sourceport'];
-
-		$pconfig['destination_type'] = 'any';
-		$pconfig['destination'] = '';
-		$pconfig['destination_subnet'] = '';
-		if (!empty($a_out[$id]['destination']['address'])) {
-			if (get_specialnet($a_out[$id]['destination']['address'])) {
-				$pconfig['destination_type'] = $pconfig['destination'];
-			} else {
-				$pconfig['destination_type'] = 'network';
-				list($pconfig['destination'], $pconfig['destination_subnet']) = explode('/', $a_out[$id]['destination']['address']);
-			}
-		}
+		address_to_pconfig($a_out[$id]['destination'], $pconfig['destination'],
+			$pconfig['destination_subnet'], $pconfig['destination_not'],
+			$none, $none);
+	
 		$pconfig['dstport'] = $a_out[$id]['dstport'];
-		$pconfig['destination_not'] = (isset($a_out[$id]['destination']['not'])) ? 1 : 0;
-
 		$pconfig['natport'] = $a_out[$id]['natport'];
+		$pconfig['target'] = $a_out[$id]['target'];
 		$pconfig['target_subnet'] = $a_out[$id]['target_subnet'];
 		$pconfig['poolopts'] = $a_out[$id]['poolopts'];
 		$pconfig['source_hash_key'] = $a_out[$id]['source_hash_key'];
@@ -444,26 +422,18 @@ function getoutNATrule($id, $json = false) {
 		if (!$pconfig['interface']) {
 			$pconfig['interface'] = "wan";
 		}
-		$pconfig['target'] = $a_out[$id]['target'];
-		if (empty($pconfig['target'])) {
-			$pconfig['target_type'] = $pconfig['interface'] . 'ip';
-		} else {
-			$pconfig['target_type'] = (get_specialnet($pconfig['target'])) ? $pconfig['target'] : 'network';
-		}
+		$pconfig['target_type'] = empty($a_out[$id]['target_type']) ? $pconfig['interface'] . 'ip' : $a_out[$id]['target_type'];
 		$pconfig['descr'] = $a_out[$id]['descr'];
 		$pconfig['nonat'] = $a_out[$id]['nonat'];
 		$pconfig['disabled'] = isset($a_out[$id]['disabled']);
 		$pconfig['staticnatport'] = isset($a_out[$id]['staticnatport']);
 		$pconfig['nosync'] = isset($a_out[$id]['nosync']);
 	} else {
-		$pconfig['source_type'] = 'any';
-		$pconfig['source'] = '';
-		$pconfig['source_subnet'] = '';
-		$pconfig['destination_type'] = 'any';
-		$pconfig['destination'] = '';
-		$pconfig['destination_subnet'] = '';
-		$pconfig['interface'] = 'wan';
-		$pconfig['target'] = $pconfig['interface'] . 'ip';
+		$pconfig['source_subnet'] = 24;
+		$pconfig['destination'] = "any";
+		$pconfig['destination_subnet'] = 24;
+		$pconfig['interface'] = "wan";
+		$pconfig['target_type'] = $pconfig['interface'] . 'ip';
 	}
 
 	return $json ? json_encode($pconfig):$pconfig;
diff --git a/src/usr/local/www/firewall_nat_out.php b/src/usr/local/www/firewall_nat_out.php
index 57032378db..bc0482219e 100644
--- a/src/usr/local/www/firewall_nat_out.php
+++ b/src/usr/local/www/firewall_nat_out.php
@@ -320,8 +320,8 @@ print($form);
 <?php
 						if (isset($natent['nonat'])) {
 							echo '<I>NO NAT</I>';
-						} elseif (array_key_exists($natent['target'], $specialnet)) {
-							echo htmlspecialchars($specialnet[$natent['target']]);
+						} elseif ($natent['target_type'] != "network" && array_key_exists($natent['target_type'], $specialnet)) {
+							echo htmlspecialchars($specialnet[$natent['target_type']]);
 						} elseif (!empty($natent['target'])) {
 							if (isset($alias['target'])):
 ?>
@@ -329,7 +329,7 @@ print($form);
 <?php
 							endif;
 ?>
-							<?=str_replace('_', '_<wbr>', htmlspecialchars($natent['target'] . ((!isset($alias['target']) && !empty($natent['target_subnet'])) ? '/' . $natent['target_subnet'] : '')))?>
+							<?=str_replace('_', '_<wbr>', htmlspecialchars(pprint_port($natent['target']))) . (!empty($natent['target_subnet'] && !isset($alias['target'])) ? '/' . $natent['target_subnet'] : '')?>
 <?php
 							if (isset($alias['target'])):
 ?>
@@ -476,8 +476,8 @@ if ($mode == "automatic" || $mode == "hybrid"):
 <?php
 		if (isset($natent['nonat'])) {
 			echo 'NO NAT';
-		} elseif (array_key_exists($natent['target'], $specialnet)) {
-			echo htmlspecialchars($specialnet[$natent['target']]);
+		} elseif ($natent['target_type'] != "network" && array_key_exists($natent['target_type'], $specialnet)) {
+			echo htmlspecialchars($specialnet[$natent['target_type']]);
 		} elseif (!empty($natent['target'])) {
 			echo $natent['target'] . (!empty($natent['target_subnet']) ? '/' . $natent['target_subnet'] : '');
 		}
diff --git a/src/usr/local/www/firewall_nat_out_edit.php b/src/usr/local/www/firewall_nat_out_edit.php
index 87ea2eed3c..5b2a0a1b00 100644
--- a/src/usr/local/www/firewall_nat_out_edit.php
+++ b/src/usr/local/www/firewall_nat_out_edit.php
@@ -126,7 +126,7 @@ $group = new Form_Group('*Source');
 $group->add(new Form_Select(
 	'source_type',
 	null,
-	$pconfig['source_type'],
+	(($pconfig['source'] == "any") || ($pconfig['source'] == "(self)")) ? $pconfig['source'] : "network",
 	get_specialnet('', [SPECIALNET_ANY, SPECIALNET_SELF, SPECIALNET_NETAL])
 ))->setHelp('Type')->setWidth('3');
 
@@ -151,14 +151,14 @@ $group = new Form_Group('*Destination');
 $group->add(new Form_Select(
 	'destination_type',
 	null,
-	$pconfig['destination_type'],
+	$pconfig['destination'] == "any" ? "any":"network",
 	get_specialnet('', [SPECIALNET_ANY, SPECIALNET_NETAL])
 ))->setHelp('Type')->setWidth('3');
 
 $group->add(new Form_IpAddress(
 	'destination',
 	null,
-	$pconfig['destination'],
+	$pconfig['destination'] == "any" ? "":$pconfig['destination'],
 	'ALIASV4V6'
 ))->addMask('destination_subnet', $pconfig['destination_subnet'])->setHelp('Destination network for the outbound NAT mapping.');
 
