diff options
author | Thomas Haller <thaller@redhat.com> | 2021-04-06 08:19:58 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-04-06 08:19:58 +0200 |
commit | 57b83108dc5654cab59904d7ef4872d6fe7558fa (patch) | |
tree | f722a4039a5b997e85cadcfffacb4bbb300fe6b9 | |
parent | 68913466af49c738d7e226f55db15be70b22dbe6 (diff) | |
parent | bae86ece1eca90673a9aa1cd15715444307262ff (diff) | |
download | NetworkManager-th/systemd.tar.gz |
systemd: merge branch systemd into masterth/systemd
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/799
31 files changed, 379 insertions, 235 deletions
diff --git a/Makefile.am b/Makefile.am index b7a3a04c29..db0b0a9f5d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2304,6 +2304,8 @@ src_core_libnm_systemd_core_la_SOURCES = \ src/core/systemd/src/libsystemd-network/lldp-neighbor.h \ src/core/systemd/src/libsystemd-network/lldp-network.c \ src/core/systemd/src/libsystemd-network/lldp-network.h \ + src/core/systemd/src/libsystemd-network/network-common.c \ + src/core/systemd/src/libsystemd-network/network-common.h \ src/core/systemd/src/libsystemd-network/network-internal.c \ src/core/systemd/src/libsystemd-network/network-internal.h \ src/core/systemd/src/libsystemd-network/sd-dhcp-client.c \ diff --git a/src/core/systemd/meson.build b/src/core/systemd/meson.build index 2de60776c0..c0d8a27c07 100644 --- a/src/core/systemd/meson.build +++ b/src/core/systemd/meson.build @@ -19,6 +19,7 @@ libnm_systemd_core = static_library( 'src/libsystemd-network/dhcp6-option.c', 'src/libsystemd-network/lldp-neighbor.c', 'src/libsystemd-network/lldp-network.c', + 'src/libsystemd-network/network-common.c', 'src/libsystemd-network/network-internal.c', 'src/libsystemd-network/sd-dhcp-client.c', 'src/libsystemd-network/sd-dhcp-lease.c', diff --git a/src/core/systemd/src/libsystemd-network/dhcp-internal.h b/src/core/systemd/src/libsystemd-network/dhcp-internal.h index 40e6b1f26f..c5c851c575 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp-internal.h +++ b/src/core/systemd/src/libsystemd-network/dhcp-internal.h @@ -12,6 +12,7 @@ #include "sd-dhcp-client.h" #include "dhcp-protocol.h" +#include "log-link.h" #include "socket-util.h" typedef struct sd_dhcp_option { @@ -65,5 +66,15 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, ui #define DHCP_CLIENT_DONT_DESTROY(client) \ _cleanup_(sd_dhcp_client_unrefp) _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client) -#define log_dhcp_client_errno(client, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) -#define log_dhcp_client(client, fmt, ...) log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) +#define log_dhcp_client_errno(client, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_dhcp_client_get_ifname(client), \ + LOG_DEBUG, _e, "DHCPv4 client: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_dhcp_client(client, fmt, ...) \ + log_dhcp_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/dhcp6-internal.h b/src/core/systemd/src/libsystemd-network/dhcp6-internal.h index 681c462315..274b14b056 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp6-internal.h +++ b/src/core/systemd/src/libsystemd-network/dhcp6-internal.h @@ -9,9 +9,11 @@ #include <netinet/in.h> #include "sd-event.h" +#include "sd-dhcp6-client.h" -#include "list.h" #include "hashmap.h" +#include "list.h" +#include "log-link.h" #include "macro.h" #include "sparse-endian.h" @@ -78,7 +80,7 @@ struct ia_ta { be32_t id; } _packed_; -struct DHCP6IA { +typedef struct DHCP6IA { uint16_t type; union { struct ia_na ia_na; @@ -87,12 +89,7 @@ struct DHCP6IA { }; LIST_HEAD(DHCP6Address, addresses); -}; - -typedef struct DHCP6IA DHCP6IA; - -#define log_dhcp6_client_errno(p, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__) -#define log_dhcp6_client(p, fmt, ...) log_dhcp6_client_errno(p, 0, fmt, ##__VA_ARGS__) +} DHCP6IA; int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code, size_t optlen, const void *optval); @@ -105,7 +102,7 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode, size_t *optlen, uint8_t **optvalue); int dhcp6_option_parse_status(DHCP6Option *option, size_t len); -int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code); +int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code); int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen, struct in6_addr **addrs, size_t count, size_t *allocated); @@ -121,3 +118,16 @@ const char *dhcp6_message_type_to_string(int s) _const_; int dhcp6_message_type_from_string(const char *s) _pure_; const char *dhcp6_message_status_to_string(int s) _const_; int dhcp6_message_status_from_string(const char *s) _pure_; + +#define log_dhcp6_client_errno(client, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_dhcp6_client_get_ifname(client), \ + LOG_DEBUG, _e, "DHCPv6 client: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_dhcp6_client(client, fmt, ...) \ + log_dhcp6_client_errno(client, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/dhcp6-option.c b/src/core/systemd/src/libsystemd-network/dhcp6-option.c index c71ef6a521..d50ce3db28 100644 --- a/src/core/systemd/src/libsystemd-network/dhcp6-option.c +++ b/src/core/systemd/src/libsystemd-network/dhcp6-option.c @@ -427,7 +427,7 @@ int dhcp6_option_parse_status(DHCP6Option *option, size_t len) { return be16toh(statusopt->status); } -static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { +static int dhcp6_option_parse_address(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { DHCP6AddressOption *addr_option = (DHCP6AddressOption *)option; DHCP6Address *addr; uint32_t lt_valid, lt_pref; @@ -439,23 +439,20 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t lt_valid = be32toh(addr_option->iaaddr.lifetime_valid); lt_pref = be32toh(addr_option->iaaddr.lifetime_preferred); - if (lt_valid == 0 || lt_pref > lt_valid) { - log_dhcp6_client(client, - "Valid lifetime of an IA address is zero or " - "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, - lt_pref, lt_valid); - return -EINVAL; - } + if (lt_valid == 0 || lt_pref > lt_valid) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Valid lifetime of an IA address is zero or " + "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, + lt_pref, lt_valid); if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*addr_option)) { r = dhcp6_option_parse_status((DHCP6Option *)addr_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*addr_option)); if (r < 0) return r; - if (r > 0) { - log_dhcp6_client(client, "Non-zero status code '%s' for address is received", - dhcp6_message_status_to_string(r)); - return -EINVAL; - } + if (r > 0) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Non-zero status code '%s' for address is received", + dhcp6_message_status_to_string(r)); } addr = new0(DHCP6Address, 1); @@ -472,7 +469,7 @@ static int dhcp6_option_parse_address(DHCP6Option *option, DHCP6IA *ia, uint32_t return 0; } -static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { +static int dhcp6_option_parse_pdprefix(sd_dhcp6_client *client, DHCP6Option *option, DHCP6IA *ia, uint32_t *ret_lifetime_valid) { DHCP6PDPrefixOption *pdprefix_option = (DHCP6PDPrefixOption *)option; DHCP6Address *prefix; uint32_t lt_valid, lt_pref; @@ -484,23 +481,20 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_ lt_valid = be32toh(pdprefix_option->iapdprefix.lifetime_valid); lt_pref = be32toh(pdprefix_option->iapdprefix.lifetime_preferred); - if (lt_valid == 0 || lt_pref > lt_valid) { - log_dhcp6_client(client, - "Valid lifetieme of a PD prefix is zero or " - "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, - lt_pref, lt_valid); - return -EINVAL; - } + if (lt_valid == 0 || lt_pref > lt_valid) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Valid lifetieme of a PD prefix is zero or " + "preferred lifetime %"PRIu32" > valid lifetime %"PRIu32, + lt_pref, lt_valid); if (be16toh(option->len) + offsetof(DHCP6Option, data) > sizeof(*pdprefix_option)) { r = dhcp6_option_parse_status((DHCP6Option *)pdprefix_option->options, be16toh(option->len) + offsetof(DHCP6Option, data) - sizeof(*pdprefix_option)); if (r < 0) return r; - if (r > 0) { - log_dhcp6_client(client, "Non-zero status code '%s' for PD prefix is received", - dhcp6_message_status_to_string(r)); - return -EINVAL; - } + if (r > 0) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "Non-zero status code '%s' for PD prefix is received", + dhcp6_message_status_to_string(r)); } prefix = new0(DHCP6Address, 1); @@ -517,7 +511,7 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia, uint32_ return 0; } -int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) { +int dhcp6_option_parse_ia(sd_dhcp6_client *client, DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) { uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX; uint16_t iatype, optlen; size_t iaaddr_offset; @@ -543,10 +537,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat lt_t1 = be32toh(ia->ia_na.lifetime_t1); lt_t2 = be32toh(ia->ia_na.lifetime_t2); - if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { - log_dhcp6_client(client, "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2); - return -EINVAL; - } + if (lt_t1 > lt_t2) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA NA T1 %"PRIu32"sec > T2 %"PRIu32"sec", + lt_t1, lt_t2); break; @@ -561,10 +555,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat lt_t1 = be32toh(ia->ia_pd.lifetime_t1); lt_t2 = be32toh(ia->ia_pd.lifetime_t2); - if (lt_t1 && lt_t2 && lt_t1 > lt_t2) { - log_dhcp6_client(client, "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", lt_t1, lt_t2); - return -EINVAL; - } + if (lt_t1 > lt_t2) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA PD T1 %"PRIu32"sec > T2 %"PRIu32"sec", + lt_t1, lt_t2); break; @@ -596,12 +590,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat switch (opt) { case SD_DHCP6_OPTION_IAADDR: - if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) { - log_dhcp6_client(client, "IA Address option not in IA NA or TA option"); - return -EINVAL; - } + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_NA, SD_DHCP6_OPTION_IA_TA)) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA Address option not in IA NA or TA option"); - r = dhcp6_option_parse_address(option, ia, <_valid); + r = dhcp6_option_parse_address(client, option, ia, <_valid); if (r < 0 && r != -EINVAL) return r; if (r >= 0 && lt_valid < lt_min) @@ -611,12 +604,11 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat case SD_DHCP6_OPTION_IA_PD_PREFIX: - if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) { - log_dhcp6_client(client, "IA PD Prefix option not in IA PD option"); - return -EINVAL; - } + if (!IN_SET(ia->type, SD_DHCP6_OPTION_IA_PD)) + return log_dhcp6_client_errno(client, SYNTHETIC_ERRNO(EINVAL), + "IA PD Prefix option not in IA PD option"); - r = dhcp6_option_parse_pdprefix(option, ia, <_valid); + r = dhcp6_option_parse_pdprefix(client, option, ia, <_valid); if (r < 0 && r != -EINVAL) return r; if (r >= 0 && lt_valid < lt_min) @@ -652,7 +644,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat switch(iatype) { case SD_DHCP6_OPTION_IA_NA: - if (!ia->ia_na.lifetime_t1 && !ia->ia_na.lifetime_t2 && lt_min != UINT32_MAX) { + if (ia->ia_na.lifetime_t1 == 0 && ia->ia_na.lifetime_t2 == 0 && lt_min != UINT32_MAX) { lt_t1 = lt_min / 2; lt_t2 = lt_min / 10 * 8; ia->ia_na.lifetime_t1 = htobe32(lt_t1); @@ -665,7 +657,7 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_stat break; case SD_DHCP6_OPTION_IA_PD: - if (!ia->ia_pd.lifetime_t1 && !ia->ia_pd.lifetime_t2 && lt_min != UINT32_MAX) { + if (ia->ia_pd.lifetime_t1 == 0 && ia->ia_pd.lifetime_t2 == 0 && lt_min != UINT32_MAX) { lt_t1 = lt_min / 2; lt_t2 = lt_min / 10 * 8; ia->ia_pd.lifetime_t1 = htobe32(lt_t1); diff --git a/src/core/systemd/src/libsystemd-network/lldp-internal.h b/src/core/systemd/src/libsystemd-network/lldp-internal.h index daedbb088f..f13555d35c 100644 --- a/src/core/systemd/src/libsystemd-network/lldp-internal.h +++ b/src/core/systemd/src/libsystemd-network/lldp-internal.h @@ -5,13 +5,14 @@ #include "sd-lldp.h" #include "hashmap.h" -#include "log.h" +#include "log-link.h" #include "prioq.h" struct sd_lldp { unsigned n_ref; int ifindex; + char *ifname; int fd; sd_event *event; @@ -32,8 +33,18 @@ struct sd_lldp { struct ether_addr filter_address; }; -#define log_lldp_errno(error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "LLDP: " fmt, ##__VA_ARGS__) -#define log_lldp(fmt, ...) log_lldp_errno(0, fmt, ##__VA_ARGS__) - const char* lldp_event_to_string(sd_lldp_event_t e) _const_; sd_lldp_event_t lldp_event_from_string(const char *s) _pure_; + +#define log_lldp_errno(lldp, error, fmt, ...) \ + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_lldp_get_ifname(lldp), \ + LOG_DEBUG, _e, "LLDP: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) +#define log_lldp(lldp, fmt, ...) \ + log_lldp_errno(lldp, 0, fmt, ##__VA_ARGS__) diff --git a/src/core/systemd/src/libsystemd-network/lldp-neighbor.c b/src/core/systemd/src/libsystemd-network/lldp-neighbor.c index 58ff0e0fbc..1b2108d8b1 100644 --- a/src/core/systemd/src/libsystemd-network/lldp-neighbor.c +++ b/src/core/systemd/src/libsystemd-network/lldp-neighbor.c @@ -114,7 +114,7 @@ sd_lldp_neighbor *lldp_neighbor_new(size_t raw_size) { return n; } -static int parse_string(char **s, const void *q, size_t n) { +static int parse_string(sd_lldp *lldp, char **s, const void *q, size_t n) { const char *p = q; char *k; @@ -122,7 +122,7 @@ static int parse_string(char **s, const void *q, size_t n) { assert(p || n == 0); if (*s) { - log_lldp("Found duplicate string, ignoring field."); + log_lldp(lldp, "Found duplicate string, ignoring field."); return 0; } @@ -135,14 +135,14 @@ static int parse_string(char **s, const void *q, size_t n) { /* Look for inner NULs */ if (memchr(p, 0, n)) { - log_lldp("Found inner NUL in string, ignoring field."); + log_lldp(lldp, "Found inner NUL in string, ignoring field."); return 0; } /* Let's escape weird chars, for security reasons */ k = cescape_length(p, n); if (!k) - return -ENOMEM; + return log_oom_debug(); free(*s); *s = k; @@ -158,27 +158,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { assert(n); - if (n->raw_size < sizeof(struct ether_header)) { - log_lldp("Received truncated packet, ignoring."); - return -EBADMSG; - } + if (n->raw_size < sizeof(struct ether_header)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received truncated packet, ignoring."); memcpy(&h, LLDP_NEIGHBOR_RAW(n), sizeof(h)); - if (h.ether_type != htobe16(ETHERTYPE_LLDP)) { - log_lldp("Received packet with wrong type, ignoring."); - return -EBADMSG; - } + if (h.ether_type != htobe16(ETHERTYPE_LLDP)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received packet with wrong type, ignoring."); if (h.ether_dhost[0] != 0x01 || h.ether_dhost[1] != 0x80 || h.ether_dhost[2] != 0xc2 || h.ether_dhost[3] != 0x00 || h.ether_dhost[4] != 0x00 || - !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) { - log_lldp("Received packet with wrong destination address, ignoring."); - return -EBADMSG; - } + !IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Received packet with wrong destination address, ignoring."); memcpy(&n->source_address, h.ether_shost, sizeof(struct ether_addr)); memcpy(&n->destination_address, h.ether_dhost, sizeof(struct ether_addr)); @@ -190,27 +187,24 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { uint8_t type; uint16_t length; - if (left < 2) { - log_lldp("TLV lacks header, ignoring."); - return -EBADMSG; - } + if (left < 2) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TLV lacks header, ignoring."); type = p[0] >> 1; length = p[1] + (((uint16_t) (p[0] & 1)) << 8); p += 2, left -= 2; - if (left < length) { - log_lldp("TLV truncated, ignoring datagram."); - return -EBADMSG; - } + if (left < length) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TLV truncated, ignoring datagram."); switch (type) { case SD_LLDP_TYPE_END: - if (length != 0) { - log_lldp("End marker TLV not zero-sized, ignoring datagram."); - return -EBADMSG; - } + if (length != 0) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "End marker TLV not zero-sized, ignoring datagram."); /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0 * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */ @@ -218,98 +212,93 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { goto end_marker; case SD_LLDP_TYPE_CHASSIS_ID: - if (length < 2 || length > 256) { /* includes the chassis subtype, hence one extra byte */ - log_lldp("Chassis ID field size out of range, ignoring datagram."); - return -EBADMSG; - } - if (n->id.chassis_id) { - log_lldp("Duplicate chassis ID field, ignoring datagram."); - return -EBADMSG; - } + if (length < 2 || length > 256) + /* includes the chassis subtype, hence one extra byte */ + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Chassis ID field size out of range, ignoring datagram."); + + if (n->id.chassis_id) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate chassis ID field, ignoring datagram."); n->id.chassis_id = memdup(p, length); if (!n->id.chassis_id) - return -ENOMEM; + return log_oom_debug(); n->id.chassis_id_size = length; break; case SD_LLDP_TYPE_PORT_ID: - if (length < 2 || length > 256) { /* includes the port subtype, hence one extra byte */ - log_lldp("Port ID field size out of range, ignoring datagram."); - return -EBADMSG; - } - if (n->id.port_id) { - log_lldp("Duplicate port ID field, ignoring datagram."); - return -EBADMSG; - } + if (length < 2 || length > 256) + /* includes the port subtype, hence one extra byte */ + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Port ID field size out of range, ignoring datagram."); + + if (n->id.port_id) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate port ID field, ignoring datagram."); n->id.port_id = memdup(p, length); if (!n->id.port_id) - return -ENOMEM; + return log_oom_debug(); n->id.port_id_size = length; break; case SD_LLDP_TYPE_TTL: - if (length != 2) { - log_lldp("TTL field has wrong size, ignoring datagram."); - return -EBADMSG; - } + if (length != 2) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "TTL field has wrong size, ignoring datagram."); - if (n->has_ttl) { - log_lldp("Duplicate TTL field, ignoring datagram."); - return -EBADMSG; - } + if (n->has_ttl) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Duplicate TTL field, ignoring datagram."); n->ttl = unaligned_read_be16(p); n->has_ttl = true; break; case SD_LLDP_TYPE_PORT_DESCRIPTION: - r = parse_string(&n->port_description, p, length); + r = parse_string(n->lldp, &n->port_description, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_NAME: - r = parse_string(&n->system_name, p, length); + r = parse_string(n->lldp, &n->system_name, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_DESCRIPTION: - r = parse_string(&n->system_description, p, length); + r = parse_string(n->lldp, &n->system_description, p, length); if (r < 0) return r; break; case SD_LLDP_TYPE_SYSTEM_CAPABILITIES: if (length != 4) - log_lldp("System capabilities field has wrong size, ignoring."); - else { - n->system_capabilities = unaligned_read_be16(p); - n->enabled_capabilities = unaligned_read_be16(p + 2); - n->has_capabilities = true; - } + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "System capabilities field has wrong size."); + n->system_capabilities = unaligned_read_be16(p); + n->enabled_capabilities = unaligned_read_be16(p + 2); + n->has_capabilities = true; break; - case SD_LLDP_TYPE_PRIVATE: { + case SD_LLDP_TYPE_PRIVATE: if (length < 4) - log_lldp("Found private TLV that is too short, ignoring."); - else { - /* RFC 8520: MUD URL */ - if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 && - p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) { - r = parse_string(&n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1, - length - 1 - sizeof(SD_LLDP_OUI_MUD)); - if (r < 0) - return r; - } + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "Found private TLV that is too short, ignoring."); + + /* RFC 8520: MUD URL */ + if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 && + p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) { + r = parse_string(n->lldp, &n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1, + length - 1 - sizeof(SD_LLDP_OUI_MUD)); + if (r < 0) + return r; } - } - break; } @@ -317,11 +306,9 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { } end_marker: - if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) { - log_lldp("One or more mandatory TLV missing in datagram. Ignoring."); - return -EBADMSG; - - } + if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) + return log_lldp_errno(n->lldp, SYNTHETIC_ERRNO(EBADMSG), + "One or more mandatory TLV missing in datagram. Ignoring."); n->rindex = sizeof(struct ether_header); diff --git a/src/core/systemd/src/libsystemd-network/network-common.c b/src/core/systemd/src/libsystemd-network/network-common.c new file mode 100644 index 0000000000..b9494c154c --- /dev/null +++ b/src/core/systemd/src/libsystemd-network/network-common.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "nm-sd-adapt-core.h" + +#include "format-util.h" +#include "network-common.h" +#include "string-util.h" + +const char *get_ifname(int ifindex, char **ifname) { + char buf[IF_NAMESIZE + 1]; + + assert(ifname); + + /* This sets ifname only when it is not set yet. */ + + if (*ifname) + return *ifname; + + if (ifindex <= 0) + return NULL; + + if (!format_ifname(ifindex, buf)) + return NULL; + + return *ifname = strdup(buf); +} diff --git a/src/core/systemd/src/libsystemd-network/network-common.h b/src/core/systemd/src/libsystemd-network/network-common.h new file mode 100644 index 0000000000..76a6c4a989 --- /dev/null +++ b/src/core/systemd/src/libsystemd-network/network-common.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +const char *get_ifname(int ifindex, char **ifname); diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c index f9875e62a7..91ef7b2c41 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -26,6 +26,7 @@ #include "hostname-util.h" #include "io-util.h" #include "memory-util.h" +#include "network-common.h" #include "random-util.h" #include "set.h" #include "sort-util.h" @@ -78,6 +79,7 @@ struct sd_dhcp_client { int event_priority; sd_event_source *timeout_resend; int ifindex; + char *ifname; int fd; uint16_t port; union sockaddr_union link; @@ -284,6 +286,23 @@ int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) { return 0; } +int sd_dhcp_client_set_ifname(sd_dhcp_client *client, const char *ifname) { + assert_return(client, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&client->ifname, ifname); +} + +const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client) { + if (!client) + return NULL; + + return get_ifname(client->ifindex, &client->ifname); +} + int sd_dhcp_client_set_mac( sd_dhcp_client *client, const uint8_t *addr, @@ -2210,6 +2229,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) { client->user_class = strv_free(client->user_class); ordered_hashmap_free(client->extra_options); ordered_hashmap_free(client->vendor_options); + free(client->ifname); return mfree(client); } diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c index e6373dab18..240d1697a3 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -27,6 +27,7 @@ #include "hexdecoct.h" #include "hostname-util.h" #include "in-addr-util.h" +#include "network-common.h" #include "random-util.h" #include "socket-util.h" #include "string-table.h" @@ -53,6 +54,7 @@ struct sd_dhcp6_client { sd_event *event; int event_priority; int ifindex; + char *ifname; DHCP6Address hint_pd_prefix; struct in6_addr local_address; uint8_t mac_addr[MAX_MAC_ADDR_LEN]; @@ -171,6 +173,23 @@ int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) { return 0; } +int sd_dhcp6_client_set_ifname(sd_dhcp6_client *client, const char *ifname) { + assert_return(client, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&client->ifname, ifname); +} + +const char *sd_dhcp6_client_get_ifname(sd_dhcp6_client *client) { + if (!client) + return NULL; + + return get_ifname(client->ifindex, &client->ifname); +} + int sd_dhcp6_client_set_local_address( sd_dhcp6_client *client, const struct in6_addr *local_address) { @@ -1182,7 +1201,7 @@ static int client_parse_message( break; } - r = dhcp6_option_parse_ia(option, &lease->ia, &ia_na_status); + r = dhcp6_option_parse_ia(client, option, &lease->ia, &ia_na_status); if (r < 0 && r != -ENOMSG) return r; @@ -1215,7 +1234,7 @@ static int client_parse_message( break; } - r = dhcp6_option_parse_ia(option, &lease->pd, &ia_pd_status); + r = dhcp6_option_parse_ia(client, option, &lease->pd, &ia_pd_status); if (r < 0 && r != -ENOMSG) return r; @@ -1797,6 +1816,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { ordered_hashmap_free(client->extra_options); strv_free(client->user_class); strv_free(client->vendor_class); + free(client->ifname); return mfree(client); } diff --git a/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c index 5792f6882d..d40fbbb727 100644 --- a/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/core/systemd/src/libsystemd-network/sd-dhcp6-lease.c @@ -208,7 +208,7 @@ int dhcp6_lease_set_dns(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) { lease->dns_count, &lease->dns_allocated); if (r < 0) - return log_dhcp6_client_errno(client, r, "Invalid DNS server option: %m"); + return r; lease->dns_count = r; @@ -323,19 +323,16 @@ int dhcp6_lease_set_sntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) if (!optlen) return 0; - if (lease->ntp || lease->ntp_fqdn) { - log_dhcp6_client(client, "NTP information already provided"); + if (lease->ntp || lease->ntp_fqdn) + return -EEXIST; - return 0; - } - - log_dhcp6_client(client, "Using deprecated SNTP information"); + /* Using deprecated SNTP information */ r = dhcp6_option_parse_ip6addrs(optval, optlen, &lease->ntp, lease->ntp_count, &lease->ntp_allocated); if (r < 0) - return log_dhcp6_client_errno(client, r, "Invalid SNTP server option: %m"); + return r; lease->ntp_count = r; diff --git a/src/core/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/core/systemd/src/libsystemd-network/sd-ipv4acd.c index dd0832957a..af83f51954 100644 --- a/src/core/systemd/src/libsystemd-network/sd-ipv4acd.c +++ b/src/core/systemd/src/libsystemd-network/sd-ipv4acd.c @@ -18,9 +18,9 @@ #include "ether-addr-util.h" #include "event-util.h" #include "fd-util.h" -#include "format-util.h" #include "in-addr-util.h" #include "log-link.h" +#include "network-common.h" #include "random-util.h" #include "siphash24.h" #include "string-table.h" @@ -58,7 +58,7 @@ struct sd_ipv4acd { int ifindex; int fd; - char ifname[IF_NAMESIZE + 1]; + char *ifname; unsigned n_iteration; unsigned n_conflict; @@ -78,7 +78,15 @@ struct sd_ipv4acd { }; #define log_ipv4acd_errno(acd, error, fmt, ...) \ - log_interface_full_errno(sd_ipv4acd_get_ifname(acd), LOG_DEBUG, error, "IPV4ACD: " fmt, ##__VA_ARGS__) + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_ipv4acd_get_ifname(acd), \ + LOG_DEBUG, _e, "IPv4ACD: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) #define log_ipv4acd(acd, fmt, ...) \ log_ipv4acd_errno(acd, 0, fmt, ##__VA_ARGS__) @@ -127,7 +135,7 @@ static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) { ipv4acd_reset(acd); sd_ipv4acd_detach_event(acd); - + free(acd->ifname); return mfree(acd); } @@ -400,16 +408,10 @@ fail: } int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int ifindex) { - char ifname[IF_NAMESIZE + 1]; - assert_return(acd, -EINVAL); assert_return(ifindex > 0, -EINVAL); assert_return(acd->state == IPV4ACD_STATE_INIT, -EBUSY); - if (!format_ifname(ifindex, ifname)) - return -ENODEV; - - strcpy(acd->ifname, ifname); acd->ifindex = ifindex; return 0; @@ -422,11 +424,21 @@ int sd_ipv4acd_get_ifindex(sd_ipv4acd *acd) { return acd->ifindex; } +int sd_ipv4acd_set_ifname(sd_ipv4acd *acd, const char *ifname) { + assert_return(acd, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&acd->ifname, ifname); +} + const char *sd_ipv4acd_get_ifname(sd_ipv4acd *acd) { if (!acd) return NULL; - return empty_to_null(acd->ifname); + return get_ifname(acd->ifindex, &acd->ifname); } int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr) { diff --git a/src/core/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/core/systemd/src/libsystemd-network/sd-ipv4ll.c index 46ecb9b07d..202700d2cb 100644 --- a/src/core/systemd/src/libsystemd-network/sd-ipv4ll.c +++ b/src/core/systemd/src/libsystemd-network/sd-ipv4ll.c @@ -52,7 +52,15 @@ struct sd_ipv4ll { }; #define log_ipv4ll_errno(ll, error, fmt, ...) \ - log_interface_full_errno(sd_ipv4ll_get_ifname(ll), LOG_DEBUG, error, "IPV4LL: " fmt, ##__VA_ARGS__) + ({ \ + int _e = (error); \ + if (DEBUG_LOGGING) \ + log_interface_full_errno( \ + sd_ipv4ll_get_ifname(ll), \ + LOG_DEBUG, _e, "IPv4LL: " fmt, \ + ##__VA_ARGS__); \ + -ERRNO_VALUE(_e); \ + }) #define log_ipv4ll(ll, fmt, ...) \ log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__) @@ -114,6 +122,13 @@ int sd_ipv4ll_get_ifindex(sd_ipv4ll *ll) { return sd_ipv4acd_get_ifindex(ll->acd); } +int sd_ipv4ll_set_ifname(sd_ipv4ll *ll, const char *ifname) { + assert_return(ll, -EINVAL); + assert_return(ifname, -EINVAL); + + return sd_ipv4acd_set_ifname(ll->acd, ifname); +} + const char *sd_ipv4ll_get_ifname(sd_ipv4ll *ll) { if (!ll) return NULL; diff --git a/src/core/systemd/src/libsystemd-network/sd-lldp.c b/src/core/systemd/src/libsystemd-network/sd-lldp.c index 4e01652efc..09c2052f91 100644 --- a/src/core/systemd/src/libsystemd-network/sd-lldp.c +++ b/src/core/systemd/src/libsystemd-network/sd-lldp.c @@ -16,6 +16,7 @@ #include "lldp-neighbor.h" #include "lldp-network.h" #include "memory-util.h" +#include "network-common.h" #include "socket-util.h" #include "sort-util.h" #include "string-table.h" @@ -41,12 +42,10 @@ static void lldp_callback(sd_lldp *lldp, sd_lldp_event_t event, sd_lldp_neighbor assert(lldp); assert(event >= 0 && event < _SD_LLDP_EVENT_MAX); - if (!lldp->callback) { - log_lldp("Received '%s' event.", lldp_event_to_string(event)); - return; - } + if (!lldp->callback) + return (void) log_lldp(lldp, "Received '%s' event.", lldp_event_to_string(event)); - log_lldp("Invoking callback for '%s' event.", lldp_event_to_string(event)); + log_lldp(lldp, "Invoking callback for '%s' event.", lldp_event_to_string(event)); lldp->callback(lldp, event, n, lldp->userdata); } @@ -188,11 +187,11 @@ static int lldp_handle_datagram(sd_lldp *lldp, sd_lldp_neighbor *n) { r = lldp_add_neighbor(lldp, n); if (r < 0) { - log_lldp_errno(r, "Failed to add datagram. Ignoring."); + log_lldp_errno(lldp, r, "Failed to add datagram. Ignoring."); return 0; } - log_lldp("Successfully processed LLDP datagram."); + log_lldp(lldp, "Successfully processed LLDP datagram."); return 0; } @@ -206,8 +205,10 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v assert(lldp); space = next_datagram_size_fd(fd); - if (space < 0) - return log_lldp_errno(space, "Failed to determine datagram size to read: %m"); + if (space < 0) { + log_lldp_errno(lldp, space, "Failed to determine datagram size to read, ignoring: %m"); + return 0; + } n = lldp_neighbor_new(space); if (!n) @@ -218,12 +219,13 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v if (IN_SET(errno, EAGAIN, EINTR)) return 0; - return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); + log_lldp_errno(lldp, errno, "Failed to read LLDP datagram, ignoring: %m"); + return 0; } if ((size_t) length != n->raw_size) { - log_lldp("Packet size mismatch."); - return -EINVAL; + log_lldp(lldp, "Packet size mismatch, ignoring"); + return 0; } /* Try to get the timestamp of this packet if it is known */ @@ -269,7 +271,7 @@ _public_ int sd_lldp_start(sd_lldp *lldp) { (void) sd_event_source_set_description(lldp->io_event_source, "lldp-io"); - log_lldp("Started LLDP client"); + log_lldp(lldp, "Started LLDP client"); return 1; fail: @@ -284,7 +286,7 @@ _public_ int sd_lldp_stop(sd_lldp *lldp) { if (lldp->fd < 0) return 0; - log_lldp("Stopping LLDP client"); + log_lldp(lldp, "Stopping LLDP client"); lldp_reset(lldp); lldp_flush_neighbors(lldp); @@ -345,6 +347,23 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) { return 0; } +int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname) { + assert_return(lldp, -EINVAL); + assert_return(ifname, -EINVAL); + + if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE)) + return -EINVAL; + + return free_and_strdup(&lldp->ifname, ifname); +} + +const char *sd_lldp_get_ifname(sd_lldp *lldp) { + if (!lldp) + return NULL; + + return get_ifname(lldp->ifindex, &lldp->ifname); +} + static sd_lldp* lldp_free(sd_lldp *lldp) { assert(lldp); @@ -356,6 +375,7 @@ static sd_lldp* lldp_free(sd_lldp *lldp) { hashmap_free(lldp->neighbor_by_id); prioq_free(lldp->neighbor_by_expiry); + free(lldp->ifname); return mfree(lldp); } @@ -400,12 +420,16 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) { int r; r = lldp_make_space(lldp, 0); - if (r < 0) - return log_lldp_errno(r, "Failed to make space: %m"); + if (r < 0) { + log_lldp_errno(lldp, r, "Failed to make space, ignoring: %m"); + return 0; + } r = lldp_start_timer(lldp, NULL); - if (r < 0) - return log_lldp_errno(r, "Failed to restart timer: %m"); + if (r < 0) { + log_lldp_errno(lldp, r, "Failed to restart timer, ignoring: %m"); + return 0; + } return 0; } diff --git a/src/core/systemd/src/systemd/sd-dhcp-client.h b/src/core/systemd/src/systemd/sd-dhcp-client.h index 822286919e..c784cbcb9a 100644 --- a/src/core/systemd/src/systemd/sd-dhcp-client.h +++ b/src/core/systemd/src/systemd/sd-dhcp-client.h @@ -125,6 +125,10 @@ int sd_dhcp_client_set_request_broadcast( int sd_dhcp_client_set_ifindex( sd_dhcp_client *client, int interface_index); +int sd_dhcp_client_set_ifname( + sd_dhcp_client *client, + const char *interface_name); +const char *sd_dhcp_client_get_ifname(sd_dhcp_client *client); int sd_dhcp_client_set_mac( sd_dhcp_client *client, const uint8_t *addr, diff --git a/src/core/systemd/src/systemd/sd-dhcp6-client.h b/src/core/systemd/src/systemd/sd-dhcp6-client.h index 84e3170130..e02d67632a 100644 --- a/src/core/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/core/systemd/src/systemd/sd-dhcp6-client.h @@ -91,6 +91,10 @@ int sd_dhcp6_client_set_callback( int sd_dhcp6_client_set_ifindex( sd_dhcp6_client *client, int interface_index); +int sd_dhcp6_client_set_ifname( + sd_dhcp6_client *client, + const char *interface_name); +const char * sd_dhcp6_client_get_ifname(sd_dhcp6_client *client); int sd_dhcp6_client_set_local_address( sd_dhcp6_client *client, const struct in6_addr *local_address); diff --git a/src/core/systemd/src/systemd/sd-ipv4acd.h b/src/core/systemd/src/systemd/sd-ipv4acd.h index 2809d8748b..1e89a81b31 100644 --- a/src/core/systemd/src/systemd/sd-ipv4acd.h +++ b/src/core/systemd/src/systemd/sd-ipv4acd.h @@ -44,6 +44,7 @@ int sd_ipv4acd_set_callback(sd_ipv4acd *acd, sd_ipv4acd_callback_t cb, void *use int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr); int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index); int sd_ipv4acd_get_ifindex(sd_ipv4acd *acd); +int sd_ipv4acd_set_ifname(sd_ipv4acd *acd, const char *interface_name); const char *sd_ipv4acd_get_ifname(sd_ipv4acd *acd); int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address); int sd_ipv4acd_is_running(sd_ipv4acd *acd); diff --git a/src/core/systemd/src/systemd/sd-ipv4ll.h b/src/core/systemd/src/systemd/sd-ipv4ll.h index aa4d174e4b..bf5596ab61 100644 --- a/src/core/systemd/src/systemd/sd-ipv4ll.h +++ b/src/core/systemd/src/systemd/sd-ipv4ll.h @@ -44,6 +44,7 @@ int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_callback_t cb, void *userdat int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr); int sd_ipv4ll_set_ifindex(sd_ipv4ll *ll, int interface_index); int sd_ipv4ll_get_ifindex(sd_ipv4ll *ll); +int sd_ipv4ll_set_ifname(sd_ipv4ll *ll, const char *interface_name); const char *sd_ipv4ll_get_ifname(sd_ipv4ll *ll); int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address); int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed); diff --git a/src/core/systemd/src/systemd/sd-lldp.h b/src/core/systemd/src/systemd/sd-lldp.h index e48e29fbc0..64047ee817 100644 --- a/src/core/systemd/src/systemd/sd-lldp.h +++ b/src/core/systemd/src/systemd/sd-lldp.h @@ -147,6 +147,8 @@ sd_event *sd_lldp_get_event(sd_lldp *lldp); int sd_lldp_set_callback(sd_lldp *lldp, sd_lldp_callback_t cb, void *userdata); int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex); +int sd_lldp_set_ifname(sd_lldp *lldp, const char *ifname); +const char *sd_lldp_get_ifname(sd_lldp *lldp); /* Controls how much and what to store in the neighbors database */ int sd_lldp_set_neighbors_max(sd_lldp *lldp, uint64_t n); diff --git a/src/core/systemd/src/systemd/sd-ndisc.h b/src/core/systemd/src/systemd/sd-ndisc.h index 49b127c018..6088def1b6 100644 --- a/src/core/systemd/src/systemd/sd-ndisc.h +++ b/src/core/systemd/src/systemd/sd-ndisc.h @@ -78,6 +78,8 @@ sd_event *sd_ndisc_get_event(sd_ndisc *nd); int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata); int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index); +int sd_ndisc_set_ifname(sd_ndisc *nd, const char *interface_name); +const char *sd_ndisc_get_ifname(sd_ndisc *nd); int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr); int sd_ndisc_get_mtu(sd_ndisc *nd, uint32_t *ret); diff --git a/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h index fd8352ab69..e15032eaa2 100644 --- a/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h +++ b/src/libnm-systemd-shared/sd-adapt-shared/nm-sd-adapt-shared.h @@ -114,6 +114,10 @@ _nm_gettid(void) #define HAVE_RT_SIGQUEUEINFO 0 #endif + #ifndef ALTIFNAMSIZ + #define ALTIFNAMSIZ 128 + #endif + #define HAVE_LINUX_TIME_TYPES_H 0 #ifndef __COMPAR_FN_T diff --git a/src/libnm-systemd-shared/src/basic/env-util.c b/src/libnm-systemd-shared/src/basic/env-util.c index 7a66eed223..a13aaac5d7 100644 --- a/src/libnm-systemd-shared/src/basic/env-util.c +++ b/src/libnm-systemd-shared/src/basic/env-util.c @@ -518,10 +518,10 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { ALTERNATE_VALUE, } state = WORD; - const char *e, *word = format, *test_value; + const char *e, *word = format, *test_value = NULL; /* test_value is initialized to appease gcc */ char *k; _cleanup_free_ char *r = NULL; - size_t i, len; + size_t i, len = 0; /* len is initialized to appease gcc */ int nest = 0; assert(format); @@ -584,13 +584,12 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { word = e+1; state = WORD; } else if (*e == ':') { - if (!(flags & REPLACE_ENV_ALLOW_EXTENDED)) + if (flags & REPLACE_ENV_ALLOW_EXTENDED) { + len = e - word - 2; + state = TEST; + } else /* Treat this as unsupported syntax, i.e. do no replacement */ state = WORD; - else { - len = e-word-2; - state = TEST; - } } break; diff --git a/src/libnm-systemd-shared/src/basic/fileio.c b/src/libnm-systemd-shared/src/basic/fileio.c index b3c5def57d..27ec9b96c8 100644 --- a/src/libnm-systemd-shared/src/basic/fileio.c +++ b/src/libnm-systemd-shared/src/basic/fileio.c @@ -124,7 +124,7 @@ int write_string_stream_ts( const struct timespec *ts) { bool needs_nl; - int r, fd; + int r, fd = -1; assert(f); assert(line); @@ -143,8 +143,8 @@ int write_string_stream_ts( needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n"); if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) { - /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so - * that the write goes out in one go, instead of two */ + /* If STDIO buffering was disabled, then let's append the newline character to the string + * itself, so that the write goes out in one go, instead of two */ line = strjoina(line, "\n"); needs_nl = false; @@ -167,6 +167,7 @@ int write_string_stream_ts( if (ts) { const struct timespec twice[2] = {*ts, *ts}; + assert(fd >= 0); if (futimens(fd, twice) < 0) return -errno; } @@ -389,20 +390,10 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re if (fd < 0) return -errno; - /* Start size for files in /proc/ which usually report a file size of 0. (Files in /sys/ report a - * file size of 4K, which is probably OK for sizing our initial buffer, and sysfs attributes can't be - * larger anyway.) - * - * It's one less than 4k, so that the malloc() below allocates exactly 4k. */ - size = 4095; - /* Limit the number of attempts to read the number of bytes returned by fstat(). */ n_retries = 3; for (;;) { - if (n_retries <= 0) - return -EIO; - if (fstat(fd, &st) < 0) return -errno; @@ -413,24 +404,20 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re assert_cc(READ_FULL_BYTES_MAX < SSIZE_MAX); if (st.st_size > 0) { if (st.st_size > READ_FULL_BYTES_MAX) - return -E2BIG; + return -EFBIG; size = st.st_size; n_retries--; } else { - /* Double the buffer size */ - if (size >= READ_FULL_BYTES_MAX) - return -E2BIG; - if (size > READ_FULL_BYTES_MAX / 2 - 1) - size = READ_FULL_BYTES_MAX; /* clamp to max */ - else - size = size * 2 + 1; /* Stay always one less than page size, so we malloc evenly */ + size = READ_FULL_BYTES_MAX; + n_retries = 0; } buf = malloc(size + 1); if (!buf) return -ENOMEM; - size = malloc_usable_size(buf) - 1; /* Use a bigger allocation if we got it anyway */ + /* Use a bigger allocation if we got it anyway, but not more than the limit. */ + size = MIN(malloc_usable_size(buf) - 1, READ_FULL_BYTES_MAX); for (;;) { ssize_t k; @@ -457,6 +444,9 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re * processing, let's try again either with a bigger guessed size or the new * file size. */ + if (n_retries <= 0) + return st.st_size > 0 ? -EIO : -EFBIG; + if (lseek(fd, 0, SEEK_SET) < 0) return -errno; @@ -470,8 +460,7 @@ int read_full_virtual_file(const char *filename, char **ret_contents, size_t *re p = realloc(buf, n + 1); if (!p) return -ENOMEM; - - buf = TAKE_PTR(p); + buf = p; } if (ret_size) diff --git a/src/libnm-systemd-shared/src/basic/ordered-set.c b/src/libnm-systemd-shared/src/basic/ordered-set.c index db979864f5..62a36b5dc7 100644 --- a/src/libnm-systemd-shared/src/basic/ordered-set.c +++ b/src/libnm-systemd-shared/src/basic/ordered-set.c @@ -37,30 +37,33 @@ int ordered_set_consume(OrderedSet *s, void *p) { return r; } -int ordered_set_put_strdup(OrderedSet *s, const char *p) { +int _ordered_set_put_strdup(OrderedSet **s, const char *p HASHMAP_DEBUG_PARAMS) { char *c; int r; assert(s); assert(p); + r = _ordered_set_ensure_allocated(s, &string_hash_ops_free HASHMAP_DEBUG_PASS_ARGS); + if (r < 0) + return r; + + if (ordered_set_contains(*s, p)) + return 0; + c = strdup(p); if (!c) return -ENOMEM; - r = ordered_set_consume(s, c); - if (r == -EEXIST) - return 0; - - return r; + return ordered_set_consume(*s, c); } -int ordered_set_put_strdupv(OrderedSet *s, char **l) { +int _ordered_set_put_strdupv(OrderedSet **s, char **l HASHMAP_DEBUG_PARAMS) { int n = 0, r; char **i; STRV_FOREACH(i, l) { - r = ordered_set_put_strdup(s, *i); + r = _ordered_set_put_strdup(s, *i HASHMAP_DEBUG_PASS_ARGS); if (r < 0) return r; @@ -70,7 +73,7 @@ int ordered_set_put_strdupv(OrderedSet *s, char **l) { return n; } -int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l) { +int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l) { int n = 0, r; char *p; diff --git a/src/libnm-systemd-shared/src/basic/ordered-set.h b/src/libnm-systemd-shared/src/basic/ordered-set.h index baf8202088..a377f20b1f 100644 --- a/src/libnm-systemd-shared/src/basic/ordered-set.h +++ b/src/libnm-systemd-shared/src/basic/ordered-set.h @@ -26,6 +26,10 @@ static inline OrderedSet* ordered_set_free_free(OrderedSet *s) { return (OrderedSet*) ordered_hashmap_free_free((OrderedHashmap*) s); } +static inline int ordered_set_contains(OrderedSet *s, const void *p) { + return ordered_hashmap_contains((OrderedHashmap*) s, p); +} + static inline int ordered_set_put(OrderedSet *s, void *p) { return ordered_hashmap_put((OrderedHashmap*) s, p, p); } @@ -59,9 +63,11 @@ static inline char** ordered_set_get_strv(OrderedSet *s) { } int ordered_set_consume(OrderedSet *s, void *p); -int ordered_set_put_strdup(OrderedSet *s, const char *p); -int ordered_set_put_strdupv(OrderedSet *s, char **l); -int ordered_set_put_string_set(OrderedSet *s, OrderedSet *l); +int _ordered_set_put_strdup(OrderedSet **s, const char *p HASHMAP_DEBUG_PARAMS); +#define ordered_set_put_strdup(s, p) _ordered_set_put_strdup(s, p HASHMAP_DEBUG_SRC_ARGS) +int _ordered_set_put_strdupv(OrderedSet **s, char **l HASHMAP_DEBUG_PARAMS); +#define ordered_set_put_strdupv(s, l) _ordered_set_put_strdupv(s, l HASHMAP_DEBUG_SRC_ARGS) +int ordered_set_put_string_set(OrderedSet **s, OrderedSet *l); void ordered_set_print(FILE *f, const char *field, OrderedSet *s); #define _ORDERED_SET_FOREACH(e, s, i) \ diff --git a/src/libnm-systemd-shared/src/basic/parse-util.c b/src/libnm-systemd-shared/src/basic/parse-util.c index 76ae8e31d7..13758108fb 100644 --- a/src/libnm-systemd-shared/src/basic/parse-util.c +++ b/src/libnm-systemd-shared/src/basic/parse-util.c @@ -93,6 +93,7 @@ int parse_mode(const char *s, mode_t *ret) { *ret = m; return 0; } +#endif /* NM_IGNORED */ int parse_ifindex(const char *s) { int ifi, r; @@ -108,6 +109,7 @@ int parse_ifindex(const char *s) { return ifi; } +#if 0 /* NM_IGNORED */ int parse_mtu(int family, const char *s, uint32_t *ret) { uint64_t u; size_t m; diff --git a/src/libnm-systemd-shared/src/basic/path-util.c b/src/libnm-systemd-shared/src/basic/path-util.c index cf1607a56c..a867e65a26 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.c +++ b/src/libnm-systemd-shared/src/basic/path-util.c @@ -1203,10 +1203,4 @@ bool prefixed_path_strv_contains(char **l, const char *path) { return false; } - -bool credential_name_valid(const char *s) { - /* We want that credential names are both valid in filenames (since that's our primary way to pass - * them around) and as fdnames (which is how we might want to pass them around eventually) */ - return filename_is_valid(s) && fdname_is_valid(s); -} #endif /* NM_IGNORED */ diff --git a/src/libnm-systemd-shared/src/basic/path-util.h b/src/libnm-systemd-shared/src/basic/path-util.h index e679e8a73d..48f0c873db 100644 --- a/src/libnm-systemd-shared/src/basic/path-util.h +++ b/src/libnm-systemd-shared/src/basic/path-util.h @@ -185,5 +185,3 @@ static inline const char *empty_to_root(const char *path) { bool path_strv_contains(char **l, const char *path); bool prefixed_path_strv_contains(char **l, const char *path); - -bool credential_name_valid(const char *s); diff --git a/src/libnm-systemd-shared/src/basic/socket-util.c b/src/libnm-systemd-shared/src/basic/socket-util.c index 0aef1617f9..da36c2806c 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.c +++ b/src/libnm-systemd-shared/src/basic/socket-util.c @@ -752,6 +752,7 @@ static const char* const ip_tos_table[] = { }; DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff); +#endif /* NM_IGNORED */ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { bool numeric = true; @@ -809,6 +810,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { return true; } +#if 0 /* NM_IGNORED */ bool address_label_valid(const char *p) { if (isempty(p)) diff --git a/src/libnm-systemd-shared/src/basic/socket-util.h b/src/libnm-systemd-shared/src/basic/socket-util.h index 51c03a1578..a8a915beeb 100644 --- a/src/libnm-systemd-shared/src/basic/socket-util.h +++ b/src/libnm-systemd-shared/src/basic/socket-util.h @@ -14,6 +14,7 @@ #include <sys/types.h> #include <sys/un.h> +#include "errno-util.h" #include "macro.h" #include "missing_network.h" #include "missing_socket.h" @@ -266,7 +267,7 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) { socklen_t sl = sizeof(v); if (getsockopt(fd, level, optname, &v, &sl) < 0) - return -errno; + return negative_errno(); if (sl != sizeof(v)) return -EIO; |