net-condition: introduce struct NetMatch

This commit is contained in:
Yu Watanabe 2020-10-29 15:04:52 +09:00
parent 26f4d32365
commit 5722fb89bc
10 changed files with 126 additions and 136 deletions

View File

@ -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
};

View File

@ -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)

View File

@ -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.",
@ -588,16 +584,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);
@ -704,13 +691,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;

View File

@ -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 */

View File

@ -171,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);

View File

@ -11,6 +11,38 @@
#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;
@ -103,76 +135,69 @@ static const char *const wifi_iftype_table[NL80211_IFTYPE_MAX+1] = {
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,
const NetMatch *match,
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,
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 dev_wifi_iftype,
const char *dev_ssid,
const struct ether_addr *dev_bssid) {
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid) {
_cleanup_free_ char *dev_iftype_str;
const char *dev_path = NULL;
_cleanup_free_ char *iftype_str;
const char *path = NULL;
dev_iftype_str = link_get_type_string(device, dev_iftype);
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", &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 &&
(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)
dev_mac = ether_aton(mac_str);
mac = ether_aton(mac_str);
}
if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac)))
if (match->mac && (!mac || !set_contains(match->mac, 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)))
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_paths, dev_path))
if (!net_condition_test_strv(match->path, path))
return false;
if (!net_condition_test_strv(match_drivers, dev_driver))
if (!net_condition_test_strv(match->driver, driver))
return false;
if (!net_condition_test_strv(match_iftypes, dev_iftype_str))
if (!net_condition_test_strv(match->iftype, iftype_str))
return false;
if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
if (!net_condition_test_ifname(match->ifname, ifname, alternative_names))
return false;
if (!net_condition_test_property(match_property, device))
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)))
if (!net_condition_test_strv(match->wifi_iftype, wifi_iftype_to_string(wifi_iftype)))
return false;
if (!net_condition_test_strv(match_ssid, dev_ssid))
if (!net_condition_test_strv(match->ssid, ssid))
return false;
if (match_bssid && (!dev_bssid || !set_contains(match_bssid, dev_bssid)))
if (match->bssid && (!bssid || !set_contains(match->bssid, bssid)))
return false;
return true;

View File

@ -10,27 +10,34 @@
#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(
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,
const NetMatch *match,
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,
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 dev_wifi_iftype,
const char *dev_ssid,
const struct ether_addr *dev_bssid);
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);

View File

@ -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)

View File

@ -51,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);
@ -169,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);
@ -274,11 +266,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

View File

@ -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;