diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 0b0fff1f65..c746ed31f8 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -1300,6 +1300,12 @@
for delivery to the real destination. This option is mandatory.
+
+ PeerPort=
+
+ Specifies the peer port number. Defaults to unset. Note that when peer port is set Peer= address is mandotory.
+
+
Protocol=
@@ -1313,7 +1319,7 @@
Peer=
- Configures peer IP address.
+ Configures peer IP address. Note that when peer address is set PeerPort= is mandotory.
diff --git a/src/network/netdev/fou-tunnel.c b/src/network/netdev/fou-tunnel.c
index 6ce2e5aec9..772f3db5e7 100644
--- a/src/network/netdev/fou-tunnel.c
+++ b/src/network/netdev/fou-tunnel.c
@@ -47,6 +47,12 @@ 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");
+ if (IN_SET(t->peer_family, AF_INET, AF_INET6)) {
+ r = sd_netlink_message_append_u16(m, FOU_ATTR_PEER_PORT, htobe16(t->peer_port));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_PEER_PORT attribute: %m");
+ }
+
switch (t->fou_encap_type) {
case NETDEV_FOO_OVER_UDP_ENCAP_DIRECT:
encap_type = FOU_ENCAP_DIRECT;
@@ -74,7 +80,7 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r
r = sd_netlink_message_append_in_addr(m, FOU_ATTR_LOCAL_V4, &t->local.in);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_LOCAL_V4 attribute: %m");
- } else {
+ } else if (t->local_family == AF_INET6) {
r = sd_netlink_message_append_in6_addr(m, FOU_ATTR_LOCAL_V6, &t->local.in6);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_LOCAL_V6 attribute: %m");
@@ -84,7 +90,7 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r
r = sd_netlink_message_append_in_addr(m, FOU_ATTR_PEER_V4, &t->peer.in);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_PEER_V4 attribute: %m");
- } else {
+ } else if (t->peer_family == AF_INET6){
r = sd_netlink_message_append_in6_addr(m, FOU_ATTR_PEER_V6, &t->peer.in6);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append FOU_ATTR_PEER_V6 attribute: %m");
@@ -233,6 +239,14 @@ static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) {
assert_not_reached("Invalid fou encap type");
}
+ if (t->peer_family == AF_UNSPEC && t->peer_port > 0)
+ return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "FooOverUDP peer port is set but peer address not configured in %s. Rejecting configuration.",
+ filename);
+ else if (t->peer_family != AF_UNSPEC && t->peer_port == 0)
+ return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+ "FooOverUDP peer port not set but peer address is configured in %s. Rejecting configuration.",
+ filename);
return 0;
}
diff --git a/src/network/netdev/fou-tunnel.h b/src/network/netdev/fou-tunnel.h
index 0402239c69..6304e6b549 100644
--- a/src/network/netdev/fou-tunnel.h
+++ b/src/network/netdev/fou-tunnel.h
@@ -21,6 +21,7 @@ typedef struct FouTunnel {
uint8_t fou_protocol;
uint16_t port;
+ uint16_t peer_port;
int local_family;
int peer_family;
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 0e712c55ae..6a6d9dc752 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -81,6 +81,7 @@ Tunnel.ISATAP, config_parse_tristate,
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)
+FooOverUDP.PeerPort, config_parse_ip_port, 0, offsetof(FouTunnel, peer_port)
FooOverUDP.Local, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, local)
FooOverUDP.Peer, config_parse_fou_tunnel_address, 0, offsetof(FouTunnel, peer)
L2TP.TunnelId, config_parse_l2tp_tunnel_id, 0, offsetof(L2tpTunnel, tunnel_id)
diff --git a/test/fuzz/fuzz-netdev-parser/directives.netdev b/test/fuzz/fuzz-netdev-parser/directives.netdev
index 2f152cbd6d..d2e10c71bd 100644
--- a/test/fuzz/fuzz-netdev-parser/directives.netdev
+++ b/test/fuzz/fuzz-netdev-parser/directives.netdev
@@ -140,6 +140,7 @@ DynamicTransmitLoadBalancing=
[FooOverUDP]
Protocol=
Port=
+PeerPort=
Encapsulation=
Local=
Peer=