summaryrefslogtreecommitdiff
path: root/src/libsystemd-network/network-internal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsystemd-network/network-internal.c')
-rw-r--r--src/libsystemd-network/network-internal.c140
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(&ether_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, &ether_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);
-}