Hello community,

here is the log from the commit of package yast2-network for openSUSE:Factory 
checked in at 2017-04-12 17:10:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-network (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-network.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-network"

Wed Apr 12 17:10:39 2017 rev:371 rq:487401 version:3.2.24

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-network/yast2-network.changes      
2017-03-29 13:22:21.867179933 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-network.new/yast2-network.changes 
2017-04-12 17:10:40.734293297 +0200
@@ -1,0 +2,23 @@
+Tue Apr  4 11:48:24 WEST 2017 - [email protected]
+
+- bsc#956755
+  - Don't propose wlan interfaces for the virtualization bridge.
+- 3.2.24
+
+-------------------------------------------------------------------
+Mon Apr  3 08:27:26 UTC 2017 - [email protected]
+
+- bnc#927629
+  - improved adding routes. Accepts netmask or prefix length.
+  - fixed column name in add route dialog from Genmask to more
+    common Netmask
+- 3.2.23
+
+-------------------------------------------------------------------
+Thu Mar 30 13:52:36 WEST 2017 - [email protected]
+
+- Fix typo in edit_nic_name dialog using bus_id instead of busid
+  (bsc#1031120)
+- 3.2.22
+
+-------------------------------------------------------------------

Old:
----
  yast2-network-3.2.21.tar.bz2

New:
----
  yast2-network-3.2.24.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-network.spec ++++++
--- /var/tmp/diff_new_pack.OFqmzi/_old  2017-04-12 17:10:41.822139301 +0200
+++ /var/tmp/diff_new_pack.OFqmzi/_new  2017-04-12 17:10:41.826138735 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-network
-Version:        3.2.21
+Version:        3.2.24
 Release:        0
 BuildArch:      noarch
 

++++++ yast2-network-3.2.21.tar.bz2 -> yast2-network-3.2.24.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/package/yast2-network.changes 
new/yast2-network-3.2.24/package/yast2-network.changes
--- old/yast2-network-3.2.21/package/yast2-network.changes      2017-03-22 
13:09:17.716003918 +0100
+++ new/yast2-network-3.2.24/package/yast2-network.changes      2017-04-11 
16:51:32.229154641 +0200
@@ -1,4 +1,27 @@
 -------------------------------------------------------------------
+Tue Apr  4 11:48:24 WEST 2017 - [email protected]
+
+- bsc#956755
+  - Don't propose wlan interfaces for the virtualization bridge.
+- 3.2.24
+
+-------------------------------------------------------------------
+Mon Apr  3 08:27:26 UTC 2017 - [email protected]
+
+- bnc#927629
+  - improved adding routes. Accepts netmask or prefix length.
+  - fixed column name in add route dialog from Genmask to more
+    common Netmask
+- 3.2.23
+
+-------------------------------------------------------------------
+Thu Mar 30 13:52:36 WEST 2017 - [email protected]
+
+- Fix typo in edit_nic_name dialog using bus_id instead of busid
+  (bsc#1031120)
+- 3.2.22
+
+-------------------------------------------------------------------
 Tue Mar 21 09:24:29 UTC 2017 - [email protected]
 
 - adapt to new version of cfa (new cfa needed for bsc#1023204)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/package/yast2-network.spec 
new/yast2-network-3.2.24/package/yast2-network.spec
--- old/yast2-network-3.2.21/package/yast2-network.spec 2017-03-22 
13:09:17.716003918 +0100
+++ new/yast2-network-3.2.24/package/yast2-network.spec 2017-04-11 
16:51:32.229154641 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-network
-Version:        3.2.21
+Version:        3.2.24
 Release:        0
 BuildArch:      noarch
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/src/include/network/lan/help.rb 
new/yast2-network-3.2.24/src/include/network/lan/help.rb
--- old/yast2-network-3.2.21/src/include/network/lan/help.rb    2017-03-22 
13:09:17.932003918 +0100
+++ new/yast2-network-3.2.24/src/include/network/lan/help.rb    2017-04-11 
16:51:32.233154641 +0200
@@ -98,8 +98,12 @@
                                ) +
                                  _(
                                    "<p>For each route, enter destination 
network IP address, gateway address,\n" \
-                                     "and netmask. To omit any of these 
values, use a dash sign \"-\". Select\n" \
-                                     "the device through which the traffic to 
the defined network will be routed.\"-\" is an alias for any interface.</p>\n"
+                                     "and netmask. You can use either IPv4 
netmask or prefix length when defining\n" \
+                                     "network part of route. Prefix length has 
to be prefixed using '/'.\n" \
+                                     "To omit any of these values, use a dash 
sign \"-\". Select\n" \
+                                     "the device through which the traffic to 
the defined network will be routed.\"-\" is an alias for any interface.\n" \
+                                     "Please note that in case of IPv6 
networks only prefix length is accepted\n" \
+                                     "for netmask definition.</p>\n"
                                  ) +
                                  # Routing dialog help 2/2
                                  _(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-network-3.2.21/src/include/network/services/routing.rb 
new/yast2-network-3.2.24/src/include/network/services/routing.rb
--- old/yast2-network-3.2.21/src/include/network/services/routing.rb    
2017-03-22 13:09:17.968003918 +0100
+++ new/yast2-network-3.2.24/src/include/network/services/routing.rb    
2017-04-11 16:51:32.237154641 +0200
@@ -86,7 +86,7 @@
                       # Table header 2/4
                       _("Gateway"),
                       # Table header 3/4
-                      _("Genmask"),
+                      _("Netmask"),
                       # Table header 4/4
                       _("Device"),
                       # Table header 5/4
@@ -140,6 +140,24 @@
       }
     end
 
+    # Validates user's input obtained from Netmask field
+    #
+    # It currently allows to use netmask for IPv4 (e.g. 255.0.0.0) or
+    # prefix length. If prefix length is used it has to start with '/'.
+    # For IPv6 network, only prefix length is allowed.
+    #
+    # @param [String] netmask or /<prefix length>
+    def valid_netmask?(netmask)
+      return false if netmask.nil? || netmask.empty?
+      return true if Netmask.Check4(netmask)
+
+      if netmask.start_with?("/")
+        return true if netmask[1..-1].to_i.between?(1, 128)
+      end
+
+      false
+    end
+
     # Route edit dialog
     # @param [Fixnum] id id of the edited route
     # @param [Yast::Term] entry edited entry
@@ -168,7 +186,7 @@
                   InputField(
                     Id(:genmask),
                     Opt(:hstretch),
-                    _("Ge&nmask"),
+                    _("&Netmask"),
                     Ops.get_string(entry, 3, "-")
                   ))
               ),
@@ -218,11 +236,8 @@
         Ops.add(Ops.add(IP.ValidChars, "default"), "/-")
       )
       UI.ChangeWidget(Id(:gateway), :ValidChars, Ops.add(IP.ValidChars, "-"))
-      UI.ChangeWidget(
-        Id(:genmask),
-        :ValidChars,
-        Ops.add(Netmask.ValidChars, "-")
-      )
+      # user can enter IPv4 netmask or prefix length (has to start with '/')
+      UI.ChangeWidget(Id(:genmask), :ValidChars, Netmask.ValidChars + "-/")
 
       if entry == term(:empty)
         UI.SetFocus(Id(:destination))
@@ -234,7 +249,6 @@
       route = nil
 
       loop do
-        route = nil
         ret = UI.UserInput
         break if ret != :ok
 
@@ -258,7 +272,7 @@
         end
         route = Builtins.add(route, val)
         val = Convert.to_string(UI.QueryWidget(Id(:genmask), :Value))
-        if val != "-" && val != "0.0.0.0" && !Netmask.Check(val)
+        if val != "-" && val != "0.0.0.0" && !valid_netmask?(val)
           # Popup::Error text
           Popup.Error(_("Subnetmask is invalid."))
           UI.SetFocus(Id(:genmask))
@@ -424,15 +438,44 @@
       false
     end
 
+    # Converts route definition for storing in routes file
+    #
+    # Basically netmask field is obsolete, so it converts
+    # the record to use CIDR notation if netmask is defined.
+    #
+    # @param route [Hash] see {RoutingClass#Routes}
+    # @return [Hash] where netmask is "-" (CIDR flavor)
+    def convert_route_conf(route)
+      return route if route["netmask"] == "-"
+
+      dest = route["destination"]
+      netmask = route["netmask"]
+
+      if Netmask.Check4(netmask)
+        cidr = Netmask.ToBits(netmask)
+      elsif netmask.start_with?("/")
+        cidr = netmask[1..-1]
+      else
+        # if it is netmask then long netmask is not supported for IPv6
+        # if it is prefix length (CIDR), then prefix it has to be prefixed by 
'/'
+        raise ArgumentError, "Invalid netmask or prefix length: #{netmask}"
+      end
+
+      route["destination"] = "#{dest}/#{cidr}"
+      route["netmask"] = "-"
+
+      route
+    end
+
     def storeRouting(_key, _event)
-      route_conf = Builtins.maplist(@r_items) do |e|
-        {
-          "destination" => Ops.get_string(e, 1, ""),
-          "gateway"     => Ops.get_string(e, 2, ""),
-          "netmask"     => Ops.get_string(e, 3, ""),
-          "device"      => Ops.get_string(e, 4, ""),
-          "extrapara"   => Ops.get_string(e, 5, "")
-        }
+      route_conf = @r_items.map do |route|
+        convert_route_conf(
+          "destination" => route[1].to_s,
+          "gateway"     => route[2].to_s,
+          "netmask"     => route[3].to_s,
+          "device"      => route[4].to_s,
+          "extrapara"   => route[5].to_s
+        )
       end
 
       @defgw = UI.QueryWidget(Id(:gw), :Value)
@@ -440,27 +483,21 @@
       @defgw6 = UI.QueryWidget(Id(:gw6), :Value)
       @defgwdev6 = UI.QueryWidget(Id(:gw6dev), :Value)
 
-      if @defgw != ""
-        route_conf = Builtins.add(
-          route_conf,
-          "destination" => "default",
-          "gateway"     => @defgw,
-          "netmask"     => "-",
-          "device"      => @defgwdev
-        )
-      end
-
-      if @defgw6 != ""
-        route_conf = Builtins.add(
-          route_conf,
-          "destination" => "default",
-          "gateway"     => @defgw6,
-          "netmask"     => "-",
-          "device"      => @defgwdev6
-        )
-      end
+      route_conf << {
+        "destination" => "default",
+        "gateway"     => @defgw,
+        "netmask"     => "-",
+        "device"      => @defgwdev
+      } if [email protected]?
+
+      route_conf << {
+        "destination" => "default",
+        "gateway"     => @defgw6,
+        "netmask"     => "-",
+        "device"      => @defgwdev6
+      } if [email protected]?
 
-      Routing.Routes = deep_copy(route_conf)
+      Routing.Routes = route_conf
       Routing.Forward_v4 = UI.QueryWidget(Id(:forward_v4), :Value)
       Routing.Forward_v6 = UI.QueryWidget(Id(:forward_v6), :Value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-network-3.2.21/src/lib/network/edit_nic_name.rb 
new/yast2-network-3.2.24/src/lib/network/edit_nic_name.rb
--- old/yast2-network-3.2.21/src/lib/network/edit_nic_name.rb   2017-03-22 
13:09:17.992003918 +0100
+++ new/yast2-network-3.2.24/src/lib/network/edit_nic_name.rb   2017-04-11 
16:51:32.241154641 +0200
@@ -103,7 +103,7 @@
                 ),
                 Left(
                   RadioButton(
-                    Id(:busid),
+                    Id(:bus_id),
                     _("BusID: %s") % @bus_id
                   )
                 )
@@ -122,7 +122,7 @@
       when MAC_UDEV_ATTR
         UI.ChangeWidget(Id(:udev_type), :CurrentButton, :mac)
       when BUSID_UDEV_ATTR
-        UI.ChangeWidget(Id(:udev_type), :CurrentButton, :busid)
+        UI.ChangeWidget(Id(:udev_type), :CurrentButton, :bus_id)
       else
         Builtins.y2error("Unknown udev rule.")
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/src/modules/Lan.rb 
new/yast2-network-3.2.24/src/modules/Lan.rb
--- old/yast2-network-3.2.21/src/modules/Lan.rb 2017-03-22 13:09:18.008003918 
+0100
+++ new/yast2-network-3.2.24/src/modules/Lan.rb 2017-04-11 16:51:32.241154641 
+0200
@@ -818,155 +818,64 @@
 
     def IfcfgsToSkipVirtualizedProposal
       skipped = []
-      Builtins.foreach(LanItems.Items) do |current, _config|
-        ifcfg = Ops.get_string(LanItems.Items, [current, "ifcfg"], "")
-        if NetworkInterfaces.GetType(ifcfg) == "br"
-          NetworkInterfaces.Edit(ifcfg)
-          Builtins.y2milestone(
-            "Bridge %1 with ports (%2) found",
-            ifcfg,
-            Ops.get_string(NetworkInterfaces.Current, "BRIDGE_PORTS", "")
-          )
-          skipped = Builtins.add(skipped, ifcfg)
-          Builtins.foreach(
-            Builtins.splitstring(
-              Ops.get_string(NetworkInterfaces.Current, "BRIDGE_PORTS", ""),
-              " "
-            )
-          ) { |port| skipped = Builtins.add(skipped, port) }
-        end
-        if NetworkInterfaces.GetType(ifcfg) == "bond"
-          NetworkInterfaces.Edit(ifcfg)
 
-          Builtins.foreach(LanItems.GetBondSlaves(ifcfg)) do |slave|
-            Builtins.y2milestone(
-              "For interface %1 found slave %2",
-              ifcfg,
-              slave
-            )
-            skipped = Builtins.add(skipped, slave)
+      LanItems.Items.each do |_current, config|
+        ifcfg = config["ifcfg"]
+        ifcfg_type = NetworkInterfaces.GetType(ifcfg)
+
+        case ifcfg_type
+        when "br"
+          skipped << ifcfg
+
+          bridge_ports = NetworkInterfaces.GetValue(ifcfg, "BRIDGE_PORTS").to_s
+
+          bridge_ports.split.each { |port| skipped << port }
+        when "bond"
+          LanItems.GetBondSlaves(ifcfg).each do |slave|
+            log.info("For interface #{ifcfg} found slave #{slave}")
+            skipped << slave
           end
+
+        # Skip also usb and wlan devices as they are not good for bridge 
proposal (bnc#710098)
+        when "usb", "wlan"
+          log.info("#{ifcfg_type} device #{ifcfg} skipped from bridge 
proposal")
+          skipped << ifcfg
         end
-        # Skip also usb device as it is not good for bridge proposal 
(bnc#710098)
-        if NetworkInterfaces.GetType(ifcfg) == "usb"
-          NetworkInterfaces.Edit(ifcfg)
-          Builtins.y2milestone(
-            "Usb device %1 skipped from bridge proposal",
-            ifcfg
-          )
-          skipped = Builtins.add(skipped, ifcfg)
-        end
-        if NetworkInterfaces.GetValue(ifcfg, "STARTMODE") == "nfsroot"
-          Builtins.y2milestone(
-            "Skipped %1 interface from bridge slaves because of nfsroot.",
-            ifcfg
-          )
-          skipped = Builtins.add(skipped, ifcfg)
-        end
-      end
-      Builtins.y2milestone("Skipped interfaces : %1", skipped)
-      deep_copy(skipped)
-    end
 
-    def ProposeVirtualized
-      # in case of virtualization use special proposal
-      # collect all interfaces that will be skipped from bridged proposal
-      skipped = IfcfgsToSkipVirtualizedProposal()
+        next unless NetworkInterfaces.GetValue(ifcfg, "STARTMODE") == "nfsroot"
 
-      # first configure all connected unconfigured devices with dhcp (with 
default parameters)
-      Builtins.foreach(LanItems.Items) do |number, lanitem|
-        if IsNotEmpty(
-          Ops.get_string(Convert.to_map(lanitem), ["hwinfo", "dev_name"], "")
-        )
-          LanItems.current = number
-          valid = Ops.get_boolean(
-            LanItems.getCurrentItem,
-            ["hwinfo", "link"],
-            false
-          ) == true
-          if !valid
-            Builtins.y2warning("item number %1 has link:false detected", 
number)
-          elsif Ops.get_string(LanItems.getCurrentItem, ["hwinfo", "type"], 
"") == "wlan"
-            Builtins.y2warning("not proposing WLAN interface")
-            valid = false
-          end
-          if !LanItems.IsCurrentConfigured && valid &&
-              !Builtins.contains(
-                skipped,
-                Ops.get_string(
-                  LanItems.getCurrentItem,
-                  ["hwinfo", "dev_name"],
-                  ""
-                )
-              )
-            Builtins.y2milestone("Not configured - start proposing")
-            LanItems.ProposeItem
-          end
-        end
+        log.info("Skipped #{ifcfg} interface from bridge slaves because of 
nfsroot.")
+
+        skipped << ifcfg
       end
+      log.info("Skipped interfaces : #{skipped}")
 
+      skipped
+    end
+
+    def ProposeVirtualized
       # then each configuration (except bridges) move to the bridge
       # and add old device name into bridge_ports
-      Builtins.foreach(LanItems.Items) do |current, _config|
-        ifcfg = Ops.get_string(LanItems.Items, [current, "ifcfg"], "")
-        if Builtins.contains(skipped, ifcfg)
-          Builtins.y2milestone("Skipping interface %1", ifcfg)
+      LanItems.Items.each do |current, config|
+        ifcfg = config["ifcfg"].to_s
+
+        bridge_name = format("br%s", NetworkInterfaces.GetFreeDevice("br"))
+
+        if !LanItems.IsBridgeable(bridge_name, current)
+          log.info "The interface #{ifcfg} is not bridgeable."
           next
-        elsif Ops.greater_than(Builtins.size(ifcfg), 0)
-          NetworkInterfaces.Edit(ifcfg)
-          old_config = deep_copy(NetworkInterfaces.Current)
-          Builtins.y2debug("Old Config %1\n%2", ifcfg, old_config)
-          new_ifcfg = Builtins.sformat(
-            "br%1",
-            NetworkInterfaces.GetFreeDevice("br")
-          )
-          Builtins.y2milestone(
-            "old configuration %1, bridge %2",
-            ifcfg,
-            new_ifcfg
-          )
-          NetworkInterfaces.Name = new_ifcfg
-          # from bridge interface remove all bonding-related stuff
-          Builtins.foreach(NetworkInterfaces.Current) do |key, _value|
-            if Builtins.issubstring(key, "BONDING")
-              Ops.set(NetworkInterfaces.Current, key, nil)
-            end
-          end
-          Ops.set(NetworkInterfaces.Current, "BRIDGE", "yes")
-          Ops.set(NetworkInterfaces.Current, "BRIDGE_PORTS", ifcfg)
-          Ops.set(NetworkInterfaces.Current, "BRIDGE_STP", "off")
-          Ops.set(NetworkInterfaces.Current, "BRIDGE_FORWARDDELAY", "0")
-          # hardcode startmode (bnc#450670), it can't be ifplugd!
-          Ops.set(NetworkInterfaces.Current, "STARTMODE", "auto")
-          # remove description - will be replaced by new (real) one
-          NetworkInterfaces.Current = Builtins.remove(
-            NetworkInterfaces.Current,
-            "NAME"
-          )
-          # remove ETHTOOLS_OPTIONS as it is useful only for real hardware
-          NetworkInterfaces.Current = Builtins.remove(
-            NetworkInterfaces.Current,
-            "ETHTOOLS_OPTIONS"
-          )
-          if NetworkInterfaces.Commit
-            # reconfigure existing device as newly created bridge's port
-            configure_as_bridge_port(ifcfg)
-
-            Ops.set(LanItems.Items, [current, "ifcfg"], new_ifcfg)
-            LanItems.force_restart = true
-            Builtins.y2internal("List %1", NetworkInterfaces.List(""))
-            # re-read configuration to see new items in UI
-            LanItems.Read
-
-            # note: LanItems.Read resets modification flag
-            # the Read is used as a trick how to update LanItems' internal
-            # cache according NetworkInterfaces' one. As NetworkInterfaces'
-            # cache was edited directly, LanItems is not aware of changes.
-            LanItems.SetModified
-          end
-        else
-          Builtins.y2warning("empty ifcfg")
         end
+
+        LanItems.current = current
+
+        propose_current_item!(config) if !LanItems.IsCurrentConfigured
+
+        next unless configure_as_bridge!(ifcfg, bridge_name)
+
+        # reconfigure existing device as newly created bridge's port
+        configure_as_bridge_port(ifcfg)
+
+        refresh_lan_items
       end
 
       nil
@@ -1088,6 +997,68 @@
         LanItems.reload_config(ifaces)
       end
     end
+
+    def configure_as_bridge!(ifcfg, bridge_name)
+      return false if !NetworkInterfaces.Edit(ifcfg)
+
+      old_config = deep_copy(NetworkInterfaces.Current)
+      log.debug("Old Config #{ifcfg}\n#{old_config}")
+
+      log.info("old configuration #{ifcfg}, bridge #{bridge_name}")
+
+      NetworkInterfaces.Name = bridge_name
+
+      # from bridge interface remove all bonding-related stuff
+      NetworkInterfaces.Current.each do |key, _value|
+        NetworkInterfaces.Current[key] = nil if key.include? "BONDING"
+      end
+
+      NetworkInterfaces.Current["BRIDGE"] = "yes"
+      NetworkInterfaces.Current["BRIDGE_PORTS"] = ifcfg
+      NetworkInterfaces.Current["BRIDGE_STP"] = "off"
+      NetworkInterfaces.Current["BRIDGE_FORWARDDELAY"] = "0"
+
+      # hardcode startmode (bnc#450670), it can't be ifplugd!
+      NetworkInterfaces.Current["STARTMODE"] = "auto"
+      # remove description - will be replaced by new (real) one
+      NetworkInterfaces.Current.delete("NAME")
+      # remove ETHTOOLS_OPTIONS as it is useful only for real hardware
+      NetworkInterfaces.Current.delete("ETHTOOLS_OPTIONS")
+
+      NetworkInterfaces.Commit
+    end
+
+    def propose_current_item!(config)
+      # first configure all connected unconfigured devices with dhcp (with 
default parameters)
+      hwinfo = config.fetch("hwinfo", {})
+
+      if hwinfo.fetch("link", false) == true
+        log.warn("item number #{LanItems.current} has link:false detected")
+
+        return false
+      end
+
+      if hwinfo.fetch("type", "") == "wlan"
+        log.warn("not proposing WLAN interface")
+
+        return false
+      end
+
+      LanItems.ProposeItem
+    end
+
+    def refresh_lan_items
+      LanItems.force_restart = true
+      log.info("List #{NetworkInterfaces.List("")}")
+      # re-read configuration to see new items in UI
+      LanItems.Read
+
+      # note: LanItems.Read resets modification flag
+      # the Read is used as a trick how to update LanItems' internal
+      # cache according NetworkInterfaces' one. As NetworkInterfaces'
+      # cache was edited directly, LanItems is not aware of changes.
+      LanItems.SetModified
+    end
   end
 
   Lan = LanClass.new
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/src/modules/LanItems.rb 
new/yast2-network-3.2.24/src/modules/LanItems.rb
--- old/yast2-network-3.2.21/src/modules/LanItems.rb    2017-03-22 
13:09:18.016003918 +0100
+++ new/yast2-network-3.2.24/src/modules/LanItems.rb    2017-04-11 
16:51:32.241154641 +0200
@@ -304,13 +304,12 @@
       return nil if !IsItemConfigured(itemId)
 
       devname = GetDeviceName(itemId)
-      devtype = NetworkInterfaces.GetType(devname)
 
-      Convert.convert(
-        Ops.get(NetworkInterfaces.FilterDevices("netcard"), [devtype, 
devname]),
-        from: "any",
-        to:   "map <string, any>"
-      )
+      NetworkInterfaces.FilterDevices("netcard").each do |_dev_type, conf|
+        return conf[devname] if conf[devname]
+      end
+
+      nil
     end
 
     def GetCurrentMap
@@ -824,9 +823,8 @@
       when "br"
         log.debug("Excluding lan item (#{itemId}: #{devname}) - is bridge")
         return false
-
-      when "tun"
-        log.debug("Excluding lan item (#{itemId}: #{devname}) - is tun")
+      when "tun", "usb", "wlan"
+        log.debug("Excluding lan item (#{itemId}: #{devname}) - is #{devtype}")
         return false
       end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/src/modules/Routing.rb 
new/yast2-network-3.2.24/src/modules/Routing.rb
--- old/yast2-network-3.2.21/src/modules/Routing.rb     2017-03-22 
13:09:18.016003918 +0100
+++ new/yast2-network-3.2.24/src/modules/Routing.rb     2017-04-11 
16:51:32.245154641 +0200
@@ -38,6 +38,26 @@
 
     include Logger
 
+    # @attribute Routes
+    # Entries of a routes(5) style routing table.
+    #
+    # An array of hashes whose keys are
+    #
+    # - "destination"
+    #     May be "default", "10.20.0.0/16" (then netmask is "-")
+    #     or "10.20.0.0" (then netmask must be a quad)
+    # - "gateway"
+    # - "netmask"
+    # - "device"
+    # - "extrapara"
+    #
+    # but the values depend on which flavor of RoutingHash this is:
+    # - the quad flavor: netmask has the form "255.255.0.0"
+    # - the CIDR flavor: netmask must be "-" (and destination is 1.1.1.1/16)
+    # - the slash flavor (only for the UI): netmask has the form "/16"
+    #
+    # @return [Array<Hash>] routing table entries
+
     # @Orig_Routes [Array]        array of hashes. Caches known routes
     #
     # @Orig_Forward_v4 [Boolean]  current status of ipv4 forwarding
@@ -161,7 +181,7 @@
 
     # Configures system for IPv4 forwarding
     #
-    # @param [Boolean] true when forwarding should be enabled
+    # @param forward_ipv4 [Boolean] true when forwarding should be enabled
     def write_ipv4_forwarding(forward_ipv4)
       sysctl_val = forward_ipv4 ? "1" : "0"
 
@@ -182,7 +202,7 @@
 
     # Configures system for IPv6 forwarding
     #
-    # @param [Boolean] true when forwarding should be enabled
+    # @param forward_ipv6 [Boolean] true when forwarding should be enabled
     def write_ipv6_forwarding(forward_ipv6)
       sysctl_val = forward_ipv6 ? "1" : "0"
 
@@ -205,6 +225,32 @@
       write_ipv6_forwarding(@Forward_v6)
     end
 
+    # Converts routes config as read from system into well-defined format
+    #
+    # Expects list of hashes as param. Hash should contain keys "destination",
+    # "gateway", "netmask", "device", "extrapara"
+    #
+    # Currently it converts "destination" in CIDR format (<ip>/<prefix_len>)
+    # and keeps just <ip> part in "destination" and puts "/<prefix_len>" into
+    # "netmask"
+    #
+    # @param routes [Array<Hash>] in quad or CIDR flavors (see {#Routes})
+    # @return [Array<Hash>] in quad or slash flavor
+    def normalize_routes(routes)
+      return routes if routes.nil? || routes.empty?
+
+      deep_copy(routes).map do |route|
+        subnet, prefix = route["destination"].split("/")
+
+        if !prefix.nil?
+          route["destination"] = subnet
+          route["netmask"] = "/#{prefix}"
+        end
+
+        route
+      end
+    end
+
     # Read routing settings
     # If no routes, sets a default gateway from Detection
     # @return true if success
@@ -234,6 +280,8 @@
       end
 
       @Routes.uniq!
+
+      @Routes = normalize_routes(@Routes)
       log.info("Routes=#{@Routes}")
 
       ReadIPForwarding()
@@ -439,7 +487,7 @@
     end
 
     # Create routing text summary
-    # @returns [String] summary text
+    # @return [String] summary text
     def Summary
       return "" if @Routes.nil? || @Routes.empty?
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/test/Makefile.am 
new/yast2-network-3.2.24/test/Makefile.am
--- old/yast2-network-3.2.21/test/Makefile.am   2017-03-22 13:09:18.028003918 
+0100
+++ new/yast2-network-3.2.24/test/Makefile.am   2017-04-11 16:51:32.245154641 
+0200
@@ -29,6 +29,7 @@
   remote_test.rb \
   routines_test.rb \
   routing_test.rb \
+  routing_helpers_test.rb \
   s390_helpers_test.rb \
   suse_firewall_4_network_test.rb \
   udev_test.rb \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/test/lan_test.rb 
new/yast2-network-3.2.24/test/lan_test.rb
--- old/yast2-network-3.2.21/test/lan_test.rb   2017-03-22 13:09:18.100003918 
+0100
+++ new/yast2-network-3.2.24/test/lan_test.rb   2017-04-11 16:51:32.249154641 
+0200
@@ -224,3 +224,168 @@
     expect(Yast::Lan.readIPv6).to be true
   end
 end
+
+describe "LanClass#IfcfgsToSkipVirtualizedProposal" do
+  let(:items) do
+    {
+      "0" => { "ifcfg" => "bond0" },
+      "1" => { "ifcfg" => "br0" },
+      "2" => { "ifcfg" => "eth0" },
+      "3" => { "ifcfg" => "eth1" },
+      "4" => { "ifcfg" => "wlan0" },
+      "5" => { "ifcfg" => "wlan1" }
+    }
+  end
+
+  let(:current_interface) do
+    {
+      "ONBOOT"       => "yes",
+      "BOOTPROTO"    => "dhcp",
+      "DEVICE"       => "br1",
+      "BRIDGE"       => "yes",
+      "BRIDGE_PORTS" => "eth1",
+      "BRIDGE_STP"   => "off",
+      "IPADDR"       => "10.0.0.1",
+      "NETMASK"      => "255.255.255.0"
+    }
+  end
+
+  context "when various interfaces are present in the system" do
+    before do
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("br0").and_return("br")
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("bond0").and_return("bond")
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("eth0").and_return("eth")
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("eth1").and_return("eth")
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("wlan0").and_return("usb")
+      allow(Yast::NetworkInterfaces).to 
receive(:GetType).with("wlan1").and_return("wlan")
+      allow(Yast::NetworkInterfaces).to 
receive(:Current).and_return(current_interface)
+      allow(Yast::NetworkInterfaces).to receive(:GetValue).and_return(nil)
+      allow(Yast::LanItems).to receive(:Items).and_return(items)
+    end
+
+    context "and one of them is a bridge" do
+      it "returns an array containining the bridge interface" do
+        (expect Yast::Lan.IfcfgsToSkipVirtualizedProposal).to include("br0")
+      end
+
+      it "returns an array containing the bridged interfaces" do
+        allow(Yast::NetworkInterfaces).to receive(:GetValue)
+          .with("br0", "BRIDGE_PORTS").and_return("eth1")
+
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to include("eth1")
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to_not 
include("eth0")
+      end
+    end
+
+    context "and one of them is a bond" do
+      let(:current_interface) do
+        {
+          "BOOTPROTO"      => "static",
+          "BONDING_MASTER" => "yes",
+          "DEVICE"         => "bond0",
+          "BONDING_SLAVE"  => "eth0"
+        }
+      end
+
+      it "returns an array containing the bonded interfaces" do
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).not_to 
include("bond0")
+      end
+    end
+
+    context "and one  of them is an usb or a wlan interface" do
+      it "returns an array containing the interface" do
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to include("wlan0", 
"wlan1")
+      end
+    end
+
+    context "and the interface startmode is 'nfsroot'" do
+      it "returns an array containing the interface" do
+        allow(Yast::NetworkInterfaces).to receive(:GetValue)
+          .with("eth0", "STARTMODE").and_return("nfsroot")
+
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to include("eth0")
+      end
+    end
+
+    context "and all the interfaces are bridgeable" do
+      let(:current_item) do
+        {
+          "BOOTPROTO" => "dhcp",
+          "STARTMODE" => "auto"
+        }
+      end
+      it "returns an empty array" do
+        allow(Yast::NetworkInterfaces).to receive(:GetType).and_return("eth")
+        expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to eql([])
+      end
+    end
+  end
+
+  context "there is no interfaces in the system" do
+    let(:items) { {} }
+    it "returns an empty array" do
+      expect(Yast::Lan.IfcfgsToSkipVirtualizedProposal).to eql([])
+    end
+  end
+end
+
+describe "LanClass#ProposeVirtualized" do
+
+  before do
+    allow(Yast::NetworkInterfaces).to 
receive(:GetFreeDevice).with("br").and_return("1")
+    allow(Yast::LanItems).to receive(:IsCurrentConfigured).and_return(true)
+    allow(Yast::Lan).to receive(:configure_as_bridge!)
+    allow(Yast::Lan).to receive(:configure_as_bridge_port)
+
+    allow(Yast::LanItems).to receive(:Items)
+      .and_return(
+        0 => { "ifcfg" => "eth0" }, 1 => { "ifcfg" => "wlan0", 2 => { "ifcfg" 
=> "br0" } }
+      )
+  end
+
+  context "when an interface is not bridgeable" do
+    it "doest not propose the interface" do
+      allow(Yast::LanItems).to receive(:IsBridgeable).with(anything, 
anything).and_return(false)
+      allow(Yast::LanItems).to receive(:IsCurrentConfigured).and_return(false)
+      expect(Yast::Lan).not_to receive(:propose_current_item!).with("ifcfg" => 
"wlan0")
+
+      Yast::Lan.ProposeVirtualized
+    end
+  end
+
+  context "when an interface is bridgeable" do
+    before do
+      allow(Yast::LanItems).to receive(:IsBridgeable).with(anything, 
0).and_return(true)
+      allow(Yast::LanItems).to receive(:IsBridgeable).with(anything, 
1).and_return(false)
+      allow(Yast::LanItems).to receive(:IsBridgeable).with(anything, 
2).and_return(false)
+    end
+
+    it "configures the interface with defaults before anything if not 
configured" do
+      allow(Yast::LanItems).to receive(:IsCurrentConfigured).and_return(false)
+      expect(Yast::Lan).to receive(:propose_current_item!).with("ifcfg" => 
"eth0")
+
+      Yast::Lan.ProposeVirtualized
+    end
+
+    it "configures a new bridge with the given interface as a bridge port" do
+      expect(Yast::Lan).to receive(:configure_as_bridge!).with("eth0", "br1")
+
+      Yast::Lan.ProposeVirtualized
+    end
+
+    it "configures the given interface as a bridge port" do
+      expect(Yast::Lan).to receive(:configure_as_bridge!).with("eth0", 
"br1").and_return(true)
+      expect(Yast::Lan).to receive(:configure_as_bridge_port).with("eth0")
+
+      Yast::Lan.ProposeVirtualized
+    end
+
+    it "refreshes lan items with the new interfaces" do
+      expect(Yast::Lan).to receive(:configure_as_bridge!).with("eth0", 
"br1").and_return(true)
+      expect(Yast::Lan).to receive(:configure_as_bridge_port).with("eth0")
+      expect(Yast::Lan).to receive(:refresh_lan_items)
+
+      Yast::Lan.ProposeVirtualized
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/test/routing_helpers_test.rb 
new/yast2-network-3.2.24/test/routing_helpers_test.rb
--- old/yast2-network-3.2.21/test/routing_helpers_test.rb       1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-network-3.2.24/test/routing_helpers_test.rb       2017-04-11 
16:51:32.253154641 +0200
@@ -0,0 +1,81 @@
+#!/usr/bin/env rspec
+
+require_relative "test_helper"
+
+require "yast"
+
+class RoutingHelpers
+  def initialize
+    Yast.include self, "network/services/routing.rb"
+  end
+end
+
+describe "RoutingHelpers" do
+  subject(:routing) { RoutingHelpers.new }
+
+  describe "#convert_route_conf" do
+    let(:common_route_conf_part) do
+      {
+        "gateway"   => "1.1.1.1",
+        "device"    => "-",
+        "extrapara" => ""
+      }
+    end
+    let(:correct_route_conf) do
+      {
+        "destination" => "1.1.1.0/24",
+        "netmask"     => "-"
+      }.merge(common_route_conf_part)
+    end
+    let(:obsolete_route_conf) do
+      {
+        "destination" => "1.1.1.0",
+        "netmask"     => "255.255.255.0"
+      }.merge(common_route_conf_part)
+    end
+
+    it "does nothing when route conf uses CIDR notation" do
+      expect(routing.convert_route_conf(correct_route_conf)).to eql 
correct_route_conf
+    end
+
+    it "converts obsolete route conf to use CIDR notation" do
+      expect(routing.convert_route_conf(obsolete_route_conf)).to eql 
correct_route_conf
+    end
+  end
+
+  describe "#valid_netmask?" do
+    it "accepts IPv4 netmask" do
+      expect(routing.valid_netmask?("255.0.0.0")).to be true
+    end
+
+    it "accepts IPv4 prefix" do
+      expect(routing.valid_netmask?("/24")).to be true
+    end
+
+    it "accepts IPv6 prefix" do
+      expect(routing.valid_netmask?("/128")).to be true
+    end
+
+    it "declines IPv6 netmask" do
+      expect(routing.valid_netmask?("fe00::")).to be false
+    end
+
+    it "declines nil or empty input" do
+      expect(routing.valid_netmask?("")).to be false
+      expect(routing.valid_netmask?(nil)).to be false
+    end
+
+    it "declines malformed prefix" do
+      expect(routing.valid_netmask?("/255/")).to be false
+      expect(routing.valid_netmask?("/255")).to be false
+      expect(routing.valid_netmask?("/-255")).to be false
+      expect(routing.valid_netmask?("/0")).to be false
+    end
+
+    it "declines malformed IPv4 netmask" do
+      expect(routing.valid_netmask?("/255.0.0.0")).to be false
+      expect(routing.valid_netmask?("255.0.255.0")).to be false
+      expect(routing.valid_netmask?("0.0.0.0")).to be false
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/test/routing_test.rb 
new/yast2-network-3.2.24/test/routing_test.rb
--- old/yast2-network-3.2.21/test/routing_test.rb       2017-03-22 
13:09:18.112003918 +0100
+++ new/yast2-network-3.2.24/test/routing_test.rb       2017-04-11 
16:51:32.253154641 +0200
@@ -228,7 +228,10 @@
       { ip_forward_v4: "1", ip_forward_v6: "0" }
     ].freeze
 
-    MOCKED_ROUTES = [{ "1" => "r1" }, { "2" => "r2" }].freeze
+    MOCKED_ROUTES = [
+      { "destination" => "r1" },
+      { "destination" => "r2" }
+    ].freeze
 
     CONFIGS_OS.each do |config|
       ipv4 = config[:ip_forward_v4]
@@ -265,4 +268,30 @@
       end
     end
   end
+
+  describe "#normalize_routes" do
+    it "puts prefix length into netmask field when destination is in CIDR 
format" do
+      input_routes = [
+        {
+          "destination" => "1.1.1.1/24"
+        }
+      ]
+
+      result = Yast::Routing.normalize_routes(input_routes)
+
+      expect(result.first["destination"]).to eql "1.1.1.1"
+      expect(result.first["netmask"]).to eql "/24"
+    end
+
+    it "does nothing when netmask is used" do
+      input_routes = [
+        {
+          "destination" => "1.1.1.1",
+          "netmask"     => "255.0.0.0"
+        }
+      ]
+
+      expect(Yast::Routing.normalize_routes(input_routes)).to eql input_routes
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-network-3.2.21/test/test_helper.rb 
new/yast2-network-3.2.24/test/test_helper.rb
--- old/yast2-network-3.2.21/test/test_helper.rb        2017-03-22 
13:09:18.112003918 +0100
+++ new/yast2-network-3.2.24/test/test_helper.rb        2017-04-11 
16:51:32.253154641 +0200
@@ -53,11 +53,8 @@
     add_filter "/test/"
   end
 
-  # For coverage we need to load all ruby files
-  # Note that clients/ are excluded because they run too eagerly by design
-  Dir["#{srcdir}/{include,modules}/**/*.rb"].each do |f|
-    require_relative f
-  end
+  # track all ruby files under src
+  SimpleCov.track_files("#{srcdir}/**/*.rb")
 
   # use coveralls for on-line code coverage reporting at Travis CI
   if ENV["TRAVIS"]


Reply via email to