diff options
| author | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2019-04-21 21:09:51 +0200 |
| commit | 85563b7fc7ec2cd21e38debb9b28db342e2e8e7c (patch) | |
| tree | cce7b0b02d28fae2df9fdf2c1804cacd1500f2d7 /src/settings/plugins/ifcfg-rh | |
| parent | 9a6dcbf895f9da01768e64b73cec88c16157d91e (diff) | |
New upstream version 1.18.0 upstream/1.18.0
Diffstat (limited to 'src/settings/plugins/ifcfg-rh')
10 files changed, 626 insertions, 182 deletions
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index 89272edb..5160dbf0 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -30,7 +30,7 @@ #include <sys/stat.h> #include <gmodule.h> -#include "nm-dbus-compat.h" +#include "nm-std-aux/nm-dbus-compat.h" #include "nm-setting-connection.h" #include "settings/nm-settings-plugin.h" #include "nm-config.h" diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 7c1db225..e5423b18 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -31,7 +31,7 @@ #include <sys/ioctl.h> #include <unistd.h> -#include "nm-utils/nm-secret-utils.h" +#include "nm-glib-aux/nm-secret-utils.h" #include "nm-connection.h" #include "nm-dbus-interface.h" #include "nm-setting-connection.h" @@ -53,7 +53,7 @@ #include "nm-setting-generic.h" #include "nm-core-internal.h" #include "nm-utils.h" -#include "nm-ethtool-utils.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "platform/nm-platform.h" #include "NetworkManagerUtils.h" @@ -82,7 +82,8 @@ static char * get_full_file_path (const char *ifcfg_path, const char *file_path) { const char *base = file_path; - char *p, *ret, *dirname; + gs_free char *dirname = NULL; + char *p; g_return_val_if_fail (ifcfg_path != NULL, NULL); g_return_val_if_fail (file_path != NULL, NULL); @@ -95,9 +96,7 @@ get_full_file_path (const char *ifcfg_path, const char *file_path) base = p + 1; dirname = g_path_get_dirname (ifcfg_path); - ret = g_build_path ("/", dirname, base, NULL); - g_free (dirname); - return ret; + return g_build_path ("/", dirname, base, NULL); } /*****************************************************************************/ @@ -207,7 +206,7 @@ _cert_get_cert_bytes (const char *ifcfg_path, { gs_free char *path = NULL; - if (g_str_has_prefix (value, "pkcs11:")) + if (NM_STR_HAS_PREFIX (value, "pkcs11:")) return _nm_setting_802_1x_cert_value_to_bytes (NM_SETTING_802_1X_CK_SCHEME_PKCS11, (guint8 *) value, -1, error); path = get_full_file_path (ifcfg_path, value); @@ -379,7 +378,7 @@ make_connection_setting (const char *file, NMSettingConnection *s_con; NMSettingConnectionLldp lldp; const char *ifcfg_name = NULL; - char *new_id; + gs_free char *new_id = NULL; const char *uuid; gs_free char *uuid_free = NULL; gs_free char *value = NULL; @@ -396,7 +395,6 @@ make_connection_setting (const char *file, new_id = make_connection_name (ifcfg, ifcfg_name, suggested, prefix); g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL); - g_free (new_id); /* Try for a UUID key before falling back to hashing the file name */ uuid = svGetValueStr (ifcfg, "UUID", &uuid_free); @@ -457,7 +455,7 @@ make_connection_setting (const char *file, if (v) { gs_free const char **items = NULL; - items = nm_utils_strsplit_set (v, " ", FALSE); + items = nm_utils_strsplit_set (v, " "); for (iter = items; iter && *iter; iter++) { if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL)) PARSE_WARNING ("invalid USERS item '%s'", *iter); @@ -473,7 +471,7 @@ make_connection_setting (const char *file, if (v) { gs_free const char **items = NULL; - items = nm_utils_strsplit_set (v, " \t", FALSE); + items = nm_utils_strsplit_set (v, " \t"); for (iter = items; iter && *iter; iter++) { if (!nm_setting_connection_add_secondary (s_con, *iter)) PARSE_WARNING ("secondary connection UUID '%s' already added", *iter); @@ -562,7 +560,6 @@ make_connection_setting (const char *file, return NM_SETTING (s_con); } -/* Returns TRUE on missing address or valid address */ static gboolean read_ip4_address (shvarFile *ifcfg, const char *tag, @@ -572,7 +569,7 @@ read_ip4_address (shvarFile *ifcfg, { gs_free char *value_to_free = NULL; const char *value; - guint32 a; + in_addr_t a; nm_assert (ifcfg); nm_assert (tag); @@ -820,7 +817,7 @@ parse_route_line (const char *line, NMIPRoute **out_route, GError **error) { - nm_auto_ip_route_unref NMIPRoute *route = NULL; + nm_auto_unref_ip_route NMIPRoute *route = NULL; gs_free const char **words_free = NULL; const char *const*words; const char *s; @@ -889,7 +886,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", FALSE); + words_free = nm_utils_strsplit_set (line, " \t\n"); words = words_free ?: NM_PTRARRAY_EMPTY (const char *); @@ -1284,7 +1281,7 @@ read_route_file (int addr_family, for (line = strtok_r (contents, "\n", &contents_rest); line; line = strtok_r (NULL, "\n", &contents_rest)) { - nm_auto_ip_route_unref NMIPRoute *route = NULL; + nm_auto_unref_ip_route NMIPRoute *route = NULL; gs_free_error GError *local = NULL; int e; @@ -1327,7 +1324,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, " ", FALSE); + options = nm_utils_strsplit_set (value, " "); if (options) { for (item = options; *item; item++) { if (!nm_setting_ip_config_add_dns_option (ip_config, *item)) @@ -1343,46 +1340,33 @@ parse_full_ip6_address (shvarFile *ifcfg, NMIPAddress **out_address, GError **error) { - char **list; - char *ip_val, *prefix_val; + NMIPAddress *addr; + NMIPAddr addr_bin; int prefix; - gboolean success = FALSE; - g_return_val_if_fail (addr_str != NULL, FALSE); - g_return_val_if_fail (out_address != NULL, FALSE); - g_return_val_if_fail (*out_address == NULL, FALSE); - g_return_val_if_fail (!error || !*error, FALSE); + nm_assert (addr_str); + nm_assert (out_address && !*out_address); + nm_assert (!error || !*error); - /* Split the address and prefix */ - list = g_strsplit_set (addr_str, "/", 2); - if (g_strv_length (list) < 1) { + if (!nm_utils_parse_inaddr_prefix_bin (AF_INET6, + addr_str, + NULL, + &addr_bin, + &prefix)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 address '%s'", addr_str); - goto error; + return FALSE; } - ip_val = list[0]; - - prefix_val = list[1]; - if (prefix_val) { - prefix = _nm_utils_ascii_str_to_int64 (prefix_val, 10, 0, 128, -1); - if (prefix < 0) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IP6 prefix '%s'", prefix_val); - goto error; - } - } else { - /* Missing prefix is treated as prefix of 64 */ + if (prefix < 0) prefix = 64; - } - *out_address = nm_ip_address_new (AF_INET6, ip_val, prefix, error); - if (*out_address) - success = TRUE; + addr = nm_ip_address_new_binary (AF_INET6, &addr_bin, prefix, error); + if (!addr) + return FALSE; -error: - g_strfreev (list); - return success; + *out_address = addr; + return TRUE; } static NMSetting * @@ -1443,13 +1427,12 @@ make_match_setting (shvarFile *ifcfg) if (!v) return NULL; - strv = nm_utils_strsplit_set (v, " \t", TRUE); + strv = nm_utils_escaped_tokens_split (v, NM_ASCII_SPACES); 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])); + nm_setting_match_add_interface_name (s_match, strv[i]); } } @@ -1722,7 +1705,7 @@ make_ip4_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) @@ -1783,7 +1766,7 @@ make_ip4_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) @@ -1809,7 +1792,8 @@ static void read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *filename) { GDir *dir; - char *dirname, *base; + gs_free char *dirname = NULL; + gs_free char *base = NULL; NMIPAddress *base_addr = NULL; GError *err = NULL; @@ -1820,9 +1804,9 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file base_addr = nm_setting_ip_config_get_address (s_ip4, 0); dirname = g_path_get_dirname (filename); - g_return_if_fail (dirname != NULL); + nm_assert (dirname != NULL); base = g_path_get_basename (filename); - g_return_if_fail (base != NULL); + nm_assert (base != NULL); dir = g_dir_open (dirname, 0, &err); if (dir) { @@ -1911,9 +1895,6 @@ read_aliases (NMSettingIPConfig *s_ip4, gboolean read_defroute, const char *file PARSE_WARNING ("can not read directory '%s': %s", dirname, err->message); g_error_free (err); } - - g_free (base); - g_free (dirname); } static NMSetting * @@ -1922,10 +1903,9 @@ make_ip6_setting (shvarFile *ifcfg, gboolean routes_read, GError **error) { - NMSettingIPConfig *s_ip6 = NULL; + gs_unref_object NMSettingIPConfig *s_ip6 = NULL; const char *v; gs_free char *value = NULL; - char *route6_path = NULL; gboolean ipv6init, ipv6forwarding, dhcp6 = FALSE; char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; const char *ipv6addr, *ipv6addr_secondaries; @@ -2060,7 +2040,7 @@ make_ip6_setting (shvarFile *ifcfg, /* Don't bother to read IP, DNS and routes when IPv6 is disabled */ if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) - return NM_SETTING (s_ip6); + return NM_SETTING (g_steal_pointer (&s_ip6)); nm_clear_g_free (&value); v = svGetValueStr (ifcfg, "DHCPV6_DUID", &value); @@ -2083,7 +2063,7 @@ make_ip6_setting (shvarFile *ifcfg, g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, v, NULL); g_object_set (s_ip6, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, - svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), NULL); + svGetValueBoolean (ifcfg, "DHCPV6_SEND_HOSTNAME", TRUE), NULL); /* Read static IP addresses. * Read them even for AUTO and DHCP methods - in this case the addresses are @@ -2099,12 +2079,12 @@ make_ip6_setting (shvarFile *ifcfg, ipv6addr_secondaries ?: "", NULL); - list = nm_utils_strsplit_set (value, " ", FALSE); + list = nm_utils_strsplit_set (value, " "); for (iter = list, i = 0; iter && *iter; iter++, i++) { NMIPAddress *addr = NULL; if (!parse_full_ip6_address (ifcfg, *iter, i, &addr, error)) - goto error; + return NULL; if (!nm_setting_ip_config_add_address (s_ip6, addr)) PARSE_WARNING ("duplicate IP6 address"); @@ -2129,7 +2109,7 @@ make_ip6_setting (shvarFile *ifcfg, if (!nm_utils_ipaddr_valid (AF_INET6, v)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IP6 address '%s'", v); - goto error; + return NULL; } g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, v, NULL); @@ -2172,18 +2152,19 @@ make_ip6_setting (shvarFile *ifcfg, /* Ignore IPv4 addresses */ } else { PARSE_WARNING ("invalid DNS server address %s", v); - goto error; + return NULL; } } if (!routes_read) { /* NOP */ } else { + gs_free char *route6_path = NULL; + /* Read static routes from route6-<interface> file */ route6_path = utils_get_route6_path (svFileGetName (ifcfg)); if (!read_route_file (AF_INET6, route6_path, s_ip6, error)) - goto error; - g_free (route6_path); + return NULL; } /* DNS searches */ @@ -2192,7 +2173,7 @@ make_ip6_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (iter = searches; *iter; iter++) { if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) @@ -2212,12 +2193,7 @@ make_ip6_setting (shvarFile *ifcfg, priority, NULL); - return NM_SETTING (s_ip6); - -error: - g_free (route6_path); - g_object_unref (s_ip6); - return NULL; + return NM_SETTING (g_steal_pointer (&s_ip6)); } static NMSetting * @@ -2551,7 +2527,7 @@ read_dcb_percent_array (shvarFile *ifcfg, return TRUE; } - split = nm_utils_strsplit_set (val, ",", FALSE); + split = nm_utils_strsplit_set (val, ","); 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, @@ -2588,10 +2564,9 @@ make_dcb_setting (shvarFile *ifcfg, NMSetting **out_setting, GError **error) { - NMSettingDcb *s_dcb = NULL; + gs_unref_object NMSettingDcb *s_dcb = NULL; gboolean dcb_on; NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE; - char *val; g_return_val_if_fail (out_setting != NULL, FALSE); @@ -2600,31 +2575,28 @@ make_dcb_setting (shvarFile *ifcfg, return TRUE; s_dcb = (NMSettingDcb *) nm_setting_dcb_new (); - g_assert (s_dcb); /* FCOE */ if (!read_dcb_app (ifcfg, s_dcb, "FCOE", &dcb_flags_props[DCB_APP_FCOE_FLAGS], NM_SETTING_DCB_APP_FCOE_PRIORITY, error)) { - g_object_unref (s_dcb); return FALSE; } if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) { + gs_free char *val = NULL; + val = svGetValueStr_cp (ifcfg, KEY_DCB_APP_FCOE_MODE); if (val) { - if (strcmp (val, NM_SETTING_DCB_FCOE_MODE_FABRIC) == 0 || - strcmp (val, NM_SETTING_DCB_FCOE_MODE_VN2VN) == 0) + if (NM_IN_STRSET (val, NM_SETTING_DCB_FCOE_MODE_FABRIC, + NM_SETTING_DCB_FCOE_MODE_VN2VN)) g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL); else { PARSE_WARNING ("invalid FCoE mode '%s'", val); g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "invalid FCoE mode"); - g_free (val); - g_object_unref (s_dcb); return FALSE; } - g_free (val); } } @@ -2633,7 +2605,6 @@ make_dcb_setting (shvarFile *ifcfg, &dcb_flags_props[DCB_APP_ISCSI_FLAGS], NM_SETTING_DCB_APP_ISCSI_PRIORITY, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2642,7 +2613,6 @@ make_dcb_setting (shvarFile *ifcfg, &dcb_flags_props[DCB_APP_FIP_FLAGS], NM_SETTING_DCB_APP_FIP_PRIORITY, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2657,7 +2627,6 @@ make_dcb_setting (shvarFile *ifcfg, "PFC", nm_setting_dcb_set_priority_flow_control, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2673,7 +2642,6 @@ make_dcb_setting (shvarFile *ifcfg, TRUE, nm_setting_dcb_set_priority_group_id, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2686,7 +2654,6 @@ make_dcb_setting (shvarFile *ifcfg, TRUE, nm_setting_dcb_set_priority_group_bandwidth, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2699,7 +2666,6 @@ make_dcb_setting (shvarFile *ifcfg, FALSE, nm_setting_dcb_set_priority_bandwidth, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2711,7 +2677,6 @@ make_dcb_setting (shvarFile *ifcfg, "STRICT", nm_setting_dcb_set_priority_strict_bandwidth, error)) { - g_object_unref (s_dcb); return FALSE; } @@ -2723,11 +2688,10 @@ make_dcb_setting (shvarFile *ifcfg, FALSE, nm_setting_dcb_set_priority_traffic_class, error)) { - g_object_unref (s_dcb); return FALSE; } - *out_setting = NM_SETTING (s_dcb); + *out_setting = NM_SETTING (g_steal_pointer (&s_dcb)); return TRUE; } @@ -2834,7 +2798,7 @@ make_wep_setting (shvarFile *ifcfg, GError **error) { gs_unref_object NMSettingWirelessSecurity *s_wsec = NULL; - char *value; + gs_free char *value = NULL; shvarFile *keys_ifcfg = NULL; int default_key_idx = 0; gboolean has_default_key = FALSE; @@ -2849,13 +2813,12 @@ make_wep_setting (shvarFile *ifcfg, if (default_key_idx == 0) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid default WEP key '%s'", value); - g_free (value); return NULL; } has_default_key = TRUE; default_key_idx--; /* convert to [0...3] */ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, (guint) default_key_idx, NULL); - g_free (value); + nm_clear_g_free (&value); } /* Read WEP key flags */ @@ -2902,23 +2865,21 @@ make_wep_setting (shvarFile *ifcfg, value = svGetValueStr_cp (ifcfg, "SECURITYMODE"); if (value) { - char *lcase; + gs_free char *lcase = NULL; lcase = g_ascii_strdown (value, -1); - g_free (value); + nm_clear_g_free (&value); - if (!strcmp (lcase, "open")) { + if (nm_streq (lcase, "open")) { g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if (!strcmp (lcase, "restricted")) { + } else if (nm_streq (lcase, "restricted")) { g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL); } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid WEP authentication algorithm '%s'", lcase); - g_free (lcase); return NULL; } - g_free (lcase); } /* If no WEP keys were given, and the keys are not agent-owned, and no @@ -2963,7 +2924,7 @@ fill_wpa_ciphers (shvarFile *ifcfg, if (!p) return TRUE; - list = nm_utils_strsplit_set (p, " ", FALSE); + list = nm_utils_strsplit_set (p, " "); 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 @@ -3233,7 +3194,7 @@ eap_peap_reader (const char *eap_method, } /* Handle options for the inner auth method */ - list = nm_utils_strsplit_set (v, " ", FALSE); + list = nm_utils_strsplit_set (v, " "); iter = list; if (iter) { if (NM_IN_STRSET (*iter, "MSCHAPV2", @@ -3311,7 +3272,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, " ", FALSE); + list = nm_utils_strsplit_set (inner_auth, " "); iter = list; if (iter) { if (NM_IN_STRSET (*iter, "mschapv2", @@ -3372,7 +3333,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", FALSE); + list1 = nm_utils_strsplit_set (fast_provisioning, " \t"); for (iter = list1; iter && *iter; iter++) { if (strcmp (*iter, "allow-unauth") == 0) allow_unauth = TRUE; @@ -3406,7 +3367,7 @@ eap_fast_reader (const char *eap_method, } /* Handle options for the inner auth method */ - list = nm_utils_strsplit_set (inner_auth, " ", FALSE); + list = nm_utils_strsplit_set (inner_auth, " "); iter = list; if (iter) { if ( !strcmp (*iter, "MSCHAPV2") @@ -3486,7 +3447,7 @@ read_8021x_list_value (shvarFile *ifcfg, if (!v) return; - strv = nm_utils_strsplit_set (v, " \t", FALSE); + strv = nm_utils_strsplit_set (v, " \t"); if (strv) g_object_set (setting, prop_name, strv, NULL); } @@ -3515,7 +3476,7 @@ fill_8021x (shvarFile *ifcfg, return NULL; } - list = nm_utils_strsplit_set (v, " ", FALSE); + list = nm_utils_strsplit_set (v, " "); s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); @@ -3829,7 +3790,7 @@ transform_hwaddr_blacklist (const char *blacklist) const char **strv; gsize i, j; - strv = nm_utils_strsplit_set (blacklist, " \t", FALSE); + strv = nm_utils_strsplit_set (blacklist, " \t"); if (!strv) return NULL; for (i = 0, j = 0; strv[j]; j++) { @@ -4147,7 +4108,7 @@ parse_ethtool_option (const char *value, gs_free const char **words = NULL; guint i; - words = nm_utils_strsplit_set (value, NULL, FALSE); + words = nm_utils_strsplit_set (value, " \t\n"); if (!words) return; @@ -4316,6 +4277,84 @@ parse_ethtool_option (const char *value, } } +static GPtrArray * +read_routing_rules_parse (shvarFile *ifcfg, + gboolean routes_read) +{ + gs_unref_ptrarray GPtrArray *arr = NULL; + gs_free const char **keys = NULL; + guint i, len; + + keys = svGetKeysSorted (ifcfg, SV_KEY_TYPE_ROUTING_RULE4 | SV_KEY_TYPE_ROUTING_RULE6, &len); + if (len == 0) + return NULL; + + if (!routes_read) { + PARSE_WARNING ("'rule-' or 'rule6-' files are present; Policy routing rules (ROUTING_RULE*) settings are ignored"); + return NULL; + } + + arr = g_ptr_array_new_full (len, (GDestroyNotify) nm_ip_routing_rule_unref); + for (i = 0; i < len; i++) { + const char *key = keys[i]; + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + gs_free_error GError *local = NULL; + gs_free char *value_to_free = NULL; + const char *value; + gboolean key_is_ipv4; + + key_is_ipv4 = (key[NM_STRLEN ("ROUTING_RULE")] == '_'); + nm_assert ( key_is_ipv4 == NM_STR_HAS_PREFIX (key, "ROUTING_RULE_")); + nm_assert ((!key_is_ipv4) == NM_STR_HAS_PREFIX (key, "ROUTING_RULE6_")); + + value = svGetValueStr (ifcfg, key, &value_to_free); + if (!value) + continue; + + rule = nm_ip_routing_rule_from_string (value, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | (key_is_ipv4 + ? NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET + : NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6), + NULL, + &local); + if (!rule) { + PARSE_WARNING ("invalid routing rule %s=\"%s\": %s", key, value, local->message); + continue; + } + + g_ptr_array_add (arr, g_steal_pointer (&rule)); + } + + if (arr->len == 0) + return NULL; + + return g_steal_pointer (&arr); +} + +static void +read_routing_rules (shvarFile *ifcfg, + gboolean routes_read, + NMSettingIPConfig *s_ip4, + NMSettingIPConfig *s_ip6) +{ + gs_unref_ptrarray GPtrArray *routing_rules = NULL; + guint i; + + routing_rules = read_routing_rules_parse (ifcfg, routes_read); + if (!routing_rules) + return; + + for (i = 0; i < routing_rules->len; i++) { + NMIPRoutingRule *rule = routing_rules->pdata[i]; + + nm_setting_ip_config_add_routing_rule ( (nm_ip_routing_rule_get_addr_family (rule) == AF_INET) + ? s_ip4 + : s_ip6, + rule); + } +} + static void parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection) { @@ -4340,7 +4379,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, ";", FALSE); + opts = nm_utils_strsplit_set (ethtool_opts, ";"); 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. */ @@ -4436,7 +4475,7 @@ make_wired_setting (shvarFile *ifcfg, gs_free const char **chans = NULL; guint32 num_chans; - chans = nm_utils_strsplit_set (value, ",", FALSE); + chans = nm_utils_strsplit_set (value, ","); num_chans = NM_PTRARRAY_LEN (chans); if (num_chans < 2 || num_chans > 3) { PARSE_WARNING ("invalid SUBCHANNELS '%s' (%u channels, 2 or 3 expected)", @@ -4470,22 +4509,23 @@ make_wired_setting (shvarFile *ifcfg, value = svGetValueStr_cp (ifcfg, "OPTIONS"); if (value) { - char **options, **iter; + gs_free const char **options = NULL; + gsize i; - iter = options = g_strsplit_set (value, " ", 0); - while (iter && *iter) { - char *equals = strchr (*iter, '='); + options = nm_utils_strsplit_set_with_empty (value, " "); + for (i = 0; options && options[i]; i++) { + const char *line = options[i]; + const char *equals; gboolean valid = FALSE; + equals = strchr (line, '='); if (equals) { - *equals = '\0'; - valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1); + ((char *) equals)[0] = '\0'; + valid = nm_setting_wired_add_s390_option (s_wired, line, equals + 1); } if (!valid) - PARSE_WARNING ("invalid s390 OPTION '%s'", *iter); - iter++; + PARSE_WARNING ("invalid s390 OPTION '%s'", line); } - g_strfreev (options); nm_clear_g_free (&value); } @@ -4759,18 +4799,18 @@ make_bond_setting (shvarFile *ifcfg, gs_free const char **items = NULL; const char *const *iter; - items = nm_utils_strsplit_set (v, " ", FALSE); + items = nm_utils_strsplit_set (v, " "); for (iter = items; iter && *iter; iter++) { - gs_strfreev char **keys = NULL; - const char *key, *val; - - keys = g_strsplit_set (*iter, "=", 2); - if (keys && *keys) { - key = *keys; - val = *(keys + 1); - if (val && key[0] && val[0]) - handle_bond_option (s_bond, key, val); - } + gs_free char *key = NULL; + const char *val; + + val = strchr (*iter, '='); + if (!val) + continue; + key = g_strndup (*iter, val - *iter); + val++; + if (key[0] && val[0]) + handle_bond_option (s_bond, key, val); } } @@ -4958,6 +4998,8 @@ handle_bridge_option (NMSetting *setting, { "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, { "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION }, { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION }, + { "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION }, + { "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION }, { "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION }, { "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION }, { "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION }, @@ -5037,19 +5079,56 @@ handle_bridging_opts (NMSetting *setting, gs_free const char **items = NULL; const char *const *iter; - items = nm_utils_strsplit_set (value, " ", FALSE); + items = nm_utils_strsplit_set (value, " "); for (iter = items; iter && *iter; iter++) { - gs_strfreev char **keys = NULL; - const char *key, *val; - - keys = g_strsplit_set (*iter, "=", 2); - if (keys && *keys) { - key = *keys; - val = *(keys + 1); - if (val && key[0] && val[0]) - func (setting, stp, key, val, opt_type); + gs_free char *key = NULL; + const char *val; + + val = strchr (*iter, '='); + if (!val) + continue; + key = g_strndup (*iter, val - *iter); + val++; + if (key[0] && val[0]) + func (setting, stp, key, val, opt_type); + } +} + +static void +read_bridge_vlans (shvarFile *ifcfg, + const char *key, + NMSetting *setting, + const char *property) +{ + gs_unref_ptrarray GPtrArray *array = NULL; + gs_free char *value_to_free = NULL; + const char *value; + + value = svGetValueStr (ifcfg, key, &value_to_free); + if (value) { + gs_free const char **strv = NULL; + const char *const *iter; + GError *local = NULL; + NMBridgeVlan *vlan; + + array = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); + + strv = nm_utils_escaped_tokens_split (value, ","); + if (strv) { + for (iter = strv; *iter; iter++) { + vlan = nm_bridge_vlan_from_str (*iter, &local); + if (!vlan) { + PARSE_WARNING ("invalid bridge VLAN: %s", local->message); + g_clear_error (&local); + continue; + } + g_ptr_array_add (array, vlan); + } } + nm_clear_g_free (&value_to_free); } + + g_object_set (setting, property, array, NULL); } static NMSetting * @@ -5110,6 +5189,11 @@ make_bridge_setting (shvarFile *ifcfg, nm_clear_g_free (&value_to_free); } + read_bridge_vlans (ifcfg, + "BRIDGE_VLANS", + NM_SETTING (s_bridge), + NM_SETTING_BRIDGE_VLANS); + return (NMSetting *) g_steal_pointer (&s_bridge); } @@ -5179,6 +5263,11 @@ make_bridge_port_setting (shvarFile *ifcfg) handle_bridging_opts (s_port, FALSE, value, handle_bridge_option, BRIDGE_OPT_TYPE_PORT_OPTION); nm_clear_g_free (&value_to_free); } + + read_bridge_vlans (ifcfg, + "BRIDGE_PORT_VLANS", + s_port, + NM_SETTING_BRIDGE_PORT_VLANS); } return s_port; @@ -5255,7 +5344,7 @@ parse_prio_map_list (NMSettingVlan *s_vlan, v = svGetValueStr (ifcfg, key, &value); if (!v) return; - list = nm_utils_strsplit_set (v, ",", FALSE); + list = nm_utils_strsplit_set (v, ","); for (iter = list; iter && *iter; iter++) { if (!strchr (*iter, ':')) @@ -5360,7 +5449,7 @@ make_vlan_setting (shvarFile *ifcfg, gs_free const char **strv = NULL; const char *const *ptr; - strv = nm_utils_strsplit_set (v, ", ", FALSE); + strv = nm_utils_strsplit_set (v, ", "); for (ptr = strv; ptr && *ptr; ptr++) { if (nm_streq (*ptr, "GVRP") && gvrp == -1) vlan_flags |= NM_VLAN_FLAG_GVRP; @@ -5502,7 +5591,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, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item)) @@ -5768,8 +5857,7 @@ connection_from_file_full (const char *filename, error); if (!s_ip6) return NULL; - else - nm_connection_add_setting (connection, s_ip6); + nm_connection_add_setting (connection, s_ip6); s_ip4 = make_ip4_setting (main_ifcfg, network_ifcfg, @@ -5778,12 +5866,15 @@ connection_from_file_full (const char *filename, error); if (!s_ip4) return NULL; - else { - read_aliases (NM_SETTING_IP_CONFIG (s_ip4), - !has_ip4_defroute && !nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (s_ip4)), - filename); - nm_connection_add_setting (connection, s_ip4); - } + read_aliases (NM_SETTING_IP_CONFIG (s_ip4), + !has_ip4_defroute && !nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (s_ip4)), + filename); + nm_connection_add_setting (connection, s_ip4); + + read_routing_rules (main_ifcfg, + !has_complex_routes_v4 && !has_complex_routes_v6, + NM_SETTING_IP_CONFIG (s_ip4), + NM_SETTING_IP_CONFIG (s_ip6)); s_sriov = make_sriov_setting (main_ifcfg); if (s_sriov) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 84c22094..c7729df5 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -22,7 +22,7 @@ #define _UTILS_H_ #include "nm-connection.h" -#include "nm-ethtool-utils.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "shvar.h" diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index ee7fd161..80b1bffe 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -30,8 +30,8 @@ #include <unistd.h> #include <stdio.h> -#include "nm-utils/nm-enum-utils.h" -#include "nm-utils/nm-io-utils.h" +#include "nm-glib-aux/nm-enum-utils.h" +#include "nm-glib-aux/nm-io-utils.h" #include "nm-manager.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" @@ -50,7 +50,7 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-meta-setting.h" -#include "nm-ethtool-utils.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "nms-ifcfg-rh-common.h" #include "nms-ifcfg-rh-reader.h" @@ -1464,6 +1464,43 @@ get_setting_default_boolean (NMSetting *setting, const char *prop) } static gboolean +write_bridge_vlans (NMSetting *setting, + const char *property_name, + shvarFile *ifcfg, + const char *key, + GError **error) +{ + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan *vlan; + GString *string; + guint i; + + g_object_get (setting, property_name, &vlans, NULL); + + if (!vlans || !vlans->len) { + svUnsetValue (ifcfg, key); + return TRUE; + } + + string = g_string_new (""); + for (i = 0; i < vlans->len; i++) { + gs_free char *vlan_str = NULL; + + vlan = vlans->pdata[i]; + vlan_str = nm_bridge_vlan_to_str (vlan, error); + if (!vlan_str) + return FALSE; + if (string->len > 0) + g_string_append (string, ","); + nm_utils_escaped_tokens_escape_gstr_assert (vlan_str, ",", string); + } + + svSetValueStr (ifcfg, key, string->str); + g_string_free (string, TRUE); + return TRUE; +} + +static gboolean write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error) { NMSettingBridge *s_bridge; @@ -1534,10 +1571,31 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire g_string_append_printf (opts, "multicast_snooping=%u", (guint32) b); } + b = nm_setting_bridge_get_vlan_filtering (s_bridge); + if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_FILTERING)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "vlan_filtering=%u", (guint32) b); + } + + i = nm_setting_bridge_get_vlan_default_pvid (s_bridge); + if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "default_pvid=%u", i); + } + if (opts->len) svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str); g_string_free (opts, TRUE); + if (!write_bridge_vlans ((NMSetting *) s_bridge, + NM_SETTING_BRIDGE_VLANS, + ifcfg, + "BRIDGE_VLANS", + error)) + return FALSE; + svSetValueStr (ifcfg, "TYPE", TYPE_BRIDGE); *wired = write_wired_for_virtual (connection, ifcfg); @@ -1550,7 +1608,7 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError ** { NMSettingBridgePort *s_port; guint32 i; - GString *opts; + GString *string; s_port = nm_connection_get_setting_bridge_port (connection); if (!s_port) @@ -1559,28 +1617,35 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError ** svUnsetValue (ifcfg, "BRIDGING_OPTS"); /* Bridge options */ - opts = g_string_sized_new (32); + string = g_string_sized_new (32); i = nm_setting_bridge_port_get_priority (s_port); if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PRIORITY)) - g_string_append_printf (opts, "priority=%u", i); + g_string_append_printf (string, "priority=%u", i); i = nm_setting_bridge_port_get_path_cost (s_port); if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PATH_COST)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "path_cost=%u", i); + if (string->len) + g_string_append_c (string, ' '); + g_string_append_printf (string, "path_cost=%u", i); } if (nm_setting_bridge_port_get_hairpin_mode (s_port)) { - if (opts->len) - g_string_append_c (opts, ' '); - g_string_append_printf (opts, "hairpin_mode=1"); + if (string->len) + g_string_append_c (string, ' '); + g_string_append_printf (string, "hairpin_mode=1"); } - if (opts->len) - svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str); - g_string_free (opts, TRUE); + if (string->len) + svSetValueStr (ifcfg, "BRIDGING_OPTS", string->str); + g_string_free (string, TRUE); + + if (!write_bridge_vlans ((NMSetting *) s_port, + NM_SETTING_BRIDGE_PORT_VLANS, + ifcfg, + "BRIDGE_PORT_VLANS", + error)) + return FALSE; return TRUE; } @@ -2310,15 +2375,17 @@ write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) 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) + name = nm_setting_match_get_interface_name (s_match, i); + if (!name || !name[0]) + continue; + + if (!str) 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)); + nm_utils_escaped_tokens_escape_gstr (name, NM_ASCII_SPACES, str); } if (str) @@ -2889,6 +2956,52 @@ write_ip6_setting (NMConnection *connection, return TRUE; } +static void +write_ip_routing_rules (NMConnection *connection, + shvarFile *ifcfg, + gboolean route_ignore) +{ + gsize idx; + int is_ipv4; + + svUnsetAll (ifcfg, SV_KEY_TYPE_ROUTING_RULE4 | SV_KEY_TYPE_ROUTING_RULE6); + + if (route_ignore) + return; + + idx = 0; + + for (is_ipv4 = 1; is_ipv4 >= 0; is_ipv4--) { + const int addr_family = is_ipv4 ? AF_INET : AF_INET6; + NMSettingIPConfig *s_ip; + guint i, num; + + s_ip = nm_connection_get_setting_ip_config (connection, addr_family); + if (!s_ip) + continue; + + num = nm_setting_ip_config_get_num_routing_rules (s_ip); + for (i = 0; i < num; i++) { + NMIPRoutingRule *rule = nm_setting_ip_config_get_routing_rule (s_ip, i); + gs_free const char *s = NULL; + char key[64]; + + s = nm_ip_routing_rule_to_string (rule, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE, + NULL, + NULL); + if (!s) + continue; + + if (is_ipv4) + numbered_tag (key, "ROUTING_RULE_", ++idx); + else + numbered_tag (key, "ROUTING_RULE6_", ++idx); + svSetValueStr (ifcfg, key, s); + } + } +} + static char * escape_id (const char *id) { @@ -3111,6 +3224,15 @@ do_write_construct (NMConnection *connection, has_complex_routes_v4 ? "" : "6"); return FALSE; } + if ( ( s_ip4 + && nm_setting_ip_config_get_num_routing_rules (s_ip4) > 0) + || ( s_ip6 + && nm_setting_ip_config_get_num_routing_rules (s_ip6) > 0)) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "Cannot configure routing rules on a connection that has an associated 'rule%s-' file", + has_complex_routes_v4 ? "" : "6"); + return FALSE; + } route_ignore = TRUE; } else route_ignore = FALSE; @@ -3128,6 +3250,10 @@ do_write_construct (NMConnection *connection, error)) return FALSE; + write_ip_routing_rules (connection, + ifcfg, + route_ignore); + write_connection_setting (s_con, ifcfg); NM_SET_OUT (out_ifcfg, g_steal_pointer (&ifcfg)); diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index f3d58e26..b399a17f 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -36,8 +36,8 @@ #include "nm-core-internal.h" #include "nm-core-utils.h" -#include "nm-utils/nm-enum-utils.h" -#include "nm-utils/nm-io-utils.h" +#include "nm-glib-aux/nm-enum-utils.h" +#include "nm-glib-aux/nm-io-utils.h" #include "c-list/src/c-list.h" /*****************************************************************************/ @@ -879,10 +879,25 @@ _is_all_digits (const char *str) #define IS_NUMBERED_TAG(key, tab_name) \ ({ \ + const char *_key2 = (key); \ + \ + ( (strncmp (_key2, tab_name, NM_STRLEN (tab_name)) == 0) \ + && _is_all_digits (&_key2[NM_STRLEN (tab_name)])); \ + }) + +#define IS_NUMBERED_TAG_PARSE(key, tab_name, out_idx) \ + ({ \ const char *_key = (key); \ + gint64 _idx; \ + gboolean _good = FALSE; \ + gint64 *_out_idx = (out_idx); \ \ - ( (strncmp (_key, tab_name, NM_STRLEN (tab_name)) == 0) \ - && _is_all_digits (&_key[NM_STRLEN (tab_name)])); \ + if ( IS_NUMBERED_TAG (_key, ""tab_name"") \ + && (_idx = _nm_utils_ascii_str_to_int64 (&_key[NM_STRLEN (tab_name)], 10, 0, G_MAXINT64, -1)) != -1) { \ + NM_SET_OUT (_out_idx, _idx); \ + _good = TRUE; \ + } \ + _good; \ }) static gboolean @@ -919,10 +934,30 @@ _svKeyMatchesType (const char *key, SvKeyType match_key_type) if (IS_NUMBERED_TAG (key, "SRIOV_VF")) return TRUE; } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE4)) { + if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE_", NULL)) + return TRUE; + } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTING_RULE6)) { + if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE6_", NULL)) + return TRUE; + } return FALSE; } +gint64 +svNumberedParseKey (const char *key) +{ + gint64 idx; + + if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE_", &idx)) + return idx; + if (IS_NUMBERED_TAG_PARSE (key, "ROUTING_RULE6_", &idx)) + return idx; + return -1; +} + GHashTable * svGetKeys (shvarFile *s, SvKeyType match_key_type) { @@ -947,6 +982,42 @@ svGetKeys (shvarFile *s, SvKeyType match_key_type) return keys; } +static int +_get_keys_sorted_cmp (gconstpointer a, + gconstpointer b, + gpointer user_data) +{ + const char *k_a = *((const char *const*) a); + const char *k_b = *((const char *const*) b); + gint64 n_a; + gint64 n_b; + + n_a = svNumberedParseKey (k_a); + n_b = svNumberedParseKey (k_b); + NM_CMP_DIRECT (n_a, n_b); + NM_CMP_RETURN (strcmp (k_a, k_b)); + nm_assert_not_reached (); + return 0; +} + +const char ** +svGetKeysSorted (shvarFile *s, + SvKeyType match_key_type, + guint *out_len) +{ + gs_unref_hashtable GHashTable *keys_hash = NULL; + + keys_hash = svGetKeys (s, match_key_type); + if (!keys_hash) { + NM_SET_OUT (out_len, 0); + return NULL; + } + return (const char **) nm_utils_hash_keys_to_array (keys_hash, + _get_keys_sorted_cmp, + NULL, + out_len); +} + /*****************************************************************************/ const char * diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 622bb474..b38a8557 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -40,6 +40,8 @@ typedef enum { SV_KEY_TYPE_TC = (1LL << 3), SV_KEY_TYPE_USER = (1LL << 4), SV_KEY_TYPE_SRIOV_VF = (1LL << 5), + SV_KEY_TYPE_ROUTING_RULE4 = (1LL << 6), + SV_KEY_TYPE_ROUTING_RULE6 = (1LL << 7), } SvKeyType; const char *svFileGetName (const shvarFile *s); @@ -67,8 +69,14 @@ char *svGetValueStr_cp (shvarFile *s, const char *key); int svParseBoolean (const char *value, int def); +gint64 svNumberedParseKey (const char *key); + GHashTable *svGetKeys (shvarFile *s, SvKeyType match_key_type); +const char **svGetKeysSorted (shvarFile *s, + SvKeyType match_key_type, + guint *out_len); + /* return TRUE if <key> resolves to any truth value (e.g. "yes", "y", "true") * return FALSE if <key> resolves to any non-truth value (e.g. "no", "n", "false") * return <def> otherwise diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected index c478db38..a8ff8df3 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Bridge_Component.cexpected @@ -2,6 +2,7 @@ HWADDR=31:33:33:37:BE:CD MTU=1492 TYPE=Ethernet BRIDGING_OPTS="priority=50 path_cost=33" +BRIDGE_PORT_VLANS="1 untagged,2 pvid,4-4094 untagged" NAME="Test Write Bridge Component" UUID=${UUID} ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Routing_Rules.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Routing_Rules.cexpected new file mode 100644 index 00000000..0c2fa035 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Routing_Rules.cexpected @@ -0,0 +1,19 @@ +TYPE=Ethernet +PROXY_METHOD=none +BROWSER_ONLY=no +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=no +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +IPV6_ADDR_GEN_MODE=stable-privacy +ROUTING_RULE_1="priority 10 from 0.0.0.0/0 table 1" +ROUTING_RULE_2="priority 10 to 192.167.8.0/24 table 2" +ROUTING_RULE6_3="priority 10 from ::/0 table 10" +ROUTING_RULE6_4="priority 10 to 1:2:3::5/24 table 22" +ROUTING_RULE6_5="priority 10 to 1:3:3::5 table 55" +NAME="Test Write Routing Rules" +UUID=${UUID} +ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main index 2bc987c2..1788efe2 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main @@ -4,5 +4,5 @@ TYPE=Bridge BOOTPROTO=dhcp STP=on DELAY=2 -BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352 multicast_snooping=0 group_fwd_mask=24" +BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352 multicast_snooping=0 group_fwd_mask=24 vlan_filtering=1 default_pvid=99" MACADDR=00:16:41:11:22:33 diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index b352fbfc..49ab04d4 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -49,7 +49,7 @@ #include "nm-setting-vlan.h" #include "nm-setting-dcb.h" #include "nm-core-internal.h" -#include "nm-ethtool-utils.h" +#include "nm-libnm-core-intern/nm-ethtool-utils.h" #include "NetworkManagerUtils.h" @@ -4465,6 +4465,101 @@ test_write_wired_dhcp (void) nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); } +static NMIPRoutingRule * +_ip_routing_rule_new (int addr_family, + const char *str) +{ + NMIPRoutingRuleAsStringFlags flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_NONE; + gs_free_error GError *local = NULL; + NMIPRoutingRule *rule; + + if (addr_family != AF_UNSPEC) { + if (addr_family == AF_INET) + flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET; + else { + g_assert (addr_family == AF_INET6); + flags = NM_IP_ROUTING_RULE_AS_STRING_FLAGS_AF_INET6; + } + } + + rule = nm_ip_routing_rule_from_string (str, + NM_IP_ROUTING_RULE_AS_STRING_FLAGS_VALIDATE + | flags, + NULL, + nmtst_get_rand_bool () ? &local : NULL); + nmtst_assert_success (rule, local); + + if (addr_family != AF_UNSPEC) + g_assert_cmpint (nm_ip_routing_rule_get_addr_family (rule), ==, addr_family); + return rule; +} + +static void +_ip_routing_rule_add_to_setting (NMSettingIPConfig *s_ip, + const char *str) +{ + nm_auto_unref_ip_routing_rule NMIPRoutingRule *rule = NULL; + + rule = _ip_routing_rule_new (nm_setting_ip_config_get_addr_family (s_ip), str); + nm_setting_ip_config_add_routing_rule (s_ip, rule); +} + +static void +test_write_routing_rules (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; + NMSettingIPConfig *s_ip4; + NMSettingIPConfig *s_ip6; + + connection = nm_simple_connection_new (); + + 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 Routing Rules", + NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + 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); + + 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_AUTO, + NULL); + + _ip_routing_rule_add_to_setting (s_ip4, "pref 10 from 0.0.0.0/0 table 1"); + _ip_routing_rule_add_to_setting (s_ip4, "priority 10 to 192.167.8.0/24 table 2"); + _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 table 10"); + _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 to 1:2:3::5/24 table 22"); + _ip_routing_rule_add_to_setting (s_ip6, "pref 10 from ::/0 to 1:3:3::5/128 table 55"); + + nmtst_assert_connection_verifies (connection); + + _writer_new_connec_exp (connection, + TEST_SCRATCH_DIR, + TEST_IFCFG_DIR"/ifcfg-Test_Write_Routing_Rules.cexpected", + &testfile); + reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); +} + static void test_write_wired_match (void) { @@ -7507,6 +7602,8 @@ test_read_bridge_main (void) g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352); g_assert_cmpuint (nm_setting_bridge_get_group_forward_mask (s_bridge), ==, 24); g_assert (!nm_setting_bridge_get_multicast_snooping (s_bridge)); + g_assert_cmpint (nm_setting_bridge_get_vlan_filtering (s_bridge), ==, TRUE); + g_assert_cmpint (nm_setting_bridge_get_vlan_default_pvid (s_bridge), ==, 99); /* MAC address */ s_wired = nm_connection_get_setting_wired (connection); @@ -7531,6 +7628,8 @@ test_write_bridge_main (void) NMIPAddress *addr; static const char *mac = "31:33:33:37:be:cd"; GError *error = NULL; + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan *vlan; connection = nm_simple_connection_new (); g_assert (connection); @@ -7551,9 +7650,23 @@ test_write_bridge_main (void) s_bridge = (NMSettingBridge *) nm_setting_bridge_new (); nm_connection_add_setting (connection, NM_SETTING (s_bridge)); + vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); + vlan = nm_bridge_vlan_new (10, 16); + nm_bridge_vlan_set_untagged (vlan, TRUE); + g_ptr_array_add (vlans, vlan); + vlan = nm_bridge_vlan_new (22, 22); + nm_bridge_vlan_set_pvid (vlan, TRUE); + nm_bridge_vlan_set_untagged (vlan, TRUE); + g_ptr_array_add (vlans, vlan); + vlan = nm_bridge_vlan_new (44, 0); + g_ptr_array_add (vlans, vlan); + g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, mac, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, 19008, + NM_SETTING_BRIDGE_VLAN_FILTERING, TRUE, + NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, 4000, + NM_SETTING_BRIDGE_VLANS, vlans, NULL); /* IP4 setting */ @@ -7631,6 +7744,8 @@ test_write_bridge_component (void) NMSetting *s_port; static const char *mac = "31:33:33:37:be:cd"; guint32 mtu = 1492; + gs_unref_ptrarray GPtrArray *vlans = NULL; + NMBridgeVlan *vlan; connection = nm_simple_connection_new (); g_assert (connection); @@ -7658,11 +7773,23 @@ test_write_bridge_component (void) NULL); /* Bridge port */ + vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref); + vlan = nm_bridge_vlan_new (1, 0); + nm_bridge_vlan_set_untagged (vlan, TRUE); + g_ptr_array_add (vlans, vlan); + vlan = nm_bridge_vlan_new (4, 4094); + nm_bridge_vlan_set_untagged (vlan, TRUE); + g_ptr_array_add (vlans, vlan); + vlan = nm_bridge_vlan_new (2, 2); + nm_bridge_vlan_set_pvid (vlan, TRUE); + g_ptr_array_add (vlans, vlan); + s_port = nm_setting_bridge_port_new (); nm_connection_add_setting (connection, s_port); g_object_set (s_port, NM_SETTING_BRIDGE_PORT_PRIORITY, 50, NM_SETTING_BRIDGE_PORT_PATH_COST, 33, + NM_SETTING_BRIDGE_PORT_VLANS, vlans, NULL); nmtst_assert_connection_verifies (connection); @@ -10168,6 +10295,7 @@ int main (int argc, char **argv) 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); + g_test_add_func (TPATH "wired/write/routing-rules", test_write_routing_rules); #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)) |