diff --git a/ChangeLog b/ChangeLog index 125cdf111e..4b022e3fab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-06-02 Tambet Ingo + + * libnm-util/nm-setting-ip4-config.[ch]: Add static routes property. + + * src/nm-ip4-config.[ch]: Store the static routes as a list of + NMIP4Address, update the getters and setters. + + * src/dhcp-manager/nm-dhcp-manager.c (nm_dhcp_manager_get_ip4_config): + Use the updated NMIP4Config routes api. + + * src/NetworkManagerUtils.c (nm_utils_merge_ip4_config): Merge + static routes as well. + + * src/NetworkManagerSystem.c (netmask_to_prefix): Implement. + (nm_system_device_set_from_ip4_config): Use the updated NMIP4Config + routes api. + 2008-05-30 Dan Williams * src/named-manager/nm-named-manager.c diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index 1044818b1e..906b25cae3 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -16,6 +16,7 @@ enum { PROP_DNS, PROP_DNS_SEARCH, PROP_ADDRESSES, + PROP_ROUTES, PROP_IGNORE_DHCP_DNS, LAST_PROP @@ -112,6 +113,9 @@ set_property (GObject *object, guint prop_id, case PROP_ADDRESSES: nm_utils_slist_free (setting->addresses, g_free); setting->addresses = nm_utils_ip4_addresses_from_gvalue (value); + case PROP_ROUTES: + nm_utils_slist_free (setting->routes, g_free); + setting->routes = nm_utils_ip4_addresses_from_gvalue (value); break; case PROP_IGNORE_DHCP_DNS: setting->ignore_dhcp_dns = g_value_get_boolean (value); @@ -141,6 +145,9 @@ get_property (GObject *object, guint prop_id, case PROP_ADDRESSES: nm_utils_ip4_addresses_to_gvalue (setting->addresses, value); break; + case PROP_ROUTES: + nm_utils_ip4_addresses_to_gvalue (setting->routes, value); + break; case PROP_IGNORE_DHCP_DNS: g_value_set_boolean (value, setting->ignore_dhcp_dns); break; @@ -195,6 +202,14 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class) DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + g_object_class_install_property + (object_class, PROP_ROUTES, + nm_param_spec_specialized (NM_SETTING_IP4_CONFIG_ROUTES, + "Routes", + "List of NMSettingIP4Addresses", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + g_object_class_install_property (object_class, PROP_IGNORE_DHCP_DNS, g_param_spec_boolean (NM_SETTING_IP4_CONFIG_IGNORE_DHCP_DNS, diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index 4925d4b0c9..a6097944d2 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -20,6 +20,7 @@ G_BEGIN_DECLS #define NM_SETTING_IP4_CONFIG_DNS "dns" #define NM_SETTING_IP4_CONFIG_DNS_SEARCH "dns-search" #define NM_SETTING_IP4_CONFIG_ADDRESSES "addresses" +#define NM_SETTING_IP4_CONFIG_ROUTES "routes" #define NM_SETTING_IP4_CONFIG_IGNORE_DHCP_DNS "ignore-dhcp-dns" #define NM_SETTING_IP4_CONFIG_METHOD_DHCP "dhcp" @@ -40,6 +41,7 @@ typedef struct { GArray *dns; /* array of guint32 */ GSList *dns_search; /* list of strings */ GSList *addresses; /* array of NMSettingIP4Address */ + GSList *routes; /* array of NMSettingIP4Address */ gboolean ignore_dhcp_dns; } NMSettingIP4Config; diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index 2a87ca2f43..681efb9319 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -275,6 +275,33 @@ add_ip4_addresses (NMIP4Config *config, const char *iface) return TRUE; } +static int +netmask_to_prefix (guint32 netmask) +{ + guchar *p; + guchar *end; + int prefix = 0; + + p = (guchar *) &netmask; + end = p + sizeof (guint32); + + while ((*p == 0xFF) && p < end) { + prefix += 8; + p++; + } + + if (p < end) { + guchar v = *p; + + while (v) { + prefix++; + v <<= 1; + } + } + + return prefix; +} + /* * nm_system_device_set_from_ip4_config * @@ -298,12 +325,14 @@ nm_system_device_set_from_ip4_config (const char *iface, len = nm_ip4_config_get_num_static_routes (config); for (i = 0; i < len; i++) { - guint32 mss = nm_ip4_config_get_mss (config); - guint32 route = nm_ip4_config_get_static_route (config, (i * 2) + 1); - guint32 saddr = nm_ip4_config_get_static_route (config, i * 2); + const NMSettingIP4Address *route = nm_ip4_config_get_static_route (config, i); - nm_system_device_set_ip4_route (iface, config, route, saddr, 32, mss); - } + nm_system_device_set_ip4_route (iface, config, + route->gateway, + route->address, + netmask_to_prefix (route->netmask), + nm_ip4_config_get_mss (config)); + } if (nm_ip4_config_get_mtu (config)) nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config)); diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index aa62a09844..eb58d789ff 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -309,6 +309,27 @@ nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) if (i == num) nm_ip4_config_add_address (ip4_config, setting_addr); } + + /* IPv4 static routes */ + for (iter = setting->routes; iter; iter = g_slist_next (iter)) { + NMSettingIP4Address *setting_route = (NMSettingIP4Address *) iter->data; + guint32 i, num; + + num = nm_ip4_config_get_num_static_routes (ip4_config); + for (i = 0; i < num; i++) { + const NMSettingIP4Address *cfg_route; + + cfg_route = nm_ip4_config_get_static_route (ip4_config, i); + /* Dupe, override with user-specified address */ + if (cfg_route->address == setting_route->address) { + nm_ip4_config_replace_static_route (ip4_config, i, setting_route); + break; + } + } + + if (i == num) + nm_ip4_config_add_static_route (ip4_config, setting_route); + } } static void diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 732b969182..508a3f6561 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -978,9 +978,14 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, } // FIXME: ensure the IP addresse and route are sane - nm_ip4_config_add_static_route (ip4_config, - (guint32) rt_addr.s_addr, - (guint32) rt_route.s_addr); + + addr = g_malloc0 (sizeof (NMSettingIP4Address)); + addr->address = (guint32) rt_addr.s_addr; + addr->netmask = 0xFFFFFFFF; /* 255.255.255.255 */ + addr->gateway = (guint32) rt_route.s_addr; + + nm_ip4_config_take_static_route (ip4_config, addr); + addr = NULL; nm_info (" static route %s gw %s", *s, *(s + 1)); } } else { diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 837502f57e..06060528dc 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -30,6 +30,7 @@ #include "NetworkManager.h" #include "NetworkManagerUtils.h" #include "nm-setting-ip4-config.h" +#include "nm-utils.h" #include #include @@ -57,7 +58,7 @@ typedef struct { gchar *hostname; gchar *nis_domain; GArray *nis_servers; - GArray *static_routes; + GSList *static_routes; } NMIP4ConfigPrivate; @@ -132,13 +133,14 @@ NMIP4Config *nm_ip4_config_copy (NMIP4Config *src_config) for (i = 0; i < len; i++) nm_ip4_config_add_nis_server (dst_config, nm_ip4_config_get_nis_server (src_config, i)); - len = nm_ip4_config_get_num_static_routes (src_config); - for (i = 0; i < len; i++) { - guint32 addr = nm_ip4_config_get_static_route (src_config, i * 2); - guint32 route = nm_ip4_config_get_static_route (src_config, (i * 2) + 1); + for (iter = src_priv->static_routes; iter; iter = g_slist_next (iter)) { + NMSettingIP4Address *src_addr = (NMSettingIP4Address *) iter->data; + NMSettingIP4Address *dst_addr; - nm_ip4_config_add_static_route (dst_config, addr, route); - } + dst_addr = g_malloc0 (sizeof (NMSettingIP4Address)); + memcpy (dst_addr, src_addr, sizeof (NMSettingIP4Address)); + nm_ip4_config_take_static_route (dst_config, dst_addr); + } return dst_config; } @@ -306,26 +308,66 @@ const char *nm_ip4_config_get_nis_domain (NMIP4Config *config) return NM_IP4_CONFIG_GET_PRIVATE (config)->nis_domain; } -void nm_ip4_config_add_static_route (NMIP4Config *config, guint32 host, guint32 gateway) +void +nm_ip4_config_take_static_route (NMIP4Config *config, + NMSettingIP4Address *address) { - g_return_if_fail (NM_IS_IP4_CONFIG (config)); + NMIP4ConfigPrivate *priv; - g_array_append_val (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, host); - g_array_append_val (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, gateway); + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + g_return_if_fail (address != NULL); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + priv->static_routes = g_slist_append (priv->static_routes, address); } -guint32 nm_ip4_config_get_static_route (NMIP4Config *config, guint i) +void +nm_ip4_config_add_static_route (NMIP4Config *config, + NMSettingIP4Address *address) { - g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); + NMIP4ConfigPrivate *priv; + NMSettingIP4Address *copy; - return g_array_index (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, guint32, i); + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + g_return_if_fail (address != NULL); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + copy = g_malloc0 (sizeof (NMSettingIP4Address)); + memcpy (copy, address, sizeof (NMSettingIP4Address)); + priv->static_routes = g_slist_append (priv->static_routes, copy); +} + +void +nm_ip4_config_replace_static_route (NMIP4Config *config, + guint i, + NMSettingIP4Address *new_address) +{ + NMIP4ConfigPrivate *priv; + GSList *old; + + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + old = g_slist_nth (priv->static_routes, i); + g_return_if_fail (old != NULL); + + g_free (old->data); + old->data = new_address; +} + +const NMSettingIP4Address * +nm_ip4_config_get_static_route (NMIP4Config *config, guint i) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); + + return (const NMSettingIP4Address *) g_slist_nth_data (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, i); } guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes->len) / 2; + return g_slist_length (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes); } @@ -518,7 +560,6 @@ nm_ip4_config_init (NMIP4Config *config) priv->nameservers = g_array_new (FALSE, TRUE, sizeof (guint32)); priv->nis_servers = g_array_new (FALSE, TRUE, sizeof (guint32)); - priv->static_routes = g_array_new (FALSE, TRUE, sizeof (guint32)); priv->domains = g_ptr_array_new (); priv->searches = g_ptr_array_new (); } @@ -528,15 +569,14 @@ finalize (GObject *object) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); - g_slist_foreach (priv->addresses, (GFunc) g_free, NULL); - g_slist_free (priv->addresses); + nm_utils_slist_free (priv->addresses, g_free); g_free (priv->hostname); g_free (priv->nis_domain); g_array_free (priv->nameservers, TRUE); g_ptr_array_free (priv->domains, TRUE); g_ptr_array_free (priv->searches, TRUE); g_array_free (priv->nis_servers, TRUE); - g_array_free (priv->static_routes, TRUE); + nm_utils_slist_free (priv->static_routes, g_free); } static void @@ -594,7 +634,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boxed (value, priv->nis_servers); break; case PROP_STATIC_ROUTES: - g_value_set_boxed (value, priv->static_routes); + ip4_addresses_to_gvalue (priv->static_routes, value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -660,10 +700,10 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) g_object_class_install_property (object_class, PROP_STATIC_ROUTES, g_param_spec_boxed (NM_IP4_CONFIG_STATIC_ROUTES, - "Static routes", - "Sattic routes", - DBUS_TYPE_G_UINT_ARRAY, - G_PARAM_READABLE)); + "Static routes", + "Static routes", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_PARAM_READABLE)); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class), &dbus_glib_nm_ip4_config_object_info); diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index cbf58791a9..de831b5e4a 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -76,8 +76,10 @@ void nm_ip4_config_add_nis_server (NMIP4Config *config, guint32 nis_server); guint32 nm_ip4_config_get_nis_server (NMIP4Config *config, guint i); guint32 nm_ip4_config_get_num_nis_servers (NMIP4Config *config); -void nm_ip4_config_add_static_route (NMIP4Config *config, guint32 addr, guint32 gateway); -guint32 nm_ip4_config_get_static_route (NMIP4Config *config, guint i); +void nm_ip4_config_take_static_route (NMIP4Config *config, NMSettingIP4Address *address); +void nm_ip4_config_add_static_route (NMIP4Config *config, NMSettingIP4Address *address); +void nm_ip4_config_replace_static_route (NMIP4Config *config, guint32 i, NMSettingIP4Address *new_address); +const NMSettingIP4Address * nm_ip4_config_get_static_route (NMIP4Config *config, guint32 i); guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config); void nm_ip4_config_set_hostname (NMIP4Config *config, const char *hostname);