mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 14:50:24 +01:00
merge: branch 'bg/wildcard-match-rh1555012'
https://bugzilla.redhat.com/show_bug.cgi?id=1555012 https://github.com/NetworkManager/NetworkManager/pull/181
This commit is contained in:
commit
0103bb33a6
28 changed files with 866 additions and 91 deletions
|
|
@ -463,6 +463,7 @@ libnm_core_lib_h_pub_real = \
|
|||
libnm-core/nm-setting-ip6-config.h \
|
||||
libnm-core/nm-setting-macsec.h \
|
||||
libnm-core/nm-setting-macvlan.h \
|
||||
libnm-core/nm-setting-match.h \
|
||||
libnm-core/nm-setting-olpc-mesh.h \
|
||||
libnm-core/nm-setting-ovs-bridge.h \
|
||||
libnm-core/nm-setting-ovs-interface.h \
|
||||
|
|
@ -536,6 +537,7 @@ libnm_core_lib_c_settings_real = \
|
|||
libnm-core/nm-setting-ip6-config.c \
|
||||
libnm-core/nm-setting-macsec.c \
|
||||
libnm-core/nm-setting-macvlan.c \
|
||||
libnm-core/nm-setting-match.c \
|
||||
libnm-core/nm-setting-olpc-mesh.c \
|
||||
libnm-core/nm-setting-ovs-bridge.c \
|
||||
libnm-core/nm-setting-ovs-interface.c \
|
||||
|
|
@ -2252,6 +2254,7 @@ EXTRA_DIST += \
|
|||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Static_Routes.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Vlan_test-vlan-interface.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-dcb-test.cexpected \
|
||||
src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-netmask-1 \
|
||||
|
|
|
|||
|
|
@ -734,6 +734,7 @@ const NmcMetaGenericInfo *const metagen_con_active_vpn[_NMC_GENERIC_INFO_TYPE_CO
|
|||
/*****************************************************************************/
|
||||
|
||||
#define NMC_FIELDS_SETTINGS_NAMES_ALL NM_SETTING_CONNECTION_SETTING_NAME","\
|
||||
NM_SETTING_MATCH_SETTING_NAME","\
|
||||
NM_SETTING_WIRED_SETTING_NAME","\
|
||||
NM_SETTING_802_1X_SETTING_NAME","\
|
||||
NM_SETTING_WIRELESS_SETTING_NAME","\
|
||||
|
|
@ -1807,7 +1808,7 @@ parse_preferred_connection_order (const char *order, GError **error)
|
|||
gboolean inverse, unique;
|
||||
int i;
|
||||
|
||||
strv = nm_utils_strsplit_set (order, ":");
|
||||
strv = nm_utils_strsplit_set (order, ":", FALSE);
|
||||
if (!strv) {
|
||||
g_set_error (error, NMCLI_ERROR, 0,
|
||||
_("incorrect string '%s' of '--order' option"), order);
|
||||
|
|
@ -2573,7 +2574,7 @@ parse_passwords (const char *passwd_file, GError **error)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
strv = nm_utils_strsplit_set (contents, "\r\n");
|
||||
strv = nm_utils_strsplit_set (contents, "\r\n", FALSE);
|
||||
for (iter = strv; *iter; iter++) {
|
||||
gs_free char *iter_s = g_strdup (*iter);
|
||||
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ _set_fcn_precheck_connection_secondaries (const char *value,
|
|||
char **iter;
|
||||
gboolean modified = FALSE;
|
||||
|
||||
strv0 = nm_utils_strsplit_set (value, " \t,");
|
||||
strv0 = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (!strv0)
|
||||
return TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ nmc_string_to_arg_array (const char *line, const char *delim, gboolean unquote,
|
|||
gs_free const char **arr0 = NULL;
|
||||
char **arr;
|
||||
|
||||
arr0 = nm_utils_strsplit_set (line ?: "", delim ?: " \t");
|
||||
arr0 = nm_utils_strsplit_set (line ?: "", delim ?: " \t", FALSE);
|
||||
if (!arr0)
|
||||
arr = g_new0 (char *, 1);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ _parse_ip_route (int family,
|
|||
nm_assert (!error || !*error);
|
||||
|
||||
str_clean = g_strstrip (g_strdup (str));
|
||||
routev = nm_utils_strsplit_set (str_clean, " \t");
|
||||
routev = nm_utils_strsplit_set (str_clean, " \t", FALSE);
|
||||
if (!routev) {
|
||||
g_set_error (error, 1, 0,
|
||||
"'%s' is not valid. %s",
|
||||
|
|
@ -313,7 +313,7 @@ _parse_team_link_watcher (const char *str,
|
|||
nm_assert (!error || !*error);
|
||||
|
||||
str_clean = g_strstrip (g_strdup (str));
|
||||
watcherv = nm_utils_strsplit_set (str_clean, " \t");
|
||||
watcherv = nm_utils_strsplit_set (str_clean, " \t", FALSE);
|
||||
if (!watcherv) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid", str);
|
||||
return NULL;
|
||||
|
|
@ -322,7 +322,7 @@ _parse_team_link_watcher (const char *str,
|
|||
for (i = 0; watcherv[i]; i++) {
|
||||
gs_free const char **pair = NULL;
|
||||
|
||||
pair = nm_utils_strsplit_set (watcherv[i], "=");
|
||||
pair = nm_utils_strsplit_set (watcherv[i], "=", FALSE);
|
||||
if (!pair) {
|
||||
g_set_error (error, 1, 0, "'%s' is not valid: %s", watcherv[i],
|
||||
"properties should be specified as 'key=value'");
|
||||
|
|
@ -1589,7 +1589,7 @@ vpn_data_item (const char *key, const char *value, gpointer user_data)
|
|||
gsize i; \
|
||||
const char *item; \
|
||||
nm_assert (!error || !*error); \
|
||||
strv = nm_utils_strsplit_set (value, " \t,"); \
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
|
||||
if (strv) { \
|
||||
for (i = 0; strv[i]; i++) { \
|
||||
if (!(item = nmc_string_is_valid (strv[i], valid_strv, error))) { \
|
||||
|
|
@ -1613,7 +1613,7 @@ vpn_data_item (const char *key, const char *value, gpointer user_data)
|
|||
\
|
||||
nm_assert (!error || !*error); \
|
||||
\
|
||||
strv = nm_utils_strsplit_set (value, ","); \
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE); \
|
||||
for (iter = strv; iter && *iter; iter++) { \
|
||||
gs_free char *left_clone = g_strstrip (g_strdup (*iter)); \
|
||||
char *left = left_clone; \
|
||||
|
|
@ -1700,7 +1700,7 @@ vpn_data_item (const char *key, const char *value, gpointer user_data)
|
|||
\
|
||||
nm_assert (!error || !*error); \
|
||||
\
|
||||
strv = nm_utils_strsplit_set (value, " \t,"); \
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
|
||||
for (iter = strv; strv && *iter; iter++) { \
|
||||
if (!nm_utils_hwaddr_aton (*iter, buf, ETH_ALEN)) { \
|
||||
g_set_error (error, 1, 0, _("'%s' is not a valid MAC"), *iter); \
|
||||
|
|
@ -1918,7 +1918,7 @@ nmc_property_set_bytes (NMSetting *setting, const char *prop, const char *value,
|
|||
goto done;
|
||||
|
||||
/* Otherwise, consider the following format: AA b 0xCc D */
|
||||
strv = nm_utils_strsplit_set (val_strip, " \t");
|
||||
strv = nm_utils_strsplit_set (val_strip, " \t", FALSE);
|
||||
array = g_byte_array_sized_new (NM_PTRARRAY_LEN (strv));
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
int v;
|
||||
|
|
@ -2138,7 +2138,7 @@ _get_fcn_802_1x_phase2_private_key (ARGS_GET_FCN)
|
|||
\
|
||||
nm_assert (error == NULL || *error == NULL); \
|
||||
\
|
||||
strv = nm_utils_strsplit_set (value, " \t,"); \
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE); \
|
||||
if (strv) { \
|
||||
for (i = 0; strv[i]; i++) \
|
||||
set_func (NM_SETTING_802_1X (setting), strv[i++]); \
|
||||
|
|
@ -2530,7 +2530,7 @@ _set_fcn_connection_permissions (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (!verify_string_list (strv, property_info->property_name, permissions_valid, error))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -2655,7 +2655,7 @@ _set_fcn_connection_secondaries (ARGS_SET_FCN)
|
|||
gs_free const char **strv = NULL;
|
||||
const char *const*iter;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (strv) {
|
||||
for (iter = strv; *iter; iter++)
|
||||
nm_setting_connection_add_secondary (NM_SETTING_CONNECTION (setting), *iter);
|
||||
|
|
@ -2861,7 +2861,7 @@ _set_fcn_dcb_flags (ARGS_SET_FCN)
|
|||
const char *const*iter;
|
||||
|
||||
/* Check for individual flag numbers */
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
t = _nm_utils_ascii_str_to_int64 (*iter, 0, 0, DCB_ALL_FLAGS, -1);
|
||||
|
||||
|
|
@ -3264,7 +3264,7 @@ _set_fcn_ip4_config_dns (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
gs_free char *addr = g_strstrip (g_strdup (*iter));
|
||||
|
||||
|
|
@ -3309,7 +3309,7 @@ _set_fcn_ip4_config_dns_search (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (!verify_string_list (strv, property_info->property_name, nmc_util_is_domain, error))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -3349,7 +3349,7 @@ _set_fcn_ip4_config_dns_options (ARGS_SET_FCN)
|
|||
nm_assert (!error || !*error);
|
||||
|
||||
nm_setting_ip_config_clear_dns_options (NM_SETTING_IP_CONFIG (setting), TRUE);
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (strv) {
|
||||
for (i = 0; strv[i]; i++)
|
||||
nm_setting_ip_config_add_dns_option (NM_SETTING_IP_CONFIG (setting), strv[i]);
|
||||
|
|
@ -3384,7 +3384,7 @@ _set_fcn_ip4_config_addresses (ARGS_SET_FCN)
|
|||
const char *const*iter;
|
||||
NMIPAddress *ip4addr;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; *iter; iter++) {
|
||||
ip4addr = _parse_ip_address (AF_INET, *iter, error);
|
||||
if (!ip4addr)
|
||||
|
|
@ -3444,7 +3444,7 @@ _set_fcn_ip4_config_routes (ARGS_SET_FCN)
|
|||
const char *const*iter;
|
||||
NMIPRoute *ip4route;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; *iter; iter++) {
|
||||
ip4route = _parse_ip_route (AF_INET, *iter, error);
|
||||
if (!ip4route)
|
||||
|
|
@ -3508,7 +3508,7 @@ _set_fcn_ip6_config_dns (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
gs_free char *addr = g_strstrip (g_strdup (*iter));
|
||||
|
||||
|
|
@ -3553,7 +3553,7 @@ _set_fcn_ip6_config_dns_search (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (!verify_string_list (strv, property_info->property_name, nmc_util_is_domain, error))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -3593,7 +3593,7 @@ _set_fcn_ip6_config_dns_options (ARGS_SET_FCN)
|
|||
nm_assert (!error || !*error);
|
||||
|
||||
nm_setting_ip_config_clear_dns_options (NM_SETTING_IP_CONFIG (setting), TRUE);
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
if (strv) {
|
||||
for (i = 0; strv[i]; i++)
|
||||
nm_setting_ip_config_add_dns_option (NM_SETTING_IP_CONFIG (setting), strv[i]);
|
||||
|
|
@ -3635,7 +3635,7 @@ _set_fcn_ip6_config_addresses (ARGS_SET_FCN)
|
|||
const char *const*iter;
|
||||
NMIPAddress *ip6addr;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
ip6addr = _parse_ip_address (AF_INET6, *iter, error);
|
||||
if (!ip6addr)
|
||||
|
|
@ -3695,7 +3695,7 @@ _set_fcn_ip6_config_routes (ARGS_SET_FCN)
|
|||
const char *const*iter;
|
||||
NMIPRoute *ip6route;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
ip6route = _parse_ip_route (AF_INET6, *iter, error);
|
||||
if (!ip6route)
|
||||
|
|
@ -3730,6 +3730,68 @@ DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_ipv6_config_routes,
|
|||
nm_setting_ip_config_remove_route,
|
||||
_validate_and_remove_ipv6_route)
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_match_interface_name (ARGS_GET_FCN)
|
||||
{
|
||||
NMSettingMatch *s_match = NM_SETTING_MATCH (setting);
|
||||
GString *str = NULL;
|
||||
guint i, num;
|
||||
|
||||
RETURN_UNSUPPORTED_GET_TYPE ();
|
||||
|
||||
num = nm_setting_match_get_num_interface_names (s_match);
|
||||
for (i = 0; i < num; i++) {
|
||||
const char *name;
|
||||
gs_free char *to_free = NULL;
|
||||
|
||||
if (i == 0)
|
||||
str = g_string_new ("");
|
||||
else
|
||||
g_string_append_c (str, ' ');
|
||||
name = nm_setting_match_get_interface_name (s_match, i);
|
||||
g_string_append (str, _nm_utils_escape_spaces (name, &to_free));
|
||||
}
|
||||
RETURN_STR_TO_FREE (g_string_free (str, FALSE));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_fcn_match_interface_name (ARGS_SET_FCN)
|
||||
{
|
||||
gs_free const char **strv = NULL;
|
||||
gsize i;
|
||||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t", TRUE);
|
||||
if (strv) {
|
||||
for (i = 0; strv[i]; i++) {
|
||||
nm_setting_match_add_interface_name (NM_SETTING_MATCH (setting),
|
||||
_nm_utils_unescape_spaces ((char *) strv[i]));
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_validate_and_remove_match_interface_name (NMSettingMatch *setting,
|
||||
const char *interface_name,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
ret = nm_setting_match_remove_interface_name_by_value (setting, interface_name);
|
||||
if (!ret)
|
||||
g_set_error (error, 1, 0,
|
||||
_("the property doesn't contain interface name '%s'"),
|
||||
interface_name);
|
||||
return ret;
|
||||
}
|
||||
DEFINE_REMOVER_INDEX_OR_VALUE (_remove_fcn_match_interface_name,
|
||||
NM_SETTING_MATCH,
|
||||
nm_setting_match_get_num_interface_names,
|
||||
nm_setting_match_remove_interface_name,
|
||||
_validate_and_remove_match_interface_name)
|
||||
|
||||
static gconstpointer
|
||||
_get_fcn_olpc_mesh_ssid (ARGS_GET_FCN)
|
||||
{
|
||||
|
|
@ -3844,7 +3906,7 @@ _set_fcn_sriov_vfs (ARGS_SET_FCN)
|
|||
NMSriovVF *vf;
|
||||
GError *local = NULL;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
vf = nm_utils_sriov_vf_from_str (*iter, &local);
|
||||
if (!vf) {
|
||||
|
|
@ -3866,7 +3928,7 @@ _set_fcn_tc_config_qdiscs (ARGS_SET_FCN)
|
|||
NMTCQdisc *tc_qdisc;
|
||||
GError *local = NULL;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
tc_qdisc = nm_utils_tc_qdisc_from_str (*iter, &local);
|
||||
if (!tc_qdisc) {
|
||||
|
|
@ -3971,7 +4033,7 @@ _set_fcn_tc_config_tfilters (ARGS_SET_FCN)
|
|||
NMTCTfilter *tc_tfilter;
|
||||
GError *local = NULL;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
tc_tfilter = nm_utils_tc_tfilter_from_str (*iter, &local);
|
||||
if (!tc_tfilter) {
|
||||
|
|
@ -4044,7 +4106,7 @@ _set_fcn_team_runner_tx_hash (ARGS_SET_FCN)
|
|||
|
||||
nm_assert (!error || !*error);
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " \t,");
|
||||
strv = nm_utils_strsplit_set (value, " \t,", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
if (!_is_valid_team_runner_tx_hash_element (*iter, error))
|
||||
return FALSE;
|
||||
|
|
@ -4116,7 +4178,7 @@ _set_fcn_team_link_watchers (ARGS_SET_FCN)
|
|||
NMTeamLinkWatcher *watcher;
|
||||
|
||||
nm_setting_team_clear_link_watchers (NM_SETTING_TEAM (setting));
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
watcher = _parse_team_link_watcher (*iter, error);
|
||||
if (!watcher)
|
||||
|
|
@ -4190,7 +4252,7 @@ _set_fcn_team_port_link_watchers (ARGS_SET_FCN)
|
|||
NMTeamLinkWatcher *watcher;
|
||||
|
||||
nm_setting_team_port_clear_link_watchers (NM_SETTING_TEAM_PORT (setting));
|
||||
strv = nm_utils_strsplit_set (value, ",");
|
||||
strv = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
for (iter = strv; strv && *iter; iter++) {
|
||||
watcher = _parse_team_link_watcher (*iter, error);
|
||||
if (!watcher)
|
||||
|
|
@ -4470,7 +4532,7 @@ _set_fcn_wired_s390_subchannels (ARGS_SET_FCN)
|
|||
gs_free const char **strv = NULL;
|
||||
gsize len;
|
||||
|
||||
strv = nm_utils_strsplit_set (value, " ,\t");
|
||||
strv = nm_utils_strsplit_set (value, " ,\t", FALSE);
|
||||
len = NM_PTRARRAY_LEN (strv);
|
||||
if (len != 2 && len != 3) {
|
||||
g_set_error (error, 1, 0, _("'%s' is not valid; 2 or 3 strings should be provided"),
|
||||
|
|
@ -6532,6 +6594,19 @@ static const NMMetaPropertyInfo *const property_infos_MACVLAN[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
#undef _CURRENT_NM_META_SETTING_TYPE
|
||||
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_MATCH
|
||||
static const NMMetaPropertyInfo *const property_infos_MATCH[] = {
|
||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_MATCH_INTERFACE_NAME,
|
||||
.property_type = DEFINE_PROPERTY_TYPE (
|
||||
.get_fcn = _get_fcn_match_interface_name,
|
||||
.set_fcn = _set_fcn_match_interface_name,
|
||||
.remove_fcn = _remove_fcn_match_interface_name,
|
||||
),
|
||||
),
|
||||
NULL
|
||||
};
|
||||
|
||||
#undef _CURRENT_NM_META_SETTING_TYPE
|
||||
#define _CURRENT_NM_META_SETTING_TYPE NM_META_SETTING_TYPE_OLPC_MESH
|
||||
static const NMMetaPropertyInfo *const property_infos_OLPC_MESH[] = {
|
||||
|
|
@ -7900,6 +7975,7 @@ _setting_init_fcn_wireless (ARGS_SETTING_INIT_FCN)
|
|||
#define SETTING_PRETTY_NAME_IP_TUNNEL N_("IP-tunnel settings")
|
||||
#define SETTING_PRETTY_NAME_MACSEC N_("MACsec connection")
|
||||
#define SETTING_PRETTY_NAME_MACVLAN N_("macvlan connection")
|
||||
#define SETTING_PRETTY_NAME_MATCH N_("Match")
|
||||
#define SETTING_PRETTY_NAME_OLPC_MESH N_("OLPC Mesh connection")
|
||||
#define SETTING_PRETTY_NAME_OVS_BRIDGE N_("OpenVSwitch bridge settings")
|
||||
#define SETTING_PRETTY_NAME_OVS_INTERFACE N_("OpenVSwitch interface settings")
|
||||
|
|
@ -8066,6 +8142,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = {
|
|||
NM_META_SETTING_VALID_PART_ITEM (ETHTOOL, FALSE),
|
||||
),
|
||||
),
|
||||
SETTING_INFO (MATCH),
|
||||
SETTING_INFO (OLPC_MESH,
|
||||
.alias = "olpc-mesh",
|
||||
.valid_parts = NM_META_SETTING_VALID_PARTS (
|
||||
|
|
@ -8209,6 +8286,7 @@ const NMMetaSettingValidPartItem *const nm_meta_setting_info_valid_parts_default
|
|||
/*****************************************************************************/
|
||||
|
||||
static const NMMetaSettingValidPartItem *const valid_settings_noslave[] = {
|
||||
NM_META_SETTING_VALID_PART_ITEM (MATCH, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM (IP4_CONFIG, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM (IP6_CONFIG, FALSE),
|
||||
NM_META_SETTING_VALID_PART_ITEM (TC_CONFIG, FALSE),
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@
|
|||
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PARENT N_("If given, specifies the parent interface name or parent connection UUID from which this MAC-VLAN interface should be created. If this property is not specified, the connection must contain an \"802-3-ethernet\" setting with a \"mac-address\" property.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_PROMISCUOUS N_("Whether the interface should be put in promiscuous mode.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_MACVLAN_TAP N_("Whether the interface should be a MACVTAP.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_MATCH_INTERFACE_NAME N_("A list of interface names to match. Each element is a shell wildcard pattern. When an element is prefixed with exclamation mark (!) the condition is inverted. A candidate interface name is considered matching when both these conditions are satisfied: (a) any of the elements not prefixed with '!' matches or there aren't such elements; (b) none of the elements prefixed with '!' match.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_FAIL_MODE N_("The bridge failure mode. One of \"secure\", \"standalone\" or empty.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_MCAST_SNOOPING_ENABLE N_("Enable or disable multicast snooping.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_OVS_BRIDGE_RSTP_ENABLE N_("Enable or disable RSTP.")
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
|
|||
<xi:include href="xml/nm-setting-ip-tunnel.xml"/>
|
||||
<xi:include href="xml/nm-setting-macsec.xml"/>
|
||||
<xi:include href="xml/nm-setting-macvlan.xml"/>
|
||||
<xi:include href="xml/nm-setting-match.xml"/>
|
||||
<xi:include href="xml/nm-setting-olpc-mesh.xml"/>
|
||||
<xi:include href="xml/nm-setting-ovs-bridge.xml"/>
|
||||
<xi:include href="xml/nm-setting-ovs-interface.xml"/>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ libnm_core_headers = files(
|
|||
'nm-setting-ip6-config.h',
|
||||
'nm-setting-macsec.h',
|
||||
'nm-setting-macvlan.h',
|
||||
'nm-setting-match.h',
|
||||
'nm-setting-olpc-mesh.h',
|
||||
'nm-setting-ovs-bridge.h',
|
||||
'nm-setting-ovs-interface.h',
|
||||
|
|
@ -79,6 +80,7 @@ libnm_core_settings_sources = files(
|
|||
'nm-setting-ip6-config.c',
|
||||
'nm-setting-macsec.c',
|
||||
'nm-setting-macvlan.c',
|
||||
'nm-setting-match.c',
|
||||
'nm-setting-olpc-mesh.c',
|
||||
'nm-setting-ovs-bridge.c',
|
||||
'nm-setting-ovs-interface.c',
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-macsec.h"
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-setting-match.h"
|
||||
#include "nm-setting-olpc-mesh.h"
|
||||
#include "nm-setting-ovs-bridge.h"
|
||||
#include "nm-setting-ovs-interface.h"
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ typedef struct _NMSettingIP4Config NMSettingIP4Config;
|
|||
typedef struct _NMSettingIP6Config NMSettingIP6Config;
|
||||
typedef struct _NMSettingMacsec NMSettingMacsec;
|
||||
typedef struct _NMSettingMacvlan NMSettingMacvlan;
|
||||
typedef struct _NMSettingMatch NMSettingMatch;
|
||||
typedef struct _NMSettingOlpcMesh NMSettingOlpcMesh;
|
||||
typedef struct _NMSettingOvsBridge NMSettingOvsBridge;
|
||||
typedef struct _NMSettingOvsInterface NMSettingOvsInterface;
|
||||
|
|
|
|||
|
|
@ -1691,8 +1691,6 @@ nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int idx)
|
|||
* Removes the DNS search domain @dns_search.
|
||||
*
|
||||
* Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not.
|
||||
*
|
||||
* Since 0.9.10
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting,
|
||||
|
|
|
|||
295
libnm-core/nm-setting-match.c
Normal file
295
libnm-core/nm-setting-match.c
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-setting-match.h"
|
||||
#include "nm-setting-private.h"
|
||||
#include "nm-utils-private.h"
|
||||
|
||||
/**
|
||||
* SECTION:nm-setting-match
|
||||
* @short_description: Properties to match a connection with a device.
|
||||
* @include: nm-setting-match.h
|
||||
**/
|
||||
|
||||
/**
|
||||
* NMSettingMatch:
|
||||
*
|
||||
* Match settings.
|
||||
*
|
||||
* Since: 1.14
|
||||
*/
|
||||
struct _NMSettingMatch {
|
||||
NMSetting parent;
|
||||
GPtrArray *interface_name;
|
||||
};
|
||||
|
||||
struct _NMSettingMatchClass {
|
||||
NMSettingClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMSettingMatch, nm_setting_match, NM_TYPE_SETTING)
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE (NMSettingMatch,
|
||||
PROP_INTERFACE_NAME,
|
||||
);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_setting_match_get_num_interface_names:
|
||||
* @setting: the #NMSettingMatch
|
||||
*
|
||||
* Returns: the number of configured interface names
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
guint
|
||||
nm_setting_match_get_num_interface_names (NMSettingMatch *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), 0);
|
||||
|
||||
return setting->interface_name->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_get_interface_name:
|
||||
* @setting: the #NMSettingMatch
|
||||
* @idx: index number of the DNS search domain to return
|
||||
*
|
||||
* Returns: the interface name at index @idx
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
const char *
|
||||
nm_setting_match_get_interface_name (NMSettingMatch *setting, int idx)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), NULL);
|
||||
|
||||
g_return_val_if_fail (idx >= 0 && idx < setting->interface_name->len, NULL);
|
||||
|
||||
return setting->interface_name->pdata[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_add_interface_name:
|
||||
* @setting: the #NMSettingMatch
|
||||
* @interface_name: the interface name to add
|
||||
*
|
||||
* Adds a new interface name to the setting.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
void
|
||||
nm_setting_match_add_interface_name (NMSettingMatch *setting,
|
||||
const char *interface_name)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_MATCH (setting));
|
||||
g_return_if_fail (interface_name != NULL);
|
||||
g_return_if_fail (interface_name[0] != '\0');
|
||||
|
||||
g_ptr_array_add (setting->interface_name, g_strdup (interface_name));
|
||||
_notify (setting, PROP_INTERFACE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_remove_interface_name:
|
||||
* @setting: the #NMSettingMatch
|
||||
* @idx: index number of the interface name
|
||||
*
|
||||
* Removes the interface name at index @idx.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
void
|
||||
nm_setting_match_remove_interface_name (NMSettingMatch *setting, int idx)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_MATCH (setting));
|
||||
|
||||
g_return_if_fail (idx >= 0 && idx < setting->interface_name->len);
|
||||
|
||||
g_ptr_array_remove_index (setting->interface_name, idx);
|
||||
_notify (setting, PROP_INTERFACE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_remove_interface_name_by_value:
|
||||
* @setting: the #NMSettingMatch
|
||||
* @interface_name: the interface name to remove
|
||||
*
|
||||
* Removes @interface_name.
|
||||
*
|
||||
* Returns: %TRUE if the interface name was found and removed; %FALSE if it was not.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_match_remove_interface_name_by_value (NMSettingMatch *setting,
|
||||
const char *interface_name)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), FALSE);
|
||||
g_return_val_if_fail (interface_name != NULL, FALSE);
|
||||
g_return_val_if_fail (interface_name[0] != '\0', FALSE);
|
||||
|
||||
for (i = 0; i < setting->interface_name->len; i++) {
|
||||
if (nm_streq (interface_name, setting->interface_name->pdata[i])) {
|
||||
g_ptr_array_remove_index (setting->interface_name, i);
|
||||
_notify (setting, PROP_INTERFACE_NAME);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_clear_interface_names:
|
||||
* @setting: the #NMSettingMatch
|
||||
*
|
||||
* Removes all configured interface names.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
void
|
||||
nm_setting_match_clear_interface_names (NMSettingMatch *setting)
|
||||
{
|
||||
g_return_if_fail (NM_IS_SETTING_MATCH (setting));
|
||||
|
||||
if (setting->interface_name->len != 0) {
|
||||
g_ptr_array_set_size (setting->interface_name, 0);
|
||||
_notify (setting, PROP_INTERFACE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_get_interface_names:
|
||||
* @setting: the #NMSettingMatch
|
||||
*
|
||||
* Returns all the interface names.
|
||||
*
|
||||
* Returns: (transfer none): the configured interface names.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
const char *const *
|
||||
nm_setting_match_get_interface_names (NMSettingMatch *setting, guint *length)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_MATCH (setting), NULL);
|
||||
g_return_val_if_fail (length, NULL);
|
||||
|
||||
NM_SET_OUT (length, setting->interface_name->len);
|
||||
return (const char *const *) setting->interface_name->pdata;
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingMatch *self = NM_SETTING_MATCH (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_INTERFACE_NAME:
|
||||
g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (self->interface_name));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMSettingMatch *self = NM_SETTING_MATCH (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_INTERFACE_NAME:
|
||||
g_ptr_array_unref (self->interface_name);
|
||||
self->interface_name = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_match_init (NMSettingMatch *setting)
|
||||
{
|
||||
setting->interface_name = g_ptr_array_new_with_free_func (g_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_match_new:
|
||||
*
|
||||
* Creates a new #NMSettingMatch object with default values.
|
||||
*
|
||||
* Returns: (transfer full): the new empty #NMSettingMatch object
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
NMSetting *
|
||||
nm_setting_match_new (void)
|
||||
{
|
||||
return (NMSetting *) g_object_new (NM_TYPE_SETTING_MATCH, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMSettingMatch *self = NM_SETTING_MATCH (object);
|
||||
|
||||
g_ptr_array_unref (self->interface_name);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_match_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_match_class_init (NMSettingMatchClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
NMSettingClass *setting_class = NM_SETTING_CLASS (klass);
|
||||
|
||||
object_class->finalize = finalize;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
/**
|
||||
* NMSettingMatch:interface-name
|
||||
*
|
||||
* A list of interface names to match. Each element is a shell wildcard
|
||||
* pattern. When an element is prefixed with exclamation mark (!) the
|
||||
* condition is inverted.
|
||||
*
|
||||
* A candidate interface name is considered matching when both these
|
||||
* conditions are satisfied: (a) any of the elements not prefixed with '!'
|
||||
* matches or there aren't such elements; (b) none of the elements
|
||||
* prefixed with '!' match.
|
||||
*
|
||||
* Since: 1.14
|
||||
**/
|
||||
obj_properties[PROP_INTERFACE_NAME] =
|
||||
g_param_spec_boxed (NM_SETTING_MATCH_INTERFACE_NAME, "", "",
|
||||
G_TYPE_STRV,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
_nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_MATCH);
|
||||
}
|
||||
63
libnm-core/nm-setting-match.h
Normal file
63
libnm-core/nm-setting-match.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_SETTING_MATCH_H
|
||||
#define NM_SETTING_MATCH_H
|
||||
|
||||
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
|
||||
#error "Only <NetworkManager.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "nm-setting.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_SETTING_MATCH (nm_setting_match_get_type ())
|
||||
#define NM_SETTING_MATCH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_MATCH, NMSettingMatch))
|
||||
#define NM_SETTING_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_MATCH, NMSettingMatchClass))
|
||||
#define NM_IS_SETTING_MATCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_MATCH))
|
||||
#define NM_IS_SETTING_MATCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_MATCH))
|
||||
#define NM_SETTING_MATCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_MATCH, NMSettingMatchClass))
|
||||
|
||||
#define NM_SETTING_MATCH_SETTING_NAME "match"
|
||||
|
||||
#define NM_SETTING_MATCH_INTERFACE_NAME "interface-name"
|
||||
|
||||
typedef struct _NMSettingMatchClass NMSettingMatchClass;
|
||||
|
||||
|
||||
NM_AVAILABLE_IN_1_14
|
||||
GType nm_setting_match_get_type (void);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
NMSetting *nm_setting_match_new (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_14
|
||||
guint nm_setting_match_get_num_interface_names (NMSettingMatch *setting);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
const char *nm_setting_match_get_interface_name (NMSettingMatch *setting, int idx);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
void nm_setting_match_remove_interface_name (NMSettingMatch *setting, int idx);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
gboolean nm_setting_match_remove_interface_name_by_value (NMSettingMatch *setting,
|
||||
const char *interface_name);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
void nm_setting_match_add_interface_name (NMSettingMatch *setting,
|
||||
const char *interface_name);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
void nm_setting_match_clear_interface_names (NMSettingMatch *setting);
|
||||
NM_AVAILABLE_IN_1_14
|
||||
const char *const *nm_setting_match_get_interface_names (NMSettingMatch *setting, guint *length);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_SETTING_MATCH_H */
|
||||
|
|
@ -2613,7 +2613,7 @@ _nm_sriov_vf_parse_vlans (NMSriovVF *vf, const char *str, GError **error)
|
|||
gs_free const char **vlans = NULL;
|
||||
guint i;
|
||||
|
||||
vlans = nm_utils_strsplit_set (str, ";");
|
||||
vlans = nm_utils_strsplit_set (str, ";", FALSE);
|
||||
if (!vlans) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ test_nm_g_slice_free_fcn (void)
|
|||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_do_test_nm_utils_strsplit_set (const char *str, ...)
|
||||
_do_test_nm_utils_strsplit_set (gboolean escape, const char *str, ...)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *args_array = g_ptr_array_new ();
|
||||
const char *const*args;
|
||||
|
|
@ -255,7 +255,7 @@ _do_test_nm_utils_strsplit_set (const char *str, ...)
|
|||
|
||||
args = (const char *const*) args_array->pdata;
|
||||
|
||||
words = nm_utils_strsplit_set (str, " \t\n");
|
||||
words = nm_utils_strsplit_set (str, " \t\n", escape);
|
||||
|
||||
if (!args[0]) {
|
||||
g_assert (!words);
|
||||
|
|
@ -268,7 +268,7 @@ _do_test_nm_utils_strsplit_set (const char *str, ...)
|
|||
g_assert (args[i]);
|
||||
g_assert (words[i]);
|
||||
g_assert (args[i][0]);
|
||||
g_assert (NM_STRCHAR_ALL (args[i], ch, !NM_IN_SET (ch, ' ', '\t', '\n')));
|
||||
g_assert (escape || NM_STRCHAR_ALL (args[i], ch, !NM_IN_SET (ch, ' ', '\t', '\n')));
|
||||
g_assert_cmpstr (args[i], ==, words[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -279,21 +279,29 @@ _do_test_nm_utils_strsplit_set (const char *str, ...)
|
|||
static void
|
||||
test_nm_utils_strsplit_set (void)
|
||||
{
|
||||
do_test_nm_utils_strsplit_set (NULL);
|
||||
do_test_nm_utils_strsplit_set ("");
|
||||
do_test_nm_utils_strsplit_set ("\t");
|
||||
do_test_nm_utils_strsplit_set (" \t\n");
|
||||
do_test_nm_utils_strsplit_set ("a", "a");
|
||||
do_test_nm_utils_strsplit_set ("a b", "a", "b");
|
||||
do_test_nm_utils_strsplit_set ("a\rb", "a\rb");
|
||||
do_test_nm_utils_strsplit_set (" a\rb ", "a\rb");
|
||||
do_test_nm_utils_strsplit_set (" a bbbd afds ere", "a", "bbbd", "afds", "ere");
|
||||
do_test_nm_utils_strsplit_set ("1 2 3 4 5 6 7 8 9 0 "
|
||||
do_test_nm_utils_strsplit_set (FALSE, NULL);
|
||||
do_test_nm_utils_strsplit_set (FALSE, "");
|
||||
do_test_nm_utils_strsplit_set (FALSE, "\t");
|
||||
do_test_nm_utils_strsplit_set (FALSE, " \t\n");
|
||||
do_test_nm_utils_strsplit_set (FALSE, "a", "a");
|
||||
do_test_nm_utils_strsplit_set (FALSE, "a b", "a", "b");
|
||||
do_test_nm_utils_strsplit_set (FALSE, "a\rb", "a\rb");
|
||||
do_test_nm_utils_strsplit_set (FALSE, " a\rb ", "a\rb");
|
||||
do_test_nm_utils_strsplit_set (FALSE, " a bbbd afds ere", "a", "bbbd", "afds", "ere");
|
||||
do_test_nm_utils_strsplit_set (FALSE,
|
||||
"1 2 3 4 5 6 7 8 9 0 "
|
||||
"1 2 3 4 5 6 7 8 9 0 "
|
||||
"1 2 3 4 5 6 7 8 9 0",
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "\\", "\\");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "\\ ", "\\ ");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "\\\\", "\\\\");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "\\\t", "\\\t");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "foo\\", "foo\\");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "bar foo\\", "bar", "foo\\");
|
||||
do_test_nm_utils_strsplit_set (TRUE, "\\ a b\\ \\ c", "\\ a", "b\\ \\ ", "c");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -7074,6 +7082,53 @@ test_ethtool_offload (void)
|
|||
g_assert_cmpstr (d->optname, ==, NM_ETHTOOL_OPTNAME_FEATURE_RXHASH);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_utils_escape_spaces (void)
|
||||
{
|
||||
char *to_free;
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces (NULL, &to_free), ==, NULL);
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces ("", &to_free), ==, "");
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces (" ", &to_free), ==, "\\ ");
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces ("\t ", &to_free), ==, "\\\t\\ ");
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces ("abc", &to_free), ==, "abc");
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces ("abc def", &to_free), ==, "abc\\ def");
|
||||
g_free (to_free);
|
||||
|
||||
g_assert_cmpstr (_nm_utils_escape_spaces ("abc\tdef", &to_free), ==, "abc\\\tdef");
|
||||
g_free (to_free);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nm_utils_unescape_spaces (void)
|
||||
{
|
||||
#define CHECK_STR(in, out) \
|
||||
G_STMT_START { \
|
||||
gs_free char *str = g_strdup (in); \
|
||||
\
|
||||
g_assert_cmpstr (_nm_utils_unescape_spaces (str), ==, out); \
|
||||
} G_STMT_END
|
||||
|
||||
CHECK_STR ("\\a", "\\a");
|
||||
CHECK_STR ("foobar", "foobar");
|
||||
CHECK_STR ("foo bar", "foo bar");
|
||||
CHECK_STR ("foo\\ bar", "foo bar");
|
||||
CHECK_STR ("foo\\", "foo\\");
|
||||
CHECK_STR ("\\\\\t", "\\\t");
|
||||
|
||||
#undef CHECK_STR
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
|
@ -7224,6 +7279,8 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx);
|
||||
g_test_add_func ("/core/general/_nm_utils_validate_json", test_nm_utils_check_valid_json);
|
||||
g_test_add_func ("/core/general/_nm_utils_team_config_equal", test_nm_utils_team_config_equal);
|
||||
g_test_add_func ("/core/general/_nm_utils_escape_spaces", test_nm_utils_escape_spaces);
|
||||
g_test_add_func ("/core/general/_nm_utils_unescape_spaces", test_nm_utils_unescape_spaces);
|
||||
g_test_add_func ("/core/general/test_nm_utils_enum", test_nm_utils_enum);
|
||||
g_test_add_func ("/core/general/nm-set-out", test_nm_set_out);
|
||||
g_test_add_func ("/core/general/route_attributes/parse", test_route_attributes_parse);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
#include "nm-setting-ip-tunnel.h"
|
||||
#include "nm-setting-macsec.h"
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-setting-match.h"
|
||||
#include "nm-setting-olpc-mesh.h"
|
||||
#include "nm-setting-ovs-bridge.h"
|
||||
#include "nm-setting-ovs-interface.h"
|
||||
|
|
|
|||
|
|
@ -1399,6 +1399,14 @@ global:
|
|||
nm_setting_ethtool_get_type;
|
||||
nm_setting_ethtool_new;
|
||||
nm_setting_ethtool_set_feature;
|
||||
nm_setting_match_add_interface_name;
|
||||
nm_setting_match_clear_interface_names;
|
||||
nm_setting_match_get_interface_name;
|
||||
nm_setting_match_get_interface_names;
|
||||
nm_setting_match_get_num_interface_names;
|
||||
nm_setting_match_get_type;
|
||||
nm_setting_match_remove_interface_name;
|
||||
nm_setting_match_remove_interface_name_by_value;
|
||||
nm_setting_sriov_add_vf;
|
||||
nm_setting_sriov_clear_vfs;
|
||||
nm_setting_sriov_get_autoprobe_drivers;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "nm-setting-ip-tunnel.h"
|
||||
#include "nm-setting-macsec.h"
|
||||
#include "nm-setting-macvlan.h"
|
||||
#include "nm-setting-match.h"
|
||||
#include "nm-setting-olpc-mesh.h"
|
||||
#include "nm-setting-ovs-bridge.h"
|
||||
#include "nm-setting-ovs-interface.h"
|
||||
|
|
@ -268,6 +269,12 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
|
|||
.setting_name = NM_SETTING_MACVLAN_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_macvlan_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_MATCH] = {
|
||||
.meta_type = NM_META_SETTING_TYPE_MATCH,
|
||||
.setting_priority = NM_SETTING_PRIORITY_AUX,
|
||||
.setting_name = NM_SETTING_MATCH_SETTING_NAME,
|
||||
.get_setting_gtype = nm_setting_match_get_type,
|
||||
},
|
||||
[NM_META_SETTING_TYPE_OLPC_MESH] = {
|
||||
.meta_type = NM_META_SETTING_TYPE_OLPC_MESH,
|
||||
.setting_priority = NM_SETTING_PRIORITY_HW_BASE,
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ typedef enum {
|
|||
NM_META_SETTING_TYPE_IP6_CONFIG,
|
||||
NM_META_SETTING_TYPE_MACSEC,
|
||||
NM_META_SETTING_TYPE_MACVLAN,
|
||||
NM_META_SETTING_TYPE_MATCH,
|
||||
NM_META_SETTING_TYPE_OVS_BRIDGE,
|
||||
NM_META_SETTING_TYPE_OVS_INTERFACE,
|
||||
NM_META_SETTING_TYPE_OVS_PATCH,
|
||||
|
|
|
|||
|
|
@ -656,6 +656,7 @@ comp_l:
|
|||
* @str: the string to split.
|
||||
* @delimiters: the set of delimiters. If %NULL, defaults to " \t\n",
|
||||
* like bash's $IFS.
|
||||
* @allow_escaping: whether delimiters can be escaped by a backslash
|
||||
*
|
||||
* This is a replacement for g_strsplit_set() which avoids copying
|
||||
* each word once (the entire strv array), but instead copies it once
|
||||
|
|
@ -664,6 +665,10 @@ comp_l:
|
|||
* Another difference from g_strsplit_set() is that this never returns
|
||||
* empty words. Multiple delimiters are combined and treated as one.
|
||||
*
|
||||
* If @allow_escaping is %TRUE, delimiters prefixed by a backslash are
|
||||
* not treated as a separator. Such delimiters and their escape
|
||||
* character are copied to the current word without unescaping them.
|
||||
*
|
||||
* Returns: %NULL if @str is %NULL or contains only delimiters.
|
||||
* Otherwise, a %NULL terminated strv array containing non-empty
|
||||
* words, split at the delimiter characters (delimiter characters
|
||||
|
|
@ -673,7 +678,7 @@ comp_l:
|
|||
* but free everything with g_free().
|
||||
*/
|
||||
const char **
|
||||
nm_utils_strsplit_set (const char *str, const char *delimiters)
|
||||
nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping)
|
||||
{
|
||||
const char **ptr, **ptr0;
|
||||
gsize alloc_size, plen, i;
|
||||
|
|
@ -681,6 +686,7 @@ nm_utils_strsplit_set (const char *str, const char *delimiters)
|
|||
char *s0;
|
||||
char *s;
|
||||
guint8 delimiters_table[256];
|
||||
gboolean escaped = FALSE;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
|
@ -692,13 +698,23 @@ nm_utils_strsplit_set (const char *str, const char *delimiters)
|
|||
for (i = 0; delimiters[i]; i++)
|
||||
delimiters_table[(guint8) delimiters[i]] = 1;
|
||||
|
||||
#define _is_delimiter(ch, delimiters_table) \
|
||||
((delimiters_table)[(guint8) (ch)] != 0)
|
||||
#define _is_delimiter(ch, delimiters_table, allow_esc, esc) \
|
||||
((delimiters_table)[(guint8) (ch)] != 0 && (!allow_esc || !esc))
|
||||
|
||||
#define next_char(p, esc) \
|
||||
G_STMT_START { \
|
||||
if (esc) \
|
||||
esc = FALSE; \
|
||||
else \
|
||||
esc = p[0] == '\\'; \
|
||||
p++; \
|
||||
} G_STMT_END
|
||||
|
||||
/* skip initial delimiters, and return of the remaining string is
|
||||
* empty. */
|
||||
while (_is_delimiter (str[0], delimiters_table))
|
||||
str++;
|
||||
while (_is_delimiter (str[0], delimiters_table, allow_escaping, escaped))
|
||||
next_char (str, escaped);
|
||||
|
||||
if (!str[0])
|
||||
return NULL;
|
||||
|
||||
|
|
@ -730,20 +746,20 @@ nm_utils_strsplit_set (const char *str, const char *delimiters)
|
|||
|
||||
ptr[plen++] = s;
|
||||
|
||||
nm_assert (s[0] && !_is_delimiter (s[0], delimiters_table));
|
||||
nm_assert (s[0] && !_is_delimiter (s[0], delimiters_table, allow_escaping, escaped));
|
||||
|
||||
while (TRUE) {
|
||||
s++;
|
||||
if (_is_delimiter (s[0], delimiters_table))
|
||||
next_char (s, escaped);
|
||||
if (_is_delimiter (s[0], delimiters_table, allow_escaping, escaped))
|
||||
break;
|
||||
if (s[0] == '\0')
|
||||
goto done;
|
||||
}
|
||||
|
||||
s[0] = '\0';
|
||||
s++;
|
||||
while (_is_delimiter (s[0], delimiters_table))
|
||||
s++;
|
||||
next_char (s, escaped);
|
||||
while (_is_delimiter (s[0], delimiters_table, allow_escaping, escaped))
|
||||
next_char (s, escaped);
|
||||
if (s[0] == '\0')
|
||||
break;
|
||||
}
|
||||
|
|
@ -1602,7 +1618,7 @@ nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid)
|
|||
|
||||
state = p[0];
|
||||
|
||||
tokens = nm_utils_strsplit_set (p, " ");
|
||||
tokens = nm_utils_strsplit_set (p, " ", FALSE);
|
||||
|
||||
if (NM_PTRARRAY_LEN (tokens) < 20)
|
||||
goto fail;
|
||||
|
|
@ -1702,3 +1718,60 @@ _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...)
|
|||
|
||||
g_slice_free1 (((gsize) nargs) * sizeof (gconstpointer), user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define IS_SPACE(c) NM_IN_SET ((c), ' ', '\t')
|
||||
|
||||
const char *
|
||||
_nm_utils_escape_spaces (const char *str, char **to_free)
|
||||
{
|
||||
const char *ptr = str;
|
||||
char *ret, *r;
|
||||
|
||||
*to_free = NULL;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
while (TRUE) {
|
||||
if (!*ptr)
|
||||
return str;
|
||||
if (IS_SPACE (*ptr))
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
ret = g_new (char, strlen (str) * 2 + 1);
|
||||
r = ret;
|
||||
*to_free = ret;
|
||||
while (*ptr) {
|
||||
if (IS_SPACE (*ptr))
|
||||
*r++ = '\\';
|
||||
*r++ = *ptr++;
|
||||
}
|
||||
*r = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
_nm_utils_unescape_spaces (char *str)
|
||||
{
|
||||
guint i, j = 0;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; str[i]; i++) {
|
||||
if (str[i] == '\\' && IS_SPACE (str[i+1]))
|
||||
i++;
|
||||
str[j++] = str[i];
|
||||
}
|
||||
str[j] = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#undef IS_SPACE
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ int nm_utils_dbus_path_cmp (const char *dbus_path_a, const char *dbus_path_b);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char **nm_utils_strsplit_set (const char *str, const char *delimiters);
|
||||
const char **nm_utils_strsplit_set (const char *str, const char *delimiters, gboolean allow_escaping);
|
||||
|
||||
gssize nm_utils_strv_find_first (char **list, gssize len, const char *needle);
|
||||
|
||||
|
|
@ -718,4 +718,7 @@ void _nm_utils_user_data_unpack (gpointer user_data, int nargs, ...);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *_nm_utils_escape_spaces (const char *str, char **to_free);
|
||||
char *_nm_utils_unescape_spaces (char *str);
|
||||
|
||||
#endif /* __NM_SHARED_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -5511,6 +5511,9 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError **
|
|||
gs_free_error GError *local = NULL;
|
||||
gs_free char *conn_iface = NULL;
|
||||
NMDeviceClass *klass;
|
||||
const char *const *patterns;
|
||||
NMSettingMatch *s_match;
|
||||
guint num_patterns;
|
||||
|
||||
klass = NM_DEVICE_GET_CLASS (self);
|
||||
if (klass->connection_type_check_compatible) {
|
||||
|
|
@ -5534,15 +5537,23 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError **
|
|||
"cannot get interface name due to %s", local->message);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!nm_streq0 (conn_iface, device_iface)) {
|
||||
} else if (!nm_streq0 (conn_iface, device_iface)) {
|
||||
nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"mismatching interface name");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s_match = (NMSettingMatch *) nm_connection_get_setting (connection,
|
||||
NM_TYPE_SETTING_MATCH);
|
||||
if (s_match) {
|
||||
patterns = nm_setting_match_get_interface_names (s_match, &num_patterns);
|
||||
if (!nm_wildcard_match_check (device_iface, patterns, num_patterns)) {
|
||||
nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"device does not satisfy match.interface-name property");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -1730,6 +1731,33 @@ nm_match_spec_join (GSList *specs)
|
|||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_wildcard_match_check (const char *str,
|
||||
const char *const *patterns,
|
||||
guint num_patterns)
|
||||
{
|
||||
guint i, neg = 0;
|
||||
|
||||
for (i = 0; i < num_patterns; i++) {
|
||||
if (patterns[i][0] == '!') {
|
||||
neg++;
|
||||
if (!fnmatch (patterns[i] + 1, str, 0))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (neg == num_patterns)
|
||||
return TRUE;
|
||||
|
||||
for (i = 0; i < num_patterns; i++) {
|
||||
if ( patterns[i][0] != '!'
|
||||
&& !fnmatch (patterns[i], str, 0))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *
|
||||
|
|
|
|||
|
|
@ -215,6 +215,10 @@ NMMatchSpecMatchType nm_match_spec_config (const GSList *specs,
|
|||
GSList *nm_match_spec_split (const char *value);
|
||||
char *nm_match_spec_join (GSList *specs);
|
||||
|
||||
gboolean nm_wildcard_match_check (const char *str,
|
||||
const char *const *patterns,
|
||||
guint num_patterns);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *nm_utils_get_ip_config_method (NMConnection *connection,
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ make_connection_setting (const char *file,
|
|||
if (v) {
|
||||
gs_free const char **items = NULL;
|
||||
|
||||
items = nm_utils_strsplit_set (v, " ");
|
||||
items = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
for (iter = items; iter && *iter; iter++) {
|
||||
if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL))
|
||||
PARSE_WARNING ("invalid USERS item '%s'", *iter);
|
||||
|
|
@ -270,7 +270,7 @@ make_connection_setting (const char *file,
|
|||
if (v) {
|
||||
gs_free const char **items = NULL;
|
||||
|
||||
items = nm_utils_strsplit_set (v, " \t");
|
||||
items = nm_utils_strsplit_set (v, " \t", FALSE);
|
||||
for (iter = items; iter && *iter; iter++) {
|
||||
if (!nm_setting_connection_add_secondary (s_con, *iter))
|
||||
PARSE_WARNING ("secondary connection UUID '%s' already added", *iter);
|
||||
|
|
@ -679,7 +679,7 @@ parse_route_line (const char *line,
|
|||
* Maybe later we want to support some form of quotation here.
|
||||
* Which of course, would be incompatible with initscripts.
|
||||
*/
|
||||
words_free = nm_utils_strsplit_set (line, " \t\n");
|
||||
words_free = nm_utils_strsplit_set (line, " \t\n", FALSE);
|
||||
|
||||
words = words_free ?: NM_PTRARRAY_EMPTY (const char *);
|
||||
|
||||
|
|
@ -1115,7 +1115,7 @@ parse_dns_options (NMSettingIPConfig *ip_config, const char *value)
|
|||
if (!nm_setting_ip_config_has_dns_options (ip_config))
|
||||
nm_setting_ip_config_clear_dns_options (ip_config, TRUE);
|
||||
|
||||
options = nm_utils_strsplit_set (value, " ");
|
||||
options = nm_utils_strsplit_set (value, " ", FALSE);
|
||||
if (options) {
|
||||
for (item = options; *item; item++) {
|
||||
if (!nm_setting_ip_config_add_dns_option (ip_config, *item))
|
||||
|
|
@ -1218,6 +1218,32 @@ make_user_setting (shvarFile *ifcfg)
|
|||
: NULL;
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_match_setting (shvarFile *ifcfg)
|
||||
{
|
||||
NMSettingMatch *s_match = NULL;
|
||||
gs_free const char **strv = NULL;
|
||||
gs_free char *value = NULL;
|
||||
const char *v;
|
||||
gsize i;
|
||||
|
||||
v = svGetValueStr (ifcfg, "MATCH_INTERFACE_NAME", &value);
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
strv = nm_utils_strsplit_set (v, " \t", TRUE);
|
||||
if (strv) {
|
||||
for (i = 0; strv[i]; i++) {
|
||||
if (!s_match)
|
||||
s_match = (NMSettingMatch *) nm_setting_match_new ();
|
||||
nm_setting_match_add_interface_name (s_match,
|
||||
_nm_utils_unescape_spaces ((char *) strv[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return (NMSetting *) s_match;
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_proxy_setting (shvarFile *ifcfg)
|
||||
{
|
||||
|
|
@ -1485,7 +1511,7 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
if (v) {
|
||||
gs_free const char **searches = NULL;
|
||||
|
||||
searches = nm_utils_strsplit_set (v, " ");
|
||||
searches = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
if (searches) {
|
||||
for (item = searches; *item; item++) {
|
||||
if (!nm_setting_ip_config_add_dns_search (s_ip4, *item))
|
||||
|
|
@ -1546,7 +1572,7 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
if (v) {
|
||||
gs_free const char **searches = NULL;
|
||||
|
||||
searches = nm_utils_strsplit_set (v, " ");
|
||||
searches = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
if (searches) {
|
||||
for (item = searches; *item; item++) {
|
||||
if (!nm_setting_ip_config_add_dns_search (s_ip4, *item))
|
||||
|
|
@ -1862,7 +1888,7 @@ make_ip6_setting (shvarFile *ifcfg,
|
|||
ipv6addr_secondaries ?: "",
|
||||
NULL);
|
||||
|
||||
list = nm_utils_strsplit_set (value, " ");
|
||||
list = nm_utils_strsplit_set (value, " ", FALSE);
|
||||
for (iter = list, i = 0; iter && *iter; iter++, i++) {
|
||||
NMIPAddress *addr = NULL;
|
||||
|
||||
|
|
@ -1955,7 +1981,7 @@ make_ip6_setting (shvarFile *ifcfg,
|
|||
if (v) {
|
||||
gs_free const char **searches = NULL;
|
||||
|
||||
searches = nm_utils_strsplit_set (v, " ");
|
||||
searches = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
if (searches) {
|
||||
for (iter = searches; *iter; iter++) {
|
||||
if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter))
|
||||
|
|
@ -2305,7 +2331,7 @@ read_dcb_percent_array (shvarFile *ifcfg,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
split = nm_utils_strsplit_set (val, ",");
|
||||
split = nm_utils_strsplit_set (val, ",", FALSE);
|
||||
if (NM_PTRARRAY_LEN (split) != 8) {
|
||||
PARSE_WARNING ("invalid %s percentage list value '%s'", prop, val);
|
||||
g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
||||
|
|
@ -2741,7 +2767,7 @@ fill_wpa_ciphers (shvarFile *ifcfg,
|
|||
if (!p)
|
||||
return TRUE;
|
||||
|
||||
list = nm_utils_strsplit_set (p, " ");
|
||||
list = nm_utils_strsplit_set (p, " ", FALSE);
|
||||
for (iter = list; iter && *iter; iter++, i++) {
|
||||
/* Ad-Hoc configurations cannot have pairwise ciphers, and can only
|
||||
* have one group cipher. Ignore any additional group ciphers and
|
||||
|
|
@ -3147,7 +3173,7 @@ eap_peap_reader (const char *eap_method,
|
|||
}
|
||||
|
||||
/* Handle options for the inner auth method */
|
||||
list = nm_utils_strsplit_set (v, " ");
|
||||
list = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
iter = list;
|
||||
if (iter) {
|
||||
if (NM_IN_STRSET (*iter, "MSCHAPV2",
|
||||
|
|
@ -3225,7 +3251,7 @@ eap_ttls_reader (const char *eap_method,
|
|||
inner_auth = g_ascii_strdown (v, -1);
|
||||
|
||||
/* Handle options for the inner auth method */
|
||||
list = nm_utils_strsplit_set (inner_auth, " ");
|
||||
list = nm_utils_strsplit_set (inner_auth, " ", FALSE);
|
||||
iter = list;
|
||||
if (iter) {
|
||||
if (NM_IN_STRSET (*iter, "mschapv2",
|
||||
|
|
@ -3286,7 +3312,7 @@ eap_fast_reader (const char *eap_method,
|
|||
if (fast_provisioning) {
|
||||
gs_free const char **list1 = NULL;
|
||||
|
||||
list1 = nm_utils_strsplit_set (fast_provisioning, " \t");
|
||||
list1 = nm_utils_strsplit_set (fast_provisioning, " \t", FALSE);
|
||||
for (iter = list1; iter && *iter; iter++) {
|
||||
if (strcmp (*iter, "allow-unauth") == 0)
|
||||
allow_unauth = TRUE;
|
||||
|
|
@ -3320,7 +3346,7 @@ eap_fast_reader (const char *eap_method,
|
|||
}
|
||||
|
||||
/* Handle options for the inner auth method */
|
||||
list = nm_utils_strsplit_set (inner_auth, " ");
|
||||
list = nm_utils_strsplit_set (inner_auth, " ", FALSE);
|
||||
iter = list;
|
||||
if (iter) {
|
||||
if ( !strcmp (*iter, "MSCHAPV2")
|
||||
|
|
@ -3400,7 +3426,7 @@ read_8021x_list_value (shvarFile *ifcfg,
|
|||
if (!v)
|
||||
return;
|
||||
|
||||
strv = nm_utils_strsplit_set (v, " \t");
|
||||
strv = nm_utils_strsplit_set (v, " \t", FALSE);
|
||||
if (strv)
|
||||
g_object_set (setting, prop_name, strv, NULL);
|
||||
}
|
||||
|
|
@ -3429,7 +3455,7 @@ fill_8021x (shvarFile *ifcfg,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
list = nm_utils_strsplit_set (v, " ");
|
||||
list = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
|
||||
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
|
||||
|
||||
|
|
@ -3738,7 +3764,7 @@ transform_hwaddr_blacklist (const char *blacklist)
|
|||
const char **strv;
|
||||
gsize i, j;
|
||||
|
||||
strv = nm_utils_strsplit_set (blacklist, " \t");
|
||||
strv = nm_utils_strsplit_set (blacklist, " \t", FALSE);
|
||||
if (!strv)
|
||||
return NULL;
|
||||
for (i = 0, j = 0; strv[j]; j++) {
|
||||
|
|
@ -4059,7 +4085,7 @@ parse_ethtool_option (const char *value,
|
|||
gs_free const char **words = NULL;
|
||||
guint i;
|
||||
|
||||
words = nm_utils_strsplit_set (value, NULL);
|
||||
words = nm_utils_strsplit_set (value, NULL, FALSE);
|
||||
if (!words)
|
||||
return;
|
||||
|
||||
|
|
@ -4252,7 +4278,7 @@ parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection)
|
|||
gs_free const char **opts = NULL;
|
||||
const char *const *iter;
|
||||
|
||||
opts = nm_utils_strsplit_set (ethtool_opts, ";");
|
||||
opts = nm_utils_strsplit_set (ethtool_opts, ";", FALSE);
|
||||
for (iter = opts; iter && iter[0]; iter++) {
|
||||
/* in case of repeated wol_passwords, parse_ethtool_option()
|
||||
* will do the right thing and clear wol_password before resetting. */
|
||||
|
|
@ -4348,7 +4374,7 @@ make_wired_setting (shvarFile *ifcfg,
|
|||
gs_free const char **chans = NULL;
|
||||
guint32 num_chans;
|
||||
|
||||
chans = nm_utils_strsplit_set (value, ",");
|
||||
chans = nm_utils_strsplit_set (value, ",", FALSE);
|
||||
num_chans = NM_PTRARRAY_LEN (chans);
|
||||
if (num_chans < 2 || num_chans > 3) {
|
||||
PARSE_WARNING ("invalid SUBCHANNELS '%s' (%u channels, 2 or 3 expected)",
|
||||
|
|
@ -4671,7 +4697,7 @@ make_bond_setting (shvarFile *ifcfg,
|
|||
gs_free const char **items = NULL;
|
||||
const char *const *iter;
|
||||
|
||||
items = nm_utils_strsplit_set (v, " ");
|
||||
items = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
for (iter = items; iter && *iter; iter++) {
|
||||
gs_strfreev char **keys = NULL;
|
||||
const char *key, *val;
|
||||
|
|
@ -4949,7 +4975,7 @@ handle_bridging_opts (NMSetting *setting,
|
|||
gs_free const char **items = NULL;
|
||||
const char *const *iter;
|
||||
|
||||
items = nm_utils_strsplit_set (value, " ");
|
||||
items = nm_utils_strsplit_set (value, " ", FALSE);
|
||||
for (iter = items; iter && *iter; iter++) {
|
||||
gs_strfreev char **keys = NULL;
|
||||
const char *key, *val;
|
||||
|
|
@ -5169,7 +5195,7 @@ parse_prio_map_list (NMSettingVlan *s_vlan,
|
|||
v = svGetValueStr (ifcfg, key, &value);
|
||||
if (!v)
|
||||
return;
|
||||
list = nm_utils_strsplit_set (v, ",");
|
||||
list = nm_utils_strsplit_set (v, ",", FALSE);
|
||||
|
||||
for (iter = list; iter && *iter; iter++) {
|
||||
if (!strchr (*iter, ':'))
|
||||
|
|
@ -5274,7 +5300,7 @@ make_vlan_setting (shvarFile *ifcfg,
|
|||
gs_free const char **strv = NULL;
|
||||
const char *const *ptr;
|
||||
|
||||
strv = nm_utils_strsplit_set (v, ", ");
|
||||
strv = nm_utils_strsplit_set (v, ", ", FALSE);
|
||||
for (ptr = strv; ptr && *ptr; ptr++) {
|
||||
if (nm_streq (*ptr, "GVRP") && gvrp == -1)
|
||||
vlan_flags |= NM_VLAN_FLAG_GVRP;
|
||||
|
|
@ -5416,7 +5442,7 @@ check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6)
|
|||
gs_free const char **searches = NULL;
|
||||
const char *const *item;
|
||||
|
||||
searches = nm_utils_strsplit_set (v, " ");
|
||||
searches = nm_utils_strsplit_set (v, " ", FALSE);
|
||||
if (searches) {
|
||||
for (item = searches; *item; item++) {
|
||||
if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item))
|
||||
|
|
@ -5441,7 +5467,7 @@ connection_from_file_full (const char *filename,
|
|||
gs_free char *type = NULL;
|
||||
char *devtype, *bootproto;
|
||||
NMSetting *s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user;
|
||||
NMSetting *s_sriov;
|
||||
NMSetting *s_sriov, *s_match;
|
||||
const char *ifcfg_name = NULL;
|
||||
gboolean has_ip4_defroute = FALSE;
|
||||
gboolean has_complex_routes_v4;
|
||||
|
|
@ -5721,6 +5747,10 @@ connection_from_file_full (const char *filename,
|
|||
if (s_user)
|
||||
nm_connection_add_setting (connection, s_user);
|
||||
|
||||
s_match = make_match_setting (parsed);
|
||||
if (s_match)
|
||||
nm_connection_add_setting (connection, s_match);
|
||||
|
||||
/* Bridge port? */
|
||||
s_port = make_bridge_port_setting (parsed);
|
||||
if (s_port)
|
||||
|
|
|
|||
|
|
@ -2285,6 +2285,38 @@ write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||
{
|
||||
NMSettingMatch *s_match;
|
||||
nm_auto_free_gstring GString *str = NULL;
|
||||
guint i, num;
|
||||
|
||||
svUnsetValue (ifcfg, "MATCH_INTERFACE_NAME");
|
||||
|
||||
s_match = (NMSettingMatch *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MATCH);
|
||||
if (!s_match)
|
||||
return TRUE;
|
||||
|
||||
num = nm_setting_match_get_num_interface_names (s_match);
|
||||
for (i = 0; i < num; i++) {
|
||||
gs_free char *to_free = NULL;
|
||||
const char *name;
|
||||
|
||||
if (i == 0)
|
||||
str = g_string_new ("");
|
||||
else
|
||||
g_string_append_c (str, ' ');
|
||||
name = nm_setting_match_get_interface_name (s_match, i);
|
||||
g_string_append (str, _nm_utils_escape_spaces (name, &to_free));
|
||||
}
|
||||
|
||||
if (str)
|
||||
svSetValueStr (ifcfg, "MATCH_INTERFACE_NAME", str->str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_res_options (shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var)
|
||||
{
|
||||
|
|
@ -3030,6 +3062,9 @@ do_write_construct (NMConnection *connection,
|
|||
if (!write_user_setting (connection, ifcfg, error))
|
||||
return FALSE;
|
||||
|
||||
if (!write_match_setting (connection, ifcfg, error))
|
||||
return FALSE;
|
||||
|
||||
write_sriov_setting (connection, ifcfg);
|
||||
|
||||
if (!write_tc_setting (connection, ifcfg, error))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
TYPE=Ethernet
|
||||
PROXY_METHOD=none
|
||||
BROWSER_ONLY=no
|
||||
MATCH_INTERFACE_NAME="ens* eth\\ 1? !veth*"
|
||||
BOOTPROTO=dhcp
|
||||
DEFROUTE=yes
|
||||
IPV4_FAILURE_FATAL=no
|
||||
IPV6INIT=no
|
||||
NAME="Test Write Wired with Match setting"
|
||||
UUID=${UUID}
|
||||
ONBOOT=yes
|
||||
|
|
@ -4434,6 +4434,67 @@ test_write_wired_dhcp (void)
|
|||
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_wired_match (void)
|
||||
{
|
||||
nmtst_auto_unlinkfile char *testfile = NULL;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
gs_unref_object NMConnection *reread = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingMatch *s_match;
|
||||
NMSettingIPConfig *s_ip4;
|
||||
NMSettingIPConfig *s_ip6;
|
||||
|
||||
connection = nm_simple_connection_new ();
|
||||
|
||||
/* Connection setting */
|
||||
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
|
||||
g_object_set (s_con,
|
||||
NM_SETTING_CONNECTION_ID, "Test Write Wired with Match setting",
|
||||
NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (),
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
||||
NULL);
|
||||
|
||||
/* Wired setting */
|
||||
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
|
||||
/* IP4 setting */
|
||||
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
||||
NULL);
|
||||
|
||||
/* IP6 setting */
|
||||
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
|
||||
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
||||
NULL);
|
||||
|
||||
/* Match setting */
|
||||
s_match = (NMSettingMatch *) nm_setting_match_new ();
|
||||
nm_setting_match_add_interface_name (s_match, "ens*");
|
||||
nm_setting_match_add_interface_name (s_match, "eth 1?");
|
||||
nm_setting_match_add_interface_name (s_match, "!veth*");
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_match));
|
||||
|
||||
nmtst_assert_connection_verifies (connection);
|
||||
_writer_new_connec_exp (connection,
|
||||
TEST_SCRATCH_DIR,
|
||||
TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_match.cexpected",
|
||||
&testfile);
|
||||
reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL);
|
||||
nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_wired_dhcp_plus_ip (void)
|
||||
{
|
||||
|
|
@ -10072,6 +10133,7 @@ int main (int argc, char **argv)
|
|||
g_test_add_func (TPATH "wired/write/dhcp", test_write_wired_dhcp);
|
||||
g_test_add_func (TPATH "wired/write-dhcp-plus-ip", test_write_wired_dhcp_plus_ip);
|
||||
g_test_add_func (TPATH "wired/write/dhcp-8021x-peap-mschapv2", test_write_wired_dhcp_8021x_peap_mschapv2);
|
||||
g_test_add_func (TPATH "wired/write/match", test_write_wired_match);
|
||||
|
||||
#define _add_test_write_wired_8021x_tls(testpath, scheme, flags) \
|
||||
nmtst_add_test_func (testpath, test_write_wired_8021x_tls, GINT_TO_POINTER (scheme), GINT_TO_POINTER (flags))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue