From 856e309d7b18cabe18c845bdf57e92958343a9ec Mon Sep 17 00:00:00 2001 From: Michael Chapman Date: Tue, 16 Aug 2016 19:07:42 +1000 Subject: networkd: avoid NULL pointer dereference in route_add If no result parameter is provided, do not attempt to write the found/newly-created route to it. This is presently not an issue as all callers currently provide a non-NULL result parameter, however we should do this for symmetry with address_add and future code robustness. --- src/network/networkd-route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index cedaf47cf8..82f9047ff6 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -322,7 +322,8 @@ int route_add( } else return r; - *ret = route; + if (ret) + *ret = route; return 0; } -- cgit v1.2.3-54-g00ecf From 3bdccf69ca626d6c2f6653044f1f68d9c9da0e42 Mon Sep 17 00:00:00 2001 From: Michael Chapman Date: Thu, 18 Aug 2016 17:46:21 +1000 Subject: networkd: do not touch link_messages when expiring routes link_messages is used during link configuration to advance the link state machine through SETTING_ADDRESSES -> SETTING_ROUTES -> CONFIGURED. If a route expires in the middle of this, it is possible for link_messages to hit zero inside route_expire_callback, rather than in route_handler or address_handler where it would trigger the next step in configuration. Should this happen, the link will not complete configuration, and it may not have its static routes configured. Since route_expire_callback does not need to do anything once the expired route has been removed from the kernel, it is safe to simply not account for the netlink request. --- src/network/networkd-route.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 82f9047ff6..5335df53c7 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -441,20 +441,14 @@ static int route_expire_callback(sd_netlink *rtnl, sd_netlink_message *m, void * assert(m); assert(link); assert(link->ifname); - assert(link->link_messages > 0); if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) return 1; - link->link_messages--; - r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) log_link_warning_errno(link, r, "could not remove route: %m"); - if (link->link_messages == 0) - log_link_debug(link, "route removed"); - return 1; } @@ -467,11 +461,8 @@ int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata) { r = route_remove(route, route->link, route_expire_callback); if (r < 0) log_warning_errno(r, "Could not remove route: %m"); - else { - /* route may not be exist in kernel. If we fail still remove it */ - route->link->link_messages++; + else route_free(route); - } return 1; } -- cgit v1.2.3-54-g00ecf From a0d95bbc38e60b1ac0b6b57d7a0ac3246d1576be Mon Sep 17 00:00:00 2001 From: Michael Chapman Date: Thu, 18 Aug 2016 17:54:12 +1000 Subject: networkd: use RT_TABLE_MAIN by default The default route table used by sd-netlink (and iproute2) is RT_TABLE_MAIN, not RT_TABLE_DEFAULT. Ensure networkd has the same idea. --- src/network/networkd-route.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 5335df53c7..b197a5da6b 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -41,7 +41,7 @@ int route_new(Route **ret) { route->family = AF_UNSPEC; route->scope = RT_SCOPE_UNIVERSE; route->protocol = RTPROT_UNSPEC; - route->table = RT_TABLE_DEFAULT; + route->table = RT_TABLE_MAIN; route->lifetime = USEC_INFINITY; *ret = route; @@ -549,14 +549,12 @@ int route_configure( if (r < 0) return log_error_errno(r, "Could not set flags: %m"); - if (route->table != RT_TABLE_DEFAULT) { - + if (route->table != RT_TABLE_MAIN) { if (route->table < 256) { r = sd_rtnl_message_route_set_table(req, route->table); if (r < 0) return log_error_errno(r, "Could not set route table: %m"); } else { - r = sd_rtnl_message_route_set_table(req, RT_TABLE_UNSPEC); if (r < 0) return log_error_errno(r, "Could not set route table: %m"); -- cgit v1.2.3-54-g00ecf From 47d2d30d83eb7494593181915967be38451d72f1 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 21 Aug 2016 09:06:28 -0400 Subject: networkd: limit the number of routes to the kernel limit (#4007) Fixes #3922. --- src/network/networkd-route.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index b197a5da6b..6f60ee5e31 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -26,10 +26,37 @@ #include "parse-util.h" #include "set.h" #include "string-util.h" +#include "sysctl-util.h" #include "util.h" -#define ROUTES_PER_LINK_MAX 2048U -#define STATIC_ROUTES_PER_NETWORK_MAX 1024U +#define ROUTES_DEFAULT_MAX_PER_FAMILY 4096U + +static unsigned routes_max(void) { + static thread_local unsigned cached = 0; + + _cleanup_free_ char *s4 = NULL, *s6 = NULL; + unsigned val4 = ROUTES_DEFAULT_MAX_PER_FAMILY, val6 = ROUTES_DEFAULT_MAX_PER_FAMILY; + + if (cached > 0) + return cached; + + if (sysctl_read("net/ipv4/route/max_size", &s4) >= 0) { + truncate_nl(s4); + if (safe_atou(s4, &val4) >= 0 && + val4 == 2147483647U) + /* This is the default "no limit" value in the kernel */ + val4 = ROUTES_DEFAULT_MAX_PER_FAMILY; + } + + if (sysctl_read("net/ipv6/route/max_size", &s6) >= 0) { + truncate_nl(s6); + (void) safe_atou(s6, &val6); + } + + cached = MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val4) + + MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val6); + return cached; +} int route_new(Route **ret) { _cleanup_route_free_ Route *route = NULL; @@ -67,7 +94,7 @@ int route_new_static(Network *network, unsigned section, Route **ret) { } } - if (network->n_static_routes >= STATIC_ROUTES_PER_NETWORK_MAX) + if (network->n_static_routes >= routes_max()) return -E2BIG; r = route_new(&route); @@ -484,7 +511,7 @@ int route_configure( assert(route->family == AF_INET || route->family == AF_INET6); if (route_get(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL) <= 0 && - set_size(link->routes) >= ROUTES_PER_LINK_MAX) + set_size(link->routes) >= routes_max()) return -E2BIG; r = sd_rtnl_message_new_route(link->manager->rtnl, &req, -- cgit v1.2.3-54-g00ecf From b68d26b8cd5b5175e84a6b7a464a96dca6d40f66 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 21 Aug 2016 13:15:26 -0400 Subject: networkd: fix typo (#4013) --- src/network/networkd-link.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 69ee7424ce..71484e3288 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2805,17 +2805,17 @@ network_file_fail: if (dhcp4_address) { r = in_addr_from_string(AF_INET, dhcp4_address, &address); if (r < 0) { - log_link_debug_errno(link, r, "Falied to parse DHCPv4 address %s: %m", dhcp4_address); + log_link_debug_errno(link, r, "Failed to parse DHCPv4 address %s: %m", dhcp4_address); goto dhcp4_address_fail; } r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) - return log_link_error_errno(link, r, "Falied to create DHCPv4 client: %m"); + return log_link_error_errno(link, r, "Failed to create DHCPv4 client: %m"); r = sd_dhcp_client_set_request_address(link->dhcp_client, &address.in); if (r < 0) - return log_link_error_errno(link, r, "Falied to set initial DHCPv4 address %s: %m", dhcp4_address); + return log_link_error_errno(link, r, "Failed to set initial DHCPv4 address %s: %m", dhcp4_address); } dhcp4_address_fail: @@ -2823,17 +2823,17 @@ dhcp4_address_fail: if (ipv4ll_address) { r = in_addr_from_string(AF_INET, ipv4ll_address, &address); if (r < 0) { - log_link_debug_errno(link, r, "Falied to parse IPv4LL address %s: %m", ipv4ll_address); + log_link_debug_errno(link, r, "Failed to parse IPv4LL address %s: %m", ipv4ll_address); goto ipv4ll_address_fail; } r = sd_ipv4ll_new(&link->ipv4ll); if (r < 0) - return log_link_error_errno(link, r, "Falied to create IPv4LL client: %m"); + return log_link_error_errno(link, r, "Failed to create IPv4LL client: %m"); r = sd_ipv4ll_set_address(link->ipv4ll, &address.in); if (r < 0) - return log_link_error_errno(link, r, "Falied to set initial IPv4LL address %s: %m", ipv4ll_address); + return log_link_error_errno(link, r, "Failed to set initial IPv4LL address %s: %m", ipv4ll_address); } ipv4ll_address_fail: -- cgit v1.2.3-54-g00ecf From 8dec4a9d2d8301102e12f8cf1d9a646e685fb1ea Mon Sep 17 00:00:00 2001 From: Felipe Sateler Date: Tue, 23 Aug 2016 06:29:30 -0300 Subject: core,network: Use const qualifiers for block-local variables in macro functions (#4019) Prevents discard-qualifiers warnings when the passed variable was const --- src/core/selinux-access.h | 2 +- src/core/unit.h | 2 +- src/network/networkd-link.h | 2 +- src/network/networkd-netdev.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h index 8f1f058a32..f46370d020 100644 --- a/src/core/selinux-access.h +++ b/src/core/selinux-access.h @@ -33,7 +33,7 @@ int mac_selinux_generic_access_check(sd_bus_message *message, const char *path, #define mac_selinux_unit_access_check(unit, message, permission, error) \ ({ \ - Unit *_unit = (unit); \ + const Unit *_unit = (unit); \ mac_selinux_generic_access_check((message), _unit->source_path ?: _unit->fragment_path, (permission), (error)); \ }) diff --git a/src/core/unit.h b/src/core/unit.h index 53875653d7..f7a65782f1 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -639,7 +639,7 @@ void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid); #define log_unit_full(unit, level, error, ...) \ ({ \ - Unit *_u = (unit); \ + const Unit *_u = (unit); \ _u ? log_object_internal(level, error, __FILE__, __LINE__, __func__, _u->manager->unit_log_field, _u->id, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 2809b1fe0b..05b2a2b323 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -186,7 +186,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); #define log_link_full(link, level, error, ...) \ ({ \ - Link *_l = (link); \ + const Link *_l = (link); \ _l ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) \ diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index b92a973b85..09863e72b4 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -180,7 +180,7 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign #define log_netdev_full(netdev, level, error, ...) \ ({ \ - NetDev *_n = (netdev); \ + const NetDev *_n = (netdev); \ _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) -- cgit v1.2.3-54-g00ecf From c436d553973b43ec5e8cf2eab84dd3e9e334295f Mon Sep 17 00:00:00 2001 From: Mantas Mikulėnas Date: Wed, 24 Aug 2016 18:26:48 +0300 Subject: networkd: do not drop config for unmanaged interfaces Flushing foreign configuration for unmanaged interfaces is outright evil, especially when it's a regular occurence with Wi-Fi. Fixes: 3104883ddc24 "networkd: remove route if carrier is lost" Ref: #3831 --- src/network/networkd-link.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 71484e3288..aab40a0eb1 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2957,9 +2957,11 @@ static int link_carrier_lost(Link *link) { if (r < 0) return r; - r = link_drop_foreign_config(link); - if (r < 0) - return r; + if (link->state != LINK_STATE_UNMANAGED) { + r = link_drop_foreign_config(link); + if (r < 0) + return r; + } r = link_handle_bound_by_list(link); if (r < 0) -- cgit v1.2.3-54-g00ecf From c7440e7401461a4bc668f5dae5b1861ed26b85dd Mon Sep 17 00:00:00 2001 From: Tobias Jungel Date: Wed, 31 Aug 2016 20:06:23 +0200 Subject: networkd: add options to bridge (#4051) This patch allows to configure AgeingTimeSec, Priority and DefaultPVID for bridge interfaces. --- man/systemd.netdev.xml | 20 ++++++++++++++++++++ src/network/networkd-netdev-bridge.c | 18 ++++++++++++++++++ src/network/networkd-netdev-bridge.h | 3 +++ src/network/networkd-netdev-gperf.gperf | 3 +++ src/shared/conf-parser.c | 1 + src/shared/conf-parser.h | 1 + 6 files changed, 46 insertions(+) (limited to 'src/network') diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index e56708a648..1f9f071b94 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -314,6 +314,26 @@ of the Listening and Learning states before the Forwarding state is entered. + + AgeingTimeSec= + + This specifies the number of seconds a MAC Address will be kept in + the forwaring database after having a packet received from this MAC Address. + + + + Priority= + + The priority of the bridge. An integer between 0 and 65535. A lower value + means higher priority. The bridge having the lowest priority will be elected as root bridge. + + + + DefaultPVID= + + This specifies the default port VLAN ID of a newly attached bridge port. + + MulticastQuerier= diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c index 12b0fe972f..bdbea7d770 100644 --- a/src/network/networkd-netdev-bridge.c +++ b/src/network/networkd-netdev-bridge.c @@ -90,6 +90,24 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_MAX_AGE attribute: %m"); } + if (b->ageing_time > 0) { + r = sd_netlink_message_append_u32(req, IFLA_BR_AGEING_TIME, usec_to_jiffies(b->ageing_time)); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_AGEING_TIME attribute: %m"); + } + + if (b->priority > 0) { + r = sd_netlink_message_append_u16(req, IFLA_BR_PRIORITY, b->priority); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_PRIORITY attribute: %m"); + } + + if (b->default_pvid > 0) { + r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_DEFAULT_PVID, b->default_pvid); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m"); + } + if (b->mcast_querier >= 0) { r = sd_netlink_message_append_u8(req, IFLA_BR_MCAST_QUERIER, b->mcast_querier); if (r < 0) diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h index 4ce0fbb6f9..53f72f1ea5 100644 --- a/src/network/networkd-netdev-bridge.h +++ b/src/network/networkd-netdev-bridge.h @@ -28,10 +28,13 @@ typedef struct Bridge { int mcast_snooping; int vlan_filtering; int stp; + uint16_t priority; + uint16_t default_pvid; usec_t forward_delay; usec_t hello_time; usec_t max_age; + usec_t ageing_time; } Bridge; DEFINE_NETDEV_CAST(BRIDGE, Bridge); diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index a1ca1a3d4e..6dbb627f15 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -102,7 +102,10 @@ Bond.ARPIntervalSec, config_parse_sec, 0, Bond.LearnPacketIntervalSec, config_parse_sec, 0, offsetof(Bond, lp_interval) Bridge.HelloTimeSec, config_parse_sec, 0, offsetof(Bridge, hello_time) Bridge.MaxAgeSec, config_parse_sec, 0, offsetof(Bridge, max_age) +Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time) Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay) +Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority) +Bridge.DefaultPVID, config_parse_vlanid, 0, offsetof(Bridge, default_pvid) Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier) Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping) Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering) diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 7cf222e4d2..f31d219418 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -460,6 +460,7 @@ int config_parse_many(const char *conf_file, DEFINE_PARSER(int, int, safe_atoi); DEFINE_PARSER(long, long, safe_atoli); +DEFINE_PARSER(uint16, uint16_t, safe_atou16); DEFINE_PARSER(uint32, uint32_t, safe_atou32); DEFINE_PARSER(uint64, uint64_t, safe_atou64); DEFINE_PARSER(unsigned, unsigned, safe_atou); diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index f6964e3fd4..3298dc0cea 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -107,6 +107,7 @@ int config_parse_many(const char *conf_file, /* possibly NULL */ int config_parse_int(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); int config_parse_unsigned(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); int config_parse_long(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); +int config_parse_uint16(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); int config_parse_uint32(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); int config_parse_uint64(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); int config_parse_double(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); -- cgit v1.2.3-54-g00ecf From 92c918b06d970cd4ce2e7e529e6093ffc46a9cfa Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 14 Sep 2016 21:45:16 +0530 Subject: networkd: add support to configure virtual CAN device (#4139) 1. add support for kind vcan 2. fixup indention netlink-types.c, networkd-netdev.c --- Makefile.am | 2 + man/systemd.netdev.xml | 6 ++- src/libsystemd/sd-netlink/netlink-types.c | 74 +++++++++++++++---------------- src/libsystemd/sd-netlink/netlink-types.h | 1 + src/network/networkd-link.c | 38 ++++++++++++++++ src/network/networkd-netdev-vcan.c | 25 +++++++++++ src/network/networkd-netdev-vcan.h | 34 ++++++++++++++ src/network/networkd-netdev.c | 4 +- src/network/networkd-netdev.h | 1 + src/network/networkd-network.c | 1 + src/network/networkd.h | 1 + 11 files changed, 147 insertions(+), 40 deletions(-) create mode 100644 src/network/networkd-netdev-vcan.c create mode 100644 src/network/networkd-netdev-vcan.h (limited to 'src/network') diff --git a/Makefile.am b/Makefile.am index 3a617560e0..946af196f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5650,6 +5650,8 @@ libnetworkd_core_la_SOURCES = \ src/network/networkd-netdev-bond.c \ src/network/networkd-netdev-bridge.h \ src/network/networkd-netdev-bridge.c \ + src/network/networkd-netdev-vcan.h \ + src/network/networkd-netdev-vcan.c \ src/network/networkd-link-bus.c \ src/network/networkd-ipv4ll.c \ src/network/networkd-dhcp4.c \ diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 1f9f071b94..78f0e25a6f 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -163,7 +163,11 @@ A virtual extensible LAN (vxlan), for connecting Cloud computing deployments. vrf - A Virtual Routing and Forwarding (VRF) interface to create separate routing and forwarding domains. + A Virtual Routing and Forwarding (VRF) interface to create separate routing and forwarding domains. + + vcan + The virtual CAN driver (vcan). Similar to the network loopback devices, + vcan offers a virtual local CAN interface. diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 566a050432..1c10dd55a7 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -303,49 +304,48 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6", [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl", [NL_UNION_LINK_INFO_DATA_VRF] = "vrf", + [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); static const NLTypeSystem rtnl_link_info_data_type_systems[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), - .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), - .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), - .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), - .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), - .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), + .types = rtnl_link_info_data_bond_types }, + [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), + .types = rtnl_link_info_data_bridge_types }, + [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), + .types = rtnl_link_info_data_vlan_types }, + [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), + .types = rtnl_link_info_data_veth_types }, + [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types }, + [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), + .types = rtnl_link_info_data_vxlan_types }, + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), - .types = rtnl_link_info_data_ip6tnl_types }, - - [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), - .types = rtnl_link_info_data_vrf_types }, - + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), + .types = rtnl_link_info_data_ip6tnl_types }, + [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), + .types = rtnl_link_info_data_vrf_types }, }; static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 7c0e598b26..42e96173de 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -87,6 +87,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL, NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL, NL_UNION_LINK_INFO_DATA_VRF, + NL_UNION_LINK_INFO_DATA_VCAN, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index aab40a0eb1..1687d9bf31 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1787,6 +1787,31 @@ static int link_down(Link *link) { return 0; } +static int link_up_can(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + + log_link_debug(link, "Bringing CAN link up"); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); + if (r < 0) + return log_link_error_errno(link, r, "Could not set link flags: %m"); + + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return 0; +} + static int link_handle_bound_to_list(Link *link) { Link *l; Iterator i; @@ -2431,6 +2456,19 @@ static int link_configure(Link *link) { assert(link->network); assert(link->state == LINK_STATE_PENDING); + if (streq_ptr(link->kind, "vcan")) { + + if (!(link->flags & IFF_UP)) { + r = link_up_can(link); + if (r < 0) { + link_enter_failed(link); + return r; + } + } + + return 0; + } + /* Drop foreign config, but ignore loopback or critical devices. * We do not want to remove loopback address or addresses used for root NFS. */ if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) { diff --git a/src/network/networkd-netdev-vcan.c b/src/network/networkd-netdev-vcan.c new file mode 100644 index 0000000000..bfce6e1962 --- /dev/null +++ b/src/network/networkd-netdev-vcan.c @@ -0,0 +1,25 @@ +/*** + This file is part of systemd. + + Copyright 2016 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "networkd-netdev-vcan.h" + +const NetDevVTable vcan_vtable = { + .object_size = sizeof(VCan), + .create_type = NETDEV_CREATE_INDEPENDENT, +}; diff --git a/src/network/networkd-netdev-vcan.h b/src/network/networkd-netdev-vcan.h new file mode 100644 index 0000000000..6ba47fd70e --- /dev/null +++ b/src/network/networkd-netdev-vcan.h @@ -0,0 +1,34 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +typedef struct VCan VCan; + +#include + +#include "networkd-netdev.h" + +struct VCan { + NetDev meta; +}; + +DEFINE_NETDEV_CAST(VCAN, VCan); + +extern const NetDevVTable vcan_vtable; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index e7edc366af..583389c8dd 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -56,7 +56,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TAP] = &tap_vtable, [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable, [NETDEV_KIND_VRF] = &vrf_vtable, - + [NETDEV_KIND_VCAN] = &vcan_vtable, }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -81,7 +81,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TAP] = "tap", [NETDEV_KIND_IP6TNL] = "ip6tnl", [NETDEV_KIND_VRF] = "vrf", - + [NETDEV_KIND_VCAN] = "vcan", }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index 09863e72b4..31b55e2791 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -56,6 +56,7 @@ typedef enum NetDevKind { NETDEV_KIND_TUN, NETDEV_KIND_TAP, NETDEV_KIND_VRF, + NETDEV_KIND_VCAN, _NETDEV_KIND_MAX, _NETDEV_KIND_INVALID = -1 } NetDevKind; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 49faba5b12..9865c8a5c0 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -479,6 +479,7 @@ int config_parse_netdev(const char *unit, case NETDEV_KIND_MACVTAP: case NETDEV_KIND_IPVLAN: case NETDEV_KIND_VXLAN: + case NETDEV_KIND_VCAN: r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue); diff --git a/src/network/networkd.h b/src/network/networkd.h index c4bd712147..cb1b73145e 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -43,6 +43,7 @@ #include "networkd-netdev-vlan.h" #include "networkd-netdev-vrf.h" #include "networkd-netdev-vxlan.h" +#include "networkd-netdev-vcan.h" #include "networkd-network.h" #include "networkd-util.h" -- cgit v1.2.3-54-g00ecf From 9b53e129874dc784376ae09774898fd08adda507 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Thu, 15 Sep 2016 10:18:59 +0530 Subject: networkd: netdev fixup copy paste error --- src/network/networkd-netdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 583389c8dd..897de9bde5 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -34,7 +34,6 @@ #include "string-util.h" const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { - [NETDEV_KIND_BRIDGE] = &bridge_vtable, [NETDEV_KIND_BOND] = &bond_vtable, [NETDEV_KIND_VLAN] = &vlan_vtable, @@ -516,7 +515,7 @@ static int netdev_create(NetDev *netdev, Link *link, r = sd_netlink_message_close_container(m); if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); r = sd_netlink_message_close_container(m); if (r < 0) -- cgit v1.2.3-54-g00ecf From a4820c463acd3777268bf6eb25284f7dab898187 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Thu, 15 Sep 2016 10:19:26 +0530 Subject: networkd: network fix log message --- src/network/networkd-network.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 9865c8a5c0..91e51e9124 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -482,7 +482,7 @@ int config_parse_netdev(const char *unit, case NETDEV_KIND_VCAN: r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Can not add NetDev '%s' to network: %m", rvalue); return 0; } -- cgit v1.2.3-54-g00ecf From 047a0dacde06740050858d72c385cc07a4091feb Mon Sep 17 00:00:00 2001 From: Jean-Sébastien Bour Date: Sat, 9 Jul 2016 16:55:26 +0200 Subject: networkd: support drop-in directories for .network files Fixes #3655. [zj: Fix the tests.] --- src/network/networkd-network.c | 18 ++++++++++++++++-- test/networkd-test.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 49faba5b12..0b36f13be8 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -40,6 +40,10 @@ static int network_load_one(Manager *manager, const char *filename) { _cleanup_network_free_ Network *network = NULL; _cleanup_fclose_ FILE *file = NULL; char *d; + const char *dropin_dirname; + _cleanup_strv_free_ char **dropin_dirs = NULL; + _cleanup_free_ char *dropin_dirs_nulstr = NULL; + size_t dropin_dirs_nulstr_size; Route *route; Address *address; int r; @@ -137,7 +141,17 @@ static int network_load_one(Manager *manager, const char *filename) { network->arp = -1; network->ipv6_accept_ra_use_dns = true; - r = config_parse(NULL, filename, file, + dropin_dirname = strjoina("/", network->name, ".network.d"); + + r = strv_extend_strv_concat(&dropin_dirs, (char**) network_dirs, dropin_dirname); + if (r < 0) + return r; + + r = strv_make_nulstr(dropin_dirs, &dropin_dirs_nulstr, &dropin_dirs_nulstr_size); + if (r < 0) + return r; + + r = config_parse_many(filename, dropin_dirs_nulstr, "Match\0" "Link\0" "Network\0" @@ -151,7 +165,7 @@ static int network_load_one(Manager *manager, const char *filename) { "BridgeFDB\0" "BridgeVLAN\0", config_item_perf_lookup, network_network_gperf_lookup, - false, false, true, network); + false, network); if (r < 0) return r; diff --git a/test/networkd-test.py b/test/networkd-test.py index 57f4c04295..baa1dc2a47 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -456,6 +456,36 @@ Domains={p}0 {p}1 {p}2 {p}3 {p}4'''.format(p=name_prefix)) self.assertRegex(contents, 'search .*{p}0 {p}1 {p}2'.format(p=name_prefix)) self.assertIn('# Total length of all search domains is too long, remaining ones ignored.', contents) + def test_dropin(self): + # we don't use this interface for this test + self.if_router = None + + self.writeConfig('/run/systemd/network/test.netdev', '''\ +[NetDev] +Name=dummy0 +Kind=dummy +MACAddress=12:34:56:78:9a:bc''') + self.writeConfig('/run/systemd/network/test.network', '''\ +[Match] +Name=dummy0 +[Network] +Address=192.168.42.100 +DNS=192.168.42.1''') + self.writeConfig('/run/systemd/network/test.network.d/dns.conf', '''\ +[Network] +DNS=127.0.0.1''') + + subprocess.check_call(['systemctl', 'start', 'systemd-networkd']) + + for timeout in range(50): + with open(RESOLV_CONF) as f: + contents = f.read() + if ' 127.0.0.1' in contents: + break + time.sleep(0.1) + self.assertIn('nameserver 192.168.42.1\n', contents) + self.assertIn('nameserver 127.0.0.1\n', contents) + if __name__ == '__main__': unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) -- cgit v1.2.3-54-g00ecf From 43688c49d1fdb585196d94e2e30bb29755fa591b Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 10 Sep 2016 11:02:40 +0100 Subject: tree-wide: rename config_parse_many to …_nulstr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for adding a version which takes a strv. --- src/basic/def.h | 2 +- src/core/main.c | 2 +- src/coredump/coredump.c | 2 +- src/journal-remote/journal-remote.c | 2 +- src/journal-remote/journal-upload.c | 2 +- src/journal/journald-server.c | 2 +- src/login/logind.c | 2 +- src/network/networkd-conf.c | 2 +- src/network/networkd-network.c | 2 +- src/resolve/resolved-conf.c | 2 +- src/shared/conf-parser.c | 16 +++++++++------- src/shared/conf-parser.h | 38 +++++++++++++++++++------------------ src/shared/sleep-config.c | 2 +- src/timesync/timesyncd-conf.c | 2 +- 14 files changed, 41 insertions(+), 37 deletions(-) (limited to 'src/network') diff --git a/src/basic/def.h b/src/basic/def.h index 1a7a0f4928..2266eff650 100644 --- a/src/basic/def.h +++ b/src/basic/def.h @@ -79,7 +79,7 @@ #endif /* Return a nulstr for a standard cascade of configuration paths, - * suitable to pass to conf_files_list_nulstr() or config_parse_many() + * suitable to pass to conf_files_list_nulstr() or config_parse_many_nulstr() * to implement drop-in directories for extending configuration * files. */ #define CONF_PATHS_NULSTR(n) \ diff --git a/src/core/main.c b/src/core/main.c index 7d8322ebd8..803307c9d5 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -715,7 +715,7 @@ static int parse_config_file(void) { CONF_PATHS_NULSTR("systemd/system.conf.d") : CONF_PATHS_NULSTR("systemd/user.conf.d"); - config_parse_many(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL); + config_parse_many_nulstr(fn, conf_dirs_nulstr, "Manager\0", config_item_table_lookup, items, false, NULL); /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY * like everywhere else. */ diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index be724aed4e..9dea10b3e1 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -128,7 +128,7 @@ static int parse_config(void) { {} }; - return config_parse_many(PKGSYSCONFDIR "/coredump.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf", CONF_PATHS_NULSTR("systemd/coredump.conf.d"), "Coredump\0", config_item_table_lookup, items, diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 80e2adb100..220c71754a 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -1198,7 +1198,7 @@ static int parse_config(void) { { "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust }, {}}; - return config_parse_many(PKGSYSCONFDIR "/journal-remote.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf", CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"), "Remote\0", config_item_table_lookup, items, false, NULL); diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 4647cfdeb3..c0f967ab94 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -542,7 +542,7 @@ static int parse_config(void) { { "Upload", "TrustedCertificateFile", config_parse_path, 0, &arg_trust }, {}}; - return config_parse_many(PKGSYSCONFDIR "/journal-upload.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf", CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"), "Upload\0", config_item_table_lookup, items, false, NULL); diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 3507910919..cc352dbae2 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1474,7 +1474,7 @@ static int server_parse_proc_cmdline(Server *s) { static int server_parse_config_file(Server *s) { assert(s); - return config_parse_many(PKGSYSCONFDIR "/journald.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf", CONF_PATHS_NULSTR("systemd/journald.conf.d"), "Journal\0", config_item_perf_lookup, journald_gperf_lookup, diff --git a/src/login/logind.c b/src/login/logind.c index bbbf4aef57..a9a06f5e28 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1002,7 +1002,7 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us static int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many(PKGSYSCONFDIR "/logind.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf", CONF_PATHS_NULSTR("systemd/logind.conf.d"), "Login\0", config_item_perf_lookup, logind_gperf_lookup, diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c index c03e2b2ebf..49bb8c18f6 100644 --- a/src/network/networkd-conf.c +++ b/src/network/networkd-conf.c @@ -29,7 +29,7 @@ int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many(PKGSYSCONFDIR "/networkd.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf", CONF_PATHS_NULSTR("systemd/networkd.conf.d"), "DHCP\0", config_item_perf_lookup, networkd_gperf_lookup, diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 0b36f13be8..1ce23b1ddb 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -151,7 +151,7 @@ static int network_load_one(Manager *manager, const char *filename) { if (r < 0) return r; - r = config_parse_many(filename, dropin_dirs_nulstr, + r = config_parse_many_nulstr(filename, dropin_dirs_nulstr, "Match\0" "Link\0" "Network\0" diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index dd233e7c4a..83f7596ac8 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -221,7 +221,7 @@ int manager_parse_config_file(Manager *m) { assert(m); - r = config_parse_many(PKGSYSCONFDIR "/resolved.conf", + r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf", CONF_PATHS_NULSTR("systemd/resolved.conf.d"), "Resolve\0", config_item_perf_lookup, resolved_gperf_lookup, diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index f31d219418..f3351c6bb2 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -397,13 +397,15 @@ int config_parse(const char *unit, } /* Parse each config file in the specified directories. */ -int config_parse_many(const char *conf_file, - const char *conf_file_dirs, - const char *sections, - ConfigItemLookup lookup, - const void *table, - bool relaxed, - void *userdata) { +int config_parse_many_nulstr( + const char *conf_file, + const char *conf_file_dirs, + const char *sections, + ConfigItemLookup lookup, + const void *table, + bool relaxed, + void *userdata) { + _cleanup_strv_free_ char **files = NULL; char **fn; int r; diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 3298dc0cea..e0b8d83dab 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -84,24 +84,26 @@ int config_item_table_lookup(const void *table, const char *section, const char * ConfigPerfItem tables */ int config_item_perf_lookup(const void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata); -int config_parse(const char *unit, - const char *filename, - FILE *f, - const char *sections, /* nulstr */ - ConfigItemLookup lookup, - const void *table, - bool relaxed, - bool allow_include, - bool warn, - void *userdata); - -int config_parse_many(const char *conf_file, /* possibly NULL */ - const char *conf_file_dirs, /* nulstr */ - const char *sections, /* nulstr */ - ConfigItemLookup lookup, - const void *table, - bool relaxed, - void *userdata); +int config_parse( + const char *unit, + const char *filename, + FILE *f, + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + const void *table, + bool relaxed, + bool allow_include, + bool warn, + void *userdata); + +int config_parse_many_nulstr( + const char *conf_file, /* possibly NULL */ + const char *conf_file_dirs, /* nulstr */ + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + const void *table, + bool relaxed, + void *userdata); /* Generic parsers */ int config_parse_int(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); diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index f00624d0f2..ed31a80c8d 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -58,7 +58,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states) { {} }; - config_parse_many(PKGSYSCONFDIR "/sleep.conf", + config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf", CONF_PATHS_NULSTR("systemd/sleep.conf.d"), "Sleep\0", config_item_table_lookup, items, false, NULL); diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c index 20c64a3354..bf25b112e1 100644 --- a/src/timesync/timesyncd-conf.c +++ b/src/timesync/timesyncd-conf.c @@ -98,7 +98,7 @@ int config_parse_servers( int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_many(PKGSYSCONFDIR "/timesyncd.conf", + return config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf", CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"), "Time\0", config_item_perf_lookup, timesyncd_gperf_lookup, -- cgit v1.2.3-54-g00ecf From 23bb31aa0a3ef7509dc5200518517d1297530534 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 10 Sep 2016 12:19:41 +0100 Subject: shared/conf-parser: add config_parse_many which takes strv with dirs This way we don't have to create a nulstr just to unpack it in a moment. --- src/network/networkd-network.c | 45 ++++++++++++------------------- src/shared/conf-parser.c | 60 ++++++++++++++++++++++++++++++++++++------ src/shared/conf-parser.h | 10 +++++++ 3 files changed, 79 insertions(+), 36 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 1ce23b1ddb..58e19e542a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -41,9 +41,6 @@ static int network_load_one(Manager *manager, const char *filename) { _cleanup_fclose_ FILE *file = NULL; char *d; const char *dropin_dirname; - _cleanup_strv_free_ char **dropin_dirs = NULL; - _cleanup_free_ char *dropin_dirs_nulstr = NULL; - size_t dropin_dirs_nulstr_size; Route *route; Address *address; int r; @@ -141,31 +138,23 @@ static int network_load_one(Manager *manager, const char *filename) { network->arp = -1; network->ipv6_accept_ra_use_dns = true; - dropin_dirname = strjoina("/", network->name, ".network.d"); - - r = strv_extend_strv_concat(&dropin_dirs, (char**) network_dirs, dropin_dirname); - if (r < 0) - return r; - - r = strv_make_nulstr(dropin_dirs, &dropin_dirs_nulstr, &dropin_dirs_nulstr_size); - if (r < 0) - return r; - - r = config_parse_many_nulstr(filename, dropin_dirs_nulstr, - "Match\0" - "Link\0" - "Network\0" - "Address\0" - "Route\0" - "DHCP\0" - "DHCPv4\0" /* compat */ - "DHCPServer\0" - "IPv6AcceptRA\0" - "Bridge\0" - "BridgeFDB\0" - "BridgeVLAN\0", - config_item_perf_lookup, network_network_gperf_lookup, - false, network); + dropin_dirname = strjoina(network->name, ".network.d"); + + r = config_parse_many(filename, network_dirs, dropin_dirname, + "Match\0" + "Link\0" + "Network\0" + "Address\0" + "Route\0" + "DHCP\0" + "DHCPv4\0" /* compat */ + "DHCPServer\0" + "IPv6AcceptRA\0" + "Bridge\0" + "BridgeFDB\0" + "BridgeVLAN\0", + config_item_perf_lookup, network_network_gperf_lookup, + false, network); if (r < 0) return r; diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index f3351c6bb2..2ec0155b71 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -396,24 +396,18 @@ int config_parse(const char *unit, return 0; } -/* Parse each config file in the specified directories. */ -int config_parse_many_nulstr( +static int config_parse_many_files( const char *conf_file, - const char *conf_file_dirs, + char **files, const char *sections, ConfigItemLookup lookup, const void *table, bool relaxed, void *userdata) { - _cleanup_strv_free_ char **files = NULL; char **fn; int r; - r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); - if (r < 0) - return r; - if (conf_file) { r = config_parse(NULL, conf_file, NULL, sections, lookup, table, relaxed, false, true, userdata); if (r < 0) @@ -429,6 +423,56 @@ int config_parse_many_nulstr( return 0; } +/* Parse each config file in the directories specified as nulstr. */ +int config_parse_many_nulstr( + const char *conf_file, + const char *conf_file_dirs, + const char *sections, + ConfigItemLookup lookup, + const void *table, + bool relaxed, + void *userdata) { + + _cleanup_strv_free_ char **files = NULL; + int r; + + r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); + if (r < 0) + return r; + + return config_parse_many_files(conf_file, files, + sections, lookup, table, relaxed, userdata); +} + +/* Parse each config file in the directories specified as strv. */ +int config_parse_many( + const char *conf_file, + const char* const* conf_file_dirs, + const char *dropin_dirname, + const char *sections, + ConfigItemLookup lookup, + const void *table, + bool relaxed, + void *userdata) { + + _cleanup_strv_free_ char **dropin_dirs = NULL; + _cleanup_strv_free_ char **files = NULL; + const char *suffix; + int r; + + suffix = strjoina("/", dropin_dirname); + r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix); + if (r < 0) + return r; + + r = conf_files_list_strv(&files, ".conf", NULL, (const char* const*) dropin_dirs); + if (r < 0) + return r; + + return config_parse_many_files(conf_file, files, + sections, lookup, table, relaxed, userdata); +} + #define DEFINE_PARSER(type, vartype, conv_func) \ int config_parse_##type( \ const char *unit, \ diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index e0b8d83dab..26ff3df16f 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -105,6 +105,16 @@ int config_parse_many_nulstr( bool relaxed, void *userdata); +int config_parse_many( + const char *conf_file, /* possibly NULL */ + const char* const* conf_file_dirs, + const char *dropin_dirname, + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + const void *table, + bool relaxed, + void *userdata); + /* Generic parsers */ int config_parse_int(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); int config_parse_unsigned(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); -- cgit v1.2.3-54-g00ecf From 2cc34d5b91684256530242b94bf6ea1f27ffa7a9 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 10 Sep 2016 14:32:19 +0100 Subject: networkd: support drop-in dirs for .network files --- src/network/networkd-netdev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index e7edc366af..9cf678a3ef 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -577,6 +577,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { _cleanup_netdev_unref_ NetDev *netdev = NULL; _cleanup_free_ NetDev *netdev_raw = NULL; _cleanup_fclose_ FILE *file = NULL; + const char *dropin_dirname; int r; assert(manager); @@ -600,11 +601,12 @@ static int netdev_load_one(Manager *manager, const char *filename) { return log_oom(); netdev_raw->kind = _NETDEV_KIND_INVALID; + dropin_dirname = strjoina(basename(filename), ".d"); - r = config_parse(NULL, filename, file, - "Match\0NetDev\0", - config_item_perf_lookup, network_netdev_gperf_lookup, - true, false, true, netdev_raw); + r = config_parse_many(filename, network_dirs, dropin_dirname, + "Match\0NetDev\0", + config_item_perf_lookup, network_netdev_gperf_lookup, + true, netdev_raw); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From 881e6b5edfd6ff82e0683678f19c887cbacab344 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 10 Sep 2016 17:44:50 +0100 Subject: networkd: change message about missing Kind If Kind is not specied, the message about "Invalid Kind" was misleading. If Kind was specified in an invalid way, we get a message in the parsing phase anyway. Reword the message to cover both cases better. --- src/network/networkd-netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 9cf678a3ef..ece4ea2e64 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -622,7 +622,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { return 0; if (netdev_raw->kind == _NETDEV_KIND_INVALID) { - log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename); + log_warning("NetDev has no Kind configured in %s. Ignoring", filename); return 0; } -- cgit v1.2.3-54-g00ecf From f594276b8659a04a8cb18ea3fef3ddb1ed10524a Mon Sep 17 00:00:00 2001 From: Jason Kölker Date: Mon, 19 Sep 2016 02:26:12 +0000 Subject: networkd: Allow specifying RouteTable for DHCP --- man/systemd.network.xml | 9 +++++++++ src/network/networkd-dhcp4.c | 3 +++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 31 +++++++++++++++++++++++++++++++ src/network/networkd-network.h | 2 ++ 5 files changed, 46 insertions(+) (limited to 'src/network') diff --git a/man/systemd.network.xml b/man/systemd.network.xml index eb7d441842..961ff64ff0 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -917,6 +917,15 @@ DHCP server. + + + RouteTable=num + + The table identifier for dhcp routes (a number between 1 and 4294967295, or 0 to unset). + The table can be retrieved using ip route show table num. + + + diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 12fb8e3fce..76d3d132ea 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -95,6 +95,7 @@ static int link_set_dhcp_routes(Link *link) { route_gw->scope = RT_SCOPE_LINK; route_gw->protocol = RTPROT_DHCP; route_gw->priority = link->network->dhcp_route_metric; + route_gw->table = link->network->dhcp_route_table; r = route_configure(route_gw, link, dhcp4_route_handler); if (r < 0) @@ -106,6 +107,7 @@ static int link_set_dhcp_routes(Link *link) { route->gw.in = gateway; route->prefsrc.in = address; route->priority = link->network->dhcp_route_metric; + route->table = link->network->dhcp_route_table; r = route_configure(route, link, dhcp4_route_handler); if (r < 0) { @@ -136,6 +138,7 @@ static int link_set_dhcp_routes(Link *link) { assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0); assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0); route->priority = link->network->dhcp_route_metric; + route->table = link->network->dhcp_route_table; r = route_configure(route, link, dhcp4_route_handler); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index b96f0b7210..65ea20c4ca 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -92,6 +92,7 @@ DHCP.VendorClassIdentifier, config_parse_string, DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid.type) DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +DHCP.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, dhcp_route_table) DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 313abca762..c7dc785b24 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -111,6 +111,7 @@ static int network_load_one(Manager *manager, const char *filename) { network->dhcp_send_hostname = true; network->dhcp_route_metric = DHCP_ROUTE_METRIC; network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID; + network->dhcp_route_table = RT_TABLE_MAIN; network->dhcp_server_emit_dns = true; network->dhcp_server_emit_ntp = true; @@ -1033,6 +1034,36 @@ int config_parse_dnssec_negative_trust_anchors( return 0; } +int config_parse_dhcp_route_table(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) { + uint32_t rt; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = safe_atou32(rvalue, &rt); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Unable to read RouteTable, ignoring assignment: %s", rvalue); + return 0; + } + + *((uint32_t *)data) = rt; + + return 0; +} + DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains, "Failed to parse DHCP use domains setting"); static const char* const dhcp_use_domains_table[_DHCP_USE_DOMAINS_MAX] = { diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 5460eb4d1c..a34dbf5c7b 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -123,6 +123,7 @@ struct Network { bool dhcp_use_routes; bool dhcp_use_timezone; unsigned dhcp_route_metric; + uint32_t dhcp_route_table; /* DHCP Server Support */ bool dhcp_server; @@ -228,6 +229,7 @@ int config_parse_dhcp_server_ntp(const char *unit, const char *filename, unsigne int config_parse_dnssec_negative_trust_anchors(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); int config_parse_dhcp_use_domains(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); int config_parse_lldp_mode(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); +int config_parse_dhcp_route_table(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); /* Legacy IPv4LL support */ int config_parse_ipv4ll(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); -- cgit v1.2.3-54-g00ecf From 2ba31d29a5ee8d72802d31cca711175c1fcdd7aa Mon Sep 17 00:00:00 2001 From: Jason Kölker Date: Mon, 19 Sep 2016 02:59:11 +0000 Subject: networkd: Allow specifying RouteTable for RAs --- man/systemd.network.xml | 9 +++++++++ src/network/networkd-ndisc.c | 6 +++--- src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 1 + src/network/networkd-network.h | 1 + 5 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 961ff64ff0..2e4d927470 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -966,6 +966,15 @@ project='man-pages'>resolv.conf5. + + + RouteTable=num + + The table identifier for dhcp routes (a number between 1 and 4294967295, or 0 to unset). + The table can be retrieved using ip route show table num. + + + diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index d9c18b32a5..c2b7970623 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -94,7 +94,7 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { } route->family = AF_INET6; - route->table = RT_TABLE_MAIN; + route->table = link->network->ipv6_accept_ra_route_table; route->protocol = RTPROT_RA; route->pref = preference; route->gw.in6 = gateway; @@ -214,7 +214,7 @@ static void ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) } route->family = AF_INET6; - route->table = RT_TABLE_MAIN; + route->table = link->network->ipv6_accept_ra_route_table; route->protocol = RTPROT_RA; route->flags = RTM_F_PREFIX; route->dst_prefixlen = prefixlen; @@ -285,7 +285,7 @@ static void ndisc_router_process_route(Link *link, sd_ndisc_router *rt) { } route->family = AF_INET6; - route->table = RT_TABLE_MAIN; + route->table = link->network->ipv6_accept_ra_route_table; route->protocol = RTPROT_RA; route->pref = preference; route->gw.in6 = gateway; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 65ea20c4ca..62779c7c48 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -97,6 +97,7 @@ DHCP.UseTimezone, config_parse_bool, DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) +IPv6AcceptRA.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, ipv6_accept_ra_route_table) DHCPServer.MaxLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_max_lease_time_usec) DHCPServer.DefaultLeaseTimeSec, config_parse_sec, 0, offsetof(Network, dhcp_server_default_lease_time_usec) DHCPServer.EmitDNS, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_dns) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index c7dc785b24..584cb96979 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -138,6 +138,7 @@ static int network_load_one(Manager *manager, const char *filename) { network->proxy_arp = -1; network->arp = -1; network->ipv6_accept_ra_use_dns = true; + network->ipv6_accept_ra_route_table = RT_TABLE_MAIN; dropin_dirname = strjoina(network->name, ".network.d"); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index a34dbf5c7b..ef4b499ab9 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -167,6 +167,7 @@ struct Network { bool ipv6_accept_ra_use_dns; DHCPUseDomains ipv6_accept_ra_use_domains; + uint32_t ipv6_accept_ra_route_table; union in_addr_union ipv6_token; IPv6PrivacyExtensions ipv6_privacy_extensions; -- cgit v1.2.3-54-g00ecf From f258e948434183a2f0a38b429bb9a2054d61d954 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Sat, 24 Sep 2016 16:07:45 +0200 Subject: networkd: do not drop config for pending interfaces (#4187) While an interface is still being processed by udev, it is in state "pending", instead of "unmanaged". We must not flush device configuration then. Further fixes commit 3104883ddc24 after commit c436d55397. Fixes #4186 --- src/network/networkd-link.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 1687d9bf31..9cd4aa2c39 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2995,7 +2995,8 @@ static int link_carrier_lost(Link *link) { if (r < 0) return r; - if (link->state != LINK_STATE_UNMANAGED) { + if (!IN_SET(link->state, LINK_STATE_UNMANAGED, LINK_STATE_PENDING)) { + log_link_debug(link, "State is %s, dropping config", link_state_to_string(link->state)); r = link_drop_foreign_config(link); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From 1cf03a4f8e5de53ca1ecc8a6dc64cb32ab8de536 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sat, 24 Sep 2016 20:18:02 -0400 Subject: systemctl,networkctl,busctl,backlight: use STRPTR_IN_SET --- src/backlight/backlight.c | 2 +- src/libsystemd/sd-bus/busctl.c | 3 +-- src/network/networkctl.c | 2 +- src/systemctl/systemctl.c | 12 +++++------- 4 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src/network') diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 45be135a23..7c59f60d5f 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -167,7 +167,7 @@ static bool validate_device(struct udev *udev, struct udev_device *device) { continue; v = udev_device_get_sysattr_value(other, "type"); - if (!streq_ptr(v, "platform") && !streq_ptr(v, "firmware")) + if (!STRPTR_IN_SET(v, "platform", "firmware")) continue; /* OK, so there's another backlight device, and it's a diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index eb042e9c81..2c3f591053 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -2003,8 +2003,7 @@ int main(int argc, char *argv[]) { goto finish; } - if (streq_ptr(argv[optind], "monitor") || - streq_ptr(argv[optind], "capture")) { + if (STRPTR_IN_SET(argv[optind], "monitor", "capture")) { r = sd_bus_set_monitor(bus, true); if (r < 0) { diff --git a/src/network/networkctl.c b/src/network/networkctl.c index d2df9b7560..6f7f41bf7d 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -122,7 +122,7 @@ static void setup_state_to_color(const char *state, const char **on, const char } else if (streq_ptr(state, "configuring")) { *on = ansi_highlight_yellow(); *off = ansi_normal(); - } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) { + } else if (STRPTR_IN_SET(state, "failed", "linger")) { *on = ansi_highlight_red(); *off = ansi_normal(); } else diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index dc8f61b049..02224896ff 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3622,7 +3622,7 @@ static void print_status_info( if (streq_ptr(i->active_state, "failed")) { active_on = ansi_highlight_red(); active_off = ansi_normal(); - } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { + } else if (STRPTR_IN_SET(i->active_state, "active", "reloading")) { active_on = ansi_highlight_green(); active_off = ansi_normal(); } else @@ -3703,12 +3703,10 @@ static void print_status_info( if (!isempty(i->result) && !streq(i->result, "success")) printf(" (Result: %s)", i->result); - timestamp = (streq_ptr(i->active_state, "active") || - streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp : - (streq_ptr(i->active_state, "inactive") || - streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp : - streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp : - i->active_exit_timestamp; + timestamp = STRPTR_IN_SET(i->active_state, "active", "reloading") ? i->active_enter_timestamp : + STRPTR_IN_SET(i->active_state, "inactive", "failed") ? i->inactive_enter_timestamp : + STRPTR_IN_SET(i->active_state, "activating") ? i->inactive_exit_timestamp : + i->active_exit_timestamp; s1 = format_timestamp_relative(since1, sizeof(since1), timestamp); s2 = format_timestamp(since2, sizeof(since2), timestamp); -- cgit v1.2.3-54-g00ecf From 82936769a81cf923c9e98fa350138eb6618bd1eb Mon Sep 17 00:00:00 2001 From: Elias Probst Date: Fri, 30 Sep 2016 13:25:25 +0200 Subject: networkd: fix "parametres" typo (#4244) --- src/network/networkd-netdev-bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c index bdbea7d770..002ad94210 100644 --- a/src/network/networkd-netdev-bridge.c +++ b/src/network/networkd-netdev-bridge.c @@ -39,7 +39,7 @@ static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, vo return 1; } - log_netdev_debug(netdev, "Bridge parametres set success"); + log_netdev_debug(netdev, "Bridge parameters set success"); return 1; } -- cgit v1.2.3-54-g00ecf From f6bb7ac5c6a200eb444f7f7ad043c01b2afa7d4c Mon Sep 17 00:00:00 2001 From: Tobias Jungel Date: Wed, 5 Oct 2016 17:06:40 +0200 Subject: networkd: use BridgeFDB as well on bridge ports (#4253) [BridgeFDB] did not apply to bridge ports so far. This patch adds the proper handling. In case of a bridge interface the correct flag NTF_MASTER is now set in the netlink call. FDB MAC addresses are now applied in link_enter_set_addresses to make sure the link is setup. --- src/network/networkd-fdb.c | 12 ++++++++++-- src/network/networkd-link.c | 37 ++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 21 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index be8aebee2d..ed5a47589e 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -107,20 +107,28 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; sd_netlink *rtnl; int r; + uint8_t flags; + Bridge *bridge; assert(link); + assert(link->network); assert(link->manager); assert(fdb_entry); rtnl = link->manager->rtnl; + bridge = BRIDGE(link->network->bridge); /* create new RTM message */ r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE); if (r < 0) return rtnl_log_create_error(r); - /* only NTF_SELF flag supported. */ - r = sd_rtnl_message_neigh_set_flags(req, NTF_SELF); + if (bridge) + flags = NTF_MASTER; + else + flags = NTF_SELF; + + r = sd_rtnl_message_neigh_set_flags(req, flags); if (r < 0) return rtnl_log_create_error(r); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9cd4aa2c39..25f46c093e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -942,6 +942,20 @@ static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) { return sd_dhcp_server_set_ntp(s, addresses, n_addresses); } +static int link_set_bridge_fdb(Link *link) { + FdbEntry *fdb_entry; + int r = 0; + + LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) { + r = fdb_entry_configure(link, fdb_entry); + if (r < 0) { + return log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m"); + } + } + + return r; +} + static int link_enter_set_addresses(Link *link) { Address *ad; int r; @@ -950,6 +964,10 @@ static int link_enter_set_addresses(Link *link) { assert(link->network); assert(link->state != _LINK_STATE_INVALID); + r = link_set_bridge_fdb(link); + if (r < 0) + return r; + link_set_state(link, LINK_STATE_SETTING_ADDRESSES); LIST_FOREACH(addresses, ad, link->network->static_addresses) { @@ -1119,21 +1137,6 @@ static int link_set_bridge_vlan(Link *link) { return r; } -static int link_set_bridge_fdb(Link *link) { - FdbEntry *fdb_entry; - int r = 0; - - LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) { - r = fdb_entry_configure(link, fdb_entry); - if (r < 0) { - log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m"); - break; - } - } - - return r; -} - static int link_set_proxy_arp(Link *link) { const char *p = NULL; int r; @@ -2477,10 +2480,6 @@ static int link_configure(Link *link) { return r; } - r = link_set_bridge_fdb(link); - if (r < 0) - return r; - r = link_set_proxy_arp(link); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From 197e2809320357772c0d2def0b53474a4b1f07fd Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Thu, 6 Oct 2016 15:15:07 +0530 Subject: networkd: fix coding style (#4294) --- src/network/networkd-link.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 25f46c093e..d9e060b6cf 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -944,16 +944,15 @@ static int link_push_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) { static int link_set_bridge_fdb(Link *link) { FdbEntry *fdb_entry; - int r = 0; + int r; LIST_FOREACH(static_fdb_entries, fdb_entry, link->network->static_fdb_entries) { r = fdb_entry_configure(link, fdb_entry); - if (r < 0) { + if (r < 0) return log_link_error_errno(link, r, "Failed to add MAC entry to static MAC table: %m"); - } } - return r; + return 0; } static int link_enter_set_addresses(Link *link) { -- cgit v1.2.3-54-g00ecf From 16441027352ba442c6664c03af852606035c4a45 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Fri, 7 Oct 2016 19:16:18 +0530 Subject: networkd: remote checksum offload for vxlan (#4110) This patch adds support to remote checksum checksum offload to VXLAN. This patch adds RemoteCheckSumTx and RemoteCheckSumRx vxlan configuration to enable remote checksum offload for transmit and receive on the VXLAN tunnel. --- man/systemd.netdev.xml | 12 ++++++++++++ src/network/networkd-netdev-gperf.gperf | 2 ++ src/network/networkd-netdev-vxlan.c | 8 ++++++++ src/network/networkd-netdev-vxlan.h | 2 ++ 4 files changed, 24 insertions(+) (limited to 'src/network') diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index e4527f2837..e378e61dd1 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -554,6 +554,18 @@ A boolean. When true, receiving zero checksums in VXLAN/IPv6 is turned on. + + RemoteCheckSumTx= + + A boolean. When true, remote transmit checksum offload of VXLAN is turned on. + + + + RemoteCheckSumRx= + + A boolean. When true, remote receive checksum offload in VXLAN is turned on. + + GroupPolicyExtension= diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index 6dbb627f15..6b7ab7ab87 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -65,6 +65,8 @@ VXLAN.RouteShortCircuit, config_parse_bool, 0, VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum) VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) +VXLAN.RemoteCheckSumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) +VXLAN.RemoteCheckSumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy) VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb) diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c index 724f9861be..706e52b698 100644 --- a/src/network/networkd-netdev-vxlan.c +++ b/src/network/networkd-netdev-vxlan.c @@ -112,6 +112,14 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_UDP_ZERO_CSUM6_RX attribute: %m"); + r = sd_netlink_message_append_u8(m, IFLA_VXLAN_REMCSUM_TX, v->remote_csum_tx); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_REMCSUM_TX attribute: %m"); + + r = sd_netlink_message_append_u8(m, IFLA_VXLAN_REMCSUM_RX, v->remote_csum_rx); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_REMCSUM_RX attribute: %m"); + r = sd_netlink_message_append_u16(m, IFLA_VXLAN_PORT, htobe16(v->dest_port)); if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT attribute: %m"); diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h index 4614c66fd1..3906820afb 100644 --- a/src/network/networkd-netdev-vxlan.h +++ b/src/network/networkd-netdev-vxlan.h @@ -50,6 +50,8 @@ struct VxLan { bool udpcsum; bool udp6zerocsumtx; bool udp6zerocsumrx; + bool remote_csum_tx; + bool remote_csum_rx; bool group_policy; struct ifla_vxlan_port_range port_range; -- cgit v1.2.3-54-g00ecf From 4b58153dd22172d817055d2a09a0cdf3f4bd9db3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 30 Aug 2016 23:18:46 +0200 Subject: core: add "invocation ID" concept to service manager This adds a new invocation ID concept to the service manager. The invocation ID identifies each runtime cycle of a unit uniquely. A new randomized 128bit ID is generated each time a unit moves from and inactive to an activating or active state. The primary usecase for this concept is to connect the runtime data PID 1 maintains about a service with the offline data the journal stores about it. Previously we'd use the unit name plus start/stop times, which however is highly racy since the journal will generally process log data after the service already ended. The "invocation ID" kinda matches the "boot ID" concept of the Linux kernel, except that it applies to an individual unit instead of the whole system. The invocation ID is passed to the activated processes as environment variable. It is additionally stored as extended attribute on the cgroup of the unit. The latter is used by journald to automatically retrieve it for each log logged message and attach it to the log entry. The environment variable is very easily accessible, even for unprivileged services. OTOH the extended attribute is only accessible to privileged processes (this is because cgroupfs only supports the "trusted." xattr namespace, not "user."). The environment variable may be altered by services, the extended attribute may not be, hence is the better choice for the journal. Note that reading the invocation ID off the extended attribute from journald is racy, similar to the way reading the unit name for a logging process is. This patch adds APIs to read the invocation ID to sd-id128: sd_id128_get_invocation() may be used in a similar fashion to sd_id128_get_boot(). PID1's own logging is updated to always include the invocation ID when it logs information about a unit. A new bus call GetUnitByInvocationID() is added that allows retrieving a bus path to a unit by its invocation ID. The bus path is built using the invocation ID, thus providing a path for referring to a unit that is valid only for the current runtime cycleof it. Outlook for the future: should the kernel eventually allow passing of cgroup information along AF_UNIX/SOCK_DGRAM messages via a unique cgroup id, then we can alter the invocation ID to be generated as hash from that rather than entirely randomly. This way we can derive the invocation race-freely from the messages. --- Makefile-man.am | 5 ++ man/sd_id128_get_machine.xml | 34 +++++++----- man/systemd.exec.xml | 10 ++++ src/basic/cgroup-util.c | 38 +++++++++++++ src/basic/cgroup-util.h | 3 ++ src/basic/log.c | 45 +++++++++------- src/basic/log.h | 10 ++-- src/core/automount.c | 4 ++ src/core/busname.c | 4 ++ src/core/cgroup.c | 21 ++++++++ src/core/dbus-manager.c | 59 +++++++++++++++++++++ src/core/dbus-unit.c | 1 + src/core/device.c | 4 ++ src/core/execute.c | 10 +++- src/core/manager.c | 24 ++++++++- src/core/manager.h | 4 ++ src/core/mount.c | 11 ++-- src/core/org.freedesktop.systemd1.conf | 4 ++ src/core/path.c | 4 ++ src/core/scope.c | 4 ++ src/core/service.c | 4 ++ src/core/slice.c | 5 ++ src/core/socket.c | 5 +- src/core/swap.c | 5 ++ src/core/target.c | 5 ++ src/core/timer.c | 6 ++- src/core/unit.c | 88 ++++++++++++++++++++++++++++++- src/core/unit.h | 10 +++- src/journal/journald-server.c | 60 ++++++++++++++++++--- src/journal/journald-server.h | 2 +- src/libsystemd/libsystemd.sym | 1 + src/libsystemd/sd-bus/bus-common-errors.c | 1 + src/libsystemd/sd-bus/bus-common-errors.h | 1 + src/libsystemd/sd-id128/id128-util.c | 13 +++++ src/libsystemd/sd-id128/id128-util.h | 6 +++ src/libsystemd/sd-id128/sd-id128.c | 22 ++++++++ src/network/networkd-link.h | 2 +- src/network/networkd-netdev.h | 2 +- src/shared/bus-util.c | 2 +- src/systemd/sd-id128.h | 2 +- 40 files changed, 486 insertions(+), 55 deletions(-) (limited to 'src/network') diff --git a/Makefile-man.am b/Makefile-man.am index ef5077cc5a..5760878fe3 100644 --- a/Makefile-man.am +++ b/Makefile-man.am @@ -395,6 +395,7 @@ MANPAGES_ALIAS += \ man/sd_id128_equal.3 \ man/sd_id128_from_string.3 \ man/sd_id128_get_boot.3 \ + man/sd_id128_get_invocation.3 \ man/sd_id128_t.3 \ man/sd_is_mq.3 \ man/sd_is_socket.3 \ @@ -745,6 +746,7 @@ man/sd_event_unrefp.3: man/sd_event_new.3 man/sd_id128_equal.3: man/sd-id128.3 man/sd_id128_from_string.3: man/sd_id128_to_string.3 man/sd_id128_get_boot.3: man/sd_id128_get_machine.3 +man/sd_id128_get_invocation.3: man/sd_id128_get_machine.3 man/sd_id128_t.3: man/sd-id128.3 man/sd_is_mq.3: man/sd_is_fifo.3 man/sd_is_socket.3: man/sd_is_fifo.3 @@ -1519,6 +1521,9 @@ man/sd_id128_from_string.html: man/sd_id128_to_string.html man/sd_id128_get_boot.html: man/sd_id128_get_machine.html $(html-alias) +man/sd_id128_get_invocation.html: man/sd_id128_get_machine.html + $(html-alias) + man/sd_id128_t.html: man/sd-id128.html $(html-alias) diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml index 2ad1f8f728..9a86c24aed 100644 --- a/man/sd_id128_get_machine.xml +++ b/man/sd_id128_get_machine.xml @@ -45,6 +45,7 @@ sd_id128_get_machine sd_id128_get_boot + sd_id128_get_invocation Retrieve 128-bit IDs @@ -62,6 +63,11 @@ sd_id128_t *ret + + int sd_id128_get_invocation + sd_id128_t *ret + + @@ -83,11 +89,15 @@ for more information. This function also internally caches the returned ID to make this call a cheap operation. - Note that sd_id128_get_boot() always - returns a UUID v4 compatible ID. - sd_id128_get_machine() will also return a - UUID v4-compatible ID on new installations but might not on older. - It is possible to convert the machine ID into a UUID v4-compatible + sd_id128_get_invocation() returns the invocation ID of the currently executed + service. In its current implementation, this reads and parses the $INVOCATION_ID environment + variable that the service manager sets when activating a service, see + systemd.exec5 for details. The + ID is cached internally. In future a different mechanism to determine the invocation ID may be added. + + Note that sd_id128_get_boot() and sd_id128_get_invocation() always + return UUID v4 compatible IDs. sd_id128_get_machine() will also return a UUID v4-compatible + ID on new installations but might not on older. It is possible to convert the machine ID into a UUID v4-compatible one. For more information, see machine-id5. @@ -107,11 +117,10 @@ Notes - The sd_id128_get_machine() and - sd_id128_get_boot() interfaces are available - as a shared library, which can be compiled and linked to with the - libsystemd pkg-config1 - file. + The sd_id128_get_machine(), sd_id128_get_boot() and + sd_id128_get_invocation() interfaces are available as a shared library, which can be compiled + and linked to with the libsystemd pkg-config1 file. @@ -121,8 +130,9 @@ systemd1, sd-id1283, machine-id5, - random4, - sd_id128_randomize3 + systemd.exec5, + sd_id128_randomize3, + random4 diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 5e6787338d..c73ccaa493 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1513,6 +1513,16 @@ + + $INVOCATION_ID + + Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted + as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into + an activating or active state, and may be used to identify this specific runtime cycle, in particular in data + stored offline, such as the journal. The same ID is passed to all processes run as part of the + unit. + + $XDG_RUNTIME_DIR diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 7675ab0299..37e6928a46 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "alloc-util.h" @@ -883,6 +884,43 @@ int cg_set_task_access( return 0; } +int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags) { + _cleanup_free_ char *fs = NULL; + int r; + + assert(path); + assert(name); + assert(value || size <= 0); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + if (setxattr(fs, name, value, size, flags) < 0) + return -errno; + + return 0; +} + +int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size) { + _cleanup_free_ char *fs = NULL; + ssize_t n; + int r; + + assert(path); + assert(name); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + n = getxattr(fs, name, value, size); + if (n < 0) + return -errno; + + return (int) n; +} + int cg_pid_get_path(const char *controller, pid_t pid, char **path) { _cleanup_fclose_ FILE *f = NULL; char line[LINE_MAX]; diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h index 1a61c7ad22..7529c9719e 100644 --- a/src/basic/cgroup-util.h +++ b/src/basic/cgroup-util.h @@ -185,6 +185,9 @@ int cg_get_keyed_attribute(const char *controller, const char *path, const char int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); +int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags); +int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size); + int cg_install_release_agent(const char *controller, const char *agent); int cg_uninstall_release_agent(const char *controller); diff --git a/src/basic/log.c b/src/basic/log.c index 6a8dad311d..bd6c96c4f8 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -330,8 +330,6 @@ static int write_to_console( const char *file, int line, const char *func, - const char *object_field, - const char *object, const char *buffer) { char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2]; @@ -390,8 +388,6 @@ static int write_to_syslog( const char *file, int line, const char *func, - const char *object_field, - const char *object, const char *buffer) { char header_priority[2 + DECIMAL_STR_MAX(int) + 1], @@ -453,8 +449,6 @@ static int write_to_kmsg( const char *file, int line, const char *func, - const char *object_field, - const char *object, const char *buffer) { char header_priority[2 + DECIMAL_STR_MAX(int) + 1], @@ -485,7 +479,8 @@ static int log_do_header( int level, int error, const char *file, int line, const char *func, - const char *object_field, const char *object) { + const char *object_field, const char *object, + const char *extra_field, const char *extra) { snprintf(header, size, "PRIORITY=%i\n" @@ -495,6 +490,7 @@ static int log_do_header( "%s%s%s" "%s%.*i%s" "%s%s%s" + "%s%s%s" "SYSLOG_IDENTIFIER=%s\n", LOG_PRI(level), LOG_FAC(level), @@ -513,6 +509,9 @@ static int log_do_header( isempty(object) ? "" : object_field, isempty(object) ? "" : object, isempty(object) ? "" : "\n", + isempty(extra) ? "" : extra_field, + isempty(extra) ? "" : extra, + isempty(extra) ? "" : "\n", program_invocation_short_name); return 0; @@ -526,6 +525,8 @@ static int write_to_journal( const char *func, const char *object_field, const char *object, + const char *extra_field, + const char *extra, const char *buffer) { char header[LINE_MAX]; @@ -535,7 +536,7 @@ static int write_to_journal( if (journal_fd < 0) return 0; - log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object); + log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra); IOVEC_SET_STRING(iovec[0], header); IOVEC_SET_STRING(iovec[1], "MESSAGE="); @@ -559,6 +560,8 @@ static int log_dispatch( const char *func, const char *object_field, const char *object, + const char *extra, + const char *extra_field, char *buffer) { assert(buffer); @@ -589,7 +592,7 @@ static int log_dispatch( log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_JOURNAL) { - k = write_to_journal(level, error, file, line, func, object_field, object, buffer); + k = write_to_journal(level, error, file, line, func, object_field, object, extra_field, extra, buffer); if (k < 0) { if (k != -EAGAIN) log_close_journal(); @@ -600,7 +603,7 @@ static int log_dispatch( if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || log_target == LOG_TARGET_SYSLOG) { - k = write_to_syslog(level, error, file, line, func, object_field, object, buffer); + k = write_to_syslog(level, error, file, line, func, buffer); if (k < 0) { if (k != -EAGAIN) log_close_syslog(); @@ -615,7 +618,7 @@ static int log_dispatch( log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_KMSG)) { - k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer); + k = write_to_kmsg(level, error, file, line, func, buffer); if (k < 0) { log_close_kmsg(); log_open_console(); @@ -623,7 +626,7 @@ static int log_dispatch( } if (k <= 0) - (void) write_to_console(level, error, file, line, func, object_field, object, buffer); + (void) write_to_console(level, error, file, line, func, buffer); buffer = e; } while (buffer); @@ -649,7 +652,7 @@ int log_dump_internal( if (_likely_(LOG_PRI(level) > log_max_level)) return -error; - return log_dispatch(level, error, file, line, func, NULL, NULL, buffer); + return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer); } int log_internalv( @@ -676,7 +679,7 @@ int log_internalv( vsnprintf(buffer, sizeof(buffer), format, ap); - return log_dispatch(level, error, file, line, func, NULL, NULL, buffer); + return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer); } int log_internal( @@ -705,6 +708,8 @@ int log_object_internalv( const char *func, const char *object_field, const char *object, + const char *extra_field, + const char *extra, const char *format, va_list ap) { @@ -738,7 +743,7 @@ int log_object_internalv( vsnprintf(b, l, format, ap); - return log_dispatch(level, error, file, line, func, object_field, object, buffer); + return log_dispatch(level, error, file, line, func, object_field, object, extra_field, extra, buffer); } int log_object_internal( @@ -749,13 +754,15 @@ int log_object_internal( const char *func, const char *object_field, const char *object, + const char *extra_field, + const char *extra, const char *format, ...) { va_list ap; int r; va_start(ap, format); - r = log_object_internalv(level, error, file, line, func, object_field, object, format, ap); + r = log_object_internalv(level, error, file, line, func, object_field, object, extra_field, extra, format, ap); va_end(ap); return r; @@ -780,7 +787,7 @@ static void log_assert( log_abort_msg = buffer; - log_dispatch(level, 0, file, line, func, NULL, NULL, buffer); + log_dispatch(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer); } noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) { @@ -888,7 +895,7 @@ int log_struct_internal( bool fallback = false; /* If the journal is available do structured logging */ - log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL); + log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL); IOVEC_SET_STRING(iovec[n++], header); va_start(ap, format); @@ -935,7 +942,7 @@ int log_struct_internal( if (!found) return -error; - return log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8); + return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8); } int log_set_target_from_string(const char *e) { diff --git a/src/basic/log.h b/src/basic/log.h index b6356228d9..2afee20bb5 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -100,18 +100,22 @@ int log_object_internal( const char *func, const char *object_field, const char *object, - const char *format, ...) _printf_(8,9); + const char *extra_field, + const char *extra, + const char *format, ...) _printf_(10,11); int log_object_internalv( int level, int error, - const char*file, + const char *file, int line, const char *func, const char *object_field, const char *object, + const char *extra_field, + const char *extra, const char *format, - va_list ap) _printf_(8,0); + va_list ap) _printf_(9,0); int log_struct_internal( int level, diff --git a/src/core/automount.c b/src/core/automount.c index bdc0e06965..7d7a0a6e46 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -800,6 +800,10 @@ static int automount_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + a->result = AUTOMOUNT_SUCCESS; automount_enter_waiting(a); return 1; diff --git a/src/core/busname.c b/src/core/busname.c index 7952cd31aa..63c7dde0bd 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -639,6 +639,10 @@ static int busname_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + n->result = BUSNAME_SUCCESS; busname_enter_making(n); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 7873f88785..20bdbc39d0 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1361,6 +1361,26 @@ int unit_attach_pids_to_cgroup(Unit *u) { return 0; } +static void cgroup_xattr_apply(Unit *u) { + char ids[SD_ID128_STRING_MAX]; + int r; + + assert(u); + + if (!MANAGER_IS_SYSTEM(u->manager)) + return; + + if (sd_id128_is_null(u->invocation_id)) + return; + + r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, + "trusted.invocation_id", + sd_id128_to_string(u->invocation_id, ids), 32, + 0); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path); +} + static bool unit_has_mask_realized(Unit *u, CGroupMask target_mask, CGroupMask enable_mask) { assert(u); @@ -1404,6 +1424,7 @@ static int unit_realize_cgroup_now(Unit *u, ManagerState state) { /* Finally, apply the necessary attributes. */ cgroup_context_apply(u, target_mask, state); + cgroup_xattr_apply(u); return 0; } diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index ea7ced2fd0..12eb55cb7f 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -464,6 +464,64 @@ static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bu return sd_bus_reply_method_return(message, "o", path); } +static int method_get_unit_by_invocation_id(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_free_ char *path = NULL; + Manager *m = userdata; + sd_id128_t id; + const void *a; + Unit *u; + size_t sz; + int r; + + assert(message); + assert(m); + + /* Anyone can call this method */ + + r = sd_bus_message_read_array(message, 'y', &a, &sz); + if (r < 0) + return r; + if (sz == 0) + id = SD_ID128_NULL; + else if (sz == 16) + memcpy(&id, a, sz); + else + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID"); + + if (sd_id128_is_null(id)) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + pid_t pid; + + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_pid(creds, &pid); + if (r < 0) + return r; + + u = manager_get_unit_by_pid(m, pid); + if (!u) + return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client " PID_FMT " not member of any unit.", pid); + } else { + u = hashmap_get(m->units_by_invocation_id, &id); + if (!u) + return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(id)); + } + + r = mac_selinux_unit_access_check(u, message, "status", error); + if (r < 0) + return r; + + /* So here's a special trick: the bus path we return actually references the unit by its invocation ID instead + * of the unit name. This means it stays valid only as long as the invocation ID stays the same. */ + path = unit_dbus_path_invocation_id(u); + if (!path) + return -ENOMEM; + + return sd_bus_reply_method_return(message, "o", path); +} + static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_free_ char *path = NULL; Manager *m = userdata; @@ -2254,6 +2312,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("GetUnitByInvocationID", "ay", "o", method_get_unit_by_invocation_id, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 5020dfba4b..245912fc0f 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -764,6 +764,7 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0), SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/core/device.c b/src/core/device.c index 16e56efcc3..8a3e888e5e 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -464,6 +464,10 @@ static void device_update_found_one(Device *d, bool add, DeviceFound found, bool if (!now) return; + /* Didn't exist before, but does now? if so, generate a new invocation ID for it */ + if (previous == DEVICE_NOT_FOUND && d->found != DEVICE_NOT_FOUND) + (void) unit_acquire_invocation_id(UNIT(d)); + if (d->found & DEVICE_FOUND_UDEV) /* When the device is known to udev we consider it * plugged. */ diff --git a/src/core/execute.c b/src/core/execute.c index d5c4e60796..7079aeed6e 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1553,10 +1553,11 @@ static int build_environment( unsigned n_env = 0; char *x; + assert(u); assert(c); assert(ret); - our_env = new0(char*, 13); + our_env = new0(char*, 14); if (!our_env) return -ENOMEM; @@ -1627,6 +1628,13 @@ static int build_environment( our_env[n_env++] = x; } + if (!sd_id128_is_null(u->invocation_id)) { + if (asprintf(&x, "INVOCATION_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id)) < 0) + return -ENOMEM; + + our_env[n_env++] = x; + } + if (exec_context_needs_term(c)) { const char *tty_path, *term = NULL; diff --git a/src/core/manager.c b/src/core/manager.c index c1dce62a18..3569249788 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -522,6 +522,7 @@ static void manager_clean_environment(Manager *m) { "LISTEN_FDNAMES", "WATCHDOG_PID", "WATCHDOG_USEC", + "INVOCATION_ID", NULL); } @@ -582,9 +583,15 @@ int manager_new(UnitFileScope scope, bool test_run, Manager **_m) { if (MANAGER_IS_SYSTEM(m)) { m->unit_log_field = "UNIT="; m->unit_log_format_string = "UNIT=%s"; + + m->invocation_log_field = "INVOCATION_ID="; + m->invocation_log_format_string = "INVOCATION_ID=" SD_ID128_FORMAT_STR; } else { m->unit_log_field = "USER_UNIT="; m->unit_log_format_string = "USER_UNIT=%s"; + + m->invocation_log_field = "USER_INVOCATION_ID="; + m->invocation_log_format_string = "USER_INVOCATION_ID=" SD_ID128_FORMAT_STR; } m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1; @@ -1062,6 +1069,7 @@ Manager* manager_free(Manager *m) { hashmap_free(m->dynamic_users); hashmap_free(m->units); + hashmap_free(m->units_by_invocation_id); hashmap_free(m->jobs); hashmap_free(m->watch_pids1); hashmap_free(m->watch_pids2); @@ -2268,6 +2276,7 @@ int manager_loop(Manager *m) { int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u) { _cleanup_free_ char *n = NULL; + sd_id128_t invocation_id; Unit *u; int r; @@ -2279,12 +2288,25 @@ int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, if (r < 0) return r; + /* Permit addressing units by invocation ID: if the passed bus path is suffixed by a 128bit ID then we use it + * as invocation ID. */ + r = sd_id128_from_string(n, &invocation_id); + if (r >= 0) { + u = hashmap_get(m->units_by_invocation_id, &invocation_id); + if (u) { + *_u = u; + return 0; + } + + return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(invocation_id)); + } + + /* If this didn't work, we use the suffix as unit name. */ r = manager_load_unit(m, n, NULL, e, &u); if (r < 0) return r; *_u = u; - return 0; } diff --git a/src/core/manager.h b/src/core/manager.h index 495440b446..29fe14e10b 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -89,6 +89,7 @@ struct Manager { /* Active jobs and units */ Hashmap *units; /* name string => Unit object n:1 */ + Hashmap *units_by_invocation_id; Hashmap *jobs; /* job id => Job object 1:1 */ /* To make it easy to iterate through the units of a specific @@ -319,6 +320,9 @@ struct Manager { const char *unit_log_field; const char *unit_log_format_string; + const char *invocation_log_field; + const char *invocation_log_format_string; + int first_boot; /* tri-state */ }; diff --git a/src/core/mount.c b/src/core/mount.c index 04025b83b9..436c0e1029 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1005,6 +1005,10 @@ static int mount_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + m->result = MOUNT_SUCCESS; m->reload_result = MOUNT_SUCCESS; m->reset_cpu_usage = true; @@ -1742,9 +1746,10 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, case MOUNT_DEAD: case MOUNT_FAILED: - /* This has just been mounted by - * somebody else, follow the state - * change. */ + + /* This has just been mounted by somebody else, follow the state change, but let's + * generate a new invocation ID for this implicitly and automatically. */ + (void) unit_acquire_invocation_id(UNIT(mount)); mount_enter_mounted(mount, MOUNT_SUCCESS); break; diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf index 647e5f736c..6caa15b0b8 100644 --- a/src/core/org.freedesktop.systemd1.conf +++ b/src/core/org.freedesktop.systemd1.conf @@ -52,6 +52,10 @@ send_interface="org.freedesktop.systemd1.Manager" send_member="GetUnitByPID"/> + + diff --git a/src/core/path.c b/src/core/path.c index 10f9b06974..83f794be89 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -577,6 +577,10 @@ static int path_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + path_mkdir(p); p->result = PATH_SUCCESS; diff --git a/src/core/scope.c b/src/core/scope.c index 65fa65493b..e7583f6d89 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -298,6 +298,10 @@ static int scope_start(Unit *u) { if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) return -ENOENT; + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + (void) unit_realize_cgroup(u); (void) unit_reset_cpu_usage(u); diff --git a/src/core/service.c b/src/core/service.c index 99a70395fc..8ce25c494c 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2033,6 +2033,10 @@ static int service_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + s->result = SERVICE_SUCCESS; s->reload_result = SERVICE_SUCCESS; s->main_pid_known = false; diff --git a/src/core/slice.c b/src/core/slice.c index c7700b8857..03fe797f27 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -187,10 +187,15 @@ static void slice_dump(Unit *u, FILE *f, const char *prefix) { static int slice_start(Unit *u) { Slice *t = SLICE(u); + int r; assert(t); assert(t->state == SLICE_DEAD); + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + (void) unit_realize_cgroup(u); (void) unit_reset_cpu_usage(u); diff --git a/src/core/socket.c b/src/core/socket.c index b9032fa5c9..ae8a1f751f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2354,11 +2354,14 @@ static int socket_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + s->result = SOCKET_SUCCESS; s->reset_cpu_usage = true; socket_enter_start_pre(s); - return 1; } diff --git a/src/core/swap.c b/src/core/swap.c index fb222b6858..0333eaefb8 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -861,6 +861,10 @@ static int swap_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + s->result = SWAP_SUCCESS; s->reset_cpu_usage = true; @@ -1189,6 +1193,7 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v case SWAP_DEAD: case SWAP_FAILED: + (void) unit_acquire_invocation_id(UNIT(swap)); swap_enter_active(swap, SWAP_SUCCESS); break; diff --git a/src/core/target.c b/src/core/target.c index 61a91aad07..765c1f3fa4 100644 --- a/src/core/target.c +++ b/src/core/target.c @@ -124,10 +124,15 @@ static void target_dump(Unit *u, FILE *f, const char *prefix) { static int target_start(Unit *u) { Target *t = TARGET(u); + int r; assert(t); assert(t->state == TARGET_DEAD); + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + target_set_state(t, TARGET_ACTIVE); return 1; } diff --git a/src/core/timer.c b/src/core/timer.c index e2b43f02f8..9538059c13 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -616,6 +616,10 @@ static int timer_start(Unit *u) { return r; } + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; + t->last_trigger = DUAL_TIMESTAMP_NULL; /* Reenable all timers that depend on unit activation time */ @@ -632,7 +636,7 @@ static int timer_start(Unit *u) { /* The timer has never run before, * make sure a stamp file exists. */ - touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); + (void) touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID); } t->result = TIMER_SUCCESS; diff --git a/src/core/unit.c b/src/core/unit.c index 693f75c928..690f7f7dd9 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -37,6 +37,7 @@ #include "execute.h" #include "fileio-label.h" #include "formats-util.h" +#include "id128-util.h" #include "load-dropin.h" #include "load-fragment.h" #include "log.h" @@ -521,6 +522,9 @@ void unit_free(Unit *u) { SET_FOREACH(t, u->names, i) hashmap_remove_value(u->manager->units, t, u); + if (!sd_id128_is_null(u->invocation_id)) + hashmap_remove_value(u->manager->units_by_invocation_id, &u->invocation_id, u); + if (u->job) { Job *j = u->job; job_uninstall(j); @@ -953,6 +957,10 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t); + if (!sd_id128_is_null(u->invocation_id)) + fprintf(f, "%s\tInvocation ID: " SD_ID128_FORMAT_STR "\n", + prefix, SD_ID128_FORMAT_VAL(u->invocation_id)); + STRV_FOREACH(j, u->documentation) fprintf(f, "%s\tDocumentation: %s\n", prefix, *j); @@ -1054,7 +1062,6 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { if (u->nop_job) job_dump(u->nop_job, f, prefix2); - } /* Common implementation for multiple backends */ @@ -2392,6 +2399,15 @@ char *unit_dbus_path(Unit *u) { return unit_dbus_path_from_name(u->id); } +char *unit_dbus_path_invocation_id(Unit *u) { + assert(u); + + if (sd_id128_is_null(u->invocation_id)) + return NULL; + + return unit_dbus_path_from_name(u->invocation_id_string); +} + int unit_set_slice(Unit *u, Unit *slice) { assert(u); assert(slice); @@ -2640,6 +2656,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { if (gid_is_valid(u->ref_gid)) unit_serialize_item_format(u, f, "ref-gid", GID_FMT, u->ref_gid); + if (!sd_id128_is_null(u->invocation_id)) + unit_serialize_item_format(u, f, "invocation-id", SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id)); + bus_track_serialize(u->bus_track, f, "ref"); if (serialize_jobs) { @@ -2914,6 +2933,19 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { if (r < 0) log_oom(); + continue; + } else if (streq(l, "invocation-id")) { + sd_id128_t id; + + r = sd_id128_from_string(v, &id); + if (r < 0) + log_unit_debug(u, "Failed to parse invocation id %s, ignoring.", v); + else { + r = unit_set_invocation_id(u, id); + if (r < 0) + log_unit_warning_errno(u, r, "Failed to set invocation ID for unit: %m"); + } + continue; } @@ -4153,3 +4185,57 @@ void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid) { if (r > 0) bus_unit_send_change_signal(u); } + +int unit_set_invocation_id(Unit *u, sd_id128_t id) { + int r; + + assert(u); + + /* Set the invocation ID for this unit. If we cannot, this will not roll back, but reset the whole thing. */ + + if (sd_id128_equal(u->invocation_id, id)) + return 0; + + if (!sd_id128_is_null(u->invocation_id)) + (void) hashmap_remove_value(u->manager->units_by_invocation_id, &u->invocation_id, u); + + if (sd_id128_is_null(id)) { + r = 0; + goto reset; + } + + r = hashmap_ensure_allocated(&u->manager->units_by_invocation_id, &id128_hash_ops); + if (r < 0) + goto reset; + + u->invocation_id = id; + sd_id128_to_string(id, u->invocation_id_string); + + r = hashmap_put(u->manager->units_by_invocation_id, &u->invocation_id, u); + if (r < 0) + goto reset; + + return 0; + +reset: + u->invocation_id = SD_ID128_NULL; + u->invocation_id_string[0] = 0; + return r; +} + +int unit_acquire_invocation_id(Unit *u) { + sd_id128_t id; + int r; + + assert(u); + + r = sd_id128_randomize(&id); + if (r < 0) + return log_unit_error_errno(u, r, "Failed to generate invocation ID for unit: %m"); + + r = unit_set_invocation_id(u, id); + if (r < 0) + return log_unit_error_errno(u, r, "Failed to set invocation ID for unit: %m"); + + return 0; +} diff --git a/src/core/unit.h b/src/core/unit.h index 3584c16d8c..a8dd3e602c 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -207,6 +207,10 @@ struct Unit { /* How to start OnFailure units */ JobMode on_failure_job_mode; + /* The current invocation ID */ + sd_id128_t invocation_id; + char invocation_id_string[SD_ID128_STRING_MAX]; /* useful when logging */ + /* Garbage collect us we nobody wants or requires us anymore */ bool stop_when_unneeded; @@ -546,6 +550,7 @@ bool unit_job_is_applicable(Unit *u, JobType j); int set_unit_path(const char *p); char *unit_dbus_path(Unit *u); +char *unit_dbus_path_invocation_id(Unit *u); int unit_load_related_unit(Unit *u, const char *type, Unit **_found); @@ -643,12 +648,15 @@ void unit_unref_uid_gid(Unit *u, bool destroy_now); void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid); +int unit_set_invocation_id(Unit *u, sd_id128_t id); +int unit_acquire_invocation_id(Unit *u); + /* Macros which append UNIT= or USER_UNIT= to the message */ #define log_unit_full(unit, level, error, ...) \ ({ \ const Unit *_u = (unit); \ - _u ? log_object_internal(level, error, __FILE__, __LINE__, __func__, _u->manager->unit_log_field, _u->id, ##__VA_ARGS__) : \ + _u ? log_object_internal(level, error, __FILE__, __LINE__, __func__, _u->manager->unit_log_field, _u->id, _u->manager->invocation_log_field, _u->invocation_id_string, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 015b74b203..f01cf1d937 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -44,6 +44,7 @@ #include "fs-util.h" #include "hashmap.h" #include "hostname-util.h" +#include "id128-util.h" #include "io-util.h" #include "journal-authenticate.h" #include "journal-file.h" @@ -56,6 +57,7 @@ #include "journald-server.h" #include "journald-stream.h" #include "journald-syslog.h" +#include "log.h" #include "missing.h" #include "mkdir.h" #include "parse-util.h" @@ -69,7 +71,6 @@ #include "string-table.h" #include "string-util.h" #include "user-util.h" -#include "log.h" #define USER_JOURNALS_MAX 1024 @@ -675,6 +676,44 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned server_schedule_sync(s, priority); } +static int get_invocation_id(const char *cgroup_root, const char *slice, const char *unit, char **ret) { + _cleanup_free_ char *escaped = NULL, *slice_path = NULL, *p = NULL; + char *copy, ids[SD_ID128_STRING_MAX]; + int r; + + /* Read the invocation ID of a unit off a unit. It's stored in the "trusted.invocation_id" extended attribute + * on the cgroup path. */ + + r = cg_slice_to_path(slice, &slice_path); + if (r < 0) + return r; + + escaped = cg_escape(unit); + if (!escaped) + return -ENOMEM; + + p = strjoin(cgroup_root, "/", slice_path, "/", escaped, NULL); + if (!p) + return -ENOMEM; + + r = cg_get_xattr(SYSTEMD_CGROUP_CONTROLLER, p, "trusted.invocation_id", ids, 32); + if (r < 0) + return r; + if (r != 32) + return -EINVAL; + ids[32] = 0; + + if (!id128_is_valid(ids)) + return -EINVAL; + + copy = strdup(ids); + if (!copy) + return -ENOMEM; + + *ret = copy; + return 0; +} + static void dispatch_message_real( Server *s, struct iovec *iovec, unsigned n, unsigned m, @@ -771,6 +810,7 @@ static void dispatch_message_real( r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c); if (r >= 0) { + _cleanup_free_ char *raw_unit = NULL, *raw_slice = NULL; char *session = NULL; x = strjoina("_SYSTEMD_CGROUP=", c); @@ -790,9 +830,8 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], owner_uid); } - if (cg_path_get_unit(c, &t) >= 0) { - x = strjoina("_SYSTEMD_UNIT=", t); - free(t); + if (cg_path_get_unit(c, &raw_unit) >= 0) { + x = strjoina("_SYSTEMD_UNIT=", raw_unit); IOVEC_SET_STRING(iovec[n++], x); } else if (unit_id && !session) { x = strjoina("_SYSTEMD_UNIT=", unit_id); @@ -808,9 +847,8 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], x); } - if (cg_path_get_slice(c, &t) >= 0) { - x = strjoina("_SYSTEMD_SLICE=", t); - free(t); + if (cg_path_get_slice(c, &raw_slice) >= 0) { + x = strjoina("_SYSTEMD_SLICE=", raw_slice); IOVEC_SET_STRING(iovec[n++], x); } @@ -820,6 +858,14 @@ static void dispatch_message_real( IOVEC_SET_STRING(iovec[n++], x); } + if (raw_slice && raw_unit) { + if (get_invocation_id(s->cgroup_root, raw_slice, raw_unit, &t) >= 0) { + x = strjoina("_SYSTEMD_INVOCATION_ID=", t); + free(t); + IOVEC_SET_STRING(iovec[n++], x); + } + } + free(c); } else if (unit_id) { x = strjoina("_SYSTEMD_UNIT=", unit_id); diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h index 784d24833d..dfb5724794 100644 --- a/src/journal/journald-server.h +++ b/src/journal/journald-server.h @@ -153,7 +153,7 @@ struct Server { #define SERVER_MACHINE_ID(s) ((s)->machine_id_field + strlen("_MACHINE_ID=")) -#define N_IOVEC_META_FIELDS 21 +#define N_IOVEC_META_FIELDS 22 #define N_IOVEC_KERNEL_FIELDS 64 #define N_IOVEC_UDEV_FIELDS 32 #define N_IOVEC_OBJECT_FIELDS 14 diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 70ea347361..d48ef6bbe2 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -509,4 +509,5 @@ global: sd_bus_track_count_sender; sd_bus_set_exit_on_disconnect; sd_bus_get_exit_on_disconnect; + sd_id128_get_invocation; } LIBSYSTEMD_231; diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index 9cc28ed564..d2a826bf6e 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -27,6 +27,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_UNIT, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_NO_UNIT_FOR_PID, ESRCH), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_EXISTS, EEXIST), SD_BUS_ERROR_MAP(BUS_ERROR_LOAD_FAILED, EIO), SD_BUS_ERROR_MAP(BUS_ERROR_JOB_FAILED, EREMOTEIO), diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index 5df21c8926..525b79fa77 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -23,6 +23,7 @@ #define BUS_ERROR_NO_SUCH_UNIT "org.freedesktop.systemd1.NoSuchUnit" #define BUS_ERROR_NO_UNIT_FOR_PID "org.freedesktop.systemd1.NoUnitForPID" +#define BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID "org.freedesktop.systemd1.NoUnitForInvocationID" #define BUS_ERROR_UNIT_EXISTS "org.freedesktop.systemd1.UnitExists" #define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed" #define BUS_ERROR_JOB_FAILED "org.freedesktop.systemd1.JobFailed" diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index c3f527d657..337eae24b4 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -192,3 +192,16 @@ int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) { return id128_write_fd(fd, f, id, do_sync); } + +void id128_hash_func(const void *p, struct siphash *state) { + siphash24_compress(p, 16, state); +} + +int id128_compare_func(const void *a, const void *b) { + return memcmp(a, b, 16); +} + +const struct hash_ops id128_hash_ops = { + .hash = id128_hash_func, + .compare = id128_compare_func, +}; diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h index 3ba59acbca..6b3855acbb 100644 --- a/src/libsystemd/sd-id128/id128-util.h +++ b/src/libsystemd/sd-id128/id128-util.h @@ -22,6 +22,8 @@ #include #include "sd-id128.h" + +#include "hash-funcs.h" #include "macro.h" char *id128_to_uuid_string(sd_id128_t id, char s[37]); @@ -43,3 +45,7 @@ int id128_read(const char *p, Id128Format f, sd_id128_t *ret); int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync); int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync); + +void id128_hash_func(const void *p, struct siphash *state); +int id128_compare_func(const void *a, const void *b) _pure_; +extern const struct hash_ops id128_hash_ops; diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index 9f47d04e61..d4450c70a0 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -129,6 +129,28 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) { return 0; } +_public_ int sd_id128_get_invocation(sd_id128_t *ret) { + static thread_local sd_id128_t saved_invocation_id = {}; + int r; + + assert_return(ret, -EINVAL); + + if (sd_id128_is_null(saved_invocation_id)) { + const char *e; + + e = secure_getenv("INVOCATION_ID"); + if (!e) + return -ENXIO; + + r = sd_id128_from_string(e, &saved_invocation_id); + if (r < 0) + return r; + } + + *ret = saved_invocation_id; + return 0; +} + static sd_id128_t make_v4_uuid(sd_id128_t id) { /* Stolen from generate_random_uuid() of drivers/char/random.c * in the kernel sources */ diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 05b2a2b323..77f72d070e 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -187,7 +187,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); #define log_link_full(link, level, error, ...) \ ({ \ const Link *_l = (link); \ - _l ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, ##__VA_ARGS__) : \ + _l ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _l->ifname, NULL, NULL, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) \ diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index 31b55e2791..70ff947b99 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -182,7 +182,7 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign #define log_netdev_full(netdev, level, error, ...) \ ({ \ const NetDev *_n = (netdev); \ - _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, ##__VA_ARGS__) : \ + _n ? log_object_internal(level, error, __FILE__, __LINE__, __func__, "INTERFACE=", _n->ifname, NULL, NULL, ##__VA_ARGS__) : \ log_internal(level, error, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ }) diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 64fcf9295f..bb90c89cc2 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1338,7 +1338,7 @@ int bus_property_get_id128( if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */ return sd_bus_message_append(reply, "ay", 0); else - return sd_bus_message_append_array(reply, 'b', id->bytes, 16); + return sd_bus_message_append_array(reply, 'y', id->bytes, 16); } #if __SIZEOF_SIZE_T__ != 8 diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h index 4dff0b9b81..ee011b1861 100644 --- a/src/systemd/sd-id128.h +++ b/src/systemd/sd-id128.h @@ -45,8 +45,8 @@ int sd_id128_from_string(const char *s, sd_id128_t *ret); int sd_id128_randomize(sd_id128_t *ret); int sd_id128_get_machine(sd_id128_t *ret); - int sd_id128_get_boot(sd_id128_t *ret); +int sd_id128_get_invocation(sd_id128_t *ret); #define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ ((const sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ -- cgit v1.2.3-54-g00ecf From e63be0847c39bfdca45c25c505922814374581a7 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Sat, 8 Oct 2016 16:35:41 +0530 Subject: networkd: address add support to configure flags (#4201) This patch enables to configure IFA_F_HOMEADDRESS IFA_F_NODAD IFA_F_MANAGETEMPADDR IFA_F_NOPREFIXROUTE IFA_F_MCAUTOJOIN --- man/systemd.network.xml | 51 +++++++++++++++++++++++++++ src/basic/missing.h | 4 +++ src/network/networkd-address.c | 59 ++++++++++++++++++++++++++++++++ src/network/networkd-address.h | 6 ++++ src/network/networkd-network-gperf.gperf | 5 +++ 5 files changed, 125 insertions(+) (limited to 'src/network') diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 0af927db19..2fb4907634 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -695,6 +695,57 @@ which is then configured to use them explicitly. + + HomeAddress= + + Takes a boolean argument. Designates this address the "home address" as defined in + RFC 6275. + Supported only on IPv6. Defaults to false. + + + + DuplicateAddressDetection= + + Takes a boolean argument. Do not perform Duplicate Address Detection + RFC 4862 when adding this address. + Supported only on IPv6. Defaults to false. + + + + ManageTemporaryAddress= + + Takes a boolean argument. If true the kernel manage temporary addresses created + from this one as template on behalf of Privacy Extensions + RFC 3041. For this to become + active, the use_tempaddr sysctl setting has to be set to a value greater than zero. + The given address needs to have a prefix length of 64. This flag allows to use privacy + extensions in a manually configured network, just like if stateless auto-configuration + was active. Defaults to false. + + + + PrefixRoute= + + Takes a boolean argument. When adding or modifying an IPv6 address, the userspace + application needs a way to suppress adding a prefix route. This is for example relevant + together with IFA_F_MANAGERTEMPADDR, where userspace creates autoconf generated addresses, + but depending on on-link, no route for the prefix should be added. Defaults to false. + + + + AutoJoin= + + Takes a boolean argument. Joining multicast group on ethernet level via + ip maddr command would not work if we have an Ethernet switch that does + IGMP snooping since the switch would not replicate multicast packets on ports that did not + have IGMP reports for the multicast addresses. Linux vxlan interfaces created via + ip link add vxlan or networkd's netdev kind vxlan have the group option + that enables then to do the required join. By extending ip address command with option + autojoin we can get similar functionality for openvswitch (OVS) vxlan + interfaces as well as other tunneling mechanisms that need to receive multicast traffic. + Defaults to no. + + diff --git a/src/basic/missing.h b/src/basic/missing.h index 13ff51cd35..4a78269e33 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -1052,6 +1052,10 @@ typedef int32_t key_serial_t; #define ETHERTYPE_LLDP 0x88cc #endif +#ifndef IFA_F_MCAUTOJOIN +#define IFA_F_MCAUTOJOIN 0x400 +#endif + #endif #include "missing_syscall.h" diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 5498e352d8..ed52d5e42d 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -571,6 +571,21 @@ int address_configure( address->flags |= IFA_F_PERMANENT; + if (address->home_address) + address->flags |= IFA_F_HOMEADDRESS; + + if (address->duplicate_address_detection) + address->flags |= IFA_F_NODAD; + + if (address->manage_temporary_address) + address->flags |= IFA_F_MANAGETEMPADDR; + + if (address->prefix_route) + address->flags |= IFA_F_NOPREFIXROUTE; + + if (address->autojoin) + address->flags |= IFA_F_MCAUTOJOIN; + r = sd_rtnl_message_addr_set_flags(req, (address->flags & 0xff)); if (r < 0) return log_error_errno(r, "Could not set flags: %m"); @@ -856,6 +871,50 @@ int config_parse_lifetime(const char *unit, return 0; } +int config_parse_address_flags(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) { + Network *network = userdata; + _cleanup_address_free_ Address *n = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = address_new_static(network, section_line, &n); + if (r < 0) + return r; + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue); + return 0; + } + + if (streq(lvalue, "HomeAddress")) + n->home_address = r; + else if (streq(lvalue, "DuplicateAddressDetection")) + n->duplicate_address_detection = r; + else if (streq(lvalue, "ManageTemporaryAddress")) + n->manage_temporary_address = r; + else if (streq(lvalue, "PrefixRoute")) + n->prefix_route = r; + else if (streq(lvalue, "AutoJoin")) + n->autojoin = r; + + return 0; +} + bool address_is_ready(const Address *a) { assert(a); diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 03c4bea7c6..bc3b4fc7f3 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -53,6 +53,11 @@ struct Address { union in_addr_union in_addr_peer; bool ip_masquerade_done:1; + bool duplicate_address_detection; + bool manage_temporary_address; + bool home_address; + bool prefix_route; + bool autojoin; LIST_FIELDS(Address, addresses); }; @@ -77,3 +82,4 @@ int config_parse_address(const char *unit, const char *filename, unsigned line, int config_parse_broadcast(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); int config_parse_label(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); int config_parse_lifetime(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); +int config_parse_address_flags(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); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 62779c7c48..5587961b9f 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -70,6 +70,11 @@ Address.Peer, config_parse_address, Address.Broadcast, config_parse_broadcast, 0, 0 Address.Label, config_parse_label, 0, 0 Address.PreferredLifetime, config_parse_lifetime, 0, 0 +Address.HomeAddress, config_parse_address_flags, 0, 0 +Address.DuplicateAddressDetection, config_parse_address_flags, 0, 0 +Address.ManageTemporaryAddress, config_parse_address_flags, 0, 0 +Address.PrefixRoute, config_parse_address_flags, 0, 0 +Address.AutoJoin, config_parse_address_flags, 0, 0 Route.Gateway, config_parse_gateway, 0, 0 Route.Destination, config_parse_destination, 0, 0 Route.Source, config_parse_destination, 0, 0 -- cgit v1.2.3-54-g00ecf From 53c06862c12918ec717ea70918039765212eee95 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Mon, 10 Oct 2016 23:22:12 +0530 Subject: networkd: rename Rename CheckSum → Checksum (#4312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- man/systemd.netdev.xml | 8 ++++---- src/network/networkd-netdev-gperf.gperf | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/network') diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index e378e61dd1..ffb66e735b 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -537,7 +537,7 @@ - UDPCheckSum= + UDPChecksum= A boolean. When true, transmitting UDP checksums when doing VXLAN/IPv4 is turned on. @@ -549,19 +549,19 @@ - UDP6ZeroCheckSumRx= + UDP6ZeroChecksumRx= A boolean. When true, receiving zero checksums in VXLAN/IPv6 is turned on. - RemoteCheckSumTx= + RemoteChecksumTx= A boolean. When true, remote transmit checksum offload of VXLAN is turned on. - RemoteCheckSumRx= + RemoteChecksumRx= A boolean. When true, remote receive checksum offload in VXLAN is turned on. diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index 6b7ab7ab87..323eaa8032 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -63,10 +63,13 @@ VXLAN.L2MissNotification, config_parse_bool, 0, VXLAN.L3MissNotification, config_parse_bool, 0, offsetof(VxLan, l3miss) VXLAN.RouteShortCircuit, config_parse_bool, 0, offsetof(VxLan, route_short_circuit) VXLAN.UDPCheckSum, config_parse_bool, 0, offsetof(VxLan, udpcsum) +VXLAN.UDPChecksum, config_parse_bool, 0, offsetof(VxLan, udpcsum) VXLAN.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) +VXLAN.UDP6ZeroChecksumRx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumrx) VXLAN.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) -VXLAN.RemoteCheckSumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) -VXLAN.RemoteCheckSumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) +VXLAN.UDP6ZeroChecksumTx, config_parse_bool, 0, offsetof(VxLan, udp6zerocsumtx) +VXLAN.RemoteChecksumTx, config_parse_bool, 0, offsetof(VxLan, remote_csum_tx) +VXLAN.RemoteChecksumRx, config_parse_bool, 0, offsetof(VxLan, remote_csum_rx) VXLAN.FDBAgeingSec, config_parse_sec, 0, offsetof(VxLan, fdb_ageing) VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy) VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb) -- cgit v1.2.3-54-g00ecf From 9f1008d5131806a390d697f2e1e994ea1e9bf83d Mon Sep 17 00:00:00 2001 From: Andrew Jeddeloh Date: Tue, 11 Oct 2016 21:28:22 -0400 Subject: networkd: add dbus interface for lease raw options (#3528) Add a dbus object to represent dhcp leases and their raw options (i.e. options 224-254). --- src/network/networkd-link-bus.c | 131 ++++++++++++++++++++++++++++++++++++++++ src/network/networkd-link.h | 5 ++ src/network/networkd-manager.c | 8 +++ 3 files changed, 144 insertions(+) (limited to 'src/network') diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 532557ed6c..10ec08351a 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -23,6 +23,7 @@ #include "networkd.h" #include "parse-util.h" #include "strv.h" +#include "dhcp-lease-internal.h" static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState); @@ -36,6 +37,50 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_END }; +static int get_private_options(sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + sd_dhcp_lease *lease = userdata; + struct sd_dhcp_raw_option *option = NULL; + int r; + + assert(bus); + assert(reply); + assert(lease); + + r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "{yay}"); + if (r < 0) + return r; + + LIST_FOREACH(options, option, lease->private_options) { + r = sd_bus_message_open_container(reply, SD_BUS_TYPE_DICT_ENTRY, "yay"); + if (r < 0) + return r; + r = sd_bus_message_append(reply, "y", option->tag); + if (r < 0) + return r; + r = sd_bus_message_append_array(reply, 'y', option->data, option->length); + if (r < 0) + return r; + r = sd_bus_message_close_container(reply); + if (r < 0) + return r; + } + return sd_bus_message_close_container(reply); +} + +const sd_bus_vtable lease_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_PROPERTY("PrivateOptions", "a{yay}", get_private_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), + + SD_BUS_VTABLE_END +}; + static char *link_bus_path(Link *link) { _cleanup_free_ char *ifindex = NULL; char *p; @@ -54,6 +99,24 @@ static char *link_bus_path(Link *link) { return p; } +static char *lease_bus_path(Link *link) { + _cleanup_free_ char *p = NULL; + char *ret = NULL; + int r; + + assert(link); + + p = link_bus_path(link); + if (!p) + return NULL; + + r = sd_bus_path_encode(p, "lease", &ret); + if (r < 0) + return NULL; + + return ret; +} + int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; Manager *m = userdata; @@ -87,6 +150,42 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** return 1; } +int lease_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; + Manager *m = userdata; + unsigned c = 0; + Link *link; + Iterator i; + + assert(bus); + assert(path); + assert(m); + assert(nodes); + + l = new0(char*, hashmap_size(m->links) + 1); + if (!l) + return -ENOMEM; + + HASHMAP_FOREACH(link, m->links, i) { + char *p; + + if (!link->dhcp_lease) + continue; + + p = lease_bus_path(link); + if (!p) + return -ENOMEM; + + l[c++] = p; + } + + l[c] = NULL; + *nodes = l; + l = NULL; + + return 1; +} + int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *identifier = NULL; Manager *m = userdata; @@ -116,6 +215,38 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void return 1; } +int lease_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { + _cleanup_free_ char *identifier = NULL; + Manager *m = userdata; + Link *link; + int ifindex, r; + + assert(bus); + assert(path); + assert(interface); + assert(m); + assert(found); + + r = sd_bus_path_decode_many(path, "/org/freedesktop/network1/link/%/lease", &identifier); + if (r <= 0) + return 0; + + r = parse_ifindex(identifier, &ifindex); + if (r < 0) + return 0; + + r = link_get(m, ifindex, &link); + if (r < 0) + return 0; + + if (!link->dhcp_lease) + return 0; + + *found = link->dhcp_lease; + + return 1; +} + int link_send_changed(Link *link, const char *property, ...) { _cleanup_free_ char *p = NULL; char **l; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 77f72d070e..1178999bb4 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -179,6 +179,11 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); int link_send_changed(Link *link, const char *property, ...) _sentinel_; +extern const sd_bus_vtable lease_vtable[]; + +int lease_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); +int lease_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); + DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); #define _cleanup_link_unref_ _cleanup_(link_unrefp) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 9174dcc7f4..0ad34e0cc2 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -176,6 +176,14 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add link enumerator: %m"); + r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link.Lease", lease_vtable, lease_object_find, m); + if (r < 0) + return log_error_errno(r, "Failed to add lease object vtable: %m"); + + r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", lease_node_enumerator, m); + if (r < 0) + return log_error_errno(r, "Failed to add lease enumerator: %m"); + r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add network object vtable: %m"); -- cgit v1.2.3-54-g00ecf From 6b430fdb7c0c2c52ea69a7d56f23d739218b13d0 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Sun, 16 Oct 2016 18:28:30 -0400 Subject: tree-wide: use mfree more --- coccinelle/mfree_return.cocci | 6 ++++++ src/basic/bitmap.c | 6 ++---- src/basic/env-util.c | 3 +-- src/basic/prioq.c | 4 +--- src/basic/replace-var.c | 3 +-- src/basic/strbuf.c | 3 +-- src/basic/string-util.c | 6 ++---- src/basic/strv.c | 9 +++------ src/core/dynamic-user.c | 4 +--- src/core/execute.c | 4 +--- src/core/manager.c | 3 +-- src/core/transaction.c | 6 ++---- src/core/unit.c | 6 ++---- src/cryptsetup/cryptsetup-generator.c | 9 +++------ src/import/curl-util.c | 4 +--- src/import/export-raw.c | 4 +--- src/import/export-tar.c | 4 +--- src/import/import-raw.c | 4 +--- src/import/import-tar.c | 4 +--- src/import/importd.c | 6 ++---- src/import/pull-job.c | 4 +--- src/import/pull-raw.c | 4 +--- src/import/pull-tar.c | 4 +--- src/journal-remote/journal-remote-write.c | 10 +++------- src/journal/journal-file.c | 3 +-- src/journal/mmap-cache.c | 6 ++---- src/journal/sd-journal.c | 9 +++------ src/libsystemd-network/ndisc-router.c | 3 +-- src/libsystemd-network/sd-dhcp-client.c | 4 +--- src/libsystemd-network/sd-dhcp-lease.c | 4 +--- src/libsystemd-network/sd-dhcp-server.c | 4 +--- src/libsystemd-network/sd-dhcp6-client.c | 4 +--- src/libsystemd-network/sd-dhcp6-lease.c | 4 +--- src/libsystemd-network/sd-ipv4acd.c | 4 +--- src/libsystemd-network/sd-ipv4ll.c | 4 +--- src/libsystemd-network/sd-lldp.c | 4 +--- src/libsystemd-network/sd-ndisc.c | 4 +--- src/libsystemd/sd-bus/bus-slot.c | 4 +--- src/libsystemd/sd-bus/bus-track.c | 8 ++------ src/libudev/libudev-list.c | 14 ++++++-------- src/libudev/libudev-monitor.c | 3 +-- src/login/logind-button.c | 9 +++------ src/login/logind-device.c | 9 +++------ src/login/logind-inhibit.c | 9 +++------ src/login/logind-seat.c | 9 +++------ src/login/logind-session.c | 12 ++++-------- src/machine/machine.c | 4 +--- src/machine/operation.c | 3 +-- src/network/networkd-wait-online-link.c | 3 +-- src/nspawn/nspawn-settings.c | 4 +--- src/resolve/resolved-dns-query.c | 8 ++------ src/resolve/resolved-dns-rr.c | 10 +++------- src/resolve/resolved-dns-scope.c | 4 +--- src/resolve/resolved-dns-search-domain.c | 4 +--- src/resolve/resolved-dns-server.c | 3 +-- src/resolve/resolved-dns-stream.c | 4 +--- src/resolve/resolved-dns-transaction.c | 3 +-- src/resolve/resolved-link.c | 6 ++---- src/resolve/resolved-manager.c | 4 +--- src/shared/machine-image.c | 3 +-- src/shared/ptyfwd.c | 3 +-- src/timesync/timesyncd-server.c | 7 ++----- src/udev/udev-ctrl.c | 3 +-- src/udev/udev-rules.c | 3 +-- 64 files changed, 105 insertions(+), 228 deletions(-) create mode 100644 coccinelle/mfree_return.cocci (limited to 'src/network') diff --git a/coccinelle/mfree_return.cocci b/coccinelle/mfree_return.cocci new file mode 100644 index 0000000000..8119fe07f2 --- /dev/null +++ b/coccinelle/mfree_return.cocci @@ -0,0 +1,6 @@ +@@ +expression p; +@@ +- free(p); +- return NULL; ++ return mfree(p); diff --git a/src/basic/bitmap.c b/src/basic/bitmap.c index f4b12fc261..f6212e6151 100644 --- a/src/basic/bitmap.c +++ b/src/basic/bitmap.c @@ -58,10 +58,8 @@ Bitmap *bitmap_copy(Bitmap *b) { return NULL; ret->bitmaps = newdup(uint64_t, b->bitmaps, b->n_bitmaps); - if (!ret->bitmaps) { - free(ret); - return NULL; - } + if (!ret->bitmaps) + return mfree(ret); ret->n_bitmaps = ret->bitmaps_allocated = b->n_bitmaps; return ret; diff --git a/src/basic/env-util.c b/src/basic/env-util.c index 7f5fddb700..b74290d6fd 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -544,8 +544,7 @@ char *replace_env(const char *format, char **env) { return k; fail: - free(r); - return NULL; + return mfree(r); } char **replace_env_argv(char **argv, char **env) { diff --git a/src/basic/prioq.c b/src/basic/prioq.c index d2ec516d29..4570b8e4ba 100644 --- a/src/basic/prioq.c +++ b/src/basic/prioq.c @@ -62,9 +62,7 @@ Prioq* prioq_free(Prioq *q) { return NULL; free(q->items); - free(q); - - return NULL; + return mfree(q); } int prioq_ensure_allocated(Prioq **q, compare_func_t compare_func) { diff --git a/src/basic/replace-var.c b/src/basic/replace-var.c index 6a204b9ec3..0d21423a9c 100644 --- a/src/basic/replace-var.c +++ b/src/basic/replace-var.c @@ -107,6 +107,5 @@ char *replace_var(const char *text, char *(*lookup)(const char *variable, void*u return r; oom: - free(r); - return NULL; + return mfree(r); } diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c index 4bef87d3c2..00aaf9e621 100644 --- a/src/basic/strbuf.c +++ b/src/basic/strbuf.c @@ -62,8 +62,7 @@ struct strbuf *strbuf_new(void) { err: free(str->buf); free(str->root); - free(str); - return NULL; + return mfree(str); } static void strbuf_node_cleanup(struct strbuf_node *node) { diff --git a/src/basic/string-util.c b/src/basic/string-util.c index dc7de5dab8..6b06e643c9 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -610,8 +610,7 @@ char *strreplace(const char *text, const char *old_string, const char *new_strin return r; oom: - free(r); - return NULL; + return mfree(r); } char *strip_tab_ansi(char **ibuf, size_t *_isz) { @@ -682,8 +681,7 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz) { if (ferror(f)) { fclose(f); - free(obuf); - return NULL; + return mfree(obuf); } fclose(f); diff --git a/src/basic/strv.c b/src/basic/strv.c index 34e464d253..0eec868eed 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -87,8 +87,7 @@ void strv_clear(char **l) { char **strv_free(char **l) { strv_clear(l); - free(l); - return NULL; + return mfree(l); } char **strv_free_erase(char **l) { @@ -426,8 +425,7 @@ char *strv_join_quoted(char **l) { return buf; oom: - free(buf); - return NULL; + return mfree(buf); } int strv_push(char ***l, char *value) { @@ -869,8 +867,7 @@ char ***strv_free_free(char ***l) { for (i = l; *i; i++) strv_free(*i); - free(l); - return NULL; + return mfree(l); } char **strv_skip(char **l, size_t n) { diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c index 1043da3eb7..e1846e1adb 100644 --- a/src/core/dynamic-user.c +++ b/src/core/dynamic-user.c @@ -42,9 +42,7 @@ static DynamicUser* dynamic_user_free(DynamicUser *d) { (void) hashmap_remove(d->manager->dynamic_users, d->name); safe_close_pair(d->storage_socket); - free(d); - - return NULL; + return mfree(d); } static int dynamic_user_add(Manager *m, const char *name, int storage_socket[2], DynamicUser **ret) { diff --git a/src/core/execute.c b/src/core/execute.c index 869522704a..59c2bd0dd2 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3740,9 +3740,7 @@ ExecRuntime *exec_runtime_unref(ExecRuntime *r) { free(r->tmp_dir); free(r->var_tmp_dir); safe_close_pair(r->netns_storage_socket); - free(r); - - return NULL; + return mfree(r); } int exec_runtime_serialize(Unit *u, ExecRuntime *rt, FILE *f, FDSet *fds) { diff --git a/src/core/manager.c b/src/core/manager.c index 3569249788..50aae0d1ba 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1119,8 +1119,7 @@ Manager* manager_free(Manager *m) { hashmap_free(m->uid_refs); hashmap_free(m->gid_refs); - free(m); - return NULL; + return mfree(m); } void manager_enumerate(Manager *m) { diff --git a/src/core/transaction.c b/src/core/transaction.c index 8370b864fb..e22e3b30c2 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -1085,10 +1085,8 @@ Transaction *transaction_new(bool irreversible) { return NULL; tr->jobs = hashmap_new(NULL); - if (!tr->jobs) { - free(tr); - return NULL; - } + if (!tr->jobs) + return mfree(tr); tr->irreversible = irreversible; diff --git a/src/core/unit.c b/src/core/unit.c index 67668bdc48..a6b8ecdcb7 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -88,10 +88,8 @@ Unit *unit_new(Manager *m, size_t size) { return NULL; u->names = set_new(&string_hash_ops); - if (!u->names) { - free(u); - return NULL; - } + if (!u->names) + return mfree(u); u->manager = m; u->type = _UNIT_TYPE_INVALID; diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index 8ac5ab730a..de0a3b6f9c 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -264,16 +264,13 @@ static crypto_device *get_crypto_device(const char *uuid) { d->keyfile = d->options = d->name = NULL; d->uuid = strdup(uuid); - if (!d->uuid) { - free(d); - return NULL; - } + if (!d->uuid) + return mfree(d); r = hashmap_put(arg_disks, d->uuid, d); if (r < 0) { free(d->uuid); - free(d); - return NULL; + return mfree(d); } } diff --git a/src/import/curl-util.c b/src/import/curl-util.c index 6990c47f48..734e1560e6 100644 --- a/src/import/curl-util.c +++ b/src/import/curl-util.c @@ -235,9 +235,7 @@ CurlGlue *curl_glue_unref(CurlGlue *g) { sd_event_source_unref(g->timer); sd_event_unref(g->event); - free(g); - - return NULL; + return mfree(g); } int curl_glue_new(CurlGlue **glue, sd_event *event) { diff --git a/src/import/export-raw.c b/src/import/export-raw.c index 6136b677dd..a3dbce1954 100644 --- a/src/import/export-raw.c +++ b/src/import/export-raw.c @@ -87,9 +87,7 @@ RawExport *raw_export_unref(RawExport *e) { free(e->buffer); free(e->path); - free(e); - - return NULL; + return mfree(e); } int raw_export_new( diff --git a/src/import/export-tar.c b/src/import/export-tar.c index d79c27f2d0..3bb6027431 100644 --- a/src/import/export-tar.c +++ b/src/import/export-tar.c @@ -91,9 +91,7 @@ TarExport *tar_export_unref(TarExport *e) { free(e->buffer); free(e->path); - free(e); - - return NULL; + return mfree(e); } int tar_export_new( diff --git a/src/import/import-raw.c b/src/import/import-raw.c index fd6b9f7703..29f3f896e5 100644 --- a/src/import/import-raw.c +++ b/src/import/import-raw.c @@ -100,9 +100,7 @@ RawImport* raw_import_unref(RawImport *i) { free(i->final_path); free(i->image_root); free(i->local); - free(i); - - return NULL; + return mfree(i); } int raw_import_new( diff --git a/src/import/import-tar.c b/src/import/import-tar.c index 8b81324fde..22f9b8c5ea 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -107,9 +107,7 @@ TarImport* tar_import_unref(TarImport *i) { free(i->final_path); free(i->image_root); free(i->local); - free(i); - - return NULL; + return mfree(i); } int tar_import_new( diff --git a/src/import/importd.c b/src/import/importd.c index 28b4302cb3..9d31a956a5 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -141,8 +141,7 @@ static Transfer *transfer_unref(Transfer *t) { safe_close(t->stdin_fd); safe_close(t->stdout_fd); - free(t); - return NULL; + return mfree(t); } DEFINE_TRIVIAL_CLEANUP_FUNC(Transfer*, transfer_unref); @@ -548,8 +547,7 @@ static Manager *manager_unref(Manager *m) { m->bus = sd_bus_flush_close_unref(m->bus); sd_event_unref(m->event); - free(m); - return NULL; + return mfree(m); } DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref); diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 6bcf35ef4e..e550df2c57 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -50,9 +50,7 @@ PullJob* pull_job_unref(PullJob *j) { free(j->payload); free(j->checksum); - free(j); - - return NULL; + return mfree(j); } static void pull_job_finish(PullJob *j, int ret) { diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c index 8993402821..0cf410a5d9 100644 --- a/src/import/pull-raw.c +++ b/src/import/pull-raw.c @@ -110,9 +110,7 @@ RawPull* raw_pull_unref(RawPull *i) { free(i->settings_path); free(i->image_root); free(i->local); - free(i); - - return NULL; + return mfree(i); } int raw_pull_new( diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c index 8c61c46f73..68e2397b02 100644 --- a/src/import/pull-tar.c +++ b/src/import/pull-tar.c @@ -114,9 +114,7 @@ TarPull* tar_pull_unref(TarPull *i) { free(i->settings_path); free(i->image_root); free(i->local); - free(i); - - return NULL; + return mfree(i); } int tar_pull_new( diff --git a/src/journal-remote/journal-remote-write.c b/src/journal-remote/journal-remote-write.c index 7bba52566e..8729372aa3 100644 --- a/src/journal-remote/journal-remote-write.c +++ b/src/journal-remote/journal-remote-write.c @@ -75,10 +75,8 @@ Writer* writer_new(RemoteServer *server) { memset(&w->metrics, 0xFF, sizeof(w->metrics)); w->mmap = mmap_cache_new(); - if (!w->mmap) { - free(w); - return NULL; - } + if (!w->mmap) + return mfree(w); w->n_ref = 1; w->server = server; @@ -103,9 +101,7 @@ Writer* writer_free(Writer *w) { if (w->mmap) mmap_cache_unref(w->mmap); - free(w); - - return NULL; + return mfree(w); } Writer* writer_unref(Writer *w) { diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 49199b269f..d3e0214731 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -394,8 +394,7 @@ JournalFile* journal_file_close(JournalFile *f) { gcry_md_close(f->hmac); #endif - free(f); - return NULL; + return mfree(f); } void journal_file_close_set(Set *s) { diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c index 293d27053a..d91247b524 100644 --- a/src/journal/mmap-cache.c +++ b/src/journal/mmap-cache.c @@ -325,10 +325,8 @@ static FileDescriptor* fd_add(MMapCache *m, int fd) { f->fd = fd; r = hashmap_put(m->fds, FD_TO_PTR(fd), f); - if (r < 0) { - free(f); - return NULL; - } + if (r < 0) + return mfree(f); return f; } diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 98c8a47afe..f2f8546086 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -387,7 +387,7 @@ _public_ int sd_journal_add_disjunction(sd_journal *j) { } static char *match_make_string(Match *m) { - char *p, *r; + char *p = NULL, *r; Match *i; bool enclose = false; @@ -397,15 +397,12 @@ static char *match_make_string(Match *m) { if (m->type == MATCH_DISCRETE) return strndup(m->data, m->size); - p = NULL; LIST_FOREACH(matches, i, m->matches) { char *t, *k; t = match_make_string(i); - if (!t) { - free(p); - return NULL; - } + if (!t) + return mfree(p); if (p) { k = strjoin(p, m->type == MATCH_OR_TERM ? " OR " : " AND ", t, NULL); diff --git a/src/libsystemd-network/ndisc-router.c b/src/libsystemd-network/ndisc-router.c index d9950b638c..41ff2b353a 100644 --- a/src/libsystemd-network/ndisc-router.c +++ b/src/libsystemd-network/ndisc-router.c @@ -49,8 +49,7 @@ _public_ sd_ndisc_router* sd_ndisc_router_unref(sd_ndisc_router *rt) { if (rt->n_ref > 0) return NULL; - free(rt); - return NULL; + return mfree(rt); } sd_ndisc_router *ndisc_router_new(size_t raw_size) { diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 179e5950bd..5ccb23922c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1873,9 +1873,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { free(client->req_opts); free(client->hostname); free(client->vendor_class_identifier); - free(client); - - return NULL; + return mfree(client); } int sd_dhcp_client_new(sd_dhcp_client **ret) { diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index ef50ed17a1..8387b185c0 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -282,9 +282,7 @@ sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease) { free(lease->static_route); free(lease->client_id); free(lease->vendor_specific); - free(lease); - - return NULL; + return mfree(lease); } static int lease_parse_u32(const uint8_t *option, size_t len, uint32_t *ret, uint32_t min) { diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 11ee2e252e..f16314a37f 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -178,9 +178,7 @@ sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) { hashmap_free(server->leases_by_client_id); free(server->bound_leases); - free(server); - - return NULL; + return mfree(server); } int sd_dhcp_server_new(sd_dhcp_server **ret, int ifindex) { diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 463fde401c..e81215f7d7 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1300,9 +1300,7 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) { sd_dhcp6_client_detach_event(client); free(client->req_opts); - free(client); - - return NULL; + return mfree(client); } int sd_dhcp6_client_new(sd_dhcp6_client **ret) { diff --git a/src/libsystemd-network/sd-dhcp6-lease.c b/src/libsystemd-network/sd-dhcp6-lease.c index 5c10a6326a..ab59977a3f 100644 --- a/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/libsystemd-network/sd-dhcp6-lease.c @@ -389,9 +389,7 @@ sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) { free(lease->ntp); lease->ntp_fqdn = strv_free(lease->ntp_fqdn); - free(lease); - - return NULL; + return mfree(lease); } int dhcp6_lease_new(sd_dhcp6_lease **ret) { diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 662885840f..4dd343c101 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -135,9 +135,7 @@ sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd) { ipv4acd_reset(acd); sd_ipv4acd_detach_event(acd); - free(acd); - - return NULL; + return mfree(acd); } int sd_ipv4acd_new(sd_ipv4acd **ret) { diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c index 5603a533a5..13209261f9 100644 --- a/src/libsystemd-network/sd-ipv4ll.c +++ b/src/libsystemd-network/sd-ipv4ll.c @@ -90,9 +90,7 @@ sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) { return NULL; sd_ipv4acd_unref(ll->acd); - free(ll); - - return NULL; + return mfree(ll); } int sd_ipv4ll_new(sd_ipv4ll **ret) { diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index 0bd1e66aa0..0702241506 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -374,9 +374,7 @@ _public_ sd_lldp* sd_lldp_unref(sd_lldp *lldp) { hashmap_free(lldp->neighbor_by_id); prioq_free(lldp->neighbor_by_expiry); - free(lldp); - - return NULL; + return mfree(lldp); } _public_ int sd_lldp_new(sd_lldp **ret) { diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 07b0d7f704..1d3be9b862 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -148,9 +148,7 @@ _public_ sd_ndisc *sd_ndisc_unref(sd_ndisc *nd) { ndisc_reset(nd); sd_ndisc_detach_event(nd); - free(nd); - - return NULL; + return mfree(nd); } _public_ int sd_ndisc_new(sd_ndisc **ret) { diff --git a/src/libsystemd/sd-bus/bus-slot.c b/src/libsystemd/sd-bus/bus-slot.c index 8e9074c7df..33590c31ac 100644 --- a/src/libsystemd/sd-bus/bus-slot.c +++ b/src/libsystemd/sd-bus/bus-slot.c @@ -212,9 +212,7 @@ _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) { bus_slot_disconnect(slot); free(slot->description); - free(slot); - - return NULL; + return mfree(slot); } _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) { diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c index 00e93a215f..4acaf24793 100644 --- a/src/libsystemd/sd-bus/bus-track.c +++ b/src/libsystemd/sd-bus/bus-track.c @@ -74,9 +74,7 @@ static struct track_item* track_item_free(struct track_item *i) { sd_bus_slot_unref(i->slot); free(i->name); - free(i); - - return NULL; + return mfree(i); } DEFINE_TRIVIAL_CLEANUP_FUNC(struct track_item*, track_item_free); @@ -206,9 +204,7 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { bus_track_remove_from_queue(track); hashmap_free(track->names); sd_bus_unref(track->bus); - free(track); - - return NULL; + return mfree(track); } static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) { diff --git a/src/libudev/libudev-list.c b/src/libudev/libudev-list.c index da496ed456..0d51322a15 100644 --- a/src/libudev/libudev-list.c +++ b/src/libudev/libudev-list.c @@ -166,17 +166,16 @@ struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char * entry = new0(struct udev_list_entry, 1); if (entry == NULL) return NULL; + entry->name = strdup(name); - if (entry->name == NULL) { - free(entry); - return NULL; - } + if (entry->name == NULL) + return mfree(entry); + if (value != NULL) { entry->value = strdup(value); if (entry->value == NULL) { free(entry->name); - free(entry); - return NULL; + return mfree(entry); } } @@ -193,8 +192,7 @@ struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char * if (entries == NULL) { free(entry->name); free(entry->value); - free(entry); - return NULL; + return mfree(entry); } list->entries = entries; list->entries_max += add; diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c index 1f9d16c450..a1f2b33ad5 100644 --- a/src/libudev/libudev-monitor.c +++ b/src/libudev/libudev-monitor.c @@ -207,8 +207,7 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c udev_monitor->sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT); if (udev_monitor->sock < 0) { log_debug_errno(errno, "error getting socket: %m"); - free(udev_monitor); - return NULL; + return mfree(udev_monitor); } } else { udev_monitor->bound = true; diff --git a/src/login/logind-button.c b/src/login/logind-button.c index baa6b7113c..90fb93bbaf 100644 --- a/src/login/logind-button.c +++ b/src/login/logind-button.c @@ -43,15 +43,12 @@ Button* button_new(Manager *m, const char *name) { return NULL; b->name = strdup(name); - if (!b->name) { - free(b); - return NULL; - } + if (!b->name) + return mfree(b); if (hashmap_put(m->buttons, b->name, b) < 0) { free(b->name); - free(b); - return NULL; + return mfree(b); } b->manager = m; diff --git a/src/login/logind-device.c b/src/login/logind-device.c index eb5edd1cd5..6537fa04bf 100644 --- a/src/login/logind-device.c +++ b/src/login/logind-device.c @@ -34,15 +34,12 @@ Device* device_new(Manager *m, const char *sysfs, bool master) { return NULL; d->sysfs = strdup(sysfs); - if (!d->sysfs) { - free(d); - return NULL; - } + if (!d->sysfs) + return mfree(d); if (hashmap_put(m->devices, d->sysfs, d) < 0) { free(d->sysfs); - free(d); - return NULL; + return mfree(d); } d->manager = m; diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c index 6c78e0dddc..c93b24009b 100644 --- a/src/login/logind-inhibit.c +++ b/src/login/logind-inhibit.c @@ -45,17 +45,14 @@ Inhibitor* inhibitor_new(Manager *m, const char* id) { return NULL; i->state_file = strappend("/run/systemd/inhibit/", id); - if (!i->state_file) { - free(i); - return NULL; - } + if (!i->state_file) + return mfree(i); i->id = basename(i->state_file); if (hashmap_put(m->inhibitors, i->id, i) < 0) { free(i->state_file); - free(i); - return NULL; + return mfree(i); } i->manager = m; diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index b5192320e4..ecc7bd2e5b 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -48,18 +48,15 @@ Seat *seat_new(Manager *m, const char *id) { return NULL; s->state_file = strappend("/run/systemd/seats/", id); - if (!s->state_file) { - free(s); - return NULL; - } + if (!s->state_file) + return mfree(s); s->id = basename(s->state_file); s->manager = m; if (hashmap_put(m->seats, s->id, s) < 0) { free(s->state_file); - free(s); - return NULL; + return mfree(s); } return s; diff --git a/src/login/logind-session.c b/src/login/logind-session.c index ba1bcc2630..cbf035f706 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -62,16 +62,13 @@ Session* session_new(Manager *m, const char *id) { return NULL; s->state_file = strappend("/run/systemd/sessions/", id); - if (!s->state_file) { - free(s); - return NULL; - } + if (!s->state_file) + return mfree(s); s->devices = hashmap_new(&devt_hash_ops); if (!s->devices) { free(s->state_file); - free(s); - return NULL; + return mfree(s); } s->id = basename(s->state_file); @@ -79,8 +76,7 @@ Session* session_new(Manager *m, const char *id) { if (hashmap_put(m->sessions, s->id, s) < 0) { hashmap_free(s->devices); free(s->state_file); - free(s); - return NULL; + return mfree(s); } s->manager = m; diff --git a/src/machine/machine.c b/src/machine/machine.c index dd046d6563..a02b9d7575 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -80,9 +80,7 @@ Machine* machine_new(Manager *manager, MachineClass class, const char *name) { fail: free(m->state_file); free(m->name); - free(m); - - return NULL; + return mfree(m); } void machine_free(Machine *m) { diff --git a/src/machine/operation.c b/src/machine/operation.c index 2bf93cb493..c966d0d21c 100644 --- a/src/machine/operation.c +++ b/src/machine/operation.c @@ -147,6 +147,5 @@ Operation *operation_free(Operation *o) { if (o->machine) LIST_REMOVE(operations_by_machine, o->machine->operations, o); - free(o); - return NULL; + return mfree(o); } diff --git a/src/network/networkd-wait-online-link.c b/src/network/networkd-wait-online-link.c index 5727422e3d..e63ba07e90 100644 --- a/src/network/networkd-wait-online-link.c +++ b/src/network/networkd-wait-online-link.c @@ -77,8 +77,7 @@ Link *link_free(Link *l) { } free(l->ifname); - free(l); - return NULL; + return mfree(l); } int link_update_rtnl(Link *l, sd_netlink_message *m) { diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c index 5f1522cfb6..09c8f070ba 100644 --- a/src/nspawn/nspawn-settings.c +++ b/src/nspawn/nspawn-settings.c @@ -101,9 +101,7 @@ Settings* settings_free(Settings *s) { expose_port_free_all(s->expose_ports); custom_mount_free_all(s->custom_mounts, s->n_custom_mounts); - free(s); - - return NULL; + return mfree(s); } bool settings_private_network(Settings *s) { diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c index 53be18efc6..e03db4d003 100644 --- a/src/resolve/resolved-dns-query.c +++ b/src/resolve/resolved-dns-query.c @@ -83,9 +83,7 @@ DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) { if (c->scope) LIST_REMOVE(candidates_by_scope, c->scope->query_candidates, c); - free(c); - - return NULL; + return mfree(c); } static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) { @@ -421,9 +419,7 @@ DnsQuery *dns_query_free(DnsQuery *q) { q->manager->n_dns_queries--; } - free(q); - - return NULL; + return mfree(q); } int dns_query_new( diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 5687588a7d..87e4abec6e 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -73,10 +73,8 @@ DnsResourceKey* dns_resource_key_new_redirect(const DnsResourceKey *key, const D return dns_resource_key_ref((DnsResourceKey*) key); k = dns_resource_key_new_consume(key->class, key->type, destination); - if (!k) { - free(destination); - return NULL; - } + if (!k) + return mfree(destination); return k; } @@ -513,9 +511,7 @@ DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) { } free(rr->to_string); - free(rr); - - return NULL; + return mfree(rr); } int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) { diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c index 03811ac8e7..8dbc7f623b 100644 --- a/src/resolve/resolved-dns-scope.c +++ b/src/resolve/resolved-dns-scope.c @@ -128,9 +128,7 @@ DnsScope* dns_scope_free(DnsScope *s) { dns_zone_flush(&s->zone); LIST_REMOVE(scopes, s->manager->dns_scopes, s); - free(s); - - return NULL; + return mfree(s); } DnsServer *dns_scope_get_dns_server(DnsScope *s) { diff --git a/src/resolve/resolved-dns-search-domain.c b/src/resolve/resolved-dns-search-domain.c index 732471027b..1386e6a17b 100644 --- a/src/resolve/resolved-dns-search-domain.c +++ b/src/resolve/resolved-dns-search-domain.c @@ -104,9 +104,7 @@ DnsSearchDomain* dns_search_domain_unref(DnsSearchDomain *d) { return NULL; free(d->name); - free(d); - - return NULL; + return mfree(d); } void dns_search_domain_unlink(DnsSearchDomain *d) { diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index 97cc8c0e09..7282848e35 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -139,8 +139,7 @@ DnsServer* dns_server_unref(DnsServer *s) { return NULL; free(s->server_string); - free(s); - return NULL; + return mfree(s); } void dns_server_unlink(DnsServer *s) { diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c index dd0e0b90e3..878bae47dc 100644 --- a/src/resolve/resolved-dns-stream.c +++ b/src/resolve/resolved-dns-stream.c @@ -343,9 +343,7 @@ DnsStream *dns_stream_unref(DnsStream *s) { dns_packet_unref(s->write_packet); dns_packet_unref(s->read_packet); - free(s); - - return NULL; + return mfree(s); } DEFINE_TRIVIAL_CLEANUP_FUNC(DnsStream*, dns_stream_unref); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index d455b6b1fa..2fce44ec8b 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -134,8 +134,7 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) { dns_answer_unref(t->validated_keys); dns_resource_key_unref(t->key); - free(t); - return NULL; + return mfree(t); } DEFINE_TRIVIAL_CLEANUP_FUNC(DnsTransaction*, dns_transaction_free); diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index ea4a007139..13e1f91192 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -101,8 +101,7 @@ Link *link_free(Link *l) { free(l->state_file); - free(l); - return NULL; + return mfree(l); } void link_allocate_scopes(Link *l) { @@ -698,8 +697,7 @@ LinkAddress *link_address_free(LinkAddress *a) { dns_resource_record_unref(a->llmnr_address_rr); dns_resource_record_unref(a->llmnr_ptr_rr); - free(a); - return NULL; + return mfree(a); } void link_address_add_rrs(LinkAddress *a, bool force_remove) { diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 40f08e8044..0954641c20 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -630,9 +630,7 @@ Manager *manager_free(Manager *m) { dns_trust_anchor_flush(&m->trust_anchor); manager_etc_hosts_flush(m); - free(m); - - return NULL; + return mfree(m); } int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c index 529d89ee2a..060f8d50c7 100644 --- a/src/shared/machine-image.c +++ b/src/shared/machine-image.c @@ -62,8 +62,7 @@ Image *image_unref(Image *i) { free(i->name); free(i->path); - free(i); - return NULL; + return mfree(i); } static char **image_settings_path(Image *image) { diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c index 24055e772b..293c6673fc 100644 --- a/src/shared/ptyfwd.c +++ b/src/shared/ptyfwd.c @@ -463,8 +463,7 @@ int pty_forward_new( PTYForward *pty_forward_free(PTYForward *f) { pty_forward_disconnect(f); - free(f); - return NULL; + return mfree(f); } int pty_forward_get_last_char(PTYForward *f, char *ch) { diff --git a/src/timesync/timesyncd-server.c b/src/timesync/timesyncd-server.c index 6bda86fe6e..57a7bf2c25 100644 --- a/src/timesync/timesyncd-server.c +++ b/src/timesync/timesyncd-server.c @@ -61,8 +61,7 @@ ServerAddress* server_address_free(ServerAddress *a) { manager_set_server_address(a->name->manager, NULL); } - free(a); - return NULL; + return mfree(a); } int server_name_new( @@ -137,9 +136,7 @@ ServerName *server_name_free(ServerName *n) { log_debug("Removed server %s.", n->string); free(n->string); - free(n); - - return NULL; + return mfree(n); } void server_name_flush_addresses(ServerName *n) { diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index f68a09d7a8..7717ac7924 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -211,8 +211,7 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { err: if (conn->sock >= 0) close(conn->sock); - free(conn); - return NULL; + return mfree(conn); } struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn) { diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 26fa52cf6c..7619c8371b 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1583,8 +1583,7 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules) { strbuf_cleanup(rules->strbuf); free(rules->uids); free(rules->gids); - free(rules); - return NULL; + return mfree(rules); } bool udev_rules_check_timestamp(struct udev_rules *rules) { -- cgit v1.2.3-54-g00ecf From 59f62519f17d7f2da81a9abcc4002497d97c7fa8 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Tue, 18 Oct 2016 08:49:08 +0530 Subject: networkd: use proper cast to access VTI6 (#4399) Fixes #4371. --- src/network/networkd-netdev-tunnel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c index 77a4734df8..9138ee4511 100644 --- a/src/network/networkd-netdev-tunnel.c +++ b/src/network/networkd-netdev-tunnel.c @@ -201,12 +201,18 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl } static int netdev_vti_fill_message_key(NetDev *netdev, Link *link, sd_netlink_message *m) { - Tunnel *t = VTI(netdev); uint32_t ikey, okey; + Tunnel *t; int r; assert(link); assert(m); + + if (netdev->kind == NETDEV_KIND_VTI) + t = VTI(netdev); + else + t = VTI6(netdev); + assert(t); if (t->key != 0) -- cgit v1.2.3-54-g00ecf From 75e2089581100ba0ae76d9e5f5dd82ae1cbc6c14 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Fri, 21 Oct 2016 02:17:16 -0400 Subject: Revert "add networkd dbus lease info" (#4435) --- src/network/networkd-link-bus.c | 131 ---------------------------------------- src/network/networkd-link.h | 5 -- src/network/networkd-manager.c | 8 --- 3 files changed, 144 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 10ec08351a..532557ed6c 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -23,7 +23,6 @@ #include "networkd.h" #include "parse-util.h" #include "strv.h" -#include "dhcp-lease-internal.h" static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState); static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState); @@ -37,50 +36,6 @@ const sd_bus_vtable link_vtable[] = { SD_BUS_VTABLE_END }; -static int get_private_options(sd_bus *bus, - const char *path, - const char *interface, - const char *property, - sd_bus_message *reply, - void *userdata, - sd_bus_error *error) { - sd_dhcp_lease *lease = userdata; - struct sd_dhcp_raw_option *option = NULL; - int r; - - assert(bus); - assert(reply); - assert(lease); - - r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "{yay}"); - if (r < 0) - return r; - - LIST_FOREACH(options, option, lease->private_options) { - r = sd_bus_message_open_container(reply, SD_BUS_TYPE_DICT_ENTRY, "yay"); - if (r < 0) - return r; - r = sd_bus_message_append(reply, "y", option->tag); - if (r < 0) - return r; - r = sd_bus_message_append_array(reply, 'y', option->data, option->length); - if (r < 0) - return r; - r = sd_bus_message_close_container(reply); - if (r < 0) - return r; - } - return sd_bus_message_close_container(reply); -} - -const sd_bus_vtable lease_vtable[] = { - SD_BUS_VTABLE_START(0), - - SD_BUS_PROPERTY("PrivateOptions", "a{yay}", get_private_options, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - - SD_BUS_VTABLE_END -}; - static char *link_bus_path(Link *link) { _cleanup_free_ char *ifindex = NULL; char *p; @@ -99,24 +54,6 @@ static char *link_bus_path(Link *link) { return p; } -static char *lease_bus_path(Link *link) { - _cleanup_free_ char *p = NULL; - char *ret = NULL; - int r; - - assert(link); - - p = link_bus_path(link); - if (!p) - return NULL; - - r = sd_bus_path_encode(p, "lease", &ret); - if (r < 0) - return NULL; - - return ret; -} - int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { _cleanup_strv_free_ char **l = NULL; Manager *m = userdata; @@ -150,42 +87,6 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** return 1; } -int lease_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) { - _cleanup_strv_free_ char **l = NULL; - Manager *m = userdata; - unsigned c = 0; - Link *link; - Iterator i; - - assert(bus); - assert(path); - assert(m); - assert(nodes); - - l = new0(char*, hashmap_size(m->links) + 1); - if (!l) - return -ENOMEM; - - HASHMAP_FOREACH(link, m->links, i) { - char *p; - - if (!link->dhcp_lease) - continue; - - p = lease_bus_path(link); - if (!p) - return -ENOMEM; - - l[c++] = p; - } - - l[c] = NULL; - *nodes = l; - l = NULL; - - return 1; -} - int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { _cleanup_free_ char *identifier = NULL; Manager *m = userdata; @@ -215,38 +116,6 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void return 1; } -int lease_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) { - _cleanup_free_ char *identifier = NULL; - Manager *m = userdata; - Link *link; - int ifindex, r; - - assert(bus); - assert(path); - assert(interface); - assert(m); - assert(found); - - r = sd_bus_path_decode_many(path, "/org/freedesktop/network1/link/%/lease", &identifier); - if (r <= 0) - return 0; - - r = parse_ifindex(identifier, &ifindex); - if (r < 0) - return 0; - - r = link_get(m, ifindex, &link); - if (r < 0) - return 0; - - if (!link->dhcp_lease) - return 0; - - *found = link->dhcp_lease; - - return 1; -} - int link_send_changed(Link *link, const char *property, ...) { _cleanup_free_ char *p = NULL; char **l; diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index 1178999bb4..77f72d070e 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -179,11 +179,6 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char *** int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); int link_send_changed(Link *link, const char *property, ...) _sentinel_; -extern const sd_bus_vtable lease_vtable[]; - -int lease_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error); -int lease_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error); - DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); #define _cleanup_link_unref_ _cleanup_(link_unrefp) diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 0ad34e0cc2..9174dcc7f4 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -176,14 +176,6 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add link enumerator: %m"); - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link.Lease", lease_vtable, lease_object_find, m); - if (r < 0) - return log_error_errno(r, "Failed to add lease object vtable: %m"); - - r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", lease_node_enumerator, m); - if (r < 0) - return log_error_errno(r, "Failed to add lease enumerator: %m"); - r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m); if (r < 0) return log_error_errno(r, "Failed to add network object vtable: %m"); -- cgit v1.2.3-54-g00ecf From 6d7c761572a1a7630512c31ad8277728a7eadcb4 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Mon, 24 Oct 2016 14:44:01 +0300 Subject: networkd-ndisc: Don't add NDisc route for local address (#4467) When systemd-networkd is run on the same IPv6 enabled interface where radvd is announcing prefixes, a route is being set up pointing to the interface address. As this will fail with an invalid argument error, the link is marked as failed and the following message like the following will appear in in the logs: systemd-networkd[21459]: eth1: Could not set NDisc route or address: Invalid argument systemd-networkd[21459]: eth1: Failed Should the interface be required by systemd-networkd-wait-online, network-online.target will wait until its timeout hits thereby significantly delaying system startup. The fix is to check whether the gateway address obtained from NDisc messages is equal to any of the interface addresses on the same link and not set the NDisc route in that case. --- src/network/networkd-ndisc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/network') diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index c2b7970623..b282634e4b 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -57,6 +57,8 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { unsigned preference; usec_t time_now; int r; + Address *address; + Iterator i; assert(link); assert(rt); @@ -75,6 +77,32 @@ static void ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { return; } + SET_FOREACH(address, link->addresses, i) { + if (!memcmp(&gateway, &address->in_addr.in6, + sizeof(address->in_addr.in6))) { + char buffer[INET6_ADDRSTRLEN]; + + log_link_debug(link, "No NDisc route added, gateway %s matches local address", + inet_ntop(AF_INET6, + &address->in_addr.in6, + buffer, sizeof(buffer))); + return; + } + } + + SET_FOREACH(address, link->addresses_foreign, i) { + if (!memcmp(&gateway, &address->in_addr.in6, + sizeof(address->in_addr.in6))) { + char buffer[INET6_ADDRSTRLEN]; + + log_link_debug(link, "No NDisc route added, gateway %s matches local address", + inet_ntop(AF_INET6, + &address->in_addr.in6, + buffer, sizeof(buffer))); + return; + } + } + r = sd_ndisc_router_get_preference(rt, &preference); if (r < 0) { log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m"); -- cgit v1.2.3-54-g00ecf From e59ace18a5982b1b6bb3de244abdb924f1abbf70 Mon Sep 17 00:00:00 2001 From: Benjamin Richter Date: Mon, 24 Oct 2016 21:24:47 +0200 Subject: networkd: fix mixup of bond options (#4470) --- src/network/networkd-netdev-bond.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c index 7913b0088e..46d1669337 100644 --- a/src/network/networkd-netdev-bond.c +++ b/src/network/networkd-netdev-bond.c @@ -268,13 +268,13 @@ static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_netlin if (b->arp_all_targets != _NETDEV_BOND_ARP_ALL_TARGETS_INVALID) { r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->arp_all_targets); if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_VALIDATE attribute: %m"); + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m"); } if (b->primary_reselect != _NETDEV_BOND_PRIMARY_RESELECT_INVALID) { - r = sd_netlink_message_append_u32(m, IFLA_BOND_ARP_ALL_TARGETS, b->primary_reselect); + r = sd_netlink_message_append_u8(m, IFLA_BOND_PRIMARY_RESELECT, b->primary_reselect); if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_ARP_ALL_TARGETS attribute: %m"); + return log_netdev_error_errno(netdev, r, "Could not append IFLA_BOND_PRIMARY_RESELECT attribute: %m"); } if (b->resend_igmp <= RESEND_IGMP_MAX) { -- cgit v1.2.3-54-g00ecf From 532538244028ca90e9a7c59ec9627a3ff17a7da8 Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Thu, 27 Oct 2016 05:01:04 +0530 Subject: networkd : verify dns ip address when parsing configuration (#4492) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Invalid IP addresses would be passed through as-is: $ networkctl status wlp3s0: ● 2: wlp3s0 Link File: /usr/lib/systemd/network/99-default.link Network File: /etc/systemd/network/wlp3s0.network Type: wlan State: routable (configured) Path: pci-0000:03:00.0 Driver: iwlwifi Vendor: Intel Corporation Model: Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN) HW Address: XXXXXXXXXX (Intel Corporate) Address: 192.168.2.103 XXXXXXXXXXX Gateway: 192.168.2.1 (Arcadyan Technology Corporation) DNS: 127.0.0.5553 Instead verify that DNS= has a valid list of addresses when parsing configuration. Fixes #4462. --- src/network/networkd-network-gperf.gperf | 2 +- src/network/networkd-network.c | 50 ++++++++++++++++++++++++++++++++ src/network/networkd-network.h | 1 + 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 5587961b9f..bcf8186c33 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -49,7 +49,7 @@ Network.EmitLLDP, config_parse_lldp_emit, Network.Address, config_parse_address, 0, 0 Network.Gateway, config_parse_gateway, 0, 0 Network.Domains, config_parse_domains, 0, 0 -Network.DNS, config_parse_strv, 0, offsetof(Network, dns) +Network.DNS, config_parse_dns, 0, 0 Network.LLMNR, config_parse_resolve_support, 0, offsetof(Network, llmnr) Network.MulticastDNS, config_parse_resolve_support, 0, offsetof(Network, mdns) Network.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Network, dnssec_mode) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 584cb96979..042232fcac 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -979,6 +979,56 @@ int config_parse_dhcp_server_ntp( } } +int config_parse_dns( + 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) { + + Network *n = userdata; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + for (;;) { + _cleanup_free_ char *w = NULL; + union in_addr_union a; + int family; + + r = extract_first_word(&rvalue, &w, WHITESPACE, EXTRACT_QUOTES|EXTRACT_RETAIN_ESCAPE); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); + break; + } + + r = in_addr_from_string_auto(w, &family, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse dns server address, ignoring: %s", w); + continue; + } + + r = strv_consume(&n->dns, w); + if (r < 0) + return log_oom(); + + w = NULL; + } + + return 0; +} + int config_parse_dnssec_negative_trust_anchors( const char *unit, const char *filename, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index ef4b499ab9..42fc82d392 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -220,6 +220,7 @@ int config_parse_netdev(const char *unit, const char *filename, unsigned line, c int config_parse_domains(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); int config_parse_tunnel(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); int config_parse_dhcp(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); +int config_parse_dns(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); int config_parse_dhcp_client_identifier(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); int config_parse_ipv6token(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); int config_parse_ipv6_privacy_extensions(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); -- cgit v1.2.3-54-g00ecf From 02affb4e6a16fbec9d6d28265c220ca95479bbd0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 25 Oct 2016 12:08:24 +0200 Subject: netword: minor memory leak fix --- src/network/networkd-ndisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index b282634e4b..6ce6bfa787 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -680,13 +680,13 @@ void ndisc_vacuum(Link *link) { SET_FOREACH(r, link->ndisc_rdnss, i) if (r->valid_until < time_now) { - (void) set_remove(link->ndisc_rdnss, r); + free(set_remove(link->ndisc_rdnss, r)); link_dirty(link); } SET_FOREACH(d, link->ndisc_dnssl, i) if (d->valid_until < time_now) { - (void) set_remove(link->ndisc_dnssl, d); + free(set_remove(link->ndisc_dnssl, d)); link_dirty(link); } } -- cgit v1.2.3-54-g00ecf From c69305ff4fe5a182cd58b66077f3db7bc7c222e1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 25 Oct 2016 12:08:43 +0200 Subject: networkd: flush DNSSL/RDNSS lists when we lose carrier Fixes: #3870 --- src/network/networkd-link.c | 7 ++++--- src/network/networkd-ndisc.c | 9 +++++++++ src/network/networkd-ndisc.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/network') diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index d9e060b6cf..aefe7335b9 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -514,13 +514,12 @@ static void link_free(Link *link) { sd_lldp_unref(link->lldp); free(link->lldp_file); + ndisc_flush(link); + sd_ipv4ll_unref(link->ipv4ll); sd_dhcp6_client_unref(link->dhcp6_client); sd_ndisc_unref(link->ndisc); - set_free_free(link->ndisc_rdnss); - set_free_free(link->ndisc_dnssl); - if (link->manager) hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); @@ -2427,6 +2426,8 @@ static int link_drop_config(Link *link) { return r; } + ndisc_flush(link); + return 0; } diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 6ce6bfa787..4853791aa5 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -690,3 +690,12 @@ void ndisc_vacuum(Link *link) { link_dirty(link); } } + +void ndisc_flush(Link *link) { + assert(link); + + /* Removes all RDNSS and DNSSL entries, without exception */ + + link->ndisc_rdnss = set_free_free(link->ndisc_rdnss); + link->ndisc_dnssl = set_free_free(link->ndisc_dnssl); +} diff --git a/src/network/networkd-ndisc.h b/src/network/networkd-ndisc.h index 2002f55107..127126190e 100644 --- a/src/network/networkd-ndisc.h +++ b/src/network/networkd-ndisc.h @@ -37,3 +37,4 @@ static inline char* NDISC_DNSSL_DOMAIN(const NDiscDNSSL *n) { int ndisc_configure(Link *link); void ndisc_vacuum(Link *link); +void ndisc_flush(Link *link); -- cgit v1.2.3-54-g00ecf