diff --git a/ChangeLog b/ChangeLog index 140112a4e..8b45c0dd9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2007-11-28 Dan Williams + + Patch from Zdeněk Jurka + + Support DHCP-provided static routes. + + * src/nm-ip4-config.h + src/nm-ip4-config.c + - Add get/set functions for static routes + + * src/dhcp-manager/nm-dhcp-manager.c + - (nm_dhcp_manager_get_ip4_config): extract static routes from the + DHCP response + + * src/NetworkManagerSystem.c + - (nm_system_device_set_from_ip4_config): set any static routes on the + interface when applying the IP4Config + 2007-11-28 Dan Williams * src/nm-device-802-11-wireless.c diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index a054ea8cb..97db4acad 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -194,6 +194,7 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) struct nl_handle * nlh = NULL; struct rtnl_addr * addr = NULL; int err; + int len, i; g_return_val_if_fail (dev != NULL, FALSE); @@ -220,6 +221,15 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev) sleep (1); nm_system_device_set_ip4_route (dev, nm_ip4_config_get_gateway (config), 0, 0, nm_ip4_config_get_mss (config)); + 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); + + nm_system_device_set_ip4_route (dev, route, saddr, 0xffffffff, mss); + } + named_mgr = nm_named_manager_get (); nm_named_manager_add_ip4_config (named_mgr, config); g_object_unref (named_mgr); diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index aa1eda871..1406b3d35 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -839,6 +839,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, char * nameservers = NULL; char * nis_domain = NULL; char * nis_servers = NULL; + char * static_routes = NULL; char * ip = NULL; //this is a general string that is used as a temporary place for ip(s) g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), NULL); @@ -909,7 +910,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, domain_names = g_hash_table_lookup (device->options, "new_domain_name"); nis_domain = g_hash_table_lookup (device->options, "new_nis_domain"); nis_servers = g_hash_table_lookup (device->options, "new_nis_servers"); - + static_routes = g_hash_table_lookup (device->options, "new_static_routes"); if (nameservers) { char **searches = g_strsplit (nameservers, " ", 0); @@ -917,6 +918,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, int ip4_nameserver; for (s = searches; *s; s++) { + // FIXME: use inet_aton ip4_nameserver = inet_addr (*s); nm_ip4_config_add_nameserver (ip4_config, ip4_nameserver); nm_info (" nameserver '%s'", *s); @@ -951,6 +953,7 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, int ip4_nis_server; for (s = searches; *s; s++) { + // FIXME: use inet_aton ip4_nis_server = inet_addr (*s); nm_ip4_config_add_nis_server (ip4_config, ip4_nis_server); nm_info (" nis server '%s'", *s); @@ -958,6 +961,37 @@ nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, g_strfreev (searches); } + if (static_routes){ + char **searches = g_strsplit (static_routes, " ", 0); + + if ((g_strv_length (searches) % 2) == 0) { + char **s; + + for (s = searches; *s; s += 2) { + struct in_addr addr; + struct in_addr route; + + if (inet_aton (*s, &addr) == 0) { + nm_warning ("DHCP provided invalid static route address: '%s'", *s); + continue; + } + if (inet_aton (*(s + 1), &route) == 0) { + nm_warning ("DHCP provided invalid static route gateway: '%s'", *(s + 1)); + continue; + } + + // FIXME: ensure the IP addresse and route are sane + nm_ip4_config_add_static_route (ip4_config, + (guint32) addr.s_addr, + (guint32) route.s_addr); + nm_info (" static route %s gw %s", *s, *(s + 1)); + } + } else { + nm_info (" static routes provided, but invalid"); + } + g_strfreev (searches); + } + /* * FIXME: * Grab the MTU from the backend. If DHCP servers can send recommended diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 1fcae77f8..f76ee1dc9 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -55,6 +55,7 @@ typedef struct { gchar * hostname; gchar * nis_domain; GArray *nis_servers; + GArray *static_routes; /* If this is a VPN/etc config that requires * another device (like Ethernet) to already have @@ -75,6 +76,7 @@ enum { PROP_DOMAINS, PROP_NIS_DOMAIN, PROP_NIS_SERVERS, + PROP_STATIC_ROUTES, LAST_PROP }; @@ -131,6 +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); + + nm_ip4_config_add_static_route (dst_config, addr, route); + } + return dst_config; } @@ -307,6 +317,28 @@ 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) +{ + g_return_if_fail (NM_IS_IP4_CONFIG (config)); + + 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); +} + +guint32 nm_ip4_config_get_static_route (NMIP4Config *config, guint i) +{ + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); + + return g_array_index (NM_IP4_CONFIG_GET_PRIVATE (config)->static_routes, guint32, 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; +} + const char *nm_ip4_config_get_domain (NMIP4Config *config, guint i) { g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); @@ -440,6 +472,7 @@ 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 (); } @@ -453,6 +486,7 @@ finalize (GObject *object) g_array_free (priv->nameservers, TRUE); g_ptr_array_free (priv->domains, TRUE); g_array_free (priv->nis_servers, TRUE); + g_array_free (priv->static_routes, TRUE); } static void @@ -489,6 +523,9 @@ get_property (GObject *object, guint prop_id, case PROP_NIS_SERVERS: g_value_set_boxed (value, priv->nis_servers); break; + case PROP_STATIC_ROUTES: + g_value_set_boxed (value, priv->static_routes); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -571,6 +608,14 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) DBUS_TYPE_G_UINT_ARRAY, G_PARAM_READABLE)); + 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)); + 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 7a708ac82..2492c0cf0 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -51,6 +51,7 @@ typedef struct { #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain" #define NM_IP4_CONFIG_NIS_SERVERS "nis-servers" +#define NM_IP4_CONFIG_STATIC_ROUTES "static-routes" GType nm_ip4_config_get_type (void); @@ -84,6 +85,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); +guint32 nm_ip4_config_get_num_static_routes (NMIP4Config *config); + void nm_ip4_config_set_hostname (NMIP4Config *config, const char *hostname); const char * nm_ip4_config_get_hostname (NMIP4Config *config);