netcf has always supported multiple IPv6 addresses, but only a single
IPv4 address. This patch remedies that, at least for the redhat driver
(also used for Fedora and CentOS).

I can't claim that the xsl transforms in redhat-(get|put).xsl are the
optimum code, but they do get the job done (no mean feat, since this
is the first time I've ever made anything beyond a cosmetic change to
an xsl script).

Similar to what NetworkManager does, the first IPv4 address is stored
in the ifcfg file as

   IPADDR=b.l.a.h
   NETMASK=b.l.a.h

while subsequent ip addresses are stored as:

   IPADDRn=b.l.a.h
   NETMASKn=b.l.a.h

where "n" is 1 - 99 (since that is what initscripts (and probably
NetworkManager) support).

A new test case with multiple IPv4 addresses has also been added -
bridge-multi.
---
 data/xml/interface.rng                             | 14 ++++++------
 data/xml/redhat-get.xsl                            | 25 ++++++++++++++++++----
 data/xml/redhat-put.xsl                            | 23 ++++++++++++++++++--
 tests/interface/bridge-multi.xml                   | 15 +++++++++++++
 .../fsroot/etc/sysconfig/network-scripts/ifcfg-br1 | 20 +++++++++++++++++
 tests/redhat/schema/bridge-multi.xml               | 24 +++++++++++++++++++++
 tests/test-redhat.c                                |  5 +++--
 7 files changed, 112 insertions(+), 14 deletions(-)
 create mode 100644 tests/interface/bridge-multi.xml
 create mode 100644 tests/redhat/fsroot/etc/sysconfig/network-scripts/ifcfg-br1
 create mode 100644 tests/redhat/schema/bridge-multi.xml

diff --git a/data/xml/interface.rng b/data/xml/interface.rng
index 7810a7a..c587da8 100644
--- a/data/xml/interface.rng
+++ b/data/xml/interface.rng
@@ -325,12 +325,14 @@
         <choice>
           <ref name="dhcp-element"/>
           <group>
-            <element name="ip">
-              <attribute name="address"><ref name="ipv4-addr"/></attribute>
-              <optional>
-                <attribute name="prefix"><ref name="ipv4-prefix"/></attribute>
-              </optional>
-            </element>
+            <zeroOrMore>
+              <element name="ip">
+                <attribute name="address"><ref name="ipv4-addr"/></attribute>
+                <optional>
+                  <attribute name="prefix"><ref 
name="ipv4-prefix"/></attribute>
+                </optional>
+              </element>
+            </zeroOrMore>
             <optional>
               <element name="route">
                 <attribute name="gateway"><ref name="ipv4-addr"/></attribute>
diff --git a/data/xml/redhat-get.xsl b/data/xml/redhat-get.xsl
index 81dc718..5970c67 100644
--- a/data/xml/redhat-get.xsl
+++ b/data/xml/redhat-get.xsl
@@ -192,10 +192,18 @@
       </xsl:when>
       <xsl:when test="ip">
         <node label="BOOTPROTO" value="none"/>
-        <node label="IPADDR" value="{ip/@address}"/>
-        <xsl:if test="ip/@prefix">
-          <node label="NETMASK" value="{ipcalc:netmask(ip/@prefix)}"/>
-        </xsl:if>
+        <xsl:for-each select="ip">
+          <xsl:if test="position() = 1">
+            <xsl:call-template name="ipv4-address">
+              <xsl:with-param name="index"/>
+            </xsl:call-template>
+          </xsl:if>
+          <xsl:if test="position() > 1 and position() &lt; 100">
+            <xsl:call-template name="ipv4-address">
+              <xsl:with-param name="index" select="position() - 1"/>
+            </xsl:call-template>
+          </xsl:if>
+        </xsl:for-each>
         <xsl:if test="route">
           <node label="GATEWAY" value="{route/@gateway}"/>
         </xsl:if>
@@ -203,6 +211,15 @@
     </xsl:choose>
   </xsl:template>
 
+  <xsl:template name="ipv4-address">
+    <xsl:param name="index"/>
+    <node label="IPADDR{$index}" value="{@address}"/>
+    <xsl:if test="@prefix">
+      <node label="NETMASK{$index}" value="{ipcalc:netmask(@prefix)}"/>
+    </xsl:if>
+  </xsl:template>
+
+
   <xsl:template name="protocol-ipv6">
     <node label="IPV6INIT" value="yes"/>
     <xsl:if test="count(autoconf) > 0">
diff --git a/data/xml/redhat-put.xsl b/data/xml/redhat-put.xsl
index ed800d6..7a3e482 100644
--- a/data/xml/redhat-put.xsl
+++ b/data/xml/redhat-put.xsl
@@ -183,8 +183,7 @@
     <xsl:variable name="uses_dhcp"
                   select="node[@label = 'BOOTPROTO']/@value = 'dhcp'"/>
     <xsl:variable name="uses_static"
-                  select="count(node[@label = 'IPADDR']) +
-                          count(node[@label = 'IPADDR0']) > 0"/>
+                  select="count(node[substring(@label,1,6) = 'IPADDR']) > 0"/>
     <xsl:variable name="uses_ipv4" select="$uses_dhcp or $uses_static"/>
     <xsl:if test="$uses_ipv4">
     <protocol family="ipv4">
@@ -197,6 +196,7 @@
           </dhcp>
         </xsl:when>
         <xsl:when test="$uses_static">
+          <!-- IPADDR and IPADDR0 must be treated differently from IPADDR1 - 
IPADDR99 -->
           <xsl:choose>
             <xsl:when test="node[@label = 'IPADDR']">
               <ip address="{node[@label = 'IPADDR']/@value}">
@@ -217,6 +217,25 @@
               <route gateway="{node[@label = 'GATEWAY0']/@value}"/>
             </xsl:when>
           </xsl:choose>
+          <xsl:for-each select="node[substring(@label, 1, 6) = 'IPADDR']">
+            <xsl:variable name="index" select="substring(@label, 7, 3)"/>
+            <xsl:if test="number($index) &gt; 0 and number($index) &lt; 100">
+              <ip address="{@value}">
+                <xsl:choose>
+                  <xsl:when test="../node[@label = concat('PREFIX', $index)]">
+                    <xsl:attribute name="prefix">
+                      <xsl:value-of select="../node[@label = concat('PREFIX', 
$index)]/@value"/>
+                    </xsl:attribute>
+                  </xsl:when>
+                  <xsl:when test="../node[@label = concat('NETMASK', $index)]">
+                    <xsl:attribute name="prefix">
+                      <xsl:value-of select="ipcalc:prefix(../node[@label = 
concat('NETMASK', $index)]/@value)"/>
+                    </xsl:attribute>
+                  </xsl:when>
+                </xsl:choose>
+              </ip>
+            </xsl:if>
+          </xsl:for-each>
         </xsl:when>
       </xsl:choose>
     </protocol>
diff --git a/tests/interface/bridge-multi.xml b/tests/interface/bridge-multi.xml
new file mode 100644
index 0000000..d476c5b
--- /dev/null
+++ b/tests/interface/bridge-multi.xml
@@ -0,0 +1,15 @@
+<interface type="bridge" name="br1">
+  <start mode="onboot"/>
+  <protocol family="ipv4">
+    <ip address="10.0.0.1" prefix="24"/>
+    <ip address="192.168.125.4" prefix="24"/>
+    <ip address="192.168.125.5" prefix="31"/>
+    <ip address="192.168.125.6"/>
+    <ip address="192.168.125.7"/>
+    <ip address="192.168.125.8"/>
+    <ip address="192.168.125.9"/>
+    <ip address="192.168.125.10"/>
+    <ip address="172.16.20.32" prefix="12"/>
+  </protocol>
+  <bridge stp="on" delay="0"/>
+</interface>
diff --git a/tests/redhat/fsroot/etc/sysconfig/network-scripts/ifcfg-br1 
b/tests/redhat/fsroot/etc/sysconfig/network-scripts/ifcfg-br1
new file mode 100644
index 0000000..5247f7b
--- /dev/null
+++ b/tests/redhat/fsroot/etc/sysconfig/network-scripts/ifcfg-br1
@@ -0,0 +1,20 @@
+# Enclosing the values in useless quotes is intentional
+DEVICE="br1"
+ONBOOT='yes'
+BOOTPROTO="none"
+TYPE="Bridge"
+DELAY=0
+STP=on
+IPADDR="10.0.0.1"
+NETMASK=255.255.255.0
+IPADDR1="192.168.125.4"
+PREFIX1=24
+IPADDR2="192.168.125.5"
+NETMASK2="255.255.255.254"
+IPADDR3="192.168.125.6"
+IPADDR4="192.168.125.7"
+IPADDR5="192.168.125.8"
+IPADDR6="192.168.125.9"
+IPADDR7="192.168.125.10"
+IPADDR8="172.16.20.32"
+PREFIX8=12
diff --git a/tests/redhat/schema/bridge-multi.xml 
b/tests/redhat/schema/bridge-multi.xml
new file mode 100644
index 0000000..24c6f9d
--- /dev/null
+++ b/tests/redhat/schema/bridge-multi.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<forest>
+  <tree path="/files/etc/sysconfig/network-scripts/ifcfg-br1">
+    <node label="DEVICE" value="br1"/>
+    <node label="ONBOOT" value="yes"/>
+    <node label="TYPE" value="Bridge"/>
+    <node label="BOOTPROTO" value="none"/>
+    <node label="IPADDR" value="10.0.0.1"/>
+    <node label="NETMASK" value="255.255.255.0"/>
+    <node label="IPADDR1" value="192.168.125.4"/>
+    <node label="NETMASK1" value="255.255.255.0"/>
+    <node label="IPADDR2" value="192.168.125.5"/>
+    <node label="NETMASK2" value="255.255.255.254"/>
+    <node label="IPADDR3" value="192.168.125.6"/>
+    <node label="IPADDR4" value="192.168.125.7"/>
+    <node label="IPADDR5" value="192.168.125.8"/>
+    <node label="IPADDR6" value="192.168.125.9"/>
+    <node label="IPADDR7" value="192.168.125.10"/>
+    <node label="IPADDR8" value="172.16.20.32"/>
+    <node label="NETMASK8" value="255.240.0.0"/>
+    <node label="STP" value="on"/>
+    <node label="DELAY" value="0"/>
+  </tree>
+</forest>
diff --git a/tests/test-redhat.c b/tests/test-redhat.c
index ab22a6a..a08bc23 100644
--- a/tests/test-redhat.c
+++ b/tests/test-redhat.c
@@ -1,7 +1,7 @@
 /*
  * test-redhat.c:
  *
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009, 2011, 2015 Red Hat Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -43,7 +43,7 @@ static void testListInterfaces(CuTest *tc) {
     int nint;
     char **names;
     static const char *const exp_names[] =
-        { "br0", "bond0", "lo", "eth3", "eth4" };
+        { "br0", "br1", "bond0", "lo", "eth3", "eth4" };
     static const int exp_nint = ARRAY_CARDINALITY(exp_names);
 
     nint = ncf_num_of_interfaces(ncf, NETCF_IFACE_ACTIVE|NETCF_IFACE_INACTIVE);
@@ -180,6 +180,7 @@ static void testTransforms(CuTest *tc) {
     assert_transforms(tc, "bridge-vlan");
     assert_transforms(tc, "bridge-empty");
     assert_transforms(tc, "bridge-bond");
+    assert_transforms(tc, "bridge-multi");
     assert_transforms(tc, "ethernet-static");
     assert_transforms(tc, "ethernet-static-no-prefix");
     assert_transforms(tc, "ethernet-dhcp");
-- 
2.1.0

_______________________________________________
netcf-devel mailing list
netcf-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/netcf-devel

Reply via email to