]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
net-condition: move net_match_config() and related conf parsers
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 28 Oct 2020 15:20:14 +0000 (00:20 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 29 Oct 2020 05:23:49 +0000 (14:23 +0900)
13 files changed:
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/libsystemd-network/sd-dhcp6-client.c
src/network/netdev/netdev-gperf.gperf
src/network/networkd-dhcp4.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/test-networkd-conf.c
src/shared/meson.build
src/shared/net-condition.c [new file with mode: 0644]
src/shared/net-condition.h [new file with mode: 0644]
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c

index cb6cff2a97530be24f61a00ecb1e58bfeabaf4c0..4abe7298be1b29b9c84441213e82ef56cb83289b 100644 (file)
@@ -8,21 +8,14 @@
 #include "sd-ndisc.h"
 
 #include "alloc-util.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 "hexdecoct.h"
 #include "log.h"
 #include "network-internal.h"
 #include "network-util.h"
 #include "parse-util.h"
 #include "siphash24.h"
-#include "socket-util.h"
-#include "string-table.h"
-#include "string-util.h"
 #include "strv.h"
 #include "util.h"
 
@@ -75,395 +68,6 @@ int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_
         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);
-
-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(device, dev_iftype);
-
-        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_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: %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();
-        }
-}
-
 size_t serialize_in_addrs(FILE *f,
                           const struct in_addr *addresses,
                           size_t size,
index 90fd2fb2aa35e98012bc2c920441f8dbfb316892..8bdaa29c7804db967e7204995dc4c2ad7cab9366 100644 (file)
@@ -1,42 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #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"
-
-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_match_strv);
-CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
-CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
-
 int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result);
 const char *net_get_name_persistent(sd_device *device);
 
index 6d27c4685eddd030cc03357ab0d2c41ab3e07d6d..43d42b4f868e05e9968e006a5e52e4840d54f927 100644 (file)
@@ -25,6 +25,7 @@
 #include "random-util.h"
 #include "socket-util.h"
 #include "string-table.h"
+#include "strv.h"
 #include "util.h"
 #include "web-util.h"
 
index 4e89761f2c9cba85773c053136a0d9ff797fff04..35cd01ef0d8757cbb64ea41b2646cf419ff322ba 100644 (file)
@@ -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;
index bb8c34f7cc5959c048e21a3a6b61c73cb54453ec..89bc15bb873742d9ba8b6249e95d977dd444829b 100644 (file)
@@ -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"
 
index 5cc9e3e8f6e47e6ab30b705815e1292a19ffa9a4..19c3b088a1b2e3469c8a8f3e51c7ceb4c359de61 100644 (file)
@@ -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"
index 426dd0a8f0bfc6dc206ee3e5b76a6c962328e0d0..dd937d37f2abba64bf13e37cdedfae4c9e6bdd48 100644 (file)
 #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"
index 030e50688a4e9ecd0a94f6340dd0a970a8b3687c..57c5068e3a48b43986807f99d96219552a14e386 100644 (file)
@@ -1,15 +1,12 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
-#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 = {};
index 260ee5a8b633e0912d0c8ccaf047c96affe4cbbd..aa3c915f3318cadfedeb040ffb562ff147018283 100644 (file)
@@ -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 (file)
index 0000000..b3bcebf
--- /dev/null
@@ -0,0 +1,403 @@
+/* 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"
+
+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(
+                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(device, dev_iftype);
+
+        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_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 (file)
index 0000000..31d5d01
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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"
+
+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_match_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_match_property);
index 20f5d7e5a45bbcb848d9b23f28c77c03692edb1b..6c8d574875cf8e89a84a336f59da11b3574d96a4 100644 (file)
@@ -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;
index fe542ca8a5becc17505826259c28818a816fe6d5..c0b74ed3d4095bbbf4176297b6aca84984cd939d 100644 (file)
@@ -18,6 +18,7 @@
 #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"