libnm: allow zero prefix length for NMIPRoute

NMIPRoute is used by NMSettingIPConfig, but also
NMIPConfig. In the former case, default routes are (still)
disallowed. But in the NMIPConfig use-case, it can make sense
to expose default routes as NMIPRoute instances.

Relax the restriction on the NMIPRoute API to allow this
future change.

No code actually supports having NMIPRoute instances with
prefix length zero (default routes). Up to now, all such uses
would be a bug.

https://bugzilla.gnome.org/show_bug.cgi?id=739969

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller
2014-11-11 15:58:58 +01:00
parent 0b59752512
commit a2e93f2de4
7 changed files with 33 additions and 11 deletions

View File

@@ -84,11 +84,11 @@ valid_ip (int family, const char *ip, GError **error)
}
static gboolean
valid_prefix (int family, guint prefix, GError **error)
valid_prefix (int family, guint prefix, GError **error, gboolean allow_zero_prefix)
{
if ( (family == AF_INET && prefix > 32)
|| (family == AF_INET6 && prefix > 128)
|| prefix == 0) {
|| (!allow_zero_prefix && prefix == 0)) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
family == AF_INET ? _("Invalid IPv4 address prefix '%u'") : _("Invalid IPv6 address prefix '%u"),
prefix);
@@ -151,7 +151,7 @@ nm_ip_address_new (int family,
if (!valid_ip (family, addr, error))
return NULL;
if (!valid_prefix (family, prefix, error))
if (!valid_prefix (family, prefix, error, FALSE))
return NULL;
address = g_slice_new0 (NMIPAddress);
@@ -187,7 +187,7 @@ nm_ip_address_new_binary (int family,
g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
g_return_val_if_fail (addr != NULL, NULL);
if (!valid_prefix (family, prefix, error))
if (!valid_prefix (family, prefix, error, FALSE))
return NULL;
address = g_slice_new0 (NMIPAddress);
@@ -423,7 +423,7 @@ nm_ip_address_set_prefix (NMIPAddress *address,
guint prefix)
{
g_return_if_fail (address != NULL);
g_return_if_fail (valid_prefix (address->family, prefix, NULL));
g_return_if_fail (valid_prefix (address->family, prefix, NULL, FALSE));
address->prefix = prefix;
}
@@ -547,7 +547,7 @@ nm_ip_route_new (int family,
if (!valid_ip (family, dest, error))
return NULL;
if (!valid_prefix (family, prefix, error))
if (!valid_prefix (family, prefix, error, TRUE))
return NULL;
if (next_hop && !valid_ip (family, next_hop, error))
return NULL;
@@ -593,7 +593,7 @@ nm_ip_route_new_binary (int family,
g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
if (!valid_prefix (family, prefix, error))
if (!valid_prefix (family, prefix, error, TRUE))
return NULL;
if (!valid_metric (metric, error))
return NULL;
@@ -836,7 +836,7 @@ nm_ip_route_set_prefix (NMIPRoute *route,
guint prefix)
{
g_return_if_fail (route != NULL);
g_return_if_fail (valid_prefix (route->family, prefix, NULL));
g_return_if_fail (valid_prefix (route->family, prefix, NULL, TRUE));
route->prefix = prefix;
}
@@ -1933,6 +1933,15 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES);
return FALSE;
}
if (nm_ip_route_get_prefix (route) == 0) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("%d. route cannot be a default route"),
i+1);
g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES);
return FALSE;
}
}
return TRUE;

View File

@@ -363,6 +363,8 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
route.metric = nm_ip_route_get_metric (s_route);
route.source = NM_IP_CONFIG_SOURCE_USER;
g_assert (route.plen > 0);
nm_ip4_config_add_route (config, &route);
}
@@ -1156,6 +1158,7 @@ nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
int i;
g_return_if_fail (new != NULL);
g_return_if_fail (new->plen > 0);
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);

View File

@@ -467,6 +467,8 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu
route.metric = nm_ip_route_get_metric (s_route);
route.source = NM_IP_CONFIG_SOURCE_USER;
g_assert (route.plen > 0);
nm_ip6_config_add_route (config, &route);
}
@@ -1163,6 +1165,7 @@ nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *new)
int i;
g_return_if_fail (new != NULL);
g_return_if_fail (new->plen > 0);
for (i = 0; i < priv->routes->len; i++ ) {
NMPlatformIP6Route *item = &g_array_index (priv->routes, NMPlatformIP6Route, i);

View File

@@ -488,7 +488,7 @@ read_one_ip4_route (shvarFile *ifcfg,
inet_pton (AF_INET, value, &netmask);
prefix = nm_utils_ip4_netmask_to_prefix (netmask);
g_free (value);
if (netmask != nm_utils_ip4_prefix_to_netmask (prefix)) {
if (prefix == 0 || netmask != nm_utils_ip4_prefix_to_netmask (prefix)) {
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Invalid IP4 netmask '%s' \"%s\"", netmask_tag, nm_utils_inet4_ntop (netmask, NULL));
goto out;

View File

@@ -397,6 +397,10 @@ create_ip4_block (gchar * ip)
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:

View File

@@ -139,6 +139,7 @@ build_route (int family,
guint32 metric = 0;
GError *error = NULL;
g_return_val_if_fail (plen, NULL);
g_return_val_if_fail (dest_str, NULL);
/* Next hop */
@@ -276,7 +277,7 @@ read_one_ip_address_or_route (GKeyFile *file,
gboolean route,
char **out_gateway)
{
guint32 plen;
guint32 plen = G_MAXUINT32;
gpointer result;
char *address_str, *plen_str, *gateway_str, *metric_str, *value, *current, *error;
@@ -330,7 +331,8 @@ read_one_ip_address_or_route (GKeyFile *file,
/* parse plen, fallback to defaults */
if (plen_str) {
if (!get_one_int (plen_str, ipv6 ? 128 : 32, key_name, &plen)) {
if (!get_one_int (plen_str, ipv6 ? 128 : 32, key_name, &plen)
|| (route && plen == 0)) {
plen = DEFAULT_PREFIX (route, ipv6);
nm_log_warn (LOGD_SETTINGS, "keyfile: invalid prefix length '%s' in '%s.%s', defaulting to %d",
plen_str, setting_name, key_name, plen);

View File

@@ -391,6 +391,7 @@ add_one_ip_route (NMSettingIPConfig *s_ip,
NMIPRoute *route;
GError *error = NULL;
g_assert (prefix > 0);
route = nm_ip_route_new (NM_IS_SETTING_IP4_CONFIG (s_ip) ? AF_INET : AF_INET6,
dest, prefix, nh, metric, &error);
g_assert_no_error (error);