Project

General

Profile

« Previous | Next » 

Revision 235c051f

Added by Jim Pingle about 7 years ago

Rework how IPsec VTI interfaces and reqid specifications for same are formed. Ticket #8544

View differences:

src/etc/inc/interfaces.inc
1212 1212
	return $gifif;
1213 1213
}
1214 1214

  
1215
/* Build a list of IPsec interfaces */
1216
function interface_ipsec_vti_list_p1($ph1ent) {
1217
	global $config;
1218
	$iface_list = array();
1219

  
1220
	if (empty($ph1ent) || !is_array($ph1ent) || !is_array($config['ipsec']['phase2'])) {
1221
		return $iface_list;
1222
	}
1223

  
1224
	$vtisubnet_spec = ipsec_vti($ph1ent, true);
1225
	if ((!$vtisubnet_spec || !is_array($vtisubnet_spec))) {
1226
		return $iface_list;
1227
	}
1228

  
1229
	/* With IKEv1 or v2+Split, each P2 gets its own conn/reqid/interface */
1230
	if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1231
		foreach ($vtisubnet_spec as $idx => $vtisub) {
1232
			$iface_list["ipsec{$ph1ent['ikeid']}00{$idx}"] = gettext("IPsec VTI") . ": ".htmlspecialchars($ph1ent['descr'] . " / " . $vtisub['descr']);
1233
		}
1234
	} else {
1235
		/* For IKEv2, only create one interface with additional addresses as aliases */
1236
		$iface_list["ipsec{$ph1ent['ikeid']}000"] = gettext("IPsec VTI") . ": ".htmlspecialchars($ph1ent['descr']);
1237
	}
1238
	return $iface_list;
1239
}
1240
function interface_ipsec_vti_list_all() {
1241
	global $config;
1242
	$iface_list = array();
1243
	if (is_array($config['ipsec']) && is_array($config['ipsec']['phase1']) && is_array($config['ipsec']['phase2'])) {
1244
		foreach ($config['ipsec']['phase1'] as $ph1ent) {
1245
			if ($ph1ent['disabled']) {
1246
				continue;
1247
			}
1248
			$iface_list = array_merge($iface_list, interface_ipsec_vti_list_p1($ph1ent));
1249
		}
1250
	}
1251
	return $iface_list;
1252
}
1253

  
1215 1254
function interface_ipsec_vti_configure($ph1ent) {
1216 1255
	global $config;
1217 1256

  
......
1220 1259
	}
1221 1260

  
1222 1261
	$vtisubnet_spec = ipsec_vti($ph1ent, true);
1262
	if ((!$vtisubnet_spec || !is_array($vtisubnet_spec))) {
1263
		return false;
1264
	}
1223 1265

  
1224
	if ($vtisubnet_spec && is_array($vtisubnet_spec)) {
1225
		$left_spec = ipsec_get_phase1_src($ph1ent);
1226
		$right_spec = $ph1ent['remote-gateway'];
1227
		$ipsecif = "ipsec{$ph1ent['ikeid']}";
1228

  
1229
		if (platform_booting() || !does_interface_exist($ipsecif)) {
1230
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " destroy", false);
1231
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " create reqid " . escapeshellarg($ph1ent['ikeid']), false);
1232
		} else {
1233
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " create reqid " . escapeshellarg($ph1ent['ikeid']), false);
1234
		}
1266
	$left_spec = ipsec_get_phase1_src($ph1ent);
1267
	$right_spec = $ph1ent['remote-gateway'];
1235 1268

  
1236
		$inet = is_ipaddrv6($left_spec) ? "inet6" : "inet";
1237
		mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " {$inet} tunnel " . escapeshellarg($left_spec) . " " . escapeshellarg($right_spec) . " up", false);
1269
	$iface_addrs = array();
1238 1270

  
1271
	/* With IKEv1 or v2+Split, each P2 gets its own conn/reqid/interface */
1272
	if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1273
		/* Form a single interface for each P2 entry */
1274
		foreach ($vtisubnet_spec as $idx => $vtisub) {
1275
			$ipsecifnum = "{$ph1ent['ikeid']}00{$idx}";
1276
			if (!is_array($iface_addrs[$ipsecifnum])) {
1277
				$iface_addrs[$ipsecifnum] = array();
1278
			}
1279
			$vtisub['alias'] = "";
1280
			$iface_addrs[$ipsecifnum][] = $vtisub;
1281
		}
1282
	} else {
1283
		/* For IKEv2, only create one interface with additional addresses as aliases */
1284
		$ipsecifnum = "{$ph1ent['ikeid']}000";
1285
		if (!is_array($iface_addrs[$ipsecifnum])) {
1286
			$iface_addrs[$ipsecifnum] = array();
1287
		}
1239 1288
		$have_v4 = false;
1240 1289
		$have_v6 = false;
1241 1290
		foreach ($vtisubnet_spec as $vtisub) {
1242
			$alias = "";
1291
			// Alias stuff
1292
			$vtisub['alias'] = "";
1243 1293
			if (is_ipaddrv6($vtisub['left'])) {
1244 1294
				if ($have_v6) {
1245
					$alias = " alias";
1246
				} else {
1247
					// Write out gwv6 file
1248
					file_put_contents("/tmp/{$ipsecif}_routerv6", $vtisub['right']);
1295
					$vtisub['alias'] = " alias";
1249 1296
				}
1250
				$inet =  "inet6";
1251 1297
				$have_v6 = true;
1252 1298
			} else {
1253 1299
				if ($have_v4) {
1254
					$alias = " alias";
1255
				} else {
1256
					// Write out gw file
1257
					file_put_contents("/tmp/{$ipsecif}_router", $vtisub['right']);
1300
					$vtisub['alias'] = " alias";
1258 1301
				}
1259
				$inet =  "inet";
1260 1302
				$have_v4 = true;
1261 1303
			}
1262
			/* ifconfig ipsec0 inet <p2 local> <p2 remote> */
1263
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " {$inet} " . escapeshellarg($vtisub['left']) . " " . escapeshellarg($vtisub['right']) . $alias, false);
1304
			$iface_addrs[$ipsecifnum][] = $vtisub;
1264 1305
		}
1306
	}
1265 1307

  
1266
		if (!platform_booting()) {
1267
			system_routing_configure($ipsecif);
1308
	foreach ($iface_addrs as $ipsecifnum => $addrs) {
1309
		$ipsecif = "ipsec{$ipsecifnum}";
1310
		if (!is_array($addrs)) {
1311
			continue;
1268 1312
		}
1313
		// Create IPsec interface
1314
		if (platform_booting() || !does_interface_exist($ipsecif)) {
1315
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " destroy", false);
1316
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " create reqid " . escapeshellarg($ipsecifnum), false);
1317
		} else {
1318
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " create reqid " . escapeshellarg($ipsecifnum), false);
1319
		}
1320

  
1321
		/* Apply the outer tunnel addresses to the interface */
1322
		$inet = is_ipaddrv6($left_spec) ? "inet6" : "inet";
1323
		mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " {$inet} tunnel " . escapeshellarg($left_spec) . " " . escapeshellarg($right_spec) . " up", false);
1324

  
1325
		/* Loop through all of the addresses for this interface and apply them as needed */
1326
		foreach ($addrs as $addr) {
1327
			// apply interface addresses
1328
			if (is_ipaddrv6($addr['left'])) {
1329
				$inet = "inet6";
1330
				$gwtype = "v6";
1331
			} else {
1332
				$inet = "inet";
1333
				$gwtype = "";
1334
			}
1335

  
1336
			mwexec("/sbin/ifconfig " . escapeshellarg($ipsecif) . " {$inet} " . escapeshellarg($addr['left']) . " " . escapeshellarg($addr['right']) . $addr['alias'], false);
1337
			/* If alias is empty, this is the first address on the interface and should be used as the gateway. */
1338
			if (empty($addr['alias'])) {
1339
				file_put_contents("/tmp/{$ipsecif}_router{$gwtype}", $addr['right']);
1340
			}
1341
		}
1342
	}
1343

  
1344
	if (!platform_booting()) {
1345
		system_routing_configure($ipsecif);
1269 1346
	}
1270 1347
}
1271 1348

  
......
1276 1353
	}
1277 1354
	if (is_array($config['ipsec']) && is_array($config['ipsec']['phase1']) && is_array($config['ipsec']['phase2'])) {
1278 1355
		foreach ($config['ipsec']['phase1'] as $ph1ent) {
1356
			if ($ph1ent['disabled']) {
1357
				continue;
1358
			}
1279 1359
			interface_ipsec_vti_configure($ph1ent);
1280 1360
		}
1281 1361
	}

Also available in: Unified diff