trivial: move a couple of functions to nm-ip[46]-config

Note that this patch doesn't effectively change any code.

Functions moved from nm-system:

* nm_system_apply_ip?_config → nm_ip?_config_commit
* ip?_dest_in_same_subnet → nm_ip?_config_destination_is_direct

Functions moved from NetworkManagerUtils:

* nm_utils_merge_ip?_config → nm_ip?_config_merge_setting

Functions renamed (and moved down to form one group):

* nm_ip?_config_new_for_interface → nm_ip?_config_capture

(The rationale for the rename is that from the achitectural point of
view it doesn't matter whether the function creates a new object or
updates an existing one. After the rename, it's obvious that
nm_ip?_config_capture() and nm_ip?_config_commit() are counterparts of
each other.)
This commit is contained in:
Pavel Šimerda
2013-07-03 10:26:19 +02:00
parent f8c8d67e93
commit 7967a6524a
11 changed files with 496 additions and 499 deletions

View File

@@ -153,229 +153,6 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix)
return (guint32) htonl (netmask);
}
void
nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
{
int i, j;
gboolean setting_never_default;
if (!setting)
return; /* Defaults are just fine */
if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) {
nm_ip4_config_reset_nameservers (ip4_config);
nm_ip4_config_reset_domains (ip4_config);
nm_ip4_config_reset_searches (ip4_config);
}
if (nm_setting_ip4_config_get_ignore_auto_routes (setting))
nm_ip4_config_reset_routes (ip4_config);
for (i = 0; i < nm_setting_ip4_config_get_num_dns (setting); i++) {
guint32 ns;
gboolean found = FALSE;
/* Avoid dupes */
ns = nm_setting_ip4_config_get_dns (setting, i);
for (j = 0; j < nm_ip4_config_get_num_nameservers (ip4_config); j++) {
if (nm_ip4_config_get_nameserver (ip4_config, j) == ns) {
found = TRUE;
break;
}
}
if (!found)
nm_ip4_config_add_nameserver (ip4_config, ns);
}
/* DNS search domains */
for (i = 0; i < nm_setting_ip4_config_get_num_dns_searches (setting); i++) {
const char *search = nm_setting_ip4_config_get_dns_search (setting, i);
gboolean found = FALSE;
/* Avoid dupes */
for (j = 0; j < nm_ip4_config_get_num_searches (ip4_config); j++) {
if (!strcmp (search, nm_ip4_config_get_search (ip4_config, j))) {
found = TRUE;
break;
}
}
if (!found)
nm_ip4_config_add_search (ip4_config, search);
}
/* IPv4 addresses */
for (i = 0; i < nm_setting_ip4_config_get_num_addresses (setting); i++) {
NMIP4Address *setting_addr = nm_setting_ip4_config_get_address (setting, i);
guint32 num;
num = nm_ip4_config_get_num_addresses (ip4_config);
for (j = 0; j < num; j++) {
NMIP4Address *cfg_addr = nm_ip4_config_get_address (ip4_config, j);
/* Dupe, override with user-specified address */
if (nm_ip4_address_get_address (cfg_addr) == nm_ip4_address_get_address (setting_addr)) {
nm_ip4_config_replace_address (ip4_config, j, setting_addr);
break;
}
}
if (j == num)
nm_ip4_config_add_address (ip4_config, setting_addr);
}
/* IPv4 routes */
for (i = 0; i < nm_setting_ip4_config_get_num_routes (setting); i++) {
NMIP4Route *setting_route = nm_setting_ip4_config_get_route (setting, i);
guint32 num;
num = nm_ip4_config_get_num_routes (ip4_config);
for (j = 0; j < num; j++) {
NMIP4Route *cfg_route = nm_ip4_config_get_route (ip4_config, j);
/* Dupe, override with user-specified route */
if ( (nm_ip4_route_get_dest (cfg_route) == nm_ip4_route_get_dest (setting_route))
&& (nm_ip4_route_get_prefix (cfg_route) == nm_ip4_route_get_prefix (setting_route))
&& (nm_ip4_route_get_next_hop (cfg_route) == nm_ip4_route_get_next_hop (setting_route))) {
nm_ip4_config_replace_route (ip4_config, j, setting_route);
break;
}
}
if (j == num)
nm_ip4_config_add_route (ip4_config, setting_route);
}
setting_never_default = nm_setting_ip4_config_get_never_default (setting);
if (nm_setting_ip4_config_get_ignore_auto_routes (setting))
nm_ip4_config_set_never_default (ip4_config, setting_never_default);
else {
if (setting_never_default)
nm_ip4_config_set_never_default (ip4_config, TRUE);
}
}
static inline gboolean
ip6_addresses_equal (const struct in6_addr *a, const struct in6_addr *b)
{
return memcmp (a, b, sizeof (struct in6_addr)) == 0;
}
/* This is exactly identical to nm_utils_merge_ip4_config, with s/4/6/,
* except that we can't compare addresses with ==.
*/
void
nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting)
{
int i, j;
if (!setting)
return; /* Defaults are just fine */
if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) {
nm_ip6_config_reset_nameservers (ip6_config);
nm_ip6_config_reset_domains (ip6_config);
nm_ip6_config_reset_searches (ip6_config);
}
if (nm_setting_ip6_config_get_ignore_auto_routes (setting))
nm_ip6_config_reset_routes (ip6_config);
for (i = 0; i < nm_setting_ip6_config_get_num_dns (setting); i++) {
const struct in6_addr *ns;
gboolean found = FALSE;
/* Avoid dupes */
ns = nm_setting_ip6_config_get_dns (setting, i);
for (j = 0; j < nm_ip6_config_get_num_nameservers (ip6_config); j++) {
if (ip6_addresses_equal (nm_ip6_config_get_nameserver (ip6_config, j), ns)) {
found = TRUE;
break;
}
}
if (!found)
nm_ip6_config_add_nameserver (ip6_config, ns);
}
/* DNS search domains */
for (i = 0; i < nm_setting_ip6_config_get_num_dns_searches (setting); i++) {
const char *search = nm_setting_ip6_config_get_dns_search (setting, i);
gboolean found = FALSE;
/* Avoid dupes */
for (j = 0; j < nm_ip6_config_get_num_searches (ip6_config); j++) {
if (!strcmp (search, nm_ip6_config_get_search (ip6_config, j))) {
found = TRUE;
break;
}
}
if (!found)
nm_ip6_config_add_search (ip6_config, search);
}
/* IPv6 addresses */
for (i = 0; i < nm_setting_ip6_config_get_num_addresses (setting); i++) {
NMIP6Address *setting_addr = nm_setting_ip6_config_get_address (setting, i);
guint32 num;
num = nm_ip6_config_get_num_addresses (ip6_config);
for (j = 0; j < num; j++) {
NMIP6Address *cfg_addr = nm_ip6_config_get_address (ip6_config, j);
/* Dupe, override with user-specified address */
if (ip6_addresses_equal (nm_ip6_address_get_address (cfg_addr), nm_ip6_address_get_address (setting_addr))) {
nm_ip6_config_replace_address (ip6_config, j, setting_addr);
break;
}
}
if (j == num)
nm_ip6_config_add_address (ip6_config, setting_addr);
}
/* IPv6 routes */
for (i = 0; i < nm_setting_ip6_config_get_num_routes (setting); i++) {
NMIP6Route *setting_route = nm_setting_ip6_config_get_route (setting, i);
guint32 num;
num = nm_ip6_config_get_num_routes (ip6_config);
for (j = 0; j < num; j++) {
NMIP6Route *cfg_route = nm_ip6_config_get_route (ip6_config, j);
/* Dupe, override with user-specified route */
if ( ip6_addresses_equal (nm_ip6_route_get_dest (cfg_route), nm_ip6_route_get_dest (setting_route))
&& (nm_ip6_route_get_prefix (cfg_route) == nm_ip6_route_get_prefix (setting_route))
&& ip6_addresses_equal (nm_ip6_route_get_next_hop (cfg_route), nm_ip6_route_get_next_hop (setting_route))) {
nm_ip6_config_replace_route (ip6_config, j, setting_route);
break;
}
}
if (j == num)
nm_ip6_config_add_route (ip6_config, setting_route);
}
if (nm_setting_ip6_config_get_never_default (setting))
nm_ip6_config_set_never_default (ip6_config, TRUE);
}
gboolean
nm_match_spec_string (const GSList *specs, const char *match)
{
const GSList *iter;
for (iter = specs; iter; iter = g_slist_next (iter)) {
if (!g_ascii_strcasecmp ((const char *) iter->data, match))
return TRUE;
}
return FALSE;
}
gboolean
nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr)
{

View File

@@ -36,9 +36,6 @@ gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
int nm_spawn_process (const char *args);
void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting);
void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting);
gboolean nm_match_spec_string (const GSList *specs, const char *string);
gboolean nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr);
gboolean nm_match_spec_s390_subchannels (const GSList *specs, const char *subchannels);

View File

@@ -1929,7 +1929,7 @@ autoip_changed (NMDevice *self,
{
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
nm_utils_merge_ip4_config (config, s_ip4);
nm_ip4_config_merge_setting (config, s_ip4);
if (!nm_device_set_ip4_config (self, config, TRUE, &reason)) {
nm_log_err (LOGD_AUTOIP4, "(%s): failed to update IP4 config in response to autoip event.",
nm_device_get_iface (self));
@@ -2179,7 +2179,7 @@ dhcp4_lease_change (NMDevice *device, NMIP4Config *config)
g_assert (connection);
/* Merge with user overrides */
nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection));
nm_ip4_config_merge_setting (config, nm_connection_get_setting_ip4_config (connection));
if (!nm_device_set_ip4_config (device, config, TRUE, &reason)) {
nm_log_warn (LOGD_DHCP4, "(%s): failed to update IPv4 config in response to DHCP event.",
@@ -2603,7 +2603,7 @@ ip6_config_merge_and_apply (NMDevice *self,
merge_ip6_configs (composite, priv->dhcp6_ip6_config);
/* Merge user overrides into the composite config */
nm_utils_merge_ip6_config (composite, nm_connection_get_setting_ip6_config (connection));
nm_ip6_config_merge_setting (composite, nm_connection_get_setting_ip6_config (connection));
success = nm_device_set_ip6_config (self, composite, TRUE, out_reason);
g_object_unref (composite);
@@ -3697,7 +3697,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data)
NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit (self, config);
/* Merge with user overrides */
nm_utils_merge_ip4_config (config, nm_connection_get_setting_ip4_config (connection));
nm_ip4_config_merge_setting (config, nm_connection_get_setting_ip4_config (connection));
if (!nm_device_set_ip4_config (self, config, TRUE, &reason)) {
nm_log_info (LOGD_DEVICE | LOGD_IP4,
@@ -4344,7 +4344,7 @@ nm_device_set_ip4_config (NMDevice *self,
priv->ip4_config = g_object_ref (new_config);
if (commit)
success = nm_system_apply_ip4_config (ip_ifindex, new_config, nm_device_get_priority (self));
success = nm_ip4_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
if (success || !commit) {
/* Export over D-Bus */
@@ -4401,7 +4401,7 @@ nm_device_set_ip6_config (NMDevice *self,
priv->ip6_config = g_object_ref (new_config);
if (commit)
success = nm_system_apply_ip6_config (ip_ifindex, new_config, nm_device_get_priority (self));
success = nm_ip6_config_commit (new_config, ip_ifindex, nm_device_get_priority (self));
if (success || !commit) {
/* Export over D-Bus */
@@ -5857,8 +5857,8 @@ update_ip_config (NMDevice *self)
if (!ifindex)
return;
ip4_config = nm_ip4_config_new_for_interface (ifindex);
ip6_config = nm_ip6_config_new_for_interface (ifindex);
ip4_config = nm_ip4_config_capture (ifindex);
ip6_config = nm_ip6_config_capture (ifindex);
nm_device_set_ip4_config (self, ip4_config, FALSE, &ignored);
nm_device_set_ip6_config (self, ip6_config, FALSE, &ignored);

View File

@@ -79,8 +79,33 @@ nm_ip4_config_new (void)
return (NMIP4Config *) g_object_new (NM_TYPE_IP4_CONFIG, NULL);
}
void
nm_ip4_config_export (NMIP4Config *config)
{
NMIP4ConfigPrivate *priv;
static guint32 counter = 0;
g_return_if_fail (NM_IS_IP4_CONFIG (config));
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
g_return_if_fail (priv->path == NULL);
priv->path = g_strdup_printf (NM_DBUS_PATH "/IP4Config/%d", counter++);
nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, config);
}
const char *
nm_ip4_config_get_dbus_path (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
return NM_IP4_CONFIG_GET_PRIVATE (config)->path;
}
/******************************************************************/
NMIP4Config *
nm_ip4_config_new_for_interface (int ifindex)
nm_ip4_config_capture (int ifindex)
{
NMIP4Config *ip4;
GArray *addrs_array, *routes_array;
@@ -128,28 +153,206 @@ nm_ip4_config_new_for_interface (int ifindex)
return ip4;
}
gboolean
nm_ip4_config_commit (NMIP4Config *config, int ifindex, int priority)
{
int mtu = nm_ip4_config_get_mtu (config);
int i;
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
/* Addresses */
{
int count = nm_ip4_config_get_num_addresses (config);
NMIP4Address *config_address;
GArray *addresses = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Address), count);
NMPlatformIP4Address address;
for (i = 0; i < count; i++) {
config_address = nm_ip4_config_get_address (config, i);
memset (&address, 0, sizeof (address));
address.address = nm_ip4_address_get_address (config_address);
address.plen = nm_ip4_address_get_prefix (config_address);
g_array_append_val (addresses, address);
}
nm_platform_ip4_address_sync (ifindex, addresses);
g_array_unref (addresses);
}
/* Routes */
{
int count = nm_ip4_config_get_num_routes (config);
NMIP4Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count);
NMPlatformIP4Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip4_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = nm_ip4_route_get_dest (config_route);
route.plen = nm_ip4_route_get_prefix (config_route);
route.gateway = nm_ip4_route_get_next_hop (config_route);
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
* the device already has an IP address on.
*/
if (nm_ip4_config_destination_is_direct (config, route.network, route.plen))
continue;
/* Don't add the default route when and the connection
* is never supposed to be the default connection.
*/
if (nm_ip4_config_get_never_default (config) && route.network == 0)
continue;
g_array_append_val (routes, route);
}
nm_platform_ip4_route_sync (ifindex, routes);
g_array_unref (routes);
}
/* MTU */
if (mtu && mtu != nm_platform_link_get_mtu (ifindex))
nm_platform_link_set_mtu (ifindex, mtu);
return TRUE;
}
void
nm_ip4_config_export (NMIP4Config *config)
nm_ip4_config_merge_setting (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
{
NMIP4ConfigPrivate *priv;
static guint32 counter = 0;
int i, j;
gboolean setting_never_default;
g_return_if_fail (NM_IS_IP4_CONFIG (config));
if (!setting)
return; /* Defaults are just fine */
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
g_return_if_fail (priv->path == NULL);
priv->path = g_strdup_printf (NM_DBUS_PATH "/IP4Config/%d", counter++);
nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, config);
if (nm_setting_ip4_config_get_ignore_auto_dns (setting)) {
nm_ip4_config_reset_nameservers (ip4_config);
nm_ip4_config_reset_domains (ip4_config);
nm_ip4_config_reset_searches (ip4_config);
}
const char *
nm_ip4_config_get_dbus_path (NMIP4Config *config)
{
g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
if (nm_setting_ip4_config_get_ignore_auto_routes (setting))
nm_ip4_config_reset_routes (ip4_config);
return NM_IP4_CONFIG_GET_PRIVATE (config)->path;
for (i = 0; i < nm_setting_ip4_config_get_num_dns (setting); i++) {
guint32 ns;
gboolean found = FALSE;
/* Avoid dupes */
ns = nm_setting_ip4_config_get_dns (setting, i);
for (j = 0; j < nm_ip4_config_get_num_nameservers (ip4_config); j++) {
if (nm_ip4_config_get_nameserver (ip4_config, j) == ns) {
found = TRUE;
break;
}
}
if (!found)
nm_ip4_config_add_nameserver (ip4_config, ns);
}
/* DNS search domains */
for (i = 0; i < nm_setting_ip4_config_get_num_dns_searches (setting); i++) {
const char *search = nm_setting_ip4_config_get_dns_search (setting, i);
gboolean found = FALSE;
/* Avoid dupes */
for (j = 0; j < nm_ip4_config_get_num_searches (ip4_config); j++) {
if (!strcmp (search, nm_ip4_config_get_search (ip4_config, j))) {
found = TRUE;
break;
}
}
if (!found)
nm_ip4_config_add_search (ip4_config, search);
}
/* IPv4 addresses */
for (i = 0; i < nm_setting_ip4_config_get_num_addresses (setting); i++) {
NMIP4Address *setting_addr = nm_setting_ip4_config_get_address (setting, i);
guint32 num;
num = nm_ip4_config_get_num_addresses (ip4_config);
for (j = 0; j < num; j++) {
NMIP4Address *cfg_addr = nm_ip4_config_get_address (ip4_config, j);
/* Dupe, override with user-specified address */
if (nm_ip4_address_get_address (cfg_addr) == nm_ip4_address_get_address (setting_addr)) {
nm_ip4_config_replace_address (ip4_config, j, setting_addr);
break;
}
}
if (j == num)
nm_ip4_config_add_address (ip4_config, setting_addr);
}
/* IPv4 routes */
for (i = 0; i < nm_setting_ip4_config_get_num_routes (setting); i++) {
NMIP4Route *setting_route = nm_setting_ip4_config_get_route (setting, i);
guint32 num;
num = nm_ip4_config_get_num_routes (ip4_config);
for (j = 0; j < num; j++) {
NMIP4Route *cfg_route = nm_ip4_config_get_route (ip4_config, j);
/* Dupe, override with user-specified route */
if ( (nm_ip4_route_get_dest (cfg_route) == nm_ip4_route_get_dest (setting_route))
&& (nm_ip4_route_get_prefix (cfg_route) == nm_ip4_route_get_prefix (setting_route))
&& (nm_ip4_route_get_next_hop (cfg_route) == nm_ip4_route_get_next_hop (setting_route))) {
nm_ip4_config_replace_route (ip4_config, j, setting_route);
break;
}
}
if (j == num)
nm_ip4_config_add_route (ip4_config, setting_route);
}
setting_never_default = nm_setting_ip4_config_get_never_default (setting);
if (nm_setting_ip4_config_get_ignore_auto_routes (setting))
nm_ip4_config_set_never_default (ip4_config, setting_never_default);
else {
if (setting_never_default)
nm_ip4_config_set_never_default (ip4_config, TRUE);
}
}
/******************************************************************/
gboolean
nm_ip4_config_destination_is_direct (NMIP4Config *config, guint32 dest, guint32 dest_prefix)
{
int num;
int i;
num = nm_ip4_config_get_num_addresses (config);
for (i = 0; i < num; i++) {
NMIP4Address *addr = nm_ip4_config_get_address (config, i);
guint32 prefix = nm_ip4_address_get_prefix (addr);
guint32 address = nm_ip4_address_get_address (addr);
if (prefix <= dest_prefix) {
guint32 masked_addr = ntohl(address) >> (32 - prefix);
guint32 masked_dest = ntohl(dest) >> (32 - prefix);
if (masked_addr == masked_dest)
return TRUE;
}
}
return FALSE;
}
/******************************************************************/
void
nm_ip4_config_take_address (NMIP4Config *config, NMIP4Address *address)

View File

@@ -51,11 +51,18 @@ GType nm_ip4_config_get_type (void);
NMIP4Config * nm_ip4_config_new (void);
NMIP4Config * nm_ip4_config_new_for_interface (int ifindex);
void nm_ip4_config_export (NMIP4Config *config);
const char * nm_ip4_config_get_dbus_path (NMIP4Config *config);
/* Integration with nm-platform and nm-setting */
NMIP4Config *nm_ip4_config_capture (int ifindex);
gboolean nm_ip4_config_commit (NMIP4Config *config, int ifindex, int priority);
void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIP4Config *setting);
/* Utility functions */
gboolean nm_ip4_config_destination_is_direct (NMIP4Config *config, guint32 dest, guint32 plen);
void nm_ip4_config_take_address (NMIP4Config *config, NMIP4Address *address);
void nm_ip4_config_add_address (NMIP4Config *config, NMIP4Address *address);
void nm_ip4_config_replace_address (NMIP4Config *config, guint32 i, NMIP4Address *new_address);

View File

@@ -74,8 +74,45 @@ nm_ip6_config_new (void)
return (NMIP6Config *) g_object_new (NM_TYPE_IP6_CONFIG, NULL);
}
void
nm_ip6_config_export (NMIP6Config *config)
{
NMIP6ConfigPrivate *priv;
static guint32 counter = 0;
g_return_if_fail (NM_IS_IP6_CONFIG (config));
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
g_return_if_fail (priv->path == NULL);
priv->path = g_strdup_printf (NM_DBUS_PATH "/IP6Config/%d", counter++);
nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, config);
}
const char *
nm_ip6_config_get_dbus_path (NMIP6Config *config)
{
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
return NM_IP6_CONFIG_GET_PRIVATE (config)->path;
}
void
nm_ip6_config_take_address (NMIP6Config *config, NMIP6Address *address)
{
NMIP6ConfigPrivate *priv;
g_return_if_fail (NM_IS_IP6_CONFIG (config));
g_return_if_fail (address != NULL);
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
priv->addresses = g_slist_append (priv->addresses, address);
}
/******************************************************************/
NMIP6Config *
nm_ip6_config_new_for_interface (int ifindex)
nm_ip6_config_capture (int ifindex)
{
NMIP6Config *ip6;
GArray *addrs_array, *routes_array;
@@ -123,41 +160,224 @@ nm_ip6_config_new_for_interface (int ifindex)
return ip6;
}
void
nm_ip6_config_export (NMIP6Config *config)
gboolean
nm_ip6_config_commit (NMIP6Config *config, int ifindex, int priority)
{
NMIP6ConfigPrivate *priv;
static guint32 counter = 0;
int i;
g_return_if_fail (NM_IS_IP6_CONFIG (config));
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
g_return_if_fail (priv->path == NULL);
/* Addresses */
{
int count = nm_ip6_config_get_num_addresses (config);
NMIP6Address *config_address;
GArray *addresses = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Address), count);
NMPlatformIP6Address address;
priv->path = g_strdup_printf (NM_DBUS_PATH "/IP6Config/%d", counter++);
nm_dbus_manager_register_object (nm_dbus_manager_get (), priv->path, config);
for (i = 0; i < count; i++) {
config_address = nm_ip6_config_get_address (config, i);
memset (&address, 0, sizeof (address));
address.address = *nm_ip6_address_get_address (config_address);
address.plen = nm_ip6_address_get_prefix (config_address);
g_array_append_val (addresses, address);
}
const char *
nm_ip6_config_get_dbus_path (NMIP6Config *config)
{
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
nm_platform_ip6_address_sync (ifindex, addresses);
g_array_unref (addresses);
}
return NM_IP6_CONFIG_GET_PRIVATE (config)->path;
/* Routes */
{
int count = nm_ip6_config_get_num_routes (config);
NMIP6Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count);
NMPlatformIP6Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip6_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = *nm_ip6_route_get_dest (config_route);
route.plen = nm_ip6_route_get_prefix (config_route);
route.gateway = *nm_ip6_route_get_next_hop (config_route);
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
* the device already has an IP address on.
*/
if (nm_ip6_config_destination_is_direct (config, &route.network, route.plen))
continue;
/* Don't add the default route when and the connection
* is never supposed to be the default connection.
*/
if (nm_ip6_config_get_never_default (config) && IN6_IS_ADDR_UNSPECIFIED (&route.network))
continue;
g_array_append_val (routes, route);
}
nm_platform_ip6_route_sync (ifindex, routes);
g_array_unref (routes);
}
return TRUE;
}
static inline gboolean
ip6_addresses_equal (const struct in6_addr *a, const struct in6_addr *b)
{
return memcmp (a, b, sizeof (struct in6_addr)) == 0;
}
void
nm_ip6_config_take_address (NMIP6Config *config, NMIP6Address *address)
nm_ip6_config_merge_setting (NMIP6Config *ip6_config, NMSettingIP6Config *setting)
{
NMIP6ConfigPrivate *priv;
int i, j;
g_return_if_fail (NM_IS_IP6_CONFIG (config));
g_return_if_fail (address != NULL);
if (!setting)
return; /* Defaults are just fine */
priv = NM_IP6_CONFIG_GET_PRIVATE (config);
priv->addresses = g_slist_append (priv->addresses, address);
if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) {
nm_ip6_config_reset_nameservers (ip6_config);
nm_ip6_config_reset_domains (ip6_config);
nm_ip6_config_reset_searches (ip6_config);
}
if (nm_setting_ip6_config_get_ignore_auto_routes (setting))
nm_ip6_config_reset_routes (ip6_config);
for (i = 0; i < nm_setting_ip6_config_get_num_dns (setting); i++) {
const struct in6_addr *ns;
gboolean found = FALSE;
/* Avoid dupes */
ns = nm_setting_ip6_config_get_dns (setting, i);
for (j = 0; j < nm_ip6_config_get_num_nameservers (ip6_config); j++) {
if (ip6_addresses_equal (nm_ip6_config_get_nameserver (ip6_config, j), ns)) {
found = TRUE;
break;
}
}
if (!found)
nm_ip6_config_add_nameserver (ip6_config, ns);
}
/* DNS search domains */
for (i = 0; i < nm_setting_ip6_config_get_num_dns_searches (setting); i++) {
const char *search = nm_setting_ip6_config_get_dns_search (setting, i);
gboolean found = FALSE;
/* Avoid dupes */
for (j = 0; j < nm_ip6_config_get_num_searches (ip6_config); j++) {
if (!strcmp (search, nm_ip6_config_get_search (ip6_config, j))) {
found = TRUE;
break;
}
}
if (!found)
nm_ip6_config_add_search (ip6_config, search);
}
/* IPv6 addresses */
for (i = 0; i < nm_setting_ip6_config_get_num_addresses (setting); i++) {
NMIP6Address *setting_addr = nm_setting_ip6_config_get_address (setting, i);
guint32 num;
num = nm_ip6_config_get_num_addresses (ip6_config);
for (j = 0; j < num; j++) {
NMIP6Address *cfg_addr = nm_ip6_config_get_address (ip6_config, j);
/* Dupe, override with user-specified address */
if (ip6_addresses_equal (nm_ip6_address_get_address (cfg_addr), nm_ip6_address_get_address (setting_addr))) {
nm_ip6_config_replace_address (ip6_config, j, setting_addr);
break;
}
}
if (j == num)
nm_ip6_config_add_address (ip6_config, setting_addr);
}
/* IPv6 routes */
for (i = 0; i < nm_setting_ip6_config_get_num_routes (setting); i++) {
NMIP6Route *setting_route = nm_setting_ip6_config_get_route (setting, i);
guint32 num;
num = nm_ip6_config_get_num_routes (ip6_config);
for (j = 0; j < num; j++) {
NMIP6Route *cfg_route = nm_ip6_config_get_route (ip6_config, j);
/* Dupe, override with user-specified route */
if ( ip6_addresses_equal (nm_ip6_route_get_dest (cfg_route), nm_ip6_route_get_dest (setting_route))
&& (nm_ip6_route_get_prefix (cfg_route) == nm_ip6_route_get_prefix (setting_route))
&& ip6_addresses_equal (nm_ip6_route_get_next_hop (cfg_route), nm_ip6_route_get_next_hop (setting_route))) {
nm_ip6_config_replace_route (ip6_config, j, setting_route);
break;
}
}
if (j == num)
nm_ip6_config_add_route (ip6_config, setting_route);
}
if (nm_setting_ip6_config_get_never_default (setting))
nm_ip6_config_set_never_default (ip6_config, TRUE);
}
gboolean
nm_match_spec_string (const GSList *specs, const char *match)
{
const GSList *iter;
for (iter = specs; iter; iter = g_slist_next (iter)) {
if (!g_ascii_strcasecmp ((const char *) iter->data, match))
return TRUE;
}
return FALSE;
}
/******************************************************************/
gboolean
nm_ip6_config_destination_is_direct (NMIP6Config *config, const struct in6_addr *dest, guint32 dest_prefix)
{
int num;
int i;
num = nm_ip6_config_get_num_addresses (config);
for (i = 0; i < num; i++) {
NMIP6Address *addr = nm_ip6_config_get_address (config, i);
guint32 prefix = nm_ip6_address_get_prefix (addr);
const struct in6_addr *address = nm_ip6_address_get_address (addr);
if (prefix <= dest_prefix) {
const guint8 *maskbytes = (const guint8 *)address;
const guint8 *addrbytes = (const guint8 *)dest;
int nbytes, nbits;
/* Copied from g_inet_address_mask_matches() */
nbytes = prefix / 8;
if (nbytes != 0 && memcmp (maskbytes, addrbytes, nbytes) != 0)
continue;
nbits = prefix % 8;
if (nbits == 0)
return TRUE;
if (maskbytes[nbytes] == (addrbytes[nbytes] & (0xFF << (8 - nbits))))
return TRUE;
}
}
return FALSE;
}
/******************************************************************/
void
nm_ip6_config_add_address (NMIP6Config *config,
NMIP6Address *address)

View File

@@ -50,11 +50,18 @@ GType nm_ip6_config_get_type (void);
NMIP6Config * nm_ip6_config_new (void);
NMIP6Config * nm_ip6_config_new_for_interface (int ifindex);
void nm_ip6_config_export (NMIP6Config *config);
const char * nm_ip6_config_get_dbus_path (NMIP6Config *config);
/* Integration with nm-platform and nm-setting */
NMIP6Config *nm_ip6_config_capture (int ifindex);
gboolean nm_ip6_config_commit (NMIP6Config *config, int ifindex, int priority);
void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIP6Config *setting);
/* Utility functions */
gboolean nm_ip6_config_destination_is_direct (NMIP6Config *config, const struct in6_addr *dest, guint32 plen);
void nm_ip6_config_take_address (NMIP6Config *config, NMIP6Address *address);
void nm_ip6_config_add_address (NMIP6Config *config, NMIP6Address *address);
void nm_ip6_config_replace_address (NMIP6Config *config, guint32 i, NMIP6Address *new_address);

View File

@@ -1623,8 +1623,8 @@ vpn_connection_deactivated (NMPolicy *policy, NMVPNConnection *vpn)
if (parent) {
parent_ip4 = nm_device_get_ip4_config (parent);
if (parent_ip4) {
if (!nm_system_apply_ip4_config (nm_device_get_ip_ifindex (parent),
parent_ip4,
if (!nm_ip4_config_commit (parent_ip4,
nm_device_get_ip_ifindex (parent),
nm_device_get_priority (parent))) {
nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device IPv4 addresses and routes.");
}
@@ -1643,8 +1643,8 @@ vpn_connection_deactivated (NMPolicy *policy, NMVPNConnection *vpn)
if (parent) {
parent_ip6 = nm_device_get_ip6_config (parent);
if (parent_ip6) {
if (!nm_system_apply_ip6_config (nm_device_get_ip_ifindex (parent),
parent_ip6,
if (!nm_ip6_config_commit (parent_ip6,
nm_device_get_ip_ifindex (parent),
nm_device_get_priority (parent))) {
nm_log_err (LOGD_VPN, "failed to re-apply VPN parent device IPv6 addresses and routes.");
}

View File

@@ -50,30 +50,6 @@
#include "nm-utils.h"
#include "nm-logging.h"
static gboolean
ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix)
{
int num;
int i;
num = nm_ip4_config_get_num_addresses (config);
for (i = 0; i < num; i++) {
NMIP4Address *addr = nm_ip4_config_get_address (config, i);
guint32 prefix = nm_ip4_address_get_prefix (addr);
guint32 address = nm_ip4_address_get_address (addr);
if (prefix <= dest_prefix) {
guint32 masked_addr = ntohl(address) >> (32 - prefix);
guint32 masked_dest = ntohl(dest) >> (32 - prefix);
if (masked_addr == masked_dest)
return TRUE;
}
}
return FALSE;
}
NMPlatformIP4Route *
nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
{
@@ -117,7 +93,7 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
* IP addresses, don't add the host route to it, but a route through the
* parent device.
*/
if (ip4_dest_in_same_subnet (parent_config, vpn_gw, 32))
if (nm_ip4_config_destination_is_direct (parent_config, vpn_gw, 32))
route->gateway = 0;
if (!nm_platform_ip4_route_add (route->ifindex,
@@ -137,115 +113,6 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, guint32 vpn_gw)
return route;
}
/*
* nm_system_apply_ip4_config
*
* Set IPv4 configuration of the device from an NMIP4Config object.
*
*/
gboolean
nm_system_apply_ip4_config (int ifindex, NMIP4Config *config, int priority)
{
int mtu = nm_ip4_config_get_mtu (config);
int i;
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
/* Addresses */
{
int count = nm_ip4_config_get_num_addresses (config);
NMIP4Address *config_address;
GArray *addresses = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Address), count);
NMPlatformIP4Address address;
for (i = 0; i < count; i++) {
config_address = nm_ip4_config_get_address (config, i);
memset (&address, 0, sizeof (address));
address.address = nm_ip4_address_get_address (config_address);
address.plen = nm_ip4_address_get_prefix (config_address);
g_array_append_val (addresses, address);
}
nm_platform_ip4_address_sync (ifindex, addresses);
g_array_unref (addresses);
}
/* Routes */
{
int count = nm_ip4_config_get_num_routes (config);
NMIP4Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count);
NMPlatformIP4Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip4_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = nm_ip4_route_get_dest (config_route);
route.plen = nm_ip4_route_get_prefix (config_route);
route.gateway = nm_ip4_route_get_next_hop (config_route);
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
* the device already has an IP address on.
*/
if (ip4_dest_in_same_subnet (config, route.network, route.plen))
continue;
/* Don't add the default route when and the connection
* is never supposed to be the default connection.
*/
if (nm_ip4_config_get_never_default (config) && route.network == 0)
continue;
g_array_append_val (routes, route);
}
nm_platform_ip4_route_sync (ifindex, routes);
g_array_unref (routes);
}
/* MTU */
if (mtu && mtu != nm_platform_link_get_mtu (ifindex))
nm_platform_link_set_mtu (ifindex, mtu);
return TRUE;
}
static gboolean
ip6_dest_in_same_subnet (NMIP6Config *config, const struct in6_addr *dest, guint32 dest_prefix)
{
int num;
int i;
num = nm_ip6_config_get_num_addresses (config);
for (i = 0; i < num; i++) {
NMIP6Address *addr = nm_ip6_config_get_address (config, i);
guint32 prefix = nm_ip6_address_get_prefix (addr);
const struct in6_addr *address = nm_ip6_address_get_address (addr);
if (prefix <= dest_prefix) {
const guint8 *maskbytes = (const guint8 *)address;
const guint8 *addrbytes = (const guint8 *)dest;
int nbytes, nbits;
/* Copied from g_inet_address_mask_matches() */
nbytes = prefix / 8;
if (nbytes != 0 && memcmp (maskbytes, addrbytes, nbytes) != 0)
continue;
nbits = prefix % 8;
if (nbits == 0)
return TRUE;
if (maskbytes[nbytes] == (addrbytes[nbytes] & (0xFF << (8 - nbits))))
return TRUE;
}
}
return FALSE;
}
NMPlatformIP6Route *
nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
const struct in6_addr *vpn_gw)
@@ -293,7 +160,7 @@ nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
* IP addresses, don't add the host route to it, but a route through the
* parent device.
*/
if (ip6_dest_in_same_subnet (parent_config, vpn_gw, 128))
if (nm_ip6_config_destination_is_direct (parent_config, vpn_gw, 128))
route->gateway = in6addr_any;
if (!nm_platform_ip6_route_add (route->ifindex,
@@ -313,78 +180,6 @@ nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
return route;
}
/*
* nm_system_apply_ip6_config
*
* Set IPv6 configuration of the device from an NMIP6Config object.
*
*/
gboolean
nm_system_apply_ip6_config (int ifindex,
NMIP6Config *config,
int priority)
{
int i;
g_return_val_if_fail (ifindex > 0, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
/* Addresses */
{
int count = nm_ip6_config_get_num_addresses (config);
NMIP6Address *config_address;
GArray *addresses = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Address), count);
NMPlatformIP6Address address;
for (i = 0; i < count; i++) {
config_address = nm_ip6_config_get_address (config, i);
memset (&address, 0, sizeof (address));
address.address = *nm_ip6_address_get_address (config_address);
address.plen = nm_ip6_address_get_prefix (config_address);
g_array_append_val (addresses, address);
}
nm_platform_ip6_address_sync (ifindex, addresses);
g_array_unref (addresses);
}
/* Routes */
{
int count = nm_ip6_config_get_num_routes (config);
NMIP6Route *config_route;
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count);
NMPlatformIP6Route route;
for (i = 0; i < count; i++) {
config_route = nm_ip6_config_get_route (config, i);
memset (&route, 0, sizeof (route));
route.network = *nm_ip6_route_get_dest (config_route);
route.plen = nm_ip6_route_get_prefix (config_route);
route.gateway = *nm_ip6_route_get_next_hop (config_route);
route.metric = priority;
/* Don't add the route if it's more specific than one of the subnets
* the device already has an IP address on.
*/
if (ip6_dest_in_same_subnet (config, &route.network, route.plen))
continue;
/* Don't add the default route when and the connection
* is never supposed to be the default connection.
*/
if (nm_ip6_config_get_never_default (config) && IN6_IS_ADDR_UNSPECIFIED (&route.network))
continue;
g_array_append_val (routes, route);
}
nm_platform_ip6_route_sync (ifindex, routes);
g_array_unref (routes);
}
return TRUE;
}
static const struct {
const char *option;
const char *default_value;

View File

@@ -24,7 +24,6 @@
#include "nm-platform.h"
#include "nm-device.h"
#include "nm-ip4-config.h"
#include "nm-setting-bond.h"
NMPlatformIP4Route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device,
@@ -32,14 +31,6 @@ NMPlatformIP4Route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device
NMPlatformIP6Route *nm_system_add_ip6_vpn_gateway_route (NMDevice *parent_device,
const struct in6_addr *vpn_gw);
gboolean nm_system_apply_ip4_config (int ifindex,
NMIP4Config *config,
int priority);
gboolean nm_system_apply_ip6_config (int ifindex,
NMIP6Config *config,
int priority);
gboolean nm_system_apply_bonding_config (const char *iface,
NMSettingBond *s_bond);
#endif

View File

@@ -609,12 +609,12 @@ nm_vpn_connection_apply_config (NMVPNConnection *connection)
nm_platform_link_set_up (priv->ip_ifindex);
if (priv->ip4_config) {
if (!nm_system_apply_ip4_config (priv->ip_ifindex, priv->ip4_config, 0))
if (!nm_ip4_config_commit (priv->ip4_config, priv->ip_ifindex, 0))
return FALSE;
}
if (priv->ip6_config) {
if (!nm_system_apply_ip6_config (priv->ip_ifindex, priv->ip6_config, 0))
if (!nm_ip6_config_commit (priv->ip6_config, priv->ip_ifindex, 0))
/* FIXME: remove ip4 config */
return FALSE;
}
@@ -906,7 +906,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
/* Merge in user overrides from the NMConnection's IPv4 setting */
s_ip4 = nm_connection_get_setting_ip4_config (priv->connection);
nm_utils_merge_ip4_config (config, s_ip4);
nm_ip4_config_merge_setting (config, s_ip4);
priv->ip4_config = config;
nm_vpn_connection_config_maybe_complete (connection, TRUE);
@@ -1043,7 +1043,7 @@ nm_vpn_connection_ip6_config_get (DBusGProxy *proxy,
/* Merge in user overrides from the NMConnection's IPv6 setting */
s_ip6 = nm_connection_get_setting_ip6_config (priv->connection);
nm_utils_merge_ip6_config (config, s_ip6);
nm_ip6_config_merge_setting (config, s_ip6);
priv->ip6_config = config;
nm_vpn_connection_config_maybe_complete (connection, TRUE);