static void cell_error_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) { guint32 col = GPOINTER_TO_UINT (data); char *value = NULL; const char *color = NULL; guint32 prefix; gboolean invalid = FALSE; gtk_tree_model_get (tree_model, iter, col, &value, -1); if (col == COL_ADDRESS) invalid = !value || !*value || !nm_utils_ipaddr_valid (AF_INET, value) || is_address_unspecified (value); else if (col == COL_PREFIX) invalid = !parse_netmask (value, &prefix); else if (col == COL_GATEWAY) { invalid = value && *value && !nm_utils_ipaddr_valid (AF_INET, value); /* Check gateway against address and prefix */ if (!invalid && possibly_wrong_gateway (tree_model, iter, value)) color = "#DDC000"; /* darker than "yellow", else selected text is hard to read */ } else g_warn_if_reached (); if (invalid) color = "red"; utils_set_cell_background (cell, color, color ? value : NULL); g_free (value); }
static ip_block * create_ip4_block (gchar * ip) { ip_block *iblock = g_slice_new0 (ip_block); guint32 tmp_ip4_addr; int i; guint length; gchar **ip_mask; /* prefix format */ if (strstr (ip, "/")) { gchar *prefix; ip_mask = g_strsplit (ip, "/", 0); length = g_strv_length (ip_mask); if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) goto error; iblock->ip = g_strdup (ip_mask[0]); prefix = ip_mask[1]; i = 0; while (i < length && g_ascii_isdigit (prefix[i])) i++; prefix[i] = '\0'; iblock->prefix = (guint32) atoi (ip_mask[1]); } else if (strstr (ip, "netmask")) { ip_mask = g_strsplit (ip, " ", 0); length = g_strv_length (ip_mask); if (!nm_utils_ipaddr_valid (AF_INET, ip_mask[0])) goto error; iblock->ip = g_strdup (ip_mask[0]); i = 0; while (i < length && !strstr (ip_mask[++i], "netmask")) ; while (i < length && ip_mask[++i][0] == '\0') ; if (i >= length) goto error; if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) goto error; iblock->prefix = nm_utils_ip4_netmask_to_prefix (tmp_ip4_addr); } else { g_slice_free (ip_block, iblock); if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, missing netmask or prefix", ip); return NULL; } if (iblock->prefix == 0 || iblock->prefix > 32) { nm_log_warn (LOGD_SETTINGS, "Can't handle ipv4 address: %s, invalid prefix", ip); goto error; } g_strfreev (ip_mask); return iblock; error: if (!is_ip6_address (ip)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 address: %s", ip); g_strfreev (ip_mask); g_free (iblock->ip); g_slice_free (ip_block, iblock); return NULL; }
static gboolean ip_route_transform_from_next_hop_string (GBinding *binding, const GValue *source_value, GValue *target_value, gpointer user_data) { int family = GPOINTER_TO_INT (user_data); NMIPRoute *route; const char *text; text = g_value_get_string (source_value); if (*text) { if (!nm_utils_ipaddr_valid (family, text)) return FALSE; } else text = NULL; /* Fetch the original property value */ g_object_get (g_binding_get_source (binding), g_binding_get_source_property (binding), &route, NULL); nm_ip_route_set_next_hop (route, text); g_value_take_boxed (target_value, route); return TRUE; }
static char * get_ip6_next_hop (gchar * next_hop) { gchar *tmp; if (!next_hop) return NULL; tmp = find_gateway_str (next_hop); if (!tmp) { nm_log_warn (LOGD_SETTINGS, "Couldn't obtain next_hop in \"%s\"", next_hop); return NULL; } tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); g_strstrip (tmp); if (!nm_utils_ipaddr_valid (AF_INET6, tmp)) goto error; return tmp; error: if (!is_ip4_address (tmp)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 next_hop: %s", tmp); g_free (tmp); return NULL; }
static char * get_ip4_gateway (gchar * gateway) { gchar *tmp, *split; if (!gateway) return NULL; tmp = find_gateway_str (gateway); if (!tmp) { nm_log_warn (LOGD_SETTINGS, "Couldn't obtain gateway in \"%s\"", gateway); return NULL; } tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); // Only one gateway is selected if ((split = strstr (tmp, "\"")) != NULL) *split = '\0'; if (!nm_utils_ipaddr_valid (AF_INET, tmp)) goto error; return tmp; error: if (!is_ip6_address (tmp)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv4 gateway: %s", tmp); g_free (tmp); return NULL; }
static ip_block * create_ip_block (gchar * ip) { ip_block *iblock = g_slice_new0 (ip_block); gchar *dup_ip = g_strdup (ip); gchar *prefix = NULL; if ((prefix = strstr (dup_ip, "/")) != NULL) { *prefix = '\0'; prefix++; } if (!nm_utils_ipaddr_valid (AF_INET6, dup_ip)) goto error; iblock->ip = dup_ip; if (prefix) { errno = 0; iblock->prefix = strtol (prefix, NULL, 10); if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { goto error; } } else iblock->prefix = 64; return iblock; error: if (!is_ip4_address (ip)) nm_log_warn (LOGD_SETTINGS, "Can't handle IPv6 address: %s", ip); g_slice_free (ip_block, iblock); g_free (dup_ip); return NULL; }
static gboolean ip_gateway_from_string (GBinding *binding, const GValue *source_value, GValue *target_value, gpointer user_data) { int family = GPOINTER_TO_INT (user_data); const char *gateway; gateway = g_value_get_string (source_value); if (gateway && !nm_utils_ipaddr_valid (family, gateway)) gateway = NULL; g_value_set_string (target_value, gateway); return TRUE; }
static gboolean possibly_wrong_gateway (GtkTreeModel *model, GtkTreeIter *iter, const char *gw_str) { char *addr_str, *prefix_str; gboolean addr_valid; guint32 prefix; gtk_tree_model_get (model, iter, COL_ADDRESS, &addr_str, -1); gtk_tree_model_get (model, iter, COL_PREFIX, &prefix_str, -1); addr_valid = addr_str && *addr_str && nm_utils_ipaddr_valid (AF_INET, addr_str) && !is_address_unspecified (addr_str) && parse_netmask (prefix_str, &prefix); if (addr_valid && !gateway_matches_address (gw_str, addr_str, prefix)) return TRUE; else return FALSE; }
static gboolean ip_addresses_check_and_copy (GBinding *binding, const GValue *source_value, GValue *target_value, gpointer user_data) { int family = GPOINTER_TO_INT (user_data); char **strings; int i; strings = g_value_get_boxed (source_value); for (i = 0; strings[i]; i++) { if (!nm_utils_ipaddr_valid (family, strings[i])) return FALSE; } g_value_set_boxed (target_value, strings); return TRUE; }
static gboolean parse_addr_prefix (const char *text, int family, char **addr, guint32 *prefix) { const char *slash; char *addrstr, *end; gboolean valid; slash = strchr (text, '/'); if (slash) addrstr = g_strndup (text, slash - text); else addrstr = g_strdup (text); valid = nm_utils_ipaddr_valid (family, addrstr); if (slash) { *prefix = strtoul (slash + 1, &end, 10); if ( *end || *prefix == 0 || (family == AF_INET && *prefix > 32) || (family == AF_INET6 && *prefix > 128)) valid = FALSE; } else if (prefix) { if (family == AF_INET) *prefix = 32; else *prefix = 128; } if (addr && valid) *addr = addrstr; else g_free (addrstr); return valid; }
static gboolean update_ip6_setting_from_if_block(NMConnection *connection, if_block *block, GError **error) { NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new()); const char *type = ifparser_getkey(block, "inet6"); gboolean is_static = type && (!strcmp("static", type) || !strcmp("v4tunnel", type)); if (!is_static) { g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); } else { NMIPAddress *addr; const char *address_v; const char *prefix_v; const char *gateway_v; const char *nameserver_v; const char *nameservers_v; const char *search_v; int prefix_int = 128; char **list, **iter; /* Address */ address_v = ifparser_getkey(block, "address"); if (!address_v) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IPv6 address"); goto error; } /* Prefix */ prefix_v = ifparser_getkey(block, "netmask"); if (prefix_v) prefix_int = g_ascii_strtoll (prefix_v, NULL, 10); /* Add the new address to the setting */ addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error); if (!addr) goto error; if (nm_setting_ip_config_add_address (s_ip6, addr)) { nm_log_info (LOGD_SETTINGS, "addresses count: %d", nm_setting_ip_config_get_num_addresses (s_ip6)); } else { nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP6 address"); } nm_ip_address_unref (addr); /* gateway */ gateway_v = ifparser_getkey (block, "gateway"); if (gateway_v) { if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv6 gateway '%s'", gateway_v); goto error; } if (!nm_setting_ip_config_get_gateway (s_ip6)) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); } nameserver_v = ifparser_getkey(block, "dns-nameserver"); ifupdown_ip6_add_dns (s_ip6, nameserver_v); nameservers_v = ifparser_getkey(block, "dns-nameservers"); ifupdown_ip6_add_dns (s_ip6, nameservers_v); if (!nm_setting_ip_config_get_num_dns (s_ip6)) nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ search_v = ifparser_getkey (block, "dns-search"); if (search_v) { list = g_strsplit_set (search_v, " \t", -1); for (iter = list; iter && *iter; iter++) { g_strstrip (*iter); if (isblank (*iter[0])) continue; if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); } g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL); } nm_connection_add_setting (connection, NM_SETTING (s_ip6)); return TRUE; error: g_object_unref (s_ip6); return FALSE; }
static gboolean update_ip4_setting_from_if_block(NMConnection *connection, if_block *block, GError **error) { NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new()); const char *type = ifparser_getkey(block, "inet"); gboolean is_static = type && !strcmp("static", type); if (!is_static) { g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); } else { guint32 tmp_mask; NMIPAddress *addr; const char *address_v; const char *netmask_v; const char *gateway_v; const char *nameserver_v; const char *nameservers_v; const char *search_v; char **list, **iter; guint32 netmask_int = 32; /* Address */ address_v = ifparser_getkey (block, "address"); if (!address_v) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IPv4 address"); goto error; } /* mask/prefix */ netmask_v = ifparser_getkey (block, "netmask"); if (netmask_v) { if (strlen (netmask_v) < 7) { netmask_int = atoi (netmask_v); } else if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv4 netmask '%s'", netmask_v); goto error; } else { netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask); } } /* Add the new address to the setting */ addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error); if (!addr) goto error; if (nm_setting_ip_config_add_address (s_ip4, addr)) { nm_log_info (LOGD_SETTINGS, "addresses count: %d", nm_setting_ip_config_get_num_addresses (s_ip4)); } else { nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP4 address"); } nm_ip_address_unref (addr); /* gateway */ gateway_v = ifparser_getkey (block, "gateway"); if (gateway_v) { if (!nm_utils_ipaddr_valid (AF_INET, gateway_v)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv4 gateway '%s'", gateway_v); goto error; } if (!nm_setting_ip_config_get_gateway (s_ip4)) g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); } nameserver_v = ifparser_getkey (block, "dns-nameserver"); ifupdown_ip4_add_dns (s_ip4, nameserver_v); nameservers_v = ifparser_getkey (block, "dns-nameservers"); ifupdown_ip4_add_dns (s_ip4, nameservers_v); if (!nm_setting_ip_config_get_num_dns (s_ip4)) nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ search_v = ifparser_getkey (block, "dns-search"); if (search_v) { list = g_strsplit_set (search_v, " \t", -1); for (iter = list; iter && *iter; iter++) { g_strstrip (*iter); if (g_ascii_isspace (*iter[0])) continue; if (!nm_setting_ip_config_add_dns_search (s_ip4, *iter)) nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } g_strfreev (list); } g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); } nm_connection_add_setting (connection, NM_SETTING (s_ip4)); return TRUE; error: g_object_unref (s_ip4); return FALSE; }
static gboolean ui_to_setting (CEPageIP4 *self, GError **error) { CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self); GtkTreeModel *model; GtkTreeIter tree_iter; int int_method = IP4_METHOD_AUTO; const char *method; GPtrArray *tmp_array = NULL; char **dns_servers = NULL; char **search_domains = NULL; GPtrArray *addresses = NULL; char *gateway = NULL; gboolean valid = FALSE, iter_valid; const char *text; gboolean ignore_auto_dns = FALSE; const char *dhcp_client_id = NULL; char **items = NULL, **iter; gboolean may_fail = FALSE; /* Method */ if (gtk_combo_box_get_active_iter (priv->method, &tree_iter)) { gtk_tree_model_get (GTK_TREE_MODEL (priv->method_store), &tree_iter, METHOD_COL_NUM, &int_method, -1); } switch (int_method) { case IP4_METHOD_LINK_LOCAL: method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; break; case IP4_METHOD_MANUAL: method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; break; case IP4_METHOD_SHARED: method = NM_SETTING_IP4_CONFIG_METHOD_SHARED; break; case IP4_METHOD_DISABLED: method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; break; case IP4_METHOD_AUTO_ADDRESSES: ignore_auto_dns = TRUE; /* fall through */ default: method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; break; } /* IP addresses */ model = gtk_tree_view_get_model (priv->addr_list); iter_valid = gtk_tree_model_get_iter_first (model, &tree_iter); addresses = g_ptr_array_sized_new (1); while (iter_valid) { char *addr = NULL, *netmask = NULL, *addr_gw = NULL; NMIPAddress *nm_addr; guint32 prefix; gtk_tree_model_get (model, &tree_iter, COL_ADDRESS, &addr, COL_PREFIX, &netmask, COL_GATEWAY, &addr_gw, -1); if ( !addr || !nm_utils_ipaddr_valid (AF_INET, addr) || is_address_unspecified (addr)) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 address \"%s\" invalid"), addr ? addr : ""); g_free (addr); g_free (netmask); g_free (addr_gw); goto out; } if (!parse_netmask (netmask, &prefix)) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 address netmask \"%s\" invalid"), netmask ? netmask : ""); g_free (addr); g_free (netmask); g_free (addr_gw); goto out; } /* Gateway is optional... */ if (addr_gw && *addr_gw && !nm_utils_ipaddr_valid (AF_INET, addr_gw)) { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 gateway \"%s\" invalid"), addr_gw); g_free (addr); g_free (netmask); g_free (addr_gw); goto out; } nm_addr = nm_ip_address_new (AF_INET, addr, prefix, NULL); g_ptr_array_add (addresses, nm_addr); if (addresses->len == 1 && addr_gw && *addr_gw) { gateway = addr_gw; addr_gw = NULL; } g_free (addr); g_free (netmask); g_free (addr_gw); iter_valid = gtk_tree_model_iter_next (model, &tree_iter); } /* Don't pass empty array to the setting */ if (!addresses->len) { g_ptr_array_free (addresses, TRUE); addresses = NULL; } /* DNS servers */ tmp_array = g_ptr_array_new (); text = gtk_entry_get_text (GTK_ENTRY (priv->dns_servers)); if (text && strlen (text)) { items = g_strsplit_set (text, ", ;:", 0); for (iter = items; *iter; iter++) { struct in_addr tmp_addr; char *stripped = g_strstrip (*iter); if (!*stripped) continue; if (inet_pton (AF_INET, stripped, &tmp_addr)) g_ptr_array_add (tmp_array, g_strdup (stripped)); else { g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("IPv4 DNS server \"%s\" invalid"), stripped); g_strfreev (items); g_ptr_array_free (tmp_array, TRUE); goto out; } } g_strfreev (items); } g_ptr_array_add (tmp_array, NULL); dns_servers = (char **) g_ptr_array_free (tmp_array, FALSE); /* Search domains */ tmp_array = g_ptr_array_new (); text = gtk_entry_get_text (GTK_ENTRY (priv->dns_searches)); if (text && strlen (text)) { items = g_strsplit_set (text, ", ;:", 0); for (iter = items; *iter; iter++) { char *stripped = g_strstrip (*iter); if (strlen (stripped)) g_ptr_array_add (tmp_array, g_strdup (stripped)); } g_strfreev (items); } g_ptr_array_add (tmp_array, NULL); search_domains = (char **) g_ptr_array_free (tmp_array, FALSE); /* DHCP client ID */ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { dhcp_client_id = gtk_entry_get_text (priv->dhcp_client_id); if (dhcp_client_id && !strlen (dhcp_client_id)) dhcp_client_id = NULL; } may_fail = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->ip4_required)); /* Update setting */ g_object_set (priv->setting, NM_SETTING_IP_CONFIG_METHOD, method, NM_SETTING_IP_CONFIG_ADDRESSES, addresses, NM_SETTING_IP_CONFIG_GATEWAY, gateway, NM_SETTING_IP_CONFIG_DNS, dns_servers, NM_SETTING_IP_CONFIG_DNS_SEARCH, search_domains, NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, dhcp_client_id, NM_SETTING_IP_CONFIG_MAY_FAIL, may_fail, NULL); valid = TRUE; out: if (addresses) { g_ptr_array_foreach (addresses, (GFunc) free_one_addr, NULL); g_ptr_array_free (addresses, TRUE); } g_free (gateway); g_strfreev (dns_servers); g_strfreev (search_domains); return valid; }
/* * nmc_parse_and_build_route: * @family: AF_INET or AF_INET6 * @first: the route destination in the form of "address/prefix" (/prefix is optional) * @second: (allow-none): next hop address, if third is not NULL. Otherwise it could be either next hop address or metric. (It can be NULL when @third is NULL). * @third: (allow-none): route metric * @error: location to store GError * * Parse route from strings and return an #NMIPRoute * * Returns: %TRUE on success, %FALSE on failure */ NMIPRoute * nmc_parse_and_build_route (int family, const char *first, const char *second, const char *third, GError **error) { int max_prefix = (family == AF_INET) ? 32 : 128; char *dest = NULL, *plen = NULL; const char *next_hop = NULL; const char *canon_dest; long int prefix = max_prefix, metric = -1; NMIPRoute *route = NULL; gboolean success = FALSE; GError *local = NULL; g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE); g_return_val_if_fail (first != NULL, FALSE); g_return_val_if_fail (second || !third, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); dest = g_strdup (first); plen = strchr (dest, '/'); /* prefix delimiter */ if (plen) *plen++ = '\0'; if (plen) { if (!nmc_string_to_int (plen, TRUE, 1, max_prefix, &prefix)) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid prefix '%s'; <1-%d> allowed"), plen, max_prefix); goto finish; } } if (second) { if (third || nm_utils_ipaddr_valid (family, second)) next_hop = second; else { /* 'second' can be a metric */ if (!nmc_string_to_int (second, TRUE, 0, G_MAXUINT32, &metric)) { g_set_error (error, 1, 0, _("the second component of route ('%s') is neither " "a next hop address nor a metric"), second); goto finish; } } } if (third) { if (!nmc_string_to_int (third, TRUE, 0, G_MAXUINT32, &metric)) { g_set_error (error, 1, 0, _("invalid metric '%s'"), third); goto finish; } } route = nm_ip_route_new (family, dest, prefix, next_hop, metric, &local); if (!route) { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("invalid route: %s"), local->message); g_clear_error (&local); goto finish; } /* We don't accept default routes as NetworkManager handles it * itself. But we have to check this after @route has normalized the * dest string. */ canon_dest = nm_ip_route_get_dest (route); if (!strcmp (canon_dest, "0.0.0.0") || !strcmp (canon_dest, "::")) { g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, _("default route cannot be added (NetworkManager handles it by itself)")); g_clear_pointer (&route, nm_ip_route_unref); goto finish; } success = TRUE; finish: g_free (dest); return route; }
static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting); int family = AF_UNSPEC; switch (priv->mode) { case NM_IP_TUNNEL_MODE_IPIP: case NM_IP_TUNNEL_MODE_SIT: case NM_IP_TUNNEL_MODE_ISATAP: case NM_IP_TUNNEL_MODE_GRE: case NM_IP_TUNNEL_MODE_VTI: family = AF_INET; break; case NM_IP_TUNNEL_MODE_IP6IP6: case NM_IP_TUNNEL_MODE_IPIP6: case NM_IP_TUNNEL_MODE_IP6GRE: case NM_IP_TUNNEL_MODE_VTI6: family = AF_INET6; break; case NM_IP_TUNNEL_MODE_UNKNOWN: break; } if (family == AF_UNSPEC) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%d' is not a valid tunnel mode"), (int) priv->mode); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE); return FALSE; } if ( priv->parent && !nm_utils_iface_valid_name (priv->parent) && !nm_utils_is_uuid (priv->parent)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is neither an UUID nor an interface name"), priv->parent); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_PARENT); return FALSE; } if (priv->local && !nm_utils_ipaddr_valid (family, priv->local)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid IPv%c address"), priv->local, family == AF_INET ? '4' : '6'); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL); return FALSE; } if (!priv->remote) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("property is missing")); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE); return FALSE; } if (!nm_utils_ipaddr_valid (family, priv->remote)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid IPv%c address"), priv->remote, family == AF_INET ? '4' : '6'); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE); return FALSE; } if ( (priv->input_key && priv->input_key[0]) || (priv->output_key && priv->output_key[0])) { if ( priv->mode != NM_IP_TUNNEL_MODE_GRE && priv->mode != NM_IP_TUNNEL_MODE_IP6GRE) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("tunnel keys can only be specified for GRE tunnels")); return FALSE; } } if (priv->input_key && priv->input_key[0]) { gint64 val; val = _nm_utils_ascii_str_to_int64 (priv->input_key, 10, 0, G_MAXUINT32, -1); if (val == -1) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid tunnel key"), priv->input_key); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_INPUT_KEY); return FALSE; } } if (priv->output_key && priv->output_key[0]) { gint64 val; val = _nm_utils_ascii_str_to_int64 (priv->output_key, 10, 0, G_MAXUINT32, -1); if (val == -1) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid tunnel key"), priv->output_key); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_OUTPUT_KEY); return FALSE; } } if (!priv->path_mtu_discovery && priv->ttl != 0) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("a fixed TTL is allowed only when path MTU discovery is enabled")); g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_TTL); return FALSE; } return TRUE; }
static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingVxlanPrivate *priv = NM_SETTING_VXLAN_GET_PRIVATE (setting); int family = AF_UNSPEC; if (!priv->remote) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY, _("property is missing")); g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE); return FALSE; } if (nm_utils_ipaddr_valid (AF_INET, priv->remote)) family = AF_INET; else if (nm_utils_ipaddr_valid (AF_INET6, priv->remote)) family = AF_INET6; else { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid IP address"), priv->remote); g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_REMOTE); return FALSE; } if (priv->local) { if (!nm_utils_ipaddr_valid (family, priv->local)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid IP%c address"), priv->local, family == AF_INET ? '4' : '6'); g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_LOCAL); return FALSE; } } if ( priv->parent && !nm_utils_iface_valid_name (priv->parent) && !nm_utils_is_uuid (priv->parent)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is neither an UUID nor an interface name"), priv->parent); g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_PARENT); return FALSE; } if ( (priv->source_port_min || priv->source_port_max) && (priv->source_port_min > priv->source_port_max)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("%d is greater than local port max %d"), priv->source_port_min, priv->source_port_max); g_prefix_error (error, "%s.%s: ", NM_SETTING_VXLAN_SETTING_NAME, NM_SETTING_VXLAN_SOURCE_PORT_MIN); return FALSE; } return TRUE; }