Skip to content

Commit

Permalink
Merge pull request #112 from mchf/master
Browse files Browse the repository at this point in the history
Ported and refactored patch from Code-11-SP2
  • Loading branch information
mchf committed Sep 11, 2013
2 parents 8011acf + e96e305 commit 922ec68
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 30 deletions.
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
3.0.7
3.0.8
2 changes: 1 addition & 1 deletion library/network/Makefile.am
Expand Up @@ -2,4 +2,4 @@
# Makefile.am for yast2/library/network
#

SUBDIRS = doc src testsuite
SUBDIRS = doc src testsuite test
54 changes: 35 additions & 19 deletions library/network/src/modules/NetworkInterfaces.rb
Expand Up @@ -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 =
Expand Down Expand Up @@ -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 <ip>/<prefix>) overrides PREFIXLEN,
# - NETMASK is used only if prefix length unspecified)
# - If prefix length and NETMASK are unspecified, 32 is implied.
#
# Canonicalize it to:
# - IPADDR="<ipv4>" PREFIXLEN="<prefix>" NETMASK="<netmask>") in case of IPv4 config
# E.g. IPADDR=10.0.0.1 PREFIXLEN=8 NETMASK=255.0.0.0
# - IPADDR="<ipv6>" PREFIXLEN="<prefix>" 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
Expand All @@ -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", ""))
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions 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)
33 changes: 33 additions & 0 deletions 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
2 changes: 0 additions & 2 deletions library/network/testsuite/tests/NetworkInterfaces.out
Expand Up @@ -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"]
3 changes: 0 additions & 3 deletions library/network/testsuite/tests/NetworkInterfaces.rb
Expand Up @@ -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)
Expand Down
12 changes: 9 additions & 3 deletions library/types/src/modules/Netmask.rb
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
26 changes: 26 additions & 0 deletions 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
7 changes: 7 additions & 0 deletions 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

Expand Down

0 comments on commit 922ec68

Please sign in to comment.