summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2020-11-27 09:04:19 +0900
committerGitHub <noreply@github.com>2020-11-27 09:04:19 +0900
commit0d5eb02134c6420a7b929915df5a1b18ba841911 (patch)
tree06456aa21b6c98a5d22185e0c9c1cd6c87f0a0a0
parent6d8325f66a40d802b280492416660246db3476a6 (diff)
parent5722fb89bcb4d0fb228c0b99b82b70e00bb6095a (diff)
downloadsystemd-0d5eb02134c6420a7b929915df5a1b18ba841911.tar.gz
Merge pull request #17478 from yuwata/split-network-internal
libsystemd-network: split network-internal.c
-rw-r--r--meson.build1
-rw-r--r--src/fuzz/meson.build1
-rw-r--r--src/libsystemd-network/dhcp-identifier.c3
-rw-r--r--src/libsystemd-network/meson.build4
-rw-r--r--src/libsystemd-network/network-internal.c645
-rw-r--r--src/libsystemd-network/network-internal.h44
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c2
-rw-r--r--src/libsystemd/sd-network/network-util.c75
-rw-r--r--src/libsystemd/sd-network/network-util.h8
-rw-r--r--src/network/meson.build3
-rw-r--r--src/network/netdev/bridge.c42
-rw-r--r--src/network/netdev/bridge.h4
-rw-r--r--src/network/netdev/macsec.c1
-rw-r--r--src/network/netdev/netdev-gperf.gperf10
-rw-r--r--src/network/netdev/netdev.c1
-rw-r--r--src/network/networkctl.c5
-rw-r--r--src/network/networkd-dhcp4.c2
-rw-r--r--src/network/networkd-dhcp6.c1
-rw-r--r--src/network/networkd-network-bus.c10
-rw-r--r--src/network/networkd-network-gperf.gperf22
-rw-r--r--src/network/networkd-network.c29
-rw-r--r--src/network/networkd-network.h12
-rw-r--r--src/network/test-networkd-conf.c9
-rw-r--r--src/network/wait-online/manager.c1
-rw-r--r--src/resolve/resolved-manager.c1
-rw-r--r--src/shared/conf-parser.c209
-rw-r--r--src/shared/conf-parser.h2
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/net-condition.c428
-rw-r--r--src/shared/net-condition.h45
-rw-r--r--src/test/meson.build5
-rw-r--r--src/udev/meson.build1
-rw-r--r--src/udev/net/link-config-gperf.gperf16
-rw-r--r--src/udev/net/link-config.c65
-rw-r--r--src/udev/net/link-config.h11
35 files changed, 869 insertions, 851 deletions
diff --git a/meson.build b/meson.build
index f406d595e6..ab2404c3c4 100644
--- a/meson.build
+++ b/meson.build
@@ -3194,7 +3194,6 @@ public_programs += executable(
c_args : '-DLOG_REALM=LOG_REALM_UDEV',
include_directories : includes,
link_with : [libudev_core,
- libsystemd_network,
libudev_static],
dependencies : [versiondep,
threads,
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
index a5fac5980e..f8f0c386b3 100644
--- a/src/fuzz/meson.build
+++ b/src/fuzz/meson.build
@@ -108,7 +108,6 @@ fuzzers += [
[['src/fuzz/fuzz-udev-rules.c'],
[libudev_core,
libudev_static,
- libsystemd_network,
libshared],
[threads,
libacl]],
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index ea9c77aa9d..953fef19fa 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_infiniband.h>
+#include <net/ethernet.h>
#include <net/if_arp.h>
#include "sd-device.h"
@@ -8,7 +9,7 @@
#include "dhcp-identifier.h"
#include "dhcp6-protocol.h"
-#include "network-internal.h"
+#include "network-util.h"
#include "siphash24.h"
#include "sparse-endian.h"
#include "stdio-util.h"
diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build
index 604cfd999b..8c68d74c82 100644
--- a/src/libsystemd-network/meson.build
+++ b/src/libsystemd-network/meson.build
@@ -17,6 +17,7 @@ sources = files('''
arp-util.h
arp-util.c
network-internal.c
+ network-internal.h
sd-ndisc.c
ndisc-internal.h
ndisc-router.h
@@ -42,10 +43,7 @@ sources = files('''
sd-lldp.c
'''.split())
-network_internal_h = files('network-internal.h')
-
libsystemd_network = static_library(
'systemd-network',
sources,
- network_internal_h,
include_directories : includes)
diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c
index e4a07419e4..12b73cd50d 100644
--- a/src/libsystemd-network/network-internal.c
+++ b/src/libsystemd-network/network-internal.c
@@ -4,658 +4,15 @@
#include <linux/if.h>
#include <netinet/ether.h>
-#include "sd-id128.h"
#include "sd-ndisc.h"
#include "alloc-util.h"
-#include "arphrd-list.h"
-#include "condition.h"
-#include "conf-parser.h"
-#include "device-util.h"
#include "dhcp-lease-internal.h"
-#include "env-util.h"
-#include "ether-addr-util.h"
+#include "extract-word.h"
#include "hexdecoct.h"
#include "log.h"
#include "network-internal.h"
#include "parse-util.h"
-#include "siphash24.h"
-#include "socket-util.h"
-#include "string-table.h"
-#include "string-util.h"
-#include "strv.h"
-#include "utf8.h"
-#include "util.h"
-
-const char *net_get_name_persistent(sd_device *device) {
- const char *name, *field;
-
- assert(device);
-
- /* fetch some persistent data unique (on this machine) to this device */
- FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC")
- if (sd_device_get_property_value(device, field, &name) >= 0)
- return name;
-
- return NULL;
-}
-
-#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
-
-int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result) {
- size_t l, sz = 0;
- const char *name;
- int r;
- uint8_t *v;
-
- assert(device);
-
- /* net_get_name_persistent() will return one of the device names based on stable information about
- * the device. If this is not available, we fall back to using the actual device name. */
- name = net_get_name_persistent(device);
- if (!name && use_sysname)
- (void) sd_device_get_sysname(device, &name);
- if (!name)
- return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA),
- "No stable identifying information found");
-
- log_device_debug(device, "Using \"%s\" as stable identifying information", name);
- l = strlen(name);
- sz = sizeof(sd_id128_t) + l;
- v = newa(uint8_t, sz);
-
- /* Fetch some persistent data unique to this machine */
- r = sd_id128_get_machine((sd_id128_t*) v);
- if (r < 0)
- return r;
- memcpy(v + sizeof(sd_id128_t), name, l);
-
- /* Let's hash the machine ID plus the device name. We use
- * a fixed, but originally randomly created hash key here. */
- *result = htole64(siphash24(v, sz, HASH_KEY.bytes));
- return 0;
-}
-
-static bool net_condition_test_strv(char * const *patterns, const char *string) {
- char * const *p;
- bool match = false, has_positive_rule = false;
-
- if (strv_isempty(patterns))
- return true;
-
- STRV_FOREACH(p, patterns) {
- const char *q = *p;
- bool invert;
-
- invert = *q == '!';
- q += invert;
-
- if (!invert)
- has_positive_rule = true;
-
- if (string && fnmatch(q, string, 0) == 0) {
- if (invert)
- return false;
- else
- match = true;
- }
- }
-
- return has_positive_rule ? match : true;
-}
-
-static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) {
- if (net_condition_test_strv(patterns, ifname))
- return true;
-
- char * const *p;
- STRV_FOREACH(p, alternative_names)
- if (net_condition_test_strv(patterns, *p))
- return true;
-
- return false;
-}
-
-static int net_condition_test_property(char * const *match_property, sd_device *device) {
- char * const *p;
-
- if (strv_isempty(match_property))
- return true;
-
- STRV_FOREACH(p, match_property) {
- _cleanup_free_ char *key = NULL;
- const char *val, *dev_val;
- bool invert, v;
-
- invert = **p == '!';
-
- val = strchr(*p + invert, '=');
- if (!val)
- return -EINVAL;
-
- key = strndup(*p + invert, val - *p - invert);
- if (!key)
- return -ENOMEM;
-
- val++;
-
- v = device &&
- sd_device_get_property_value(device, key, &dev_val) >= 0 &&
- fnmatch(val, dev_val, 0) == 0;
-
- if (invert ? v : !v)
- return false;
- }
-
- return true;
-}
-
-static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
- [NL80211_IFTYPE_ADHOC] = "ad-hoc",
- [NL80211_IFTYPE_STATION] = "station",
- [NL80211_IFTYPE_AP] = "ap",
- [NL80211_IFTYPE_AP_VLAN] = "ap-vlan",
- [NL80211_IFTYPE_WDS] = "wds",
- [NL80211_IFTYPE_MONITOR] = "monitor",
- [NL80211_IFTYPE_MESH_POINT] = "mesh-point",
- [NL80211_IFTYPE_P2P_CLIENT] = "p2p-client",
- [NL80211_IFTYPE_P2P_GO] = "p2p-go",
- [NL80211_IFTYPE_P2P_DEVICE] = "p2p-device",
- [NL80211_IFTYPE_OCB] = "ocb",
- [NL80211_IFTYPE_NAN] = "nan",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
-
-char *link_get_type_string(unsigned short iftype, sd_device *device) {
- const char *t, *devtype;
- char *p;
-
- if (device &&
- sd_device_get_devtype(device, &devtype) >= 0 &&
- !isempty(devtype))
- return strdup(devtype);
-
- t = arphrd_to_name(iftype);
- if (!t)
- return NULL;
-
- p = strdup(t);
- if (!p)
- return NULL;
-
- ascii_strlower(p);
- return p;
-}
-
-bool net_match_config(Set *match_mac,
- Set *match_permanent_mac,
- char * const *match_paths,
- char * const *match_drivers,
- char * const *match_iftypes,
- char * const *match_names,
- char * const *match_property,
- char * const *match_wifi_iftype,
- char * const *match_ssid,
- Set *match_bssid,
- sd_device *device,
- const struct ether_addr *dev_mac,
- const struct ether_addr *dev_permanent_mac,
- const char *dev_driver,
- unsigned short dev_iftype,
- const char *dev_name,
- char * const *alternative_names,
- enum nl80211_iftype dev_wifi_iftype,
- const char *dev_ssid,
- const struct ether_addr *dev_bssid) {
-
- _cleanup_free_ char *dev_iftype_str;
- const char *dev_path = NULL;
-
- dev_iftype_str = link_get_type_string(dev_iftype, device);
-
- if (device) {
- const char *mac_str;
-
- (void) sd_device_get_property_value(device, "ID_PATH", &dev_path);
- if (!dev_driver)
- (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &dev_driver);
- if (!dev_name)
- (void) sd_device_get_sysname(device, &dev_name);
- if (!dev_mac &&
- sd_device_get_sysattr_value(device, "address", &mac_str) >= 0)
- dev_mac = ether_aton(mac_str);
- }
-
- if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
- return false;
-
- if (match_permanent_mac &&
- (!dev_permanent_mac ||
- ether_addr_is_null(dev_permanent_mac) ||
- !set_contains(match_permanent_mac, dev_permanent_mac)))
- return false;
-
- if (!net_condition_test_strv(match_paths, dev_path))
- return false;
-
- if (!net_condition_test_strv(match_drivers, dev_driver))
- return false;
-
- if (!net_condition_test_strv(match_iftypes, dev_iftype_str))
- return false;
-
- if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
- return false;
-
- if (!net_condition_test_property(match_property, device))
- return false;
-
- if (!net_condition_test_strv(match_wifi_iftype, wifi_iftype_to_string(dev_wifi_iftype)))
- return false;
-
- if (!net_condition_test_strv(match_ssid, dev_ssid))
- return false;
-
- if (match_bssid && (!dev_bssid || !set_contains(match_bssid, dev_bssid)))
- return false;
-
- return true;
-}
-
-int config_parse_net_condition(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) {
-
- ConditionType cond = ltype;
- Condition **list = data, *c;
- bool negate;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (isempty(rvalue)) {
- *list = condition_free_list_type(*list, cond);
- return 0;
- }
-
- negate = rvalue[0] == '!';
- if (negate)
- rvalue++;
-
- c = condition_new(cond, rvalue, false, negate);
- if (!c)
- return log_oom();
-
- /* Drop previous assignment. */
- *list = condition_free_list_type(*list, cond);
-
- LIST_PREPEND(conditions, *list, c);
- return 0;
-}
-
-int config_parse_match_strv(
- 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) {
-
- const char *p = rvalue;
- char ***sv = data;
- bool invert;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- if (isempty(rvalue)) {
- *sv = strv_free(*sv);
- return 0;
- }
-
- invert = *p == '!';
- p += invert;
-
- for (;;) {
- _cleanup_free_ char *word = NULL, *k = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
- if (r == 0)
- return 0;
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
- return 0;
- }
-
- if (invert) {
- k = strjoin("!", word);
- if (!k)
- return log_oom();
- } else
- k = TAKE_PTR(word);
-
- r = strv_consume(sv, TAKE_PTR(k));
- if (r < 0)
- return log_oom();
- }
-}
-
-int config_parse_match_ifnames(
- 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) {
-
- const char *p = rvalue;
- char ***sv = data;
- bool invert;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- invert = *p == '!';
- p += invert;
-
- for (;;) {
- _cleanup_free_ char *word = NULL, *k = NULL;
-
- r = extract_first_word(&p, &word, NULL, 0);
- if (r == 0)
- return 0;
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Failed to parse interface name list: %s", rvalue);
- return 0;
- }
-
- if (!ifname_valid_full(word, ltype)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Interface name is not valid or too long, ignoring assignment: %s", word);
- continue;
- }
-
- if (invert) {
- k = strjoin("!", word);
- if (!k)
- return log_oom();
- } else
- k = TAKE_PTR(word);
-
- r = strv_consume(sv, TAKE_PTR(k));
- if (r < 0)
- return log_oom();
- }
-}
-
-int config_parse_match_property(
- 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) {
-
- const char *p = rvalue;
- char ***sv = data;
- bool invert;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- invert = *p == '!';
- p += invert;
-
- for (;;) {
- _cleanup_free_ char *word = NULL, *k = NULL;
-
- r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
- if (r == 0)
- return 0;
- if (r == -ENOMEM)
- return log_oom();
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Invalid syntax, ignoring: %s", rvalue);
- return 0;
- }
-
- if (!env_assignment_is_valid(word)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Invalid property or value, ignoring assignment: %s", word);
- continue;
- }
-
- if (invert) {
- k = strjoin("!", word);
- if (!k)
- return log_oom();
- } else
- k = TAKE_PTR(word);
-
- r = strv_consume(sv, TAKE_PTR(k));
- if (r < 0)
- return log_oom();
- }
-}
-
-int config_parse_ifalias(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) {
-
- char **s = data;
- _cleanup_free_ char *n = NULL;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = strdup(rvalue);
- if (!n)
- return log_oom();
-
- if (!ascii_is_valid(n) || strlen(n) >= IFALIASZ) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Interface alias is not ASCII clean or is too long, ignoring assignment: %s", rvalue);
- return 0;
- }
-
- if (isempty(n))
- *s = mfree(*s);
- else
- free_and_replace(*s, n);
-
- return 0;
-}
-
-int config_parse_hwaddr(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_free_ struct ether_addr *n = NULL;
- struct ether_addr **hwaddr = data;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- n = new0(struct ether_addr, 1);
- if (!n)
- return log_oom();
-
- 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;
- }
-
- free_and_replace(*hwaddr, 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 (isempty(rvalue)) {
- /* Empty assignment resets the list */
- *hwaddrs = set_free_free(*hwaddrs);
- return 0;
- }
-
- 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;
-}
-
-int config_parse_bridge_port_priority(
- 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) {
-
- uint16_t i;
- int r;
-
- assert(filename);
- assert(lvalue);
- assert(rvalue);
- assert(data);
-
- r = safe_atou16(rvalue, &i);
- if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse bridge port priority, ignoring: %s", rvalue);
- return 0;
- }
-
- if (i > LINK_BRIDGE_PORT_PRIORITY_MAX) {
- log_syntax(unit, LOG_ERR, filename, line, r,
- "Bridge port priority is larger than maximum %u, ignoring: %s", LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue);
- return 0;
- }
-
- *((uint16_t *)data) = i;
-
- return 0;
-}
size_t serialize_in_addrs(FILE *f,
const struct in_addr *addresses,
diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h
index 5dae5ab306..e5b853c0cd 100644
--- a/src/libsystemd-network/network-internal.h
+++ b/src/libsystemd-network/network-internal.h
@@ -1,53 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
-#include <linux/nl80211.h>
#include <stdbool.h>
+#include <stdio.h>
-#include "sd-device.h"
#include "sd-dhcp-lease.h"
-#include "conf-parser.h"
-#include "set.h"
-#include "strv.h"
-
-#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
-#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
-
-char *link_get_type_string(unsigned short iftype, sd_device *device);
-bool net_match_config(Set *match_mac,
- Set *match_permanent_mac,
- char * const *match_paths,
- char * const *match_drivers,
- char * const *match_iftypes,
- char * const *match_names,
- char * const *match_property,
- char * const *match_wifi_iftype,
- char * const *match_ssid,
- Set *match_bssid,
- sd_device *device,
- const struct ether_addr *dev_mac,
- const struct ether_addr *dev_permanent_mac,
- const char *dev_driver,
- unsigned short dev_iftype,
- const char *dev_name,
- char * const *alternative_names,
- enum nl80211_iftype dev_wifi_iftype,
- const char *dev_ssid,
- const struct ether_addr *dev_bssid);
-
-CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
-CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
-CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
-CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
-CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
-CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
-CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
-CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
-
-int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
-const char *net_get_name_persistent(sd_device *device);
-
size_t serialize_in_addrs(FILE *f,
const struct in_addr *addresses,
size_t size,
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 30ac526fc9..97fd5fd4fb 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -21,10 +21,10 @@
#include "hexdecoct.h"
#include "hostname-util.h"
#include "in-addr-util.h"
-#include "network-internal.h"
#include "random-util.h"
#include "socket-util.h"
#include "string-table.h"
+#include "strv.h"
#include "util.h"
#include "web-util.h"
diff --git a/src/libsystemd/sd-network/network-util.c b/src/libsystemd/sd-network/network-util.c
index 7753431fc0..acf7500970 100644
--- a/src/libsystemd/sd-network/network-util.c
+++ b/src/libsystemd/sd-network/network-util.c
@@ -1,8 +1,14 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "sd-id128.h"
+
#include "alloc-util.h"
+#include "arphrd-list.h"
+#include "device-util.h"
#include "fd-util.h"
#include "network-util.h"
+#include "siphash24.h"
+#include "sparse-endian.h"
#include "string-table.h"
#include "strv.h"
@@ -103,3 +109,72 @@ int parse_operational_state_range(const char *str, LinkOperationalStateRange *ou
return 0;
}
+
+char *link_get_type_string(sd_device *device, unsigned short iftype) {
+ const char *t;
+ char *p;
+
+ if (device &&
+ sd_device_get_devtype(device, &t) >= 0 &&
+ !isempty(t))
+ return strdup(t);
+
+ t = arphrd_to_name(iftype);
+ if (!t)
+ return NULL;
+
+ p = strdup(t);
+ if (!p)
+ return NULL;
+
+ return ascii_strlower(p);
+}
+
+const char *net_get_name_persistent(sd_device *device) {
+ const char *name, *field;
+
+ assert(device);
+
+ /* fetch some persistent data unique (on this machine) to this device */
+ FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC")
+ if (sd_device_get_property_value(device, field, &name) >= 0)
+ return name;
+
+ return NULL;
+}
+
+#define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a)
+
+int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result) {
+ size_t l, sz = 0;
+ const char *name;
+ int r;
+ uint8_t *v;
+
+ assert(device);
+
+ /* net_get_name_persistent() will return one of the device names based on stable information about
+ * the device. If this is not available, we fall back to using the actual device name. */
+ name = net_get_name_persistent(device);
+ if (!name && use_sysname)
+ (void) sd_device_get_sysname(device, &name);
+ if (!name)
+ return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA),
+ "No stable identifying information found");
+
+ log_device_debug(device, "Using \"%s\" as stable identifying information", name);
+ l = strlen(name);
+ sz = sizeof(sd_id128_t) + l;
+ v = newa(uint8_t, sz);
+
+ /* Fetch some persistent data unique to this machine */
+ r = sd_id128_get_machine((sd_id128_t*) v);
+ if (r < 0)
+ return r;
+ memcpy(v + sizeof(sd_id128_t), name, l);
+
+ /* Let's hash the machine ID plus the device name. We use
+ * a fixed, but originally randomly created hash key here. */
+ *result = htole64(siphash24(v, sz, HASH_KEY.bytes));
+ return 0;
+}
diff --git a/src/libsystemd/sd-network/network-util.h b/src/libsystemd/sd-network/network-util.h
index 8cfd894b5a..762b15746f 100644
--- a/src/libsystemd/sd-network/network-util.h
+++ b/src/libsystemd/sd-network/network-util.h
@@ -1,6 +1,10 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "sd-device.h"
#include "sd-network.h"
#include "macro.h"
@@ -58,3 +62,7 @@ typedef struct LinkOperationalStateRange {
LINK_OPERSTATE_ROUTABLE }
int parse_operational_state_range(const char *str, LinkOperationalStateRange *out);
+
+char *link_get_type_string(sd_device *device, unsigned short iftype);
+int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
+const char *net_get_name_persistent(sd_device *device);
diff --git a/src/network/meson.build b/src/network/meson.build
index f5ca183088..4123873c60 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -171,7 +171,7 @@ systemd_networkd_wait_online_sources = files('''
wait-online/manager.c
wait-online/manager.h
wait-online/wait-online.c
-'''.split()) + network_internal_h
+'''.split())
networkctl_sources = files('networkctl.c')
@@ -214,7 +214,6 @@ if conf.get('ENABLE_NETWORKD') == 1
libnetworkd_core = static_library(
'networkd-core',
sources,
- network_internal_h,
networkd_gperf_c,
networkd_network_gperf_c,
netdev_gperf_c,
diff --git a/src/network/netdev/bridge.c b/src/network/netdev/bridge.c
index 1f59cd8b42..38432f1578 100644
--- a/src/network/netdev/bridge.c
+++ b/src/network/netdev/bridge.c
@@ -4,7 +4,6 @@
#include "bridge.h"
#include "netlink-util.h"
-#include "network-internal.h"
#include "networkd-manager.h"
#include "string-table.h"
#include "vlan-util.h"
@@ -342,6 +341,47 @@ int config_parse_bridge_igmp_version(
return 0;
}
+int config_parse_bridge_port_priority(
+ 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) {
+
+ uint16_t i;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* This is used in networkd-network-gperf.gperf. */
+
+ r = safe_atou16(rvalue, &i);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse bridge port priority, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (i > LINK_BRIDGE_PORT_PRIORITY_MAX) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Bridge port priority is larger than maximum %u, ignoring: %s",
+ LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue);
+ return 0;
+ }
+
+ *((uint16_t *)data) = i;
+
+ return 0;
+}
+
static void bridge_init(NetDev *n) {
Bridge *b;
diff --git a/src/network/netdev/bridge.h b/src/network/netdev/bridge.h
index d6abda99e8..f3276c5c41 100644
--- a/src/network/netdev/bridge.h
+++ b/src/network/netdev/bridge.h
@@ -7,6 +7,9 @@
#include "conf-parser.h"
#include "netdev.h"
+#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
+#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
+
typedef struct Bridge {
NetDev meta;
@@ -45,3 +48,4 @@ MulticastRouter multicast_router_from_string(const char *s) _pure_;
CONFIG_PARSER_PROTOTYPE(config_parse_multicast_router);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_igmp_version);
+CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
diff --git a/src/network/netdev/macsec.c b/src/network/netdev/macsec.c
index 82e71c3920..313277ca16 100644
--- a/src/network/netdev/macsec.c
+++ b/src/network/netdev/macsec.c
@@ -12,7 +12,6 @@
#include "macsec.h"
#include "memory-util.h"
#include "netlink-util.h"
-#include "network-internal.h"
#include "networkd-manager.h"
#include "path-util.h"
#include "socket-util.h"
diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf
index 4e89761f2c..35cd01ef0d 100644
--- a/src/network/netdev/netdev-gperf.gperf
+++ b/src/network/netdev/netdev-gperf.gperf
@@ -7,23 +7,23 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "bond.h"
#include "bridge.h"
#include "conf-parser.h"
+#include "fou-tunnel.h"
#include "geneve.h"
#include "ipvlan.h"
+#include "l2tp-tunnel.h"
#include "macsec.h"
#include "macvlan.h"
+#include "net-condition.h"
+#include "netdev.h"
#include "tunnel.h"
#include "tuntap.h"
#include "veth.h"
#include "vlan-util.h"
#include "vlan.h"
-#include "vxlan.h"
#include "vrf.h"
-#include "netdev.h"
-#include "network-internal.h"
#include "vxcan.h"
+#include "vxlan.h"
#include "wireguard.h"
-#include "fou-tunnel.h"
-#include "l2tp-tunnel.h"
#include "xfrm.h"
%}
struct ConfigPerfItem;
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 9f390b5781..71a4f603be 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -23,7 +23,6 @@
#include "netdev.h"
#include "netdevsim.h"
#include "netlink-util.h"
-#include "network-internal.h"
#include "networkd-manager.h"
#include "nlmon.h"
#include "path-lookup.h"
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 63a90bc13d..c415fb1a74 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -44,6 +44,7 @@
#include "main-func.h"
#include "netlink-util.h"
#include "network-internal.h"
+#include "network-util.h"
#include "pager.h"
#include "parse-util.h"
#include "pretty-print.h"
@@ -704,7 +705,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
setup_state = strdup("unmanaged");
setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
- t = link_get_type_string(links[i].iftype, links[i].sd_device);
+ t = link_get_type_string(links[i].sd_device, links[i].iftype);
r = table_add_many(table,
TABLE_INT, links[i].ifindex,
@@ -1428,7 +1429,7 @@ static int link_status_one(
(void) sd_device_get_property_value(info->sd_device, "ID_MODEL", &model);
}
- t = link_get_type_string(info->iftype, info->sd_device);
+ t = link_get_type_string(info->sd_device, info->iftype);
(void) sd_network_link_get_network_file(info->ifindex, &network);
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 02d33841b6..3983b33527 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -17,7 +17,7 @@
#include "networkd-manager.h"
#include "networkd-network.h"
#include "string-table.h"
-#include "string-util.h"
+#include "strv.h"
#include "sysctl-util.h"
#include "web-util.h"
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index d4d4182ee5..95025acbfd 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -13,7 +13,6 @@
#include "hashmap.h"
#include "hostname-util.h"
#include "missing_network.h"
-#include "network-internal.h"
#include "networkd-address.h"
#include "networkd-dhcp6.h"
#include "networkd-link.h"
diff --git a/src/network/networkd-network-bus.c b/src/network/networkd-network-bus.c
index 0e5f1488d8..8c52faf185 100644
--- a/src/network/networkd-network-bus.c
+++ b/src/network/networkd-network-bus.c
@@ -45,11 +45,11 @@ const sd_bus_vtable network_vtable[] = {
SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match_name), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match.mac), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match.path), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match.driver), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match.iftype), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("MatchName", "as", NULL, offsetof(Network, match.ifname), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_VTABLE_END
};
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 5cc9e3e8f6..619c6a8c59 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -5,7 +5,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include <stddef.h>
#include "conf-parser.h"
#include "netem.h"
-#include "network-internal.h"
+#include "net-condition.h"
#include "networkd-address-label.h"
#include "networkd-address.h"
#include "networkd-can.h"
@@ -41,16 +41,16 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
-Match.MACAddress, config_parse_hwaddrs, 0, offsetof(Network, match_mac)
-Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(Network, match_permanent_mac)
-Match.Path, config_parse_match_strv, 0, offsetof(Network, match_path)
-Match.Driver, config_parse_match_strv, 0, offsetof(Network, match_driver)
-Match.Type, config_parse_match_strv, 0, offsetof(Network, match_type)
-Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype)
-Match.SSID, config_parse_match_strv, 0, offsetof(Network, match_ssid)
-Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match_bssid)
-Match.Name, config_parse_match_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Network, match_name)
-Match.Property, config_parse_match_property, 0, offsetof(Network, match_property)
+Match.MACAddress, config_parse_hwaddrs, 0, offsetof(Network, match.mac)
+Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(Network, match.permanent_mac)
+Match.Path, config_parse_match_strv, 0, offsetof(Network, match.path)
+Match.Driver, config_parse_match_strv, 0, offsetof(Network, match.driver)
+Match.Type, config_parse_match_strv, 0, offsetof(Network, match.iftype)
+Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match.wifi_iftype)
+Match.SSID, config_parse_match_strv, 0, offsetof(Network, match.ssid)
+Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match.bssid)
+Match.Name, config_parse_match_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(Network, match.ifname)
+Match.Property, config_parse_match_property, 0, offsetof(Network, match.property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, conditions)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 3254641461..195bf3aaae 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -12,11 +12,11 @@
#include "fd-util.h"
#include "hostname-util.h"
#include "in-addr-util.h"
-#include "networkd-dhcp-server.h"
-#include "network-internal.h"
+#include "net-condition.h"
#include "networkd-address-label.h"
#include "networkd-address.h"
#include "networkd-dhcp-common.h"
+#include "networkd-dhcp-server.h"
#include "networkd-fdb.h"
#include "networkd-manager.h"
#include "networkd-mdb.h"
@@ -161,11 +161,7 @@ int network_verify(Network *network) {
assert(network);
assert(network->filename);
- if (set_isempty(network->match_mac) && set_isempty(network->match_permanent_mac) &&
- strv_isempty(network->match_path) && strv_isempty(network->match_driver) &&
- strv_isempty(network->match_type) && strv_isempty(network->match_name) &&
- strv_isempty(network->match_property) && strv_isempty(network->match_wlan_iftype) &&
- strv_isempty(network->match_ssid) && !network->conditions)
+ if (net_match_is_empty(&network->match) && !network->conditions)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: No valid settings found in the [Match] section, ignoring file. "
"To match all interfaces, add Name=* in the [Match] section.",
@@ -589,16 +585,7 @@ static Network *network_free(Network *network) {
free(network->filename);
- set_free_free(network->match_mac);
- set_free_free(network->match_permanent_mac);
- strv_free(network->match_path);
- strv_free(network->match_driver);
- strv_free(network->match_type);
- strv_free(network->match_name);
- strv_free(network->match_property);
- strv_free(network->match_wlan_iftype);
- strv_free(network->match_ssid);
- set_free_free(network->match_bssid);
+ net_match_clear(&network->match);
condition_free_list(network->conditions);
free(network->description);
@@ -705,13 +692,9 @@ int network_get(Manager *manager, unsigned short iftype, sd_device *device,
assert(ret);
ORDERED_HASHMAP_FOREACH(network, manager->networks)
- if (net_match_config(network->match_mac, network->match_permanent_mac,
- network->match_path, network->match_driver,
- network->match_type, network->match_name, network->match_property,
- network->match_wlan_iftype, network->match_ssid, network->match_bssid,
- device, mac, permanent_mac, driver, iftype,
+ if (net_match_config(&network->match, device, mac, permanent_mac, driver, iftype,
ifname, alternative_names, wlan_iftype, ssid, bssid)) {
- if (network->match_name && device) {
+ if (network->match.ifname && device) {
const char *attr;
uint8_t name_assign_type = NET_NAME_UNKNOWN;
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index fd0fe056b2..17e7d432c9 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -10,6 +10,7 @@
#include "condition.h"
#include "conf-parser.h"
#include "hashmap.h"
+#include "net-condition.h"
#include "netdev.h"
#include "networkd-brvlan.h"
#include "networkd-dhcp-common.h"
@@ -65,16 +66,7 @@ struct Network {
char *description;
/* [Match] section */
- Set *match_mac;
- Set *match_permanent_mac;
- char **match_path;
- char **match_driver;
- char **match_type;
- char **match_name;
- char **match_property;
- char **match_wlan_iftype;
- char **match_ssid;
- Set *match_bssid;
+ NetMatch match;
LIST_HEAD(Condition, conditions);
/* Master or stacked netdevs */
diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c
index 0fe81886bd..d068a4644d 100644
--- a/src/network/test-networkd-conf.c
+++ b/src/network/test-networkd-conf.c
@@ -1,15 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include "ether-addr-util.h"
#include "hexdecoct.h"
#include "log.h"
#include "macro.h"
-#include "set.h"
-#include "string-util.h"
-
-#include "network-internal.h"
+#include "net-condition.h"
#include "networkd-conf.h"
#include "networkd-network.h"
+#include "strv.h"
static void test_config_parse_duid_type_one(const char *rvalue, int ret, DUIDType expected, usec_t expected_time) {
DUID actual = {};
@@ -174,7 +171,7 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign
assert_se(network = new0(Network, 1));
network->n_ref = 1;
assert_se(network->filename = strdup("hogehoge.network"));
- assert_se(config_parse_match_ifnames("network", "filename", 1, "section", 1, "Name", 0, "*", &network->match_name, network) == 0);
+ assert_se(config_parse_match_ifnames("network", "filename", 1, "section", 1, "Name", 0, "*", &network->match.ifname, network) == 0);
assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0);
assert_se(ordered_hashmap_size(network->addresses_by_section) == 1);
assert_se(network_verify(network) >= 0);
diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/manager.c
index 79994bd49c..e3b350f526 100644
--- a/src/network/wait-online/manager.c
+++ b/src/network/wait-online/manager.c
@@ -8,7 +8,6 @@
#include "link.h"
#include "manager.h"
#include "netlink-util.h"
-#include "network-internal.h"
#include "strv.h"
#include "time-util.h"
#include "util.h"
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 7690eac8cd..0331922124 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -20,7 +20,6 @@
#include "io-util.h"
#include "missing_network.h"
#include "netlink-util.h"
-#include "network-internal.h"
#include "ordered-set.h"
#include "parse-util.h"
#include "random-util.h"
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 35d301d9db..e8b3dc78f9 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -11,6 +11,7 @@
#include "conf-files.h"
#include "conf-parser.h"
#include "def.h"
+#include "ether-addr-util.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
@@ -24,6 +25,7 @@
#include "process-util.h"
#include "rlimit-util.h"
#include "sd-id128.h"
+#include "set.h"
#include "signal-util.h"
#include "socket-util.h"
#include "string-util.h"
@@ -251,15 +253,16 @@ static int parse_line(
}
/* Go through the file and parse each line */
-int config_parse(const char *unit,
- const char *filename,
- FILE *f,
- const char *sections,
- ConfigItemLookup lookup,
- const void *table,
- ConfigParseFlags flags,
- void *userdata,
- usec_t *ret_mtime) {
+int config_parse(
+ const char *unit,
+ const char *filename,
+ FILE *f,
+ const char *sections,
+ ConfigItemLookup lookup,
+ const void *table,
+ ConfigParseFlags flags,
+ void *userdata,
+ usec_t *ret_mtime) {
_cleanup_free_ char *section = NULL, *continuation = NULL;
_cleanup_fclose_ FILE *ours = NULL;
@@ -522,16 +525,17 @@ DEFINE_PARSER(sec, usec_t, parse_sec);
DEFINE_PARSER(sec_def_infinity, usec_t, parse_sec_def_infinity);
DEFINE_PARSER(mode, mode_t, parse_mode);
-int config_parse_iec_size(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_iec_size(
+ 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) {
size_t *sz = data;
uint64_t v;
@@ -608,16 +612,17 @@ int config_parse_iec_uint64(
return 0;
}
-int config_parse_bool(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_bool(
+ 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 k;
bool *b = data;
@@ -1181,16 +1186,17 @@ int config_parse_rlimit(
return 0;
}
-int config_parse_permille(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_permille(
+ 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) {
unsigned *permille = data;
int r;
@@ -1212,17 +1218,20 @@ int config_parse_permille(const char* unit,
return 0;
}
-int config_parse_vlanprotocol(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_vlanprotocol(
+ 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 *vlan_protocol = data;
+
assert(filename);
assert(lvalue);
@@ -1244,4 +1253,106 @@ int config_parse_vlanprotocol(const char* unit,
return 0;
}
+int config_parse_hwaddr(
+ 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_free_ struct ether_addr *n = NULL;
+ struct ether_addr **hwaddr = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *hwaddr = mfree(*hwaddr);
+ return 0;
+ }
+
+ n = new0(struct ether_addr, 1);
+ if (!n)
+ return log_oom();
+
+ r = ether_addr_from_string(rvalue, n);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Not a valid MAC address, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ free_and_replace(*hwaddr, 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) {
+
+ Set **hwaddrs = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ /* Empty assignment resets the list */
+ *hwaddrs = set_free_free(*hwaddrs);
+ return 0;
+ }
+
+ for (const char *p = rvalue;;) {
+ _cleanup_free_ char *word = NULL;
+ _cleanup_free_ struct ether_addr *n = NULL;
+
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r == 0)
+ return 0;
+ 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_WARNING, filename, line, r,
+ "Not a valid MAC address, ignoring: %s", word);
+ continue;
+ }
+
+ r = set_ensure_put(hwaddrs, &ether_addr_hash_ops, n);
+ if (r < 0)
+ return log_oom();
+ if (r > 0)
+ TAKE_PTR(n); /* avoid cleanup */
+ }
+}
+
DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index f115cb23af..b194821937 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -147,6 +147,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
+CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
+CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
CONFIG_PARSER_PROTOTYPE(config_parse_percent);
typedef enum Disabled {
diff --git a/src/shared/meson.build b/src/shared/meson.build
index f30fe44995..53165541ac 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -169,6 +169,8 @@ shared_sources = files('''
module-util.h
mount-util.c
mount-util.h
+ net-condition.c
+ net-condition.h
netif-naming-scheme.c
netif-naming-scheme.h
nscd-flush.c
diff --git a/src/shared/net-condition.c b/src/shared/net-condition.c
new file mode 100644
index 0000000000..bdc8bc3fe4
--- /dev/null
+++ b/src/shared/net-condition.c
@@ -0,0 +1,428 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <netinet/ether.h>
+
+#include "condition.h"
+#include "env-util.h"
+#include "log.h"
+#include "net-condition.h"
+#include "network-util.h"
+#include "socket-util.h"
+#include "string-table.h"
+#include "strv.h"
+
+void net_match_clear(NetMatch *match) {
+ if (!match)
+ return;
+
+ match->mac = set_free_free(match->mac);
+ match->permanent_mac = set_free_free(match->permanent_mac);
+ match->path = strv_free(match->path);
+ match->driver = strv_free(match->driver);
+ match->iftype = strv_free(match->iftype);
+ match->ifname = strv_free(match->ifname);
+ match->property = strv_free(match->property);
+ match->wifi_iftype = strv_free(match->wifi_iftype);
+ match->ssid = strv_free(match->ssid);
+ match->bssid = set_free_free(match->bssid);
+}
+
+bool net_match_is_empty(const NetMatch *match) {
+ assert(match);
+
+ return
+ set_isempty(match->mac) &&
+ set_isempty(match->permanent_mac) &&
+ strv_isempty(match->path) &&
+ strv_isempty(match->driver) &&
+ strv_isempty(match->iftype) &&
+ strv_isempty(match->ifname) &&
+ strv_isempty(match->property) &&
+ strv_isempty(match->wifi_iftype) &&
+ strv_isempty(match->ssid) &&
+ set_isempty(match->bssid);
+}
+
+static bool net_condition_test_strv(char * const *patterns, const char *string) {
+ char * const *p;
+ bool match = false, has_positive_rule = false;
+
+ if (strv_isempty(patterns))
+ return true;
+
+ STRV_FOREACH(p, patterns) {
+ const char *q = *p;
+ bool invert;
+
+ invert = *q == '!';
+ q += invert;
+
+ if (!invert)
+ has_positive_rule = true;
+
+ if (string && fnmatch(q, string, 0) == 0) {
+ if (invert)
+ return false;
+ else
+ match = true;
+ }
+ }
+
+ return has_positive_rule ? match : true;
+}
+
+static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) {
+ if (net_condition_test_strv(patterns, ifname))
+ return true;
+
+ char * const *p;
+ STRV_FOREACH(p, alternative_names)
+ if (net_condition_test_strv(patterns, *p))
+ return true;
+
+ return false;
+}
+
+static int net_condition_test_property(char * const *match_property, sd_device *device) {
+ char * const *p;
+
+ if (strv_isempty(match_property))
+ return true;
+
+ STRV_FOREACH(p, match_property) {
+ _cleanup_free_ char *key = NULL;
+ const char *val, *dev_val;
+ bool invert, v;
+
+ invert = **p == '!';
+
+ val = strchr(*p + invert, '=');
+ if (!val)
+ return -EINVAL;
+
+ key = strndup(*p + invert, val - *p - invert);
+ if (!key)
+ return -ENOMEM;
+
+ val++;
+
+ v = device &&
+ sd_device_get_property_value(device, key, &dev_val) >= 0 &&
+ fnmatch(val, dev_val, 0) == 0;
+
+ if (invert ? v : !v)
+ return false;
+ }
+
+ return true;
+}
+
+static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
+ [NL80211_IFTYPE_ADHOC] = "ad-hoc",
+ [NL80211_IFTYPE_STATION] = "station",
+ [NL80211_IFTYPE_AP] = "ap",
+ [NL80211_IFTYPE_AP_VLAN] = "ap-vlan",
+ [NL80211_IFTYPE_WDS] = "wds",
+ [NL80211_IFTYPE_MONITOR] = "monitor",
+ [NL80211_IFTYPE_MESH_POINT] = "mesh-point",
+ [NL80211_IFTYPE_P2P_CLIENT] = "p2p-client",
+ [NL80211_IFTYPE_P2P_GO] = "p2p-go",
+ [NL80211_IFTYPE_P2P_DEVICE] = "p2p-device",
+ [NL80211_IFTYPE_OCB] = "ocb",
+ [NL80211_IFTYPE_NAN] = "nan",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(wifi_iftype, enum nl80211_iftype);
+
+bool net_match_config(
+ const NetMatch *match,
+ sd_device *device,
+ const struct ether_addr *mac,
+ const struct ether_addr *permanent_mac,
+ const char *driver,
+ unsigned short iftype,
+ const char *ifname,
+ char * const *alternative_names,
+ enum nl80211_iftype wifi_iftype,
+ const char *ssid,
+ const struct ether_addr *bssid) {
+
+ _cleanup_free_ char *iftype_str;
+ const char *path = NULL;
+
+ assert(match);
+
+ iftype_str = link_get_type_string(device, iftype);
+
+ if (device) {
+ const char *mac_str;
+
+ (void) sd_device_get_property_value(device, "ID_PATH", &path);
+ if (!driver)
+ (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &driver);
+ if (!ifname)
+ (void) sd_device_get_sysname(device, &ifname);
+ if (!mac &&
+ sd_device_get_sysattr_value(device, "address", &mac_str) >= 0)
+ mac = ether_aton(mac_str);
+ }
+
+ if (match->mac && (!mac || !set_contains(match->mac, mac)))
+ return false;
+
+ if (match->permanent_mac &&
+ (!permanent_mac ||
+ ether_addr_is_null(permanent_mac) ||
+ !set_contains(match->permanent_mac, permanent_mac)))
+ return false;
+
+ if (!net_condition_test_strv(match->path, path))
+ return false;
+
+ if (!net_condition_test_strv(match->driver, driver))
+ return false;
+
+ if (!net_condition_test_strv(match->iftype, iftype_str))
+ return false;
+
+ if (!net_condition_test_ifname(match->ifname, ifname, alternative_names))
+ return false;
+
+ if (!net_condition_test_property(match->property, device))
+ return false;
+
+ if (!net_condition_test_strv(match->wifi_iftype, wifi_iftype_to_string(wifi_iftype)))
+ return false;
+
+ if (!net_condition_test_strv(match->ssid, ssid))
+ return false;
+
+ if (match->bssid && (!bssid || !set_contains(match->bssid, bssid)))
+ return false;
+
+ return true;
+}
+
+int config_parse_net_condition(
+ 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) {
+
+ ConditionType cond = ltype;
+ Condition **list = data, *c;
+ bool negate;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *list = condition_free_list_type(*list, cond);
+ return 0;
+ }
+
+ negate = rvalue[0] == '!';
+ if (negate)
+ rvalue++;
+
+ c = condition_new(cond, rvalue, false, negate);
+ if (!c)
+ return log_oom();
+
+ /* Drop previous assignment. */
+ *list = condition_free_list_type(*list, cond);
+
+ LIST_PREPEND(conditions, *list, c);
+ return 0;
+}
+
+int config_parse_match_strv(
+ 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) {
+
+ const char *p = rvalue;
+ char ***sv = data;
+ bool invert;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *sv = strv_free(*sv);
+ return 0;
+ }
+
+ invert = *p == '!';
+ p += invert;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
+ if (r < 0)
+ return log_oom();
+ }
+}
+
+int config_parse_match_ifnames(
+ 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) {
+
+ const char *p = rvalue;
+ char ***sv = data;
+ bool invert;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *sv = strv_free(*sv);
+ return 0;
+ }
+
+ invert = *p == '!';
+ p += invert;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Failed to parse interface name list, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (!ifname_valid_full(word, ltype)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Interface name is not valid or too long, ignoring assignment: %s", word);
+ continue;
+ }
+
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
+ if (r < 0)
+ return log_oom();
+ }
+}
+
+int config_parse_match_property(
+ 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) {
+
+ const char *p = rvalue;
+ char ***sv = data;
+ bool invert;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *sv = strv_free(*sv);
+ return 0;
+ }
+
+ invert = *p == '!';
+ p += invert;
+
+ for (;;) {
+ _cleanup_free_ char *word = NULL, *k = NULL;
+
+ r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
+ if (r == 0)
+ return 0;
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Invalid syntax, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (!env_assignment_is_valid(word)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Invalid property or value, ignoring assignment: %s", word);
+ continue;
+ }
+
+ if (invert) {
+ k = strjoin("!", word);
+ if (!k)
+ return log_oom();
+ } else
+ k = TAKE_PTR(word);
+
+ r = strv_consume(sv, TAKE_PTR(k));
+ if (r < 0)
+ return log_oom();
+ }
+}
diff --git a/src/shared/net-condition.h b/src/shared/net-condition.h
new file mode 100644
index 0000000000..61058849a9
--- /dev/null
+++ b/src/shared/net-condition.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <linux/nl80211.h>
+#include <stdbool.h>
+
+#include "sd-device.h"
+
+#include "conf-parser.h"
+#include "ether-addr-util.h"
+#include "set.h"
+
+typedef struct NetMatch {
+ Set *mac;
+ Set *permanent_mac;
+ char **path;
+ char **driver;
+ char **iftype;
+ char **ifname;
+ char **property;
+ char **wifi_iftype;
+ char **ssid;
+ Set *bssid;
+} NetMatch;
+
+void net_match_clear(NetMatch *match);
+bool net_match_is_empty(const NetMatch *match);
+
+bool net_match_config(
+ const NetMatch *match,
+ sd_device *device,
+ const struct ether_addr *mac,
+ const struct ether_addr *permanent_mac,
+ const char *driver,
+ unsigned short iftype,
+ const char *ifname,
+ char * const *alternative_names,
+ enum nl80211_iftype wifi_iftype,
+ const char *ssid,
+ const struct ether_addr *bssid);
+
+CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
diff --git a/src/test/meson.build b/src/test/meson.build
index 6234294947..12bcf35708 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -126,8 +126,7 @@ tests += [
[['src/test/test-dns-domain.c'],
[libcore,
- libshared,
- libsystemd_network],
+ libshared],
[]],
[['src/test/test-boot-timestamps.c'],
@@ -530,7 +529,6 @@ tests += [
libjournal_core,
libudev_core,
libudev_static,
- libsystemd_network,
libshared],
[threads,
libseccomp,
@@ -766,7 +764,6 @@ tests += [
[['src/test/test-udev.c'],
[libudev_core,
libudev_static,
- libsystemd_network,
libshared],
[threads,
librt,
diff --git a/src/udev/meson.build b/src/udev/meson.build
index 5eb0f994a5..d67b459388 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -206,7 +206,6 @@ fuzzers += [
'src/fuzz/fuzz.h'],
[libudev_core,
libudev_static,
- libsystemd_network,
libshared],
[threads,
libacl]],
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 20f5d7e5a4..dc107170cc 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -6,7 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "conf-parser.h"
#include "ethtool-util.h"
#include "link-config.h"
-#include "network-internal.h"
+#include "net-condition.h"
#include "socket-util.h"
%}
struct ConfigPerfItem;
@@ -20,13 +20,13 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
-Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac)
-Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_permanent_mac)
-Match.OriginalName, config_parse_match_ifnames, 0, offsetof(link_config, match_name)
-Match.Path, config_parse_match_strv, 0, offsetof(link_config, match_path)
-Match.Driver, config_parse_match_strv, 0, offsetof(link_config, match_driver)
-Match.Type, config_parse_match_strv, 0, offsetof(link_config, match_type)
-Match.Property, config_parse_match_property, 0, offsetof(link_config, match_property)
+Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match.mac)
+Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match.permanent_mac)
+Match.OriginalName, config_parse_match_ifnames, 0, offsetof(link_config, match.ifname)
+Match.Path, config_parse_match_strv, 0, offsetof(link_config, match.path)
+Match.Driver, config_parse_match_strv, 0, offsetof(link_config, match.driver)
+Match.Type, config_parse_match_strv, 0, offsetof(link_config, match.iftype)
+Match.Property, config_parse_match_property, 0, offsetof(link_config, match.property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions)
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index d12fd0e299..cbeaad9ccc 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -18,9 +18,10 @@
#include "link-config.h"
#include "log.h"
#include "memory-util.h"
+#include "net-condition.h"
#include "netif-naming-scheme.h"
#include "netlink-util.h"
-#include "network-internal.h"
+#include "network-util.h"
#include "parse-util.h"
#include "path-lookup.h"
#include "path-util.h"
@@ -30,6 +31,7 @@
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
+#include "utf8.h"
struct link_config_ctx {
LIST_HEAD(link_config, links);
@@ -49,13 +51,7 @@ static void link_config_free(link_config *link) {
free(link->filename);
- set_free_free(link->match_mac);
- set_free_free(link->match_permanent_mac);
- strv_free(link->match_path);
- strv_free(link->match_driver);
- strv_free(link->match_type);
- strv_free(link->match_name);
- strv_free(link->match_property);
+ net_match_clear(&link->match);
condition_free_list(link->conditions);
free(link->description);
@@ -167,9 +163,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) {
if (r < 0)
return r;
- if (set_isempty(link->match_mac) && set_isempty(link->match_permanent_mac) &&
- strv_isempty(link->match_path) && strv_isempty(link->match_driver) && strv_isempty(link->match_type) &&
- strv_isempty(link->match_name) && strv_isempty(link->match_property) && !link->conditions) {
+ if (net_match_is_empty(&link->match) && !link->conditions) {
log_warning("%s: No valid settings found in the [Match] section, ignoring file. "
"To match all interfaces, add OriginalName=* in the [Match] section.",
filename);
@@ -279,11 +273,8 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
(void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
LIST_FOREACH(links, link, ctx->links) {
- if (net_match_config(link->match_mac, link->match_permanent_mac, link->match_path, link->match_driver,
- link->match_type, link->match_name, link->match_property, NULL, NULL, NULL,
- device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL)) {
-
- if (link->match_name && !strv_contains(link->match_name, "*") && name_assign_type == NET_NAME_ENUM)
+ if (net_match_config(&link->match, device, NULL, &permanent_mac, NULL, iftype, NULL, NULL, 0, NULL, NULL)) {
+ if (link->match.ifname && !strv_contains(link->match.ifname, "*") && name_assign_type == NET_NAME_ENUM)
log_device_warning(device, "Config file %s is applied to device based on potentially unpredictable interface name.",
link->filename);
else
@@ -668,6 +659,48 @@ int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret) {
return 0;
}
+int config_parse_ifalias(
+ 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) {
+
+ char **s = data;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (!isempty(rvalue)) {
+ *s = mfree(*s);
+ return 0;
+ }
+
+ if (!ascii_is_valid(rvalue)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Interface alias is not ASCII clean, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ if (strlen(rvalue) >= IFALIASZ) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Interface alias is too long, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ if (free_and_strdup(s, rvalue) < 0)
+ return log_oom();
+
+ return 0;
+}
+
static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = {
[MAC_ADDRESS_POLICY_PERSISTENT] = "persistent",
[MAC_ADDRESS_POLICY_RANDOM] = "random",
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index eab1849fcd..1beecb10ea 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -7,7 +7,7 @@
#include "conf-parser.h"
#include "ethtool-util.h"
#include "list.h"
-#include "set.h"
+#include "net-condition.h"
typedef struct link_config_ctx link_config_ctx;
typedef struct link_config link_config;
@@ -35,13 +35,7 @@ typedef enum NamePolicy {
struct link_config {
char *filename;
- Set *match_mac;
- Set *match_permanent_mac;
- char **match_path;
- char **match_driver;
- char **match_type;
- char **match_name;
- char **match_property;
+ NetMatch match;
LIST_HEAD(Condition, conditions);
char *description;
@@ -93,6 +87,7 @@ MACAddressPolicy mac_address_policy_from_string(const char *p) _pure_;
/* gperf lookup function */
const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
+CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
CONFIG_PARSER_PROTOTYPE(config_parse_mac_address_policy);
CONFIG_PARSER_PROTOTYPE(config_parse_name_policy);
CONFIG_PARSER_PROTOTYPE(config_parse_alternative_names_policy);