diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 386c18b25c..3ff1a036ff 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -1900,6 +1900,32 @@
When unset, the kernel's default will be used.
+
+ ProxyARP=
+
+ Takes a boolean. Configures whether proxy ARP to be enabled on this port.
+ When unset, the kernel's default will be used.
+
+
+
+ ProxyARPWiFi=
+
+ Takes a boolean. Configures whether proxy ARP to be enabled on this port
+ which meets extended requirements by IEEE 802.11 and Hotspot 2.0 specifications.
+ When unset, the kernel's default will be used.
+
+
+
+ MulticastRouter=
+
+ Configures this port for having multicast routers attached. A port with a multicast
+ router will receive all multicast traffic. Takes one of no
+ to disable multicast routers on this port, query to let the system detect
+ the presence of routers, permanent to permanently enable multicast traffic
+ forwarding on this port, or temporary to enable multicast routers temporarily
+ on this port, not depending on incoming queries. When unset, the kernel's default will be used.
+
+
Cost=
diff --git a/src/network/netdev/bond.h b/src/network/netdev/bond.h
index 12f59cd946..038272f107 100644
--- a/src/network/netdev/bond.h
+++ b/src/network/netdev/bond.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
#include
#include "in-addr-util.h"
diff --git a/src/network/netdev/fou-tunnel.c b/src/network/netdev/fou-tunnel.c
index 2d4481e060..b5d4690f21 100644
--- a/src/network/netdev/fou-tunnel.c
+++ b/src/network/netdev/fou-tunnel.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
#include
+#include
#include
#include "conf-parser.h"
diff --git a/src/network/netdev/fou-tunnel.h b/src/network/netdev/fou-tunnel.h
index 51eeac41bd..a93d2dc02f 100644
--- a/src/network/netdev/fou-tunnel.h
+++ b/src/network/netdev/fou-tunnel.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
#include
#include "in-addr-util.h"
diff --git a/src/network/netdev/ipvlan.h b/src/network/netdev/ipvlan.h
index 78f09dbb2d..eb67b5c195 100644
--- a/src/network/netdev/ipvlan.h
+++ b/src/network/netdev/ipvlan.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
#include
#include "netdev/netdev.h"
diff --git a/src/network/netdev/l2tp-tunnel.c b/src/network/netdev/l2tp-tunnel.c
index 2a74d89e5d..6ac23052bb 100644
--- a/src/network/netdev/l2tp-tunnel.c
+++ b/src/network/netdev/l2tp-tunnel.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include
diff --git a/src/network/netdev/l2tp-tunnel.h b/src/network/netdev/l2tp-tunnel.h
index a97c924c5d..d314b98703 100644
--- a/src/network/netdev/l2tp-tunnel.h
+++ b/src/network/netdev/l2tp-tunnel.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
#include
#include "in-addr-util.h"
diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c
index ccc37cded4..c82a6fd0ac 100644
--- a/src/network/netdev/macsec.c
+++ b/src/network/netdev/macsec.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include
#include
diff --git a/src/network/netdev/macsec.h b/src/network/netdev/macsec.h
index 2bd08ac500..2a3443a6d4 100644
--- a/src/network/netdev/macsec.h
+++ b/src/network/netdev/macsec.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
#include
#include "in-addr-util.h"
diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c
index 84f6af8578..e69a009c31 100644
--- a/src/network/netdev/tunnel.c
+++ b/src/network/netdev/tunnel.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include
#include
diff --git a/src/network/netdev/tuntap.c b/src/network/netdev/tuntap.c
index 951138d257..d08acf0c66 100644
--- a/src/network/netdev/tuntap.c
+++ b/src/network/netdev/tuntap.c
@@ -2,12 +2,12 @@
#include
#include
-#include
#include
#include
#include
#include
#include
+#include
#include "alloc-util.h"
#include "fd-util.h"
diff --git a/src/network/netdev/vcan.h b/src/network/netdev/vcan.h
index 6f62686d08..671b5cb639 100644
--- a/src/network/netdev/vcan.h
+++ b/src/network/netdev/vcan.h
@@ -3,6 +3,7 @@
typedef struct VCan VCan;
+#include
#include
#include "netdev/netdev.h"
diff --git a/src/network/netdev/veth.c b/src/network/netdev/veth.c
index 3ad95ade0f..a0a0b8e39e 100644
--- a/src/network/netdev/veth.c
+++ b/src/network/netdev/veth.c
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include
-#include
#include
+#include
#include "sd-netlink.h"
diff --git a/src/network/netdev/vlan.c b/src/network/netdev/vlan.c
index dd548b338a..4d939ab045 100644
--- a/src/network/netdev/vlan.c
+++ b/src/network/netdev/vlan.c
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include
-#include
#include
+#include
#include "netdev/vlan.h"
#include "vlan-util.h"
diff --git a/src/network/netdev/wireguard.h b/src/network/netdev/wireguard.h
index 862f2a99c4..ce336c985a 100644
--- a/src/network/netdev/wireguard.h
+++ b/src/network/netdev/wireguard.h
@@ -2,6 +2,7 @@
typedef struct Wireguard Wireguard;
+#include
#include
#include "in-addr-util.h"
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index a42eb8686e..23831d25b6 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include "alloc-util.h"
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 7db59d3aca..afa3e2cfd6 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -3,7 +3,7 @@
Copyright © 2014 Intel Corporation. All rights reserved.
***/
-#include
+#include
#include
#include "sd-radv.h"
@@ -418,7 +418,7 @@ static int dhcp6_address_change(
uint32_t lifetime_valid) {
_cleanup_(address_freep) Address *addr = NULL;
- char buffer[INET6_ADDRSTRLEN];
+ _cleanup_free_ char *buffer = NULL;
int r;
r = address_new(&addr);
@@ -426,7 +426,7 @@ static int dhcp6_address_change(
return r;
addr->family = AF_INET6;
- memcpy(&addr->in_addr.in6, ip6_addr, sizeof(*ip6_addr));
+ addr->in_addr.in6 = *ip6_addr;
addr->flags = IFA_F_NOPREFIXROUTE;
addr->prefixlen = 128;
@@ -434,10 +434,10 @@ static int dhcp6_address_change(
addr->cinfo.ifa_prefered = lifetime_preferred;
addr->cinfo.ifa_valid = lifetime_valid;
+ (void) in_addr_to_string(addr->family, &addr->in_addr, &buffer);
log_link_info(link,
"DHCPv6 address %s/%d timeout preferred %d valid %d",
- inet_ntop(AF_INET6, &addr->in_addr.in6, buffer, sizeof(buffer)),
- addr->prefixlen, lifetime_preferred, lifetime_valid);
+ strnull(buffer), addr->prefixlen, lifetime_preferred, lifetime_valid);
r = address_configure(addr, link, dhcp6_address_handler, true);
if (r < 0)
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 79e90f2f5a..8fb8a64e6d 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include "network-internal.h"
diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c
index e2d77e9ad2..863171b071 100644
--- a/src/network/networkd-ipv6-proxy-ndp.c
+++ b/src/network/networkd-ipv6-proxy-ndp.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index f13fcb7b6e..2b6ff2b6c5 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
-#include
+#include
#include
#include
#include
@@ -1136,20 +1136,20 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
log_debug("Copying NTP server information from %s", link->ifname);
STRV_FOREACH(a, link->network->ntp) {
- struct in_addr ia;
+ union in_addr_union ia;
/* Only look for IPv4 addresses */
- if (inet_pton(AF_INET, *a, &ia) <= 0)
+ if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
- if (in4_addr_is_null(&ia) || in4_addr_is_localhost(&ia))
+ if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
- addresses[n_addresses++] = ia;
+ addresses[n_addresses++] = ia.in;
}
if (link->network->dhcp_use_ntp && link->dhcp_lease) {
@@ -1592,7 +1592,6 @@ static int link_set_bridge(Link *link) {
r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROTECT, link->network->allow_port_to_be_root);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROTECT attribute: %m");
-
}
if (link->network->unicast_flood >= 0) {
@@ -1625,6 +1624,18 @@ static int link_set_bridge(Link *link) {
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_LEARNING attribute: %m");
}
+ if (link->network->bridge_proxy_arp >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP, link->network->bridge_proxy_arp);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP attribute: %m");
+ }
+
+ if (link->network->bridge_proxy_arp_wifi >= 0) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_PROXYARP_WIFI, link->network->bridge_proxy_arp_wifi);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PROXYARP_WIFI attribute: %m");
+ }
+
if (link->network->cost != 0) {
r = sd_netlink_message_append_u32(req, IFLA_BRPORT_COST, link->network->cost);
if (r < 0)
@@ -1637,6 +1648,12 @@ static int link_set_bridge(Link *link) {
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
}
+ if (link->network->multicast_router != _MULTICAST_ROUTER_INVALID) {
+ r = sd_netlink_message_append_u8(req, IFLA_BRPORT_MULTICAST_ROUTER, link->network->multicast_router);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_MULTICAST_ROUTER attribute: %m");
+ }
+
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_LINKINFO attribute: %m");
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index a842d131a5..1af25dc812 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -1,9 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include
#include
+#include
#include
#include
-#include
#include "sd-daemon.h"
#include "sd-netlink.h"
@@ -477,19 +478,17 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo
}
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
+ _cleanup_free_ char *buf = NULL;
Manager *m = userdata;
Link *link = NULL;
uint16_t type;
- unsigned char flags;
- int family;
- unsigned char prefixlen;
- unsigned char scope;
+ unsigned char flags, prefixlen, scope;
union in_addr_union in_addr = IN_ADDR_NULL;
struct ifa_cacheinfo cinfo;
Address *address = NULL;
- char buf[INET6_ADDRSTRLEN], valid_buf[FORMAT_TIMESPAN_MAX];
+ char valid_buf[FORMAT_TIMESPAN_MAX];
const char *valid_str = NULL;
- int r, ifindex;
+ int ifindex, family, r;
assert(rtnl);
assert(message);
@@ -577,8 +576,9 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
assert_not_reached("Received unsupported address family");
}
- if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN)) {
- log_link_warning(link, "Could not print address, ignoring");
+ r = in_addr_to_string(family, &in_addr, &buf);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Could not print address, ignoring: %m");
return 0;
}
@@ -586,12 +586,10 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
if (r < 0 && r != -ENODATA) {
log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m");
return 0;
- } else if (r >= 0) {
- if (cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
- valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
- cinfo.ifa_valid * USEC_PER_SEC,
- USEC_PER_SEC);
- }
+ } else if (r >= 0 && cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
+ valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
+ cinfo.ifa_valid * USEC_PER_SEC,
+ USEC_PER_SEC);
(void) address_get(link, family, &in_addr, prefixlen, &address);
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
index 1084a3a60b..06fa9d8d32 100644
--- a/src/network/networkd-manager.h
+++ b/src/network/networkd-manager.h
@@ -1,8 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
-#include
-
#include "sd-bus.h"
#include "sd-device.h"
#include "sd-event.h"
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 3b54652805..325f7ae592 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -66,12 +66,11 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (address->family != AF_INET6)
continue;
if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) {
- char buffer[INET6_ADDRSTRLEN];
+ _cleanup_free_ char *buffer = NULL;
+ (void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer);
log_link_debug(link, "No NDisc route added, gateway %s matches local address",
- inet_ntop(AF_INET6,
- &address->in_addr.in6,
- buffer, sizeof(buffer)));
+ strnull(buffer));
return 0;
}
}
@@ -80,12 +79,11 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (address->family != AF_INET6)
continue;
if (in_addr_equal(AF_INET6, &gateway, &address->in_addr)) {
- char buffer[INET6_ADDRSTRLEN];
+ _cleanup_free_ char *buffer = NULL;
+ (void) in_addr_to_string(AF_INET6, &address->in_addr, &buffer);
log_link_debug(link, "No NDisc route added, gateway %s matches local address",
- inet_ntop(AF_INET6,
- &address->in_addr.in6,
- buffer, sizeof(buffer)));
+ strnull(buffer));
return 0;
}
}
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 5a3c99a38f..c6036e29fa 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -178,7 +178,10 @@ Bridge.MulticastFlood, config_parse_tristate,
Bridge.MulticastToUnicast, config_parse_tristate, 0, offsetof(Network, multicast_to_unicast)
Bridge.NeighborSuppression, config_parse_tristate, 0, offsetof(Network, neighbor_suppression)
Bridge.Learning, config_parse_tristate, 0, offsetof(Network, learning)
+Bridge.ProxyARP, config_parse_tristate, 0, offsetof(Network, bridge_proxy_arp)
+Bridge.ProxyARPWiFi, config_parse_tristate, 0, offsetof(Network, bridge_proxy_arp_wifi)
Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority)
+Bridge.MulticastRouter, config_parse_multicast_router, 0, offsetof(Network, multicast_router)
BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0
BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0
BridgeFDB.Destination, config_parse_fdb_destination, 0, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index c02140d93f..d39aaa207b 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -1,5 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include
+#include
#include
#include "alloc-util.h"
@@ -386,7 +388,10 @@ int network_load_one(Manager *manager, const char *filename) {
.multicast_to_unicast = -1,
.neighbor_suppression = -1,
.learning = -1,
+ .bridge_proxy_arp = -1,
+ .bridge_proxy_arp_wifi = -1,
.priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
+ .multicast_router = _MULTICAST_ROUTER_INVALID,
.lldp_mode = LLDP_MODE_ROUTERS_ONLY,
@@ -1115,7 +1120,8 @@ int config_parse_dhcp_server_dns(
for (;;) {
_cleanup_free_ char *w = NULL;
- struct in_addr a, *m;
+ union in_addr_union a;
+ struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
@@ -1128,9 +1134,10 @@ int config_parse_dhcp_server_dns(
if (r == 0)
break;
- if (inet_pton(AF_INET, w, &a) <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Failed to parse DNS server address, ignoring: %s", w);
+ r = in_addr_from_string(AF_INET, w, &a);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse DNS server address '%s', ignoring assignment: %m", w);
continue;
}
@@ -1138,7 +1145,7 @@ int config_parse_dhcp_server_dns(
if (!m)
return log_oom();
- m[n->n_dhcp_server_dns++] = a;
+ m[n->n_dhcp_server_dns++] = a.in;
n->dhcp_server_dns = m;
}
@@ -1275,7 +1282,8 @@ int config_parse_dhcp_server_ntp(
for (;;) {
_cleanup_free_ char *w = NULL;
- struct in_addr a, *m;
+ union in_addr_union a;
+ struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
@@ -1288,9 +1296,10 @@ int config_parse_dhcp_server_ntp(
if (r == 0)
return 0;
- if (inet_pton(AF_INET, w, &a) <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Failed to parse NTP server address, ignoring: %s", w);
+ r = in_addr_from_string(AF_INET, w, &a);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse NTP server address '%s', ignoring: %m", w);
continue;
}
@@ -1298,7 +1307,7 @@ int config_parse_dhcp_server_ntp(
if (!m)
return log_oom();
- m[n->n_dhcp_server_ntp++] = a;
+ m[n->n_dhcp_server_ntp++] = a.in;
n->dhcp_server_ntp = m;
}
}
@@ -1780,3 +1789,14 @@ int config_parse_required_for_online(
return 0;
}
+
+static const char* const multicast_router_table[_MULTICAST_ROUTER_MAX] = {
+ [MULTICAST_ROUTER_NONE] = "no",
+ [MULTICAST_ROUTER_TEMPORARY_QUERY] = "query",
+ [MULTICAST_ROUTER_PERMANENT] = "permanent",
+ [MULTICAST_ROUTER_TEMPORARY] = "temporary",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(multicast_router, MulticastRouter, _MULTICAST_ROUTER_INVALID);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_multicast_router, multicast_router, MulticastRouter,
+ "Failed to parse bridge multicast router setting");
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 6ad25045df..366f9d3f39 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include
+#include
+
#include "sd-bus.h"
#include "sd-device.h"
@@ -84,6 +87,15 @@ typedef enum RADVPrefixDelegation {
_RADV_PREFIX_DELEGATION_INVALID = -1,
} RADVPrefixDelegation;
+typedef enum MulticastRouter {
+ MULTICAST_ROUTER_NONE = MDB_RTR_TYPE_DISABLED,
+ MULTICAST_ROUTER_TEMPORARY_QUERY = MDB_RTR_TYPE_TEMP_QUERY,
+ MULTICAST_ROUTER_PERMANENT = MDB_RTR_TYPE_PERM,
+ MULTICAST_ROUTER_TEMPORARY = MDB_RTR_TYPE_TEMP,
+ _MULTICAST_ROUTER_MAX,
+ _MULTICAST_ROUTER_INVALID = -1,
+} MulticastRouter;
+
typedef struct Manager Manager;
struct Network {
@@ -182,8 +194,11 @@ struct Network {
int multicast_to_unicast;
int neighbor_suppression;
int learning;
+ int bridge_proxy_arp;
+ int bridge_proxy_arp_wifi;
uint32_t cost;
uint16_t priority;
+ MulticastRouter multicast_router;
bool use_br_vlan;
uint16_t pvid;
@@ -319,6 +334,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
+CONFIG_PARSER_PROTOTYPE(config_parse_multicast_router);
/* Legacy IPv4LL support */
CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
@@ -340,3 +356,6 @@ LLDPMode lldp_mode_from_string(const char *s) _pure_;
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
+
+const char* multicast_router_to_string(MulticastRouter i) _const_;
+MulticastRouter multicast_router_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-routing-policy-rule.h b/src/network/networkd-routing-policy-rule.h
index 28699ba236..4ee0b5489e 100644
--- a/src/network/networkd-routing-policy-rule.h
+++ b/src/network/networkd-routing-policy-rule.h
@@ -2,6 +2,7 @@
#pragma once
#include
+#include
#include
#include
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 4b04aa0463..090f3777a5 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include
#include
#include
diff --git a/src/network/test-network.c b/src/network/test-network.c
index 21ee97e84e..23fcea666e 100644
--- a/src/network/test-network.c
+++ b/src/network/test-network.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
+#include
#include
#include "sd-device.h"
@@ -15,32 +16,31 @@
static void test_deserialize_in_addr(void) {
_cleanup_free_ struct in_addr *addresses = NULL;
_cleanup_free_ struct in6_addr *addresses6 = NULL;
- struct in_addr a, b, c;
- struct in6_addr d, e, f;
+ union in_addr_union a, b, c, d, e, f;
int size;
const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8";
- assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0);
- assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0);
+ assert_se(in_addr_from_string(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) < 0);
+ assert_se(in_addr_from_string(AF_INET6, "192.168.0.1", &d) < 0);
- assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1);
- assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1);
- assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1);
- assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1);
- assert_se(inet_pton(AF_INET6, "::1", &e) == 1);
- assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1);
+ assert_se(in_addr_from_string(AF_INET, "192.168.0.1", &a) >= 0);
+ assert_se(in_addr_from_string(AF_INET, "192.168.0.2", &b) >= 0);
+ assert_se(in_addr_from_string(AF_INET, "192.168.0.3", &c) >= 0);
+ assert_se(in_addr_from_string(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) >= 0);
+ assert_se(in_addr_from_string(AF_INET6, "::1", &e) >= 0);
+ assert_se(in_addr_from_string(AF_INET6, "1:0:0:0:0:0:0:8", &f) >= 0);
assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0);
assert_se(size == 3);
- assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr)));
- assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr)));
- assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr)));
+ assert_se(in_addr_equal(AF_INET, &a, (union in_addr_union *) &addresses[0]));
+ assert_se(in_addr_equal(AF_INET, &b, (union in_addr_union *) &addresses[1]));
+ assert_se(in_addr_equal(AF_INET, &c, (union in_addr_union *) &addresses[2]));
assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0);
assert_se(size == 3);
- assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr)));
- assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr)));
- assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr)));
+ assert_se(in_addr_equal(AF_INET6, &d, (union in_addr_union *) &addresses6[0]));
+ assert_se(in_addr_equal(AF_INET6, &e, (union in_addr_union *) &addresses6[1]));
+ assert_se(in_addr_equal(AF_INET6, &f, (union in_addr_union *) &addresses6[2]));
}
static void test_deserialize_dhcp_routes(void) {
@@ -146,13 +146,13 @@ static void test_address_equality(void) {
a2->family = AF_INET;
assert_se(address_equal(a1, a2));
- assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in));
+ assert_se(in_addr_from_string(AF_INET, "192.168.3.9", &a1->in_addr) >= 0);
assert_se(!address_equal(a1, a2));
- assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in));
+ assert_se(in_addr_from_string(AF_INET, "192.168.3.9", &a2->in_addr) >= 0);
assert_se(address_equal(a1, a2));
- assert_se(inet_pton(AF_INET, "192.168.3.10", &a1->in_addr_peer.in));
+ assert_se(in_addr_from_string(AF_INET, "192.168.3.10", &a1->in_addr_peer) >= 0);
assert_se(address_equal(a1, a2));
- assert_se(inet_pton(AF_INET, "192.168.3.11", &a2->in_addr_peer.in));
+ assert_se(in_addr_from_string(AF_INET, "192.168.3.11", &a2->in_addr_peer) >= 0);
assert_se(address_equal(a1, a2));
a1->prefixlen = 10;
assert_se(!address_equal(a1, a2));
@@ -163,14 +163,14 @@ static void test_address_equality(void) {
assert_se(!address_equal(a1, a2));
a2->family = AF_INET6;
- assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6));
- assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6));
+ assert_se(in_addr_from_string(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr) >= 0);
+ assert_se(in_addr_from_string(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr) >= 0);
assert_se(address_equal(a1, a2));
a2->prefixlen = 8;
assert_se(address_equal(a1, a2));
- assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6));
+ assert_se(in_addr_from_string(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr) >= 0);
assert_se(!address_equal(a1, a2));
}
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index d327b27308..d27e0ad201 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -18,11 +18,11 @@
***/
#include
-#include
-#include
#include
#include
#include
+#include
+#include
#include "sd-event.h"
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 2cf8b6fa04..97e8e4a580 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -10,6 +10,9 @@ MulticastToUnicast=
MulticastFlood=
NeighborSuppression=
Learning=
+ProxyARP=
+ProxyARPWiFi=
+MulticastRouter=
[Match]
KernelVersion=
Type=