summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2018-08-23 16:10:29 -0300
committerRenato Botelho <renato@netgate.com>2018-08-23 16:10:33 -0300
commit2c1d7c12fa4f41a69d6c9267a34b1b767a1da522 (patch)
tree60421873fe91c8382e16128150ad4a23ec8606ca
parentcca5b9efa622d8a597baaad59e8e2d729be02f48 (diff)
downloadpfsense-2c1d7c12fa4f41a69d6c9267a34b1b767a1da522.zip
pfsense-2c1d7c12fa4f41a69d6c9267a34b1b767a1da522.tar.gz
Implement #1335:
Let VLANs to have a different MAC address than its parent. While here also fixes #8138 and do not ignore <spoofmac> for interfaces without hwaddr field
-rw-r--r--src/etc/inc/interfaces.inc128
1 files changed, 103 insertions, 25 deletions
diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc
index 54ef2e3..411e441 100644
--- a/src/etc/inc/interfaces.inc
+++ b/src/etc/inc/interfaces.inc
@@ -335,7 +335,6 @@ function interface_is_vlan($if = NULL) {
}
function vlan_interface($vlan = NULL) {
-
if ($vlan == NULL || !is_array($vlan) || !isset($vlan['if']) ||
!isset($vlan['tag']) || !vlan_valid_tag($vlan['tag'])) {
return (NULL);
@@ -343,6 +342,59 @@ function vlan_interface($vlan = NULL) {
return ("{$vlan['if']}.{$vlan['tag']}");
}
+function interface_set_macaddr($interface, $mac_addr) {
+ if (empty($mac_addr) || !is_macaddr($mac_addr)) {
+ return;
+ }
+
+ $current_mac = get_interface_mac($interface);
+
+ /*
+ * Don't try to reapply the MAC if it's already applied.
+ * When ifconfig link is used, it cycles the interface down/up, which
+ * triggers the interface config again, which attempts to apply the
+ * MAC again, which cycles the link again...
+ */
+ if ($mac_addr != $current_mac) {
+ mwexec("/sbin/ifconfig " . escapeshellarg($interface) .
+ " link " . escapeshellarg($mac_addr));
+ }
+}
+
+function vlan_chilren_set_macaddr($interface) {
+ global $config;
+
+ if (!is_array($config['vlans']['vlan']) ||
+ !count($config['vlans']['vlan'])) {
+ return;
+ }
+
+ if (interface_is_vlan($interface)) {
+ return;
+ }
+
+ $macinfo = pfSense_get_interface_addresses($interface);
+ if (!isset($macinfo["hwaddr"]) || $macinfo["hwaddr"] ==
+ "00:00:00:00:00:00") {
+ return;
+ }
+
+ foreach ($config['vlans']['vlan'] as $vlan) {
+ if ($vlan['if'] != $interface) {
+ continue;
+ }
+
+ foreach ($config['interfaces'] as $ifcfg) {
+ if ($ifcfg['if'] != $vlan['vlanif'] ||
+ empty($ifcfg['spoofmac'])) {
+ continue;
+ }
+
+ interface_set_macaddr($ifcfg['if'], $ifcfg['spoofmac']);
+ }
+ }
+}
+
function interfaces_vlan_configure($realif = "") {
global $config, $g;
if (platform_booting()) {
@@ -3716,6 +3768,12 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven
// Need code to handle MLPPP if we ever use $realhwif for MLPPP handling
$realhwif = $realhwif_array[0];
+ if (interface_is_vlan($realif) && !interface_is_qinq($realif)) {
+ $macaddr_if = $realif;
+ } else {
+ $macaddr_if = $realhwif;
+ }
+
if (!platform_booting() && !(substr($realif, 0, 4) == "ovpn") && !(substr($realif, 0, 5) == "ipsec")) {
/* remove all IPv4 and IPv6 addresses */
$tmpifaces = pfSense_getall_interface_addresses($realif);
@@ -3766,36 +3824,24 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven
interface_wireless_configure($realif, $wancfg, $wancfg['wireless']);
}
- $current_mac = get_interface_mac($realhwif);
- $vendor_mac = get_interface_vendor_mac($realhwif);
- /*
- * Do not change the MAC address if the interface does not store the original
- * vendor MAC address.
- */
- if ($vendor_mac != NULL) {
- /* Get the vendor MAC. Use source dependent upon whether or not booting. */
- if (platform_booting()) {
- $vendor_mac = $current_mac;
- }
+ $current_mac = get_interface_mac($macaddr_if);
+ $vendor_mac = get_interface_vendor_mac($macaddr_if);
+
+ if ($current_mac != "ff:ff:ff:ff:ff:ff") {
$mac_addr = $wancfg['spoofmac'] ?: $vendor_mac;
- /*
- * Don't try to reapply the MAC if it's already applied.
- * When ifconfig link is used, it cycles the interface down/up, which triggers
- * the interface config again, which attempts to apply the MAC again,
- * which cycles the link again...
- */
+
if (!empty($mac_addr) && ($mac_addr != $current_mac)) {
- mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
- " link " . escapeshellarg($mac_addr));
+ interface_set_macaddr($macaddr_if, $mac_addr);
+ vlan_chilren_set_macaddr($macaddr_if);
}
- } elseif ($current_mac == "ff:ff:ff:ff:ff:ff") {
+ } else {
/* this is not a valid mac address. generate a
* temporary mac address so the machine can get online.
*/
echo gettext("Generating new MAC address.");
$random_mac = generate_random_mac_address();
- mwexec("/sbin/ifconfig " . escapeshellarg($realhwif) .
- " link " . escapeshellarg($random_mac));
+ interface_set_macaddr($macaddr_if, $random_mac);
+ vlan_chilren_set_macaddr($macaddr_if);
$wancfg['spoofmac'] = $random_mac;
write_config(sprintf(gettext('The invalid MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac));
file_notice("MAC Address altered", sprintf(gettext('The invalid MAC address (ff:ff:ff:ff:ff:ff) on interface %1$s has been automatically replaced with %2$s'), $realif, $random_mac), "Interfaces");
@@ -6620,10 +6666,42 @@ function get_interface_mac($interface) {
}
function get_interface_vendor_mac($interface) {
- $macinfo = pfSense_get_interface_addresses($interface);
- if (isset($macinfo["hwaddr"]) && $macinfo["hwaddr"] != "00:00:00:00:00:00") {
+ global $config, $g;
+
+ if (interface_is_vlan($interface) && !interface_is_qinq($interface)) {
+ $realhwif_array = get_parent_interface($interface);
+ $realhwif = $realhwif_array[0];
+
+ $ifcfg = convert_real_interface_to_friendly_interface_name(
+ $realhwif);
+
+ if (!empty($config['interfaces'][$ifcfg]['spoofmac'])) {
+ $macaddr = $config['interfaces'][$ifcfg]['spoofmac'];
+ if (is_macaddr($macaddr)) {
+ return ($macaddr);
+ }
+ }
+ } else {
+ $realhwif = $interface;
+ }
+
+ $macinfo = pfSense_get_interface_addresses($realhwif);
+ if (isset($macinfo["hwaddr"]) && $macinfo["hwaddr"] !=
+ "00:00:00:00:00:00") {
return ($macinfo["hwaddr"]);
}
+
+ $hwaddr_file = "{$g['tmp_path']}/{$realhwif}_hwaddr";
+ if (file_exists($hwaddr_file)) {
+ $macaddr = trim(file_get_contents($hwaddr_file));
+ if (is_macaddr($macaddr)) {
+ return ($macaddr);
+ }
+ } elseif (is_macaddr($macinfo['macaddr'])) {
+ /* Save original macaddress to be restored when necessary */
+ @file_put_contents($hwaddr_file, $macinfo['macaddr']);
+ }
+
return (NULL);
}
OpenPOWER on IntegriCloud