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:
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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,29 +153,207 @@ 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);
|
||||
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);
|
||||
}
|
||||
|
||||
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_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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_ip6_config_get_dbus_path (NMIP6Config *config)
|
||||
static inline gboolean
|
||||
ip6_addresses_equal (const struct in6_addr *a, const struct in6_addr *b)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
|
||||
|
||||
return NM_IP6_CONFIG_GET_PRIVATE (config)->path;
|
||||
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)
|
||||
|
@@ -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);
|
||||
|
@@ -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.");
|
||||
}
|
||||
|
209
src/nm-system.c
209
src/nm-system.c
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user