summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-04-02 06:10:07 +0900
committerGitHub <noreply@github.com>2019-04-02 06:10:07 +0900
commit7a24df5eccdd04aad45d5e8195662e87d7dd4af1 (patch)
tree506c8b515fd3202e9e48736b31e921fab70e8cac
parentd2e1b2fd67d44830417b64d26f2945d752b75d9e (diff)
parent4b6a6d1e37a39ca7c8705f9a3e8411847c47d348 (diff)
downloadsystemd-7a24df5eccdd04aad45d5e8195662e87d7dd4af1.tar.gz
Merge pull request #12155 from yuwata/network-fix-and-extend-foo-over-udp-support
network: fix and extend Foo over UDP
-rw-r--r--man/systemd.netdev.xml26
-rw-r--r--src/network/netdev/fou-tunnel.c109
-rw-r--r--src/network/netdev/fou-tunnel.h1
-rw-r--r--src/network/netdev/netdev-gperf.gperf2
-rw-r--r--src/network/netdev/tunnel.c44
-rw-r--r--test/test-network/conf/25-fou-gre.netdev14
-rw-r--r--test/test-network/conf/25-fou-gretap.netdev13
-rw-r--r--test/test-network/conf/25-fou-ipip.netdev12
-rw-r--r--test/test-network/conf/25-fou-ipproto-gre.netdev8
-rw-r--r--test/test-network/conf/25-fou-ipproto-ipip.netdev8
-rw-r--r--test/test-network/conf/25-fou-sit.netdev11
-rw-r--r--test/test-network/conf/25-gre-tunnel-local-any.netdev2
-rw-r--r--test/test-network/conf/25-gre-tunnel-remote-any.netdev2
-rw-r--r--test/test-network/conf/25-gre-tunnel.netdev3
-rw-r--r--test/test-network/conf/25-gretap-tunnel-local-any.netdev2
-rw-r--r--test/test-network/conf/25-gretap-tunnel.netdev2
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py76
17 files changed, 293 insertions, 42 deletions
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 8ccc7c1a5a..a44018cad6 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -1008,7 +1008,8 @@
<term><varname>FooOverUDP=</varname></term>
<listitem>
<para>Takes a boolean. Specifies whether <varname>FooOverUDP=</varname> tunnel is to be configured.
- Defaults to false. For more detail information see
+ Defaults to false. This takes effects only for IPIP, SIT, GRE, and GRETAP tunnels.
+ For more detail information see
<ulink url="https://lwn.net/Articles/614348">Foo over UDP</ulink></para>
</listitem>
</varlistentry>
@@ -1016,7 +1017,7 @@
<term><varname>FOUDestinationPort=</varname></term>
<listitem>
<para>This setting specifies the UDP destination port for encapsulation.
- This field is mandatory and is not set by default.</para>
+ This field is mandatory when <varname>FooOverUDP=yes</varname>, and is not set by default.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1029,7 +1030,7 @@
<varlistentry>
<term><varname>Encapsulation=</varname></term>
<listitem>
- <para>Accepts the same key as <literal>[FooOverUDP]</literal></para>
+ <para>Accepts the same key as in the <literal>[FooOverUDP]</literal> section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1075,13 +1076,6 @@
<variablelist class='network-directives'>
<varlistentry>
- <term><varname>Protocol=</varname></term>
- <listitem>
- <para>The <varname>Protocol=</varname> specifies the protocol number of the
- packets arriving at the UDP port. This field is mandatory and is not set by default. Valid range is 1-255.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term><varname>Encapsulation=</varname></term>
<listitem>
<para>Specifies the encapsulation mechanism used to store networking packets of various protocols inside the UDP packets. Supports the following values:
@@ -1103,7 +1097,17 @@
for delivery to the real destination. This option is mandatory.</para>
</listitem>
</varlistentry>
- </variablelist>
+ <varlistentry>
+ <term><varname>Protocol=</varname></term>
+ <listitem>
+ <para>The <varname>Protocol=</varname> specifies the protocol number of the packets arriving
+ at the UDP port. When <varname>Encapsulation=FooOverUDP</varname>, this field is mandatory
+ and is not set by default. Takes an IP protocol name such as <literal>gre</literal> or
+ <literal>ipip</literal>, or an integer within the range 1-255. When
+ <varname>Encapsulation=GenericUDPEncapsulation</varname>, this must not be specified.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
<refsect1>
<title>[Peer] Section Options</title>
diff --git a/src/network/netdev/fou-tunnel.c b/src/network/netdev/fou-tunnel.c
index 4dbcb574df..2d4481e060 100644
--- a/src/network/netdev/fou-tunnel.c
+++ b/src/network/netdev/fou-tunnel.c
@@ -5,8 +5,10 @@
#include <linux/ip.h>
#include "conf-parser.h"
+#include "ip-protocol-list.h"
#include "missing.h"
#include "netdev/fou-tunnel.h"
+#include "netlink-util.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "parse-util.h"
@@ -27,6 +29,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_fou_encap_type, fou_encap_type, FooOverUDP
static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
FouTunnel *t;
+ uint8_t encap_type;
int r;
assert(netdev);
@@ -43,7 +46,18 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_PORT attribute: %m");
- r = sd_netlink_message_append_u8(m, FOU_ATTR_TYPE, FOU_ENCAP_GUE);
+ switch (t->fou_encap_type) {
+ case NETDEV_FOO_OVER_UDP_ENCAP_DIRECT:
+ encap_type = FOU_ENCAP_DIRECT;
+ break;
+ case NETDEV_FOO_OVER_UDP_ENCAP_GUE:
+ encap_type = FOU_ENCAP_GUE;
+ break;
+ default:
+ assert_not_reached("invalid encap type");
+ }
+
+ r = sd_netlink_message_append_u8(m, FOU_ATTR_TYPE, encap_type);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_TYPE attribute: %m");
@@ -55,15 +69,32 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_IPPROTO attribute: %m");
- *ret = m;
- m = NULL;
-
+ *ret = TAKE_PTR(m);
return 0;
}
+static int fou_tunnel_create_handler(sd_netlink *rtnl, sd_netlink_message *m, NetDev *netdev) {
+ int r;
+
+ assert(netdev);
+ assert(netdev->state != _NETDEV_STATE_INVALID);
+
+ r = sd_netlink_message_get_errno(m);
+ if (r == -EEXIST)
+ log_netdev_info(netdev, "netdev exists, using existing without changing its parameters");
+ else if (r < 0) {
+ log_netdev_warning_errno(netdev, r, "netdev could not be created: %m");
+ netdev_drop(netdev);
+
+ return 1;
+ }
+
+ log_netdev_debug(netdev, "FooOverUDP tunnel is created");
+ return 1;
+}
+
static int netdev_fou_tunnel_create(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
- uint32_t serial;
int r;
assert(netdev);
@@ -73,10 +104,49 @@ static int netdev_fou_tunnel_create(NetDev *netdev) {
if (r < 0)
return r;
- r = sd_netlink_send(netdev->manager->genl, m, &serial);
- if (r < 0 && r != -EADDRINUSE)
- return log_netdev_error_errno(netdev, r, "Failed to add FooOverUDP tunnel: %m");
+ r = netlink_call_async(netdev->manager->genl, NULL, m, fou_tunnel_create_handler,
+ netdev_destroy_callback, netdev);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Failed to create FooOverUDP tunnel: %m");
+ netdev_ref(netdev);
+ return 0;
+}
+
+int config_parse_ip_protocol(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ uint8_t *protocol = data;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ assert_cc(IPPROTO_MAX-1 <= UINT8_MAX);
+
+ r = parse_ip_protocol(rvalue);
+ if (r < 0) {
+ r = safe_atou8(rvalue, protocol);
+ if (r < 0)
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse IP protocol '%s' for Foo over UDP tunnel, "
+ "ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ *protocol = r;
return 0;
}
@@ -90,14 +160,21 @@ static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) {
assert(t);
- if (t->fou_encap_type == NETDEV_FOO_OVER_UDP_ENCAP_DIRECT && t->fou_protocol <= 0) {
- log_netdev_error(netdev, "FooOverUDP protocol not configured in %s. Rejecting configuration.", filename);
- return -EINVAL;
- }
-
- if (t->fou_encap_type == NETDEV_FOO_OVER_UDP_ENCAP_GUE && t->fou_protocol > 0) {
- log_netdev_error(netdev, "FooOverUDP GUE can't be set with protocol configured in %s. Rejecting configuration.", filename);
- return -EINVAL;
+ switch (t->fou_encap_type) {
+ case NETDEV_FOO_OVER_UDP_ENCAP_DIRECT:
+ if (t->fou_protocol <= 0)
+ return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "FooOverUDP protocol not configured in %s. Rejecting configuration.",
+ filename);
+ break;
+ case NETDEV_FOO_OVER_UDP_ENCAP_GUE:
+ if (t->fou_protocol > 0)
+ return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "FooOverUDP GUE can't be set with protocol configured in %s. Rejecting configuration.",
+ filename);
+ break;
+ default:
+ assert_not_reached("Invalid fou encap type");
}
return 0;
diff --git a/src/network/netdev/fou-tunnel.h b/src/network/netdev/fou-tunnel.h
index b8abed19bd..0e3fd7dd76 100644
--- a/src/network/netdev/fou-tunnel.h
+++ b/src/network/netdev/fou-tunnel.h
@@ -34,3 +34,4 @@ const char *fou_encap_type_to_string(FooOverUDPEncapType d) _const_;
FooOverUDPEncapType fou_encap_type_from_string(const char *d) _pure_;
CONFIG_PARSER_PROTOTYPE(config_parse_fou_encap_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_protocol);
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 1677e937b6..fcd2ec2097 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -75,7 +75,7 @@ Tunnel.IPv6RapidDeploymentPrefix, config_parse_6rd_prefix, 0,
Tunnel.ERSPANIndex, config_parse_uint32, 0, offsetof(Tunnel, erspan_index)
Tunnel.SerializeTunneledPackets, config_parse_tristate, 0, offsetof(Tunnel, gre_erspan_sequence)
Tunnel.ISATAP, config_parse_tristate, 0, offsetof(Tunnel, isatap)
-FooOverUDP.Protocol, config_parse_uint8, 0, offsetof(FouTunnel, fou_protocol)
+FooOverUDP.Protocol, config_parse_ip_protocol, 0, offsetof(FouTunnel, fou_protocol)
FooOverUDP.Encapsulation, config_parse_fou_encap_type, 0, offsetof(FouTunnel, fou_encap_type)
FooOverUDP.Port, config_parse_ip_port, 0, offsetof(FouTunnel, port)
L2TP.TunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, tunnel_id)
diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c
index 8599020d22..719b5e4add 100644
--- a/src/network/netdev/tunnel.c
+++ b/src/network/netdev/tunnel.c
@@ -72,7 +72,7 @@ static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_ne
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_PMTUDISC attribute: %m");
- if (netdev->kind == NETDEV_KIND_IPIP && t->fou_tunnel) {
+ if (t->fou_tunnel) {
r = sd_netlink_message_append_u16(m, IFLA_IPTUN_ENCAP_TYPE, t->fou_encap_type);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_ENCAP_TYPE attribute: %m");
@@ -214,6 +214,20 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_OFLAGS, attribute: %m");
+ if (t->fou_tunnel) {
+ r = sd_netlink_message_append_u16(m, IFLA_GRE_ENCAP_TYPE, t->fou_encap_type);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_ENCAP_TYPE attribute: %m");
+
+ r = sd_netlink_message_append_u16(m, IFLA_GRE_ENCAP_SPORT, htobe16(t->encap_src_port));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_ENCAP_SPORT attribute: %m");
+
+ r = sd_netlink_message_append_u16(m, IFLA_GRE_ENCAP_DPORT, htobe16(t->fou_destination_port));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GRE_ENCAP_DPORT attribute: %m");
+ }
+
return r;
}
@@ -669,23 +683,26 @@ int config_parse_6rd_prefix(const char* unit,
return 0;
}
-static void ipip_init(NetDev *n) {
- Tunnel *t = IPIP(n);
+static void ipip_sit_init(NetDev *n) {
+ Tunnel *t;
assert(n);
- assert(t);
-
- t->pmtudisc = true;
- t->fou_encap_type = FOU_ENCAP_DIRECT;
-}
-static void sit_init(NetDev *n) {
- Tunnel *t = SIT(n);
+ switch (n->kind) {
+ case NETDEV_KIND_IPIP:
+ t = IPIP(n);
+ break;
+ case NETDEV_KIND_SIT:
+ t = SIT(n);
+ break;
+ default:
+ assert_not_reached("invalid netdev kind");
+ }
- assert(n);
assert(t);
t->pmtudisc = true;
+ t->fou_encap_type = FOU_ENCAP_DIRECT;
t->isatap = -1;
}
@@ -727,6 +744,7 @@ static void gre_erspan_init(NetDev *n) {
t->pmtudisc = true;
t->gre_erspan_sequence = -1;
+ t->fou_encap_type = FOU_ENCAP_DIRECT;
}
static void ip6gre_init(NetDev *n) {
@@ -759,7 +777,7 @@ static void ip6tnl_init(NetDev *n) {
const NetDevVTable ipip_vtable = {
.object_size = sizeof(Tunnel),
- .init = ipip_init,
+ .init = ipip_sit_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_ipip_sit_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
@@ -768,7 +786,7 @@ const NetDevVTable ipip_vtable = {
const NetDevVTable sit_vtable = {
.object_size = sizeof(Tunnel),
- .init = sit_init,
+ .init = ipip_sit_init,
.sections = "Match\0NetDev\0Tunnel\0",
.fill_message_create = netdev_ipip_sit_fill_message_create,
.create_type = NETDEV_CREATE_STACKED,
diff --git a/test/test-network/conf/25-fou-gre.netdev b/test/test-network/conf/25-fou-gre.netdev
new file mode 100644
index 0000000000..6ace606ed5
--- /dev/null
+++ b/test/test-network/conf/25-fou-gre.netdev
@@ -0,0 +1,14 @@
+[NetDev]
+Name=gretun96
+Kind=gre
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
+Key=1.2.5.103
+SerializeTunneledPackets=true
+Independent=true
+
+FooOverUDP=yes
+FOUDestinationPort=55556
+FOUSourcePort=1001
diff --git a/test/test-network/conf/25-fou-gretap.netdev b/test/test-network/conf/25-fou-gretap.netdev
new file mode 100644
index 0000000000..97fbc13d3c
--- /dev/null
+++ b/test/test-network/conf/25-fou-gretap.netdev
@@ -0,0 +1,13 @@
+[NetDev]
+Name=gretap96
+Kind=gretap
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
+Key=1.2.5.106
+SerializeTunneledPackets=true
+Independent=true
+
+FooOverUDP=yes
+FOUDestinationPort=55556
diff --git a/test/test-network/conf/25-fou-ipip.netdev b/test/test-network/conf/25-fou-ipip.netdev
new file mode 100644
index 0000000000..2f52157490
--- /dev/null
+++ b/test/test-network/conf/25-fou-ipip.netdev
@@ -0,0 +1,12 @@
+[NetDev]
+Name=ipiptun96
+Kind=ipip
+MTUBytes=1480
+
+[Tunnel]
+Local=192.168.223.238
+Remote=192.169.224.239
+Independent=true
+
+FooOverUDP=yes
+FOUDestinationPort=55555
diff --git a/test/test-network/conf/25-fou-ipproto-gre.netdev b/test/test-network/conf/25-fou-ipproto-gre.netdev
new file mode 100644
index 0000000000..09ecd9efb4
--- /dev/null
+++ b/test/test-network/conf/25-fou-ipproto-gre.netdev
@@ -0,0 +1,8 @@
+[NetDev]
+Name=fou98
+Kind=fou
+
+[FooOverUDP]
+Encapsulation=FooOverUDP
+Port=55556
+Protocol=GRE
diff --git a/test/test-network/conf/25-fou-ipproto-ipip.netdev b/test/test-network/conf/25-fou-ipproto-ipip.netdev
new file mode 100644
index 0000000000..b00d5ce588
--- /dev/null
+++ b/test/test-network/conf/25-fou-ipproto-ipip.netdev
@@ -0,0 +1,8 @@
+[NetDev]
+Name=fou99
+Kind=fou
+
+[FooOverUDP]
+Encapsulation=FooOverUDP
+Port=55555
+Protocol=ipip
diff --git a/test/test-network/conf/25-fou-sit.netdev b/test/test-network/conf/25-fou-sit.netdev
new file mode 100644
index 0000000000..f1b4f32574
--- /dev/null
+++ b/test/test-network/conf/25-fou-sit.netdev
@@ -0,0 +1,11 @@
+[NetDev]
+Name=sittun96
+Kind=sit
+
+[Tunnel]
+Local=10.65.223.238
+Remote=10.65.223.239
+Independent=true
+
+FooOverUDP=yes
+FOUDestinationPort=55555
diff --git a/test/test-network/conf/25-gre-tunnel-local-any.netdev b/test/test-network/conf/25-gre-tunnel-local-any.netdev
index 69a92c6c44..36bc55690a 100644
--- a/test/test-network/conf/25-gre-tunnel-local-any.netdev
+++ b/test/test-network/conf/25-gre-tunnel-local-any.netdev
@@ -5,3 +5,5 @@ Kind=gre
[Tunnel]
Local=any
Remote=10.65.223.239
+Key=104
+SerializeTunneledPackets=false
diff --git a/test/test-network/conf/25-gre-tunnel-remote-any.netdev b/test/test-network/conf/25-gre-tunnel-remote-any.netdev
index 286b2699ed..74c02c9c82 100644
--- a/test/test-network/conf/25-gre-tunnel-remote-any.netdev
+++ b/test/test-network/conf/25-gre-tunnel-remote-any.netdev
@@ -5,3 +5,5 @@ Kind=gre
[Tunnel]
Local=10.65.223.238
Remote=any
+Key=105
+SerializeTunneledPackets=false
diff --git a/test/test-network/conf/25-gre-tunnel.netdev b/test/test-network/conf/25-gre-tunnel.netdev
index 94d9320cdb..89c7fe1266 100644
--- a/test/test-network/conf/25-gre-tunnel.netdev
+++ b/test/test-network/conf/25-gre-tunnel.netdev
@@ -5,3 +5,6 @@ Kind=gre
[Tunnel]
Local=10.65.223.238
Remote=10.65.223.239
+InputKey=1.2.3.103
+OutputKey=1.2.4.103
+SerializeTunneledPackets=true
diff --git a/test/test-network/conf/25-gretap-tunnel-local-any.netdev b/test/test-network/conf/25-gretap-tunnel-local-any.netdev
index 19e8d61d62..17abcf69fc 100644
--- a/test/test-network/conf/25-gretap-tunnel-local-any.netdev
+++ b/test/test-network/conf/25-gretap-tunnel-local-any.netdev
@@ -5,3 +5,5 @@ Kind=gretap
[Tunnel]
Local=any
Remote=10.65.223.239
+Key=107
+SerializeTunneledPackets=true
diff --git a/test/test-network/conf/25-gretap-tunnel.netdev b/test/test-network/conf/25-gretap-tunnel.netdev
index 769e7653e4..912daf5bf1 100644
--- a/test/test-network/conf/25-gretap-tunnel.netdev
+++ b/test/test-network/conf/25-gretap-tunnel.netdev
@@ -5,3 +5,5 @@ Kind=gretap
[Tunnel]
Local=10.65.223.238
Remote=10.65.223.239
+Key=106
+SerializeTunneledPackets=true
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index d43301ae33..a246379644 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -201,8 +201,10 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'erspan98',
'erspan99',
'geneve99',
+ 'gretap96',
'gretap98',
'gretap99',
+ 'gretun96',
'gretun97',
'gretun98',
'gretun99',
@@ -214,6 +216,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'ip6tnl97',
'ip6tnl98',
'ip6tnl99',
+ 'ipiptun96',
'ipiptun97',
'ipiptun98',
'ipiptun99',
@@ -221,6 +224,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'isataptun99',
'macvlan99',
'macvtap99',
+ 'sittun96',
'sittun97',
'sittun98',
'sittun99',
@@ -257,6 +261,12 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
'25-bridge.netdev',
'25-erspan-tunnel-local-any.netdev',
'25-erspan-tunnel.netdev',
+ '25-fou-gretap.netdev',
+ '25-fou-gre.netdev',
+ '25-fou-ipip.netdev',
+ '25-fou-ipproto-gre.netdev',
+ '25-fou-ipproto-ipip.netdev',
+ '25-fou-sit.netdev',
'25-geneve.netdev',
'25-gretap-tunnel-local-any.netdev',
'25-gretap-tunnel.netdev',
@@ -572,12 +582,24 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'gre remote 10.65.223.239 local 10.65.223.238 dev dummy98')
+ self.assertRegex(output, 'ikey 1.2.3.103')
+ self.assertRegex(output, 'okey 1.2.4.103')
+ self.assertRegex(output, 'iseq')
+ self.assertRegex(output, 'oseq')
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun98']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'gre remote 10.65.223.239 local any dev dummy98')
+ self.assertRegex(output, 'ikey 0.0.0.104')
+ self.assertRegex(output, 'okey 0.0.0.104')
+ self.assertNotRegex(output, 'iseq')
+ self.assertNotRegex(output, 'oseq')
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun97']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'gre remote any local 10.65.223.238 dev dummy98')
+ self.assertRegex(output, 'ikey 0.0.0.105')
+ self.assertRegex(output, 'okey 0.0.0.105')
+ self.assertNotRegex(output, 'iseq')
+ self.assertNotRegex(output, 'oseq')
def test_ip6gre_tunnel(self):
self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretun.network',
@@ -611,9 +633,17 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretap99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'gretap remote 10.65.223.239 local 10.65.223.238 dev dummy98')
+ self.assertRegex(output, 'ikey 0.0.0.106')
+ self.assertRegex(output, 'okey 0.0.0.106')
+ self.assertRegex(output, 'iseq')
+ self.assertRegex(output, 'oseq')
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretap98']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'gretap remote 10.65.223.239 local any dev dummy98')
+ self.assertRegex(output, 'ikey 0.0.0.107')
+ self.assertRegex(output, 'okey 0.0.0.107')
+ self.assertRegex(output, 'iseq')
+ self.assertRegex(output, 'oseq')
def test_ip6gretap_tunnel(self):
self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gretap-tunnel.netdev', 'ip6gretap.network',
@@ -747,11 +777,18 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan99']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'erspan remote 172.16.1.100 local 172.16.1.200')
- self.assertRegex(output, '101')
+ self.assertRegex(output, 'ikey 0.0.0.101')
+ self.assertRegex(output, 'okey 0.0.0.101')
+ self.assertRegex(output, 'iseq')
+ self.assertRegex(output, 'oseq')
output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan98']).rstrip().decode('utf-8')
print(output)
self.assertRegex(output, 'erspan remote 172.16.1.100 local any')
self.assertRegex(output, '102')
+ self.assertRegex(output, 'ikey 0.0.0.102')
+ self.assertRegex(output, 'okey 0.0.0.102')
+ self.assertRegex(output, 'iseq')
+ self.assertRegex(output, 'oseq')
def test_tunnel_independent(self):
self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
@@ -759,6 +796,43 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertTrue(self.link_exits('ipiptun99'))
+ @expectedFailureIfModuleIsNotAvailable('fou')
+ def test_fou(self):
+ # The following redundant check is necessary for CentOS CI.
+ # Maybe, error handling in lookup_id() in sd-netlink/generic-netlink.c needs to be updated.
+ self.assertTrue(is_module_available('fou'))
+
+ self.copy_unit_to_networkd_unit_path('25-fou-ipproto-ipip.netdev', '25-fou-ipproto-gre.netdev',
+ '25-fou-ipip.netdev', '25-fou-sit.netdev',
+ '25-fou-gre.netdev', '25-fou-gretap.netdev')
+ self.start_networkd()
+
+ self.assertTrue(self.link_exits('ipiptun96'))
+ self.assertTrue(self.link_exits('sittun96'))
+ self.assertTrue(self.link_exits('gretun96'))
+ self.assertTrue(self.link_exits('gretap96'))
+
+ output = subprocess.check_output(['ip', 'fou', 'show']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'port 55555 ipproto 4')
+ self.assertRegex(output, 'port 55556 ipproto 47')
+
+ output = subprocess.check_output(['ip', '-d', 'link', 'show', 'ipiptun96']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
+ output = subprocess.check_output(['ip', '-d', 'link', 'show', 'sittun96']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55555')
+ output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretun96']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'encap fou encap-sport 1001 encap-dport 55556')
+ output = subprocess.check_output(['ip', '-d', 'link', 'show', 'gretap96']).rstrip().decode('utf-8')
+ print(output)
+ self.assertRegex(output, 'encap fou encap-sport auto encap-dport 55556')
+
+ subprocess.call(['ip', 'fou', 'del', 'port', '55555'])
+ subprocess.call(['ip', 'fou', 'del', 'port', '55556'])
+
def test_vxlan(self):
self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network', '11-dummy.netdev')
self.start_networkd()