Laine Stump
2015-03-26 18:42:56 UTC
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() < 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) > 0 and number($index) < 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");
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() < 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) > 0 and number($index) < 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
2.1.0