From patchwork Wed Mar 24 16:47:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo-Andres Hofmann X-Patchwork-Id: 3981 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 4F5DgH3bvVz40Qq for ; Wed, 24 Mar 2021 16:47:39 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "R3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 4F5DgD4q1Vz1wp; Wed, 24 Mar 2021 16:47:36 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4F5DgD33gZz30MR; Wed, 24 Mar 2021 16:47:36 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail01.haj.ipfire.org", Issuer "R3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4F5DgC2Bbrz2xmm for ; Wed, 24 Mar 2021 16:47:35 +0000 (UTC) Received: from arche.uberspace.de (arche.uberspace.de [185.26.156.147]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 4F5DgB2j88z9k for ; Wed, 24 Mar 2021 16:47:34 +0000 (UTC) Received: (qmail 15064 invoked from network); 24 Mar 2021 16:47:33 -0000 Received: from localhost (HELO localhost) (127.0.0.1) by arche.uberspace.de with SMTP; 24 Mar 2021 16:47:33 -0000 From: Leo-Andres Hofmann To: development@lists.ipfire.org Subject: [PATCH 2/2] zoneconf.cgi: Avoid unnecessary MAC address changes Date: Wed, 24 Mar 2021 17:47:16 +0100 Message-Id: <20210324164716.387-2-hofmann@leo-andres.de> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20210324164716.387-1-hofmann@leo-andres.de> References: <20210324164716.387-1-hofmann@leo-andres.de> MIME-Version: 1.0 ARC-Authentication-Results: i=1; mail01.ipfire.org; dkim=none; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=lists.ipfire.org; s=202003rsa; t=1616604454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rWhGxEf55/oeY0oQ8Oh5SUbjCpB0n4kj+GDSeBE3MPs=; b=oUinspGvFQPG9DwodiAwSOyYiRrw5AKhLE4vBiXq8bRP4A9cDvLNNE3GjsjF80jn06QvHm J0trNGrPERN9viOINarBMxR4oXXdcCfVf3KBjRPVVbGzSrIEWafphHE/4yR0VHwGiweSOh SwEEUf0+iVlGrZuVvqkwjGkW2LXUEfMRuEg5zE4P+fsbx9wu13oOyaORlMxRicEcSNkIEo FAdAIIsYWQTF32O4sR5GaRNFZHUQw7LbZFRsRxcpMEgFnDS/regXJvB9IJi9Ebsjwrwjf/ Wf+yXlEdawFUsfvRYfEdaFb+445958RDL5Dyy3NE/j8UhM7ZVvf+by5IFHAyBw== ARC-Seal: i=1; s=202003rsa; d=lists.ipfire.org; t=1616604454; a=rsa-sha256; cv=none; b=MJi/Fg3p6hIcHVyLc21xFrVO1Aftv6vMUlsZq2O8mo7Sd4Go3UnScEYLxmu0h3ss7Rsx4+ onMBiSS/0z55ThWeRSVd9ctAKNUXR/QEO34YYoQr5jIpE8q9aFexxp+pmRBgG0Cl9b+ag/ ytu2n6eaIfOg6eRM4Ko5OgeYMXZShQgb/ls2R3gnC5hy81nRO1caZRqRxS0XCrqxhaYrHD lLYzr48tcF8SsJVbUOf61+7U/98oLQTZUf0rFz0HSt3uxc/Y74Xf/9K2M22LR3E1hwt0K8 4wdwZJ2JwDnOuELIahH4lT2Cdq/fxX7m1nZzGM8G1zY2WCHnPvNZA726g6hfWg== X-Rspamd-Server: mail01.haj.ipfire.org X-Spamd-Result: default: False [-0.35 / 11.00]; R_MISSING_CHARSET(2.50)[]; IP_REPUTATION_HAM(-2.05)[asn: 205766(-0.29), country: DE(-0.01), ip: 185.26.156.147(-0.73)]; TO_DN_NONE(0.00)[]; BROKEN_CONTENT_TYPE(1.50)[]; R_SPF_ALLOW(-0.20)[+mx]; ARC_SIGNED(0.00)[lists.ipfire.org:s=202003rsa:i=1]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:205766, ipnet:185.26.156.0/24, country:DE]; RCVD_TLS_LAST(0.00)[]; BAYES_HAM(-3.00)[99.99%]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MIME_GOOD(-0.10)[text/plain]; DMARC_NA(0.00)[leo-andres.de]; RCPT_COUNT_ONE(0.00)[1]; MID_CONTAINS_FROM(1.00)[]; RCVD_COUNT_TWO(0.00)[2] X-Rspamd-Queue-Id: 4F5DgB2j88z9k Authentication-Results: mail01.ipfire.org; dkim=none; spf=pass (mail01.ipfire.org: domain of hofmann@leo-andres.de designates 185.26.156.147 as permitted sender) smtp.mailfrom=hofmann@leo-andres.de; dmarc=none X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" Ensure that a bridge always has a MAC address configured, to prevent udev/network-hotplug-bridges assigning random addresses at each start. Cache previously generated MAC addresses so that they are not regenerated each time the configuration is saved by the user. Add more comments to existing code. Fixes: #12583 Signed-off-by: Leo-Andres Hofmann --- html/cgi-bin/zoneconf.cgi | 47 ++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/html/cgi-bin/zoneconf.cgi b/html/cgi-bin/zoneconf.cgi index c0d44764f..ad0ec85fa 100644 --- a/html/cgi-bin/zoneconf.cgi +++ b/html/cgi-bin/zoneconf.cgi @@ -195,17 +195,23 @@ foreach (@nics) { ### Evaluate POST parameters ### if ($cgiparams{"ACTION"} eq $Lang::tr{"save"}) { - my %VALIDATE_nic_check = (); - my $VALIDATE_error = ""; + my %VALIDATE_nic_check = (); # array of flags (assigned, restricted/pppoe, vlan, ...) per NIC + my $VALIDATE_error = ""; # contains an error message if the config validation failed # Loop trough all known zones to ensure a complete configuration file is created foreach (@Network::known_network_zones) { my $uc = uc $_; - my $slave_string = ""; + my $slave_string = ""; # list of interfaces attached to the bridge my $zone_mode = $cgiparams{"MODE $uc"}; my $VALIDATE_vlancount = 0; my $VALIDATE_zoneslaves = 0; + # Each zone can contain up to one bridge and up to one VLAN, + # cache their mac addresses to prevent unnecessary changes + my $bridge_mac = $ethsettings{"${uc}_MACADDR"}; + my $vlan_mac = $vlansettings{"${uc}_MAC_ADDRESS"}; + + # Clear old configuration $ethsettings{"${uc}_MACADDR"} = ""; $ethsettings{"${uc}_MODE"} = ""; $ethsettings{"${uc}_SLAVES"} = ""; @@ -236,23 +242,47 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{"save"}) { next; } + # Zone in bridge mode: Always assign a MAC to the bridge + if($zone_mode eq "BRIDGE") { + # Ensure that the bridge's cached MAC does not come from a real NIC + # (this could happen if the zone was in default mode before) + foreach (@nics) { + my $nic_mac = $_->[0]; + if(Network::is_mac_equal($bridge_mac, $nic_mac)) { + $bridge_mac = ""; + last; + } + } + + # Generate random MAC if none was configured + if(! Network::valid_mac($bridge_mac)) { + $bridge_mac = Network::random_mac(); + } + + # Assign the address to the bridge + $ethsettings{"${uc}_MACADDR"} = $bridge_mac; + } + foreach (@nics) { my $mac = $_->[0]; my $nic_access = $cgiparams{"ACCESS $uc $mac"}; next unless ($nic_access); + # This NIC is to be assigned: check preconditions if ($nic_access ne "NONE") { if ($VALIDATE_nic_check{"RESTRICT $mac"}) { # If this interface is already assigned to RED in PPP mode, throw an error $VALIDATE_error = $Lang::tr{"zoneconf val ppp assignment error"}; last; } + # Enforce bridge mode when you try to assign multiple NICs to a zone if ($zone_mode ne "BRIDGE" && $VALIDATE_zoneslaves > 0 && $nic_access ne "") { $VALIDATE_error = $Lang::tr{"zoneconf val zoneslave amount error"}; last; } + # Mark this NIC as "accessed by zone" $VALIDATE_nic_check{"ACC $mac"} = 1; $VALIDATE_zoneslaves++; } @@ -265,6 +295,7 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{"save"}) { $VALIDATE_nic_check{"NATIVE $mac"} = 1; + # Zone in bridge mode: Add NIC to slave list. Otherwise access NIC directly if ($zone_mode eq "BRIDGE") { $slave_string = "${slave_string}${mac} "; } else { @@ -286,14 +317,18 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{"save"}) { last; } - my $rnd_mac = &Network::random_mac(); + # Generate random MAC if none was configured + if(! Network::valid_mac($vlan_mac)) { + $vlan_mac = Network::random_mac(); + } $vlansettings{"${uc}_PARENT_DEV"} = $mac; $vlansettings{"${uc}_VLAN_ID"} = $vlan_tag; - $vlansettings{"${uc}_MAC_ADDRESS"} = $rnd_mac; + $vlansettings{"${uc}_MAC_ADDRESS"} = $vlan_mac; # Generated MAC + # Zone in bridge mode: Add VLAN to slave list if ($zone_mode eq "BRIDGE") { - $slave_string = "${slave_string}${rnd_mac} "; + $slave_string = "${slave_string}${vlan_mac} "; } $VALIDATE_vlancount++; # We can't allow more than one VLAN per zone