diff options
Diffstat (limited to 'src/libsystemd-network/network-internal.c')
-rw-r--r-- | src/libsystemd-network/network-internal.c | 140 |
1 files changed, 87 insertions, 53 deletions
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 584a1f36ac..0849b44ee2 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright (C) 2013 Tom Gundersen <teg@jklm.no> - - 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 <http://www.gnu.org/licenses/>. -***/ #include <arpa/inet.h> #include <linux/if.h> @@ -96,7 +78,7 @@ static bool net_condition_test_strv(char * const *raw_patterns, /* If the patterns begin with "!", edit it out and negate the test. */ if (raw_patterns[0][0] == '!') { char **patterns; - unsigned i, length; + size_t i, length; length = strv_length(raw_patterns) + 1; /* Include the NULL. */ patterns = newa(char*, length); @@ -110,7 +92,7 @@ static bool net_condition_test_strv(char * const *raw_patterns, return string && strv_fnmatch(raw_patterns, string, 0); } -bool net_match_config(const struct ether_addr *match_mac, +bool net_match_config(Set *match_mac, char * const *match_paths, char * const *match_drivers, char * const *match_types, @@ -142,7 +124,7 @@ bool net_match_config(const struct ether_addr *match_mac, if (match_arch && condition_test(match_arch) <= 0) return false; - if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN))) + if (match_mac && dev_mac && !set_contains(match_mac, dev_mac)) return false; if (!net_condition_test_strv(match_paths, dev_path)) @@ -276,10 +258,9 @@ int config_parse_ifalias(const char *unit, } free(*s); - if (*n) { - *s = n; - n = NULL; - } else + if (*n) + *s = TAKE_PTR(n); + else *s = NULL; return 0; @@ -295,10 +276,9 @@ int config_parse_hwaddr(const char *unit, const char *rvalue, void *data, void *userdata) { + + _cleanup_free_ struct ether_addr *n = NULL; struct ether_addr **hwaddr = data; - struct ether_addr *n; - const char *start; - size_t offset; int r; assert(filename); @@ -310,17 +290,86 @@ int config_parse_hwaddr(const char *unit, if (!n) return log_oom(); - start = rvalue + strspn(rvalue, WHITESPACE); - r = ether_addr_from_string(start, n, &offset); + r = ether_addr_from_string(rvalue, n); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address, ignoring assignment: %s", rvalue); + return 0; + } + + *hwaddr = TAKE_PTR(n); + + return 0; +} + +int config_parse_hwaddrs(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) { + + _cleanup_set_free_free_ Set *s = NULL; + const char *p = rvalue; + Set **hwaddrs = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); - if (r || (start[offset + strspn(start + offset, WHITESPACE)] != '\0')) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue); - free(n); + if (isempty(rvalue)) { + /* Empty assignment resets the list */ + *hwaddrs = set_free_free(*hwaddrs); return 0; } - free(*hwaddr); - *hwaddr = n; + s = set_new(ðer_addr_hash_ops); + if (!s) + return log_oom(); + + for (;;) { + _cleanup_free_ char *word = NULL; + _cleanup_free_ struct ether_addr *n = NULL; + + r = extract_first_word(&p, &word, NULL, 0); + if (r == 0) + break; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); + return 0; + } + + n = new(struct ether_addr, 1); + if (!n) + return log_oom(); + + r = ether_addr_from_string(word, n); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring: %s", word); + continue; + } + + r = set_put(s, n); + if (r < 0) + return log_oom(); + if (r > 0) + n = NULL; /* avoid cleanup */ + } + + r = set_ensure_allocated(hwaddrs, ðer_addr_hash_ops); + if (r < 0) + return log_oom(); + + r = set_move(*hwaddrs, s); + if (r < 0) + return log_oom(); return 0; } @@ -393,7 +442,6 @@ int config_parse_bridge_port_priority( return 0; } - void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) { unsigned i; @@ -437,8 +485,7 @@ int deserialize_in_addrs(struct in_addr **ret, const char *string) { size++; } - *ret = addresses; - addresses = NULL; + *ret = TAKE_PTR(addresses); return size; } @@ -491,8 +538,7 @@ int deserialize_in6_addrs(struct in6_addr **ret, const char *string) { size++; } - *ret = addresses; - addresses = NULL; + *ret = TAKE_PTR(addresses); return size; } @@ -585,8 +631,7 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_size = size; *ret_allocated = allocated; - *ret = routes; - routes = NULL; + *ret = TAKE_PTR(routes); return 0; } @@ -606,14 +651,3 @@ int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t siz return 0; } - -int deserialize_dhcp_option(void **data, size_t *data_len, const char *string) { - assert(data); - assert(data_len); - assert(string); - - if (strlen(string) % 2) - return -EINVAL; - - return unhexmem(string, strlen(string), (void **)data, data_len); -} |