diff --git a/VERSION b/VERSION index 2451c27ca..67786e246 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.7 +3.0.8 diff --git a/library/network/Makefile.am b/library/network/Makefile.am index 8096f035c..f17c44b29 100644 --- a/library/network/Makefile.am +++ b/library/network/Makefile.am @@ -2,4 +2,4 @@ # Makefile.am for yast2/library/network # -SUBDIRS = doc src testsuite +SUBDIRS = doc src testsuite test diff --git a/library/network/src/modules/NetworkInterfaces.rb b/library/network/src/modules/NetworkInterfaces.rb index 6a7069365..b12d95462 100644 --- a/library/network/src/modules/NetworkInterfaces.rb +++ b/library/network/src/modules/NetworkInterfaces.rb @@ -45,6 +45,7 @@ def main Yast.import "String" Yast.import "TypeRepository" Yast.import "FileUtils" + Yast.import "IP" # False suppresses tones of logs 'NetworkInterfaces.ycp:ABC Check(eth,id-00:aa:bb:cc:dd:ee,)' @report_every_check = @@ -605,19 +606,30 @@ def CanonicalizeStartmode(ifcfg) deep_copy(ifcfg) end - # Canonicalize netmask data (#46885) - # Sysconfig allows: - # IPADDR=10.0.0.1/8 - # IPADDR=10.0.0.1 PREFIXLEN=8 - # IPADDR=10.0.0.1 NETMASK=255.0.0.0 - # (IPADDR overrides PREFIXLEN, NETMASK used only if prefix length unspecified) - # If prefix length and NETMASK are unspecified, 32 is implied. - # Canonicalize it to - # IPADDR=10.0.0.1 PREFIXLEN= NETMASK=255.0.0.0 - # @param [Hash{String => Object}] ifcfg a map containing IPADDR and possibly NETMASK, PREFIXLEN - # and possibly other fields - # @return the map with IPADDR, NETMASK adjusted; PREFIXLEN "" - # others unchanged. If IPADDR is empty, return the original. + # + # Canonicalize static ip configuration obtained from sysconfig. (suse#46885) + # + # Static ip configuration formats supported by sysconfig: + # 1) IPADDR=10.0.0.1/8 + # 2) IPADDR=10.0.0.1 PREFIXLEN=8 + # 3) IPADDR=10.0.0.1 NETMASK=255.0.0.0 + # + # Features: + # - IPADDR (in form /) overrides PREFIXLEN, + # - NETMASK is used only if prefix length unspecified) + # - If prefix length and NETMASK are unspecified, 32 is implied. + # + # Canonicalize it to: + # - IPADDR="" PREFIXLEN="" NETMASK="") in case of IPv4 config + # E.g. IPADDR=10.0.0.1 PREFIXLEN=8 NETMASK=255.0.0.0 + # - IPADDR="" PREFIXLEN="" NETMASK="") in case of IPv6 config + # E.g. IPADDR=2001:15c0:668e::5 PREFIXLEN=48 NETMASK="" + # + # @param ifcfg a map with netconfig (ifcfg) configuration for a one device + # @return a map with IPADDR, NETMASK and PREFIXLEN adjusted if IPADDR is present. + # Returns original ifcfg if IPADDR is not present. In case of error, + # returns nil. + # def CanonicalizeIP(ifcfg) ifcfg = deep_copy(ifcfg) return nil if ifcfg == nil @@ -628,8 +640,10 @@ def CanonicalizeIP(ifcfg) ) ipaddr = Ops.get(ip_and_prefix, 0, "") return deep_copy(ifcfg) if ipaddr == "" # DHCP or inconsistent + prefixlen = Ops.get(ip_and_prefix, 1, "") prefixlen = Ops.get_string(ifcfg, "PREFIXLEN", "") if prefixlen == "" + if prefixlen == "" prefixlen = Builtins.tostring( Netmask.ToBits(Ops.get_string(ifcfg, "NETMASK", "")) @@ -638,12 +652,14 @@ def CanonicalizeIP(ifcfg) # Now we have ipaddr and prefixlen # Let's compute the rest - netmask = Netmask.FromBits(Builtins.tointeger(prefixlen)) - ret = deep_copy(ifcfg) - Ops.set(ret, "IPADDR", ipaddr) - Ops.set(ret, "PREFIXLEN", prefixlen) - Ops.set(ret, "NETMASK", netmask) - deep_copy(ret) + netmask = "" + netmask = Netmask.FromBits(Builtins.tointeger(prefixlen)) if IP.Check4( ipaddr) + + Ops.set(ifcfg, "IPADDR", ipaddr) + Ops.set(ifcfg, "PREFIXLEN", prefixlen) + Ops.set(ifcfg, "NETMASK", netmask) + + ifcfg end # Conceal secret information, such as WEP keys, so that the output diff --git a/library/network/test/Makefile.am b/library/network/test/Makefile.am new file mode 100644 index 000000000..cfb8e1271 --- /dev/null +++ b/library/network/test/Makefile.am @@ -0,0 +1,5 @@ +TESTS = load_ipv6_cfg_test.rb +TEST_EXTENSIONS = .rb +RB_LOG_COMPILER = ruby +VERBOSE = 1 +EXTRA_DIST = $(TESTS) diff --git a/library/network/test/load_ipv6_cfg_test.rb b/library/network/test/load_ipv6_cfg_test.rb new file mode 100644 index 000000000..0f3ac2504 --- /dev/null +++ b/library/network/test/load_ipv6_cfg_test.rb @@ -0,0 +1,33 @@ +#! /usr/bin/env ruby + +require "minitest/spec" +require "minitest/autorun" + +require "yast" + +Yast.import "NetworkInterfaces" + +# mocked IPv6 relevant part of loaded ifcfg +IPV6_IFCFG = [ + { + :data => { "IPADDR" => "2001:15c0:668e::5", "PREFIXLEN" => "48" }, + :expected => { "IPADDR" => "2001:15c0:668e::5", "PREFIXLEN" => "48", "NETMASK" => "" } + }, + { + :data => { "IPADDR" => "2001:15c0:668e::5/48", "PREFIXLEN" => "" }, + :expected => { "IPADDR" => "2001:15c0:668e::5", "PREFIXLEN" => "48", "NETMASK" => "" } + }, + { + :data => { "IPADDR" => "2a00:8a00:6000:40::451", "PREFIXLEN" => "119" }, + :expected => { "IPADDR" => "2a00:8a00:6000:40::451", "PREFIXLEN" => "119", "NETMASK" => "" } + } +] + +describe "When reading devices configuration with IPv6 setup" do + it "Sets ipaddr, prefix and empty mask" do + IPV6_IFCFG.each do |ipv6_ifcfg| + canonical_ifcfg = Yast::NetworkInterfaces.CanonicalizeIP( ipv6_ifcfg[ :data]) + canonical_ifcfg.must_equal( ipv6_ifcfg[ :expected]) + end + end +end diff --git a/library/network/testsuite/tests/NetworkInterfaces.out b/library/network/testsuite/tests/NetworkInterfaces.out index 88b7a7d0d..a49755637 100644 --- a/library/network/testsuite/tests/NetworkInterfaces.out +++ b/library/network/testsuite/tests/NetworkInterfaces.out @@ -32,5 +32,3 @@ Return $["IPADDR":"10.0.0.1", "NETMASK":"255.0.0.0", "PREFIXLEN":"8", "other":"d Return nil Return $[] Return $["IPADDR":"10.0.0.1", "NETMASK":"255.255.255.255", "PREFIXLEN":"32", "other":"data"] -Return $["IPADDR":"2001:15c0:668e::5", "NETMASK":"", "PREFIXLEN":"48"] -Return $["IPADDR":"2001:15c0:668e::5", "NETMASK":"", "PREFIXLEN":"48"] diff --git a/library/network/testsuite/tests/NetworkInterfaces.rb b/library/network/testsuite/tests/NetworkInterfaces.rb index 563d06acc..aaf94f691 100644 --- a/library/network/testsuite/tests/NetworkInterfaces.rb +++ b/library/network/testsuite/tests/NetworkInterfaces.rb @@ -80,9 +80,6 @@ def main nil, {}, { "IPADDR" => "10.0.0.1", "other" => "data" }, - # IPv6 - { "IPADDR" => "2001:15c0:668e::5", "PREFIXLEN" => "48" }, - { "IPADDR" => "2001:15c0:668e::5/48", "PREFIXLEN" => "" } ] Builtins.foreach(@addresses) { |address| TEST(lambda do NetworkInterfaces.CanonicalizeIP(address) diff --git a/library/types/src/modules/Netmask.rb b/library/types/src/modules/Netmask.rb index c3ac619ce..7f0826da9 100644 --- a/library/types/src/modules/Netmask.rb +++ b/library/types/src/modules/Netmask.rb @@ -108,10 +108,16 @@ def Check(netmask) Check4(netmask) || Check6(netmask) end - # Convert netmask in bits form (20) to netmask string (255.255.240.0) - # @param [Fixnum] bits number of bits in netmask - # @return netmask string + # + # Convert netmask in bits form (20) to IPv4 netmask string (255.255.240.0) + # + # @param bits number of bits in netmask + # @return netmask string or empty string in case of invalid bits (e.g. + # when prefix is incompatible with IPv4) + # def FromBits(bits) + return "" unless bits.between?( 0, 32) + b = Ops.divide(bits, 8) d = Ops.modulo(bits, 8) diff --git a/library/types/test/Makefile.am b/library/types/test/Makefile.am index 27552cb84..5c7a58784 100644 --- a/library/types/test/Makefile.am +++ b/library/types/test/Makefile.am @@ -1,4 +1,4 @@ -TESTS = ip_test.rb +TESTS = ip_test.rb ipv4_netmask_test.rb TEST_EXTENSIONS = .rb RB_LOG_COMPILER = ruby VERBOSE = 1 diff --git a/library/types/test/ipv4_netmask_test.rb b/library/types/test/ipv4_netmask_test.rb new file mode 100755 index 000000000..52c7099e2 --- /dev/null +++ b/library/types/test/ipv4_netmask_test.rb @@ -0,0 +1,26 @@ +#! /usr/bin/env ruby + +require "minitest/spec" +require "minitest/autorun" + +require "yast" + +Yast.import "Netmask" + +describe "When creating netmask from prefixlen" do + it "returns valid netmask for prefix shorter than 32 bits" do + 0.upto 32 do |prefix_len| + Yast::Netmask.FromBits( prefix_len).wont_be_empty + end + end + + it "returns empty netmask for prefix longer than 32 bits" do + 33.upto 128 do |prefix_len| + Yast::Netmask.FromBits( prefix_len).must_be_empty + end + end + + it "returns empty netmask for incorrect prefix length" do + Yast::Netmask.FromBits( -1).must_be_empty + end +end diff --git a/package/yast2.changes b/package/yast2.changes index 4c4dd9804..afdccf9dc 100644 --- a/package/yast2.changes +++ b/package/yast2.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Sep 3 08:47:37 UTC 2013 - mfilka@suse.com + +- bnc#837517 + - fixed misinterpreting IPv6 prefixes when converting to netmask +- 3.0.8 + ------------------------------------------------------------------- Thu Aug 29 05:57:29 UTC 2013 - jreidinger@suse.com