mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-21 09:50:06 +01:00
core: rework tracking of gateway/default-route in ip-config
Instead of having 3 properties @gateway, @never_default and @has_gateway on NMIP4Config/NMIP6Config that determine the default-route, track the default-route as a regular route. The gateway setting is the configuration knob for the default-route. Since an NMIP4Config/NMIP6Config instance only has one gateway property, it cannot track more then one default-routes (see related bug rh#1445417). Especially with policy routing, it might be interesting to configure a default-route in multiple tables. Also, later it might be interesting to allow adding default-routes as regular static routes in a connection, so that the user can configure additional route parameters for the default-route or add default-routes in multiple tables. With this patch, default-routes now have a rt_source property according to their origin. Also, the previous commits of this branch broke handling of the default-route :) . That should be working now again.
This commit is contained in:
parent
2bdfc092d4
commit
5c299454b4
34 changed files with 1096 additions and 893 deletions
|
|
@ -474,6 +474,15 @@ act_stage3_ip4_config_start (NMDevice *device,
|
|||
}
|
||||
|
||||
priv->ppp_manager = nm_ppp_manager_create (ppp_iface, &err);
|
||||
|
||||
if (priv->ppp_manager) {
|
||||
nm_ppp_manager_set_route_parameters (priv->ppp_manager,
|
||||
nm_device_get_route_table (device, AF_INET, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET),
|
||||
nm_device_get_route_table (device, AF_INET6, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET6));
|
||||
}
|
||||
|
||||
if ( !priv->ppp_manager
|
||||
|| !nm_ppp_manager_start (priv->ppp_manager, req,
|
||||
nm_setting_adsl_get_username (s_adsl),
|
||||
|
|
|
|||
|
|
@ -999,6 +999,7 @@ ppp_ip4_config (NMPPPManager *ppp_manager,
|
|||
static NMActStageReturn
|
||||
pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *out_failure_reason)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE (self);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMSettingPppoe *s_pppoe;
|
||||
NMActRequest *req;
|
||||
|
|
@ -1010,9 +1011,17 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *out_
|
|||
s_pppoe = (NMSettingPppoe *) nm_device_get_applied_setting ((NMDevice *) self, NM_TYPE_SETTING_PPPOE);
|
||||
g_return_val_if_fail (s_pppoe, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
priv->ppp_manager = nm_ppp_manager_create (nm_device_get_iface (NM_DEVICE (self)),
|
||||
priv->ppp_manager = nm_ppp_manager_create (nm_device_get_iface (device),
|
||||
&err);
|
||||
|
||||
if (priv->ppp_manager) {
|
||||
nm_ppp_manager_set_route_parameters (priv->ppp_manager,
|
||||
nm_device_get_route_table (device, AF_INET, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET),
|
||||
nm_device_get_route_table (device, AF_INET6, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET6));
|
||||
}
|
||||
|
||||
if ( !priv->ppp_manager
|
||||
|| !nm_ppp_manager_start (priv->ppp_manager, req,
|
||||
nm_setting_pppoe_get_username (s_pppoe),
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE (self);
|
||||
NMSettingPppoe *s_pppoe;
|
||||
NMActRequest *req;
|
||||
GError *err = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
req = nm_device_get_act_request (NM_DEVICE (self));
|
||||
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
|
@ -149,14 +149,22 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
g_clear_object (&priv->pending_ip4_config);
|
||||
nm_clear_g_free (&priv->pending_ifname);
|
||||
|
||||
priv->ppp_manager = nm_ppp_manager_create (nm_setting_pppoe_get_parent (s_pppoe), &err);
|
||||
priv->ppp_manager = nm_ppp_manager_create (nm_setting_pppoe_get_parent (s_pppoe), &error);
|
||||
|
||||
if (priv->ppp_manager) {
|
||||
nm_ppp_manager_set_route_parameters (priv->ppp_manager,
|
||||
nm_device_get_route_table (device, AF_INET, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET),
|
||||
nm_device_get_route_table (device, AF_INET6, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET6));
|
||||
}
|
||||
|
||||
if ( !priv->ppp_manager
|
||||
|| !nm_ppp_manager_start (priv->ppp_manager, req,
|
||||
nm_setting_pppoe_get_username (s_pppoe),
|
||||
30, 0, &err)) {
|
||||
_LOGW (LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", err->message);
|
||||
g_error_free (err);
|
||||
30, 0, &error)) {
|
||||
_LOGW (LOGD_DEVICE | LOGD_PPP, "PPPoE failed to start: %s", error->message);
|
||||
g_error_free (error);
|
||||
|
||||
g_clear_object (&priv->ppp_manager);
|
||||
|
||||
|
|
|
|||
|
|
@ -339,6 +339,9 @@ typedef struct _NMDevicePrivate {
|
|||
bool v4_commit_first_time:1;
|
||||
bool v6_commit_first_time:1;
|
||||
|
||||
bool default_route_metric_penalty_ip4_has:1;
|
||||
bool default_route_metric_penalty_ip6_has:1;
|
||||
|
||||
NMDeviceSysIfaceState sys_iface_state:2;
|
||||
|
||||
bool v4_route_table_initalized:1;
|
||||
|
|
@ -366,11 +369,6 @@ typedef struct _NMDevicePrivate {
|
|||
NMIP4Config * wwan_ip4_config; /* WWAN configuration */
|
||||
GSList * vpn4_configs; /* VPNs which use this device */
|
||||
|
||||
const NMPObject *default_route4;
|
||||
const NMPObject *default_route6;
|
||||
const NMPObject *default_routegw4;
|
||||
const NMPObject *default_routegw6;
|
||||
|
||||
bool v4_has_shadowed_routes;
|
||||
const char *ip4_rp_filter;
|
||||
|
||||
|
|
@ -1665,24 +1663,35 @@ _get_route_metric_default (NMDevice *self)
|
|||
return 11000;
|
||||
}
|
||||
|
||||
static guint32
|
||||
route_metric_with_penalty (NMDevice *self, guint32 metric)
|
||||
static gboolean
|
||||
default_route_metric_penalty_detect (NMDevice *self)
|
||||
{
|
||||
#if WITH_CONCHECK
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const guint32 PENALTY = 20000;
|
||||
|
||||
/* Beware: for IPv6, a metric of 0 effectively means 1024.
|
||||
* Only pass a normalized IPv6 metric (nm_utils_ip6_route_metric_normalize). */
|
||||
|
||||
/* currently we don't differentiate between IPv4 and IPv6 when detecting
|
||||
* connectivity. */
|
||||
if ( priv->connectivity_state != NM_CONNECTIVITY_FULL
|
||||
&& nm_connectivity_check_enabled (nm_connectivity_get ())) {
|
||||
if (metric >= G_MAXUINT32 - PENALTY)
|
||||
return G_MAXUINT32;
|
||||
return metric + PENALTY;
|
||||
&& nm_connectivity_check_enabled (nm_connectivity_get ())) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return metric;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint32
|
||||
default_route_metric_penalty_get (NMDevice *self, int addr_family)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_assert_addr_family (addr_family);
|
||||
|
||||
if ( addr_family == AF_INET
|
||||
? priv->default_route_metric_penalty_ip4_has
|
||||
: priv->default_route_metric_penalty_ip6_has)
|
||||
return 20000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint32
|
||||
|
|
@ -1736,13 +1745,17 @@ nm_device_get_route_table (NMDevice *self,
|
|||
int addr_family,
|
||||
gboolean fallback_main)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMDevicePrivate *priv;
|
||||
NMConnection *connection;
|
||||
NMSettingIPConfig *s_ip;
|
||||
guint32 route_table = 0;
|
||||
|
||||
nm_assert_addr_family (addr_family);
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), RT_TABLE_MAIN);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
/* the route table setting affects how we sync routes. We shall
|
||||
* not change it while the device is active, hence, cache it. */
|
||||
if (addr_family == AF_INET) {
|
||||
|
|
@ -1801,24 +1814,14 @@ nm_device_get_best_default_route (NMDevice *self,
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
/* Prefer the best default-route we have in ipx_config.
|
||||
*
|
||||
* Otherwise, use priv->default_routeX. Usually, we would
|
||||
* expect that if ipx_config has no default route, then
|
||||
* also priv->default_routeX is unset. This is just to cover
|
||||
* a case I cannot imagine now. */
|
||||
switch (addr_family) {
|
||||
case AF_INET:
|
||||
return (priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL)
|
||||
?: priv->default_route4;
|
||||
return priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL;
|
||||
case AF_INET6:
|
||||
return (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL)
|
||||
?: priv->default_route6;
|
||||
return priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL;
|
||||
case AF_UNSPEC:
|
||||
return (priv->ip4_config ? nm_ip4_config_best_default_route_get (priv->ip4_config) : NULL)
|
||||
?: priv->default_route4
|
||||
?: (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL)
|
||||
?: priv->default_route6;
|
||||
?: (priv->ip6_config ? nm_ip6_config_best_default_route_get (priv->ip6_config) : NULL);
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
|
@ -5767,15 +5770,11 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
NMConnection *connection;
|
||||
gboolean success;
|
||||
NMIP4Config *composite;
|
||||
const guint32 default_route_metric = nm_device_get_route_metric (self, AF_INET);
|
||||
guint32 gateway;
|
||||
gboolean connection_has_default_route, connection_is_never_default;
|
||||
gboolean ignore_auto_routes = FALSE;
|
||||
gboolean ignore_auto_dns = FALSE;
|
||||
gboolean ignore_default_routes = FALSE;
|
||||
GSList *iter;
|
||||
NMPlatformIP4Route default_route;
|
||||
gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
|
||||
gboolean add_default_route = TRUE;
|
||||
|
||||
/* Apply ignore-auto-routes and ignore-auto-dns settings */
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
|
|
@ -5785,6 +5784,7 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
if (s_ip4) {
|
||||
ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip4);
|
||||
ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip4);
|
||||
ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip4);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5797,17 +5797,22 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
ensure_con_ip4_config (self);
|
||||
}
|
||||
|
||||
if (commit)
|
||||
priv->default_route_metric_penalty_ip4_has = default_route_metric_penalty_detect (self);
|
||||
|
||||
if (priv->dev_ip4_config) {
|
||||
nm_ip4_config_merge (composite, priv->dev_ip4_config,
|
||||
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
|
||||
| (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
|
||||
for (iter = priv->vpn4_configs; iter; iter = iter->next)
|
||||
nm_ip4_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip4_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
|
||||
if (priv->ext_ip4_config)
|
||||
nm_ip4_config_merge (composite, priv->ext_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip4_config_merge (composite, priv->ext_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
|
||||
/* Merge WWAN config *last* to ensure modem-given settings overwrite
|
||||
* any external stuff set by pppd or other scripts.
|
||||
|
|
@ -5815,87 +5820,23 @@ ip4_config_merge_and_apply (NMDevice *self,
|
|||
if (priv->wwan_ip4_config) {
|
||||
nm_ip4_config_merge (composite, priv->wwan_ip4_config,
|
||||
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
|
||||
| (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
|
||||
/* Merge user overrides into the composite config. For assumed connections,
|
||||
* con_ip4_config is empty. */
|
||||
if (priv->con_ip4_config)
|
||||
nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
|
||||
/* Add the default route... */
|
||||
|
||||
if (!commit) {
|
||||
/* during a non-commit event, we always pickup whatever is configured. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* for external connections, we always pickup whatever is configured. */
|
||||
if (nm_device_sys_iface_state_is_external (self))
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
connection_has_default_route
|
||||
= nm_utils_connection_has_default_route (connection, AF_INET, &connection_is_never_default);
|
||||
|
||||
if ( !priv->v4_commit_first_time
|
||||
&& connection_is_never_default) {
|
||||
/* If the connection is explicitly configured as never-default, we enforce the (absence of the)
|
||||
* default-route only once. That allows the user to configure a connection as never-default,
|
||||
* but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
|
||||
if (!connection_has_default_route)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
if (!nm_ip4_config_get_num_addresses (composite)) {
|
||||
/* without addresses we can have no default route. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
gateway = nm_ip4_config_get_gateway (composite);
|
||||
if ( !nm_ip4_config_has_gateway (composite)
|
||||
&& nm_device_get_device_type (self) != NM_DEVICE_TYPE_MODEM)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
add_default_route = FALSE;
|
||||
|
||||
memset (&default_route, 0, sizeof (default_route));
|
||||
default_route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
default_route.gateway = gateway;
|
||||
default_route.table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (self, AF_INET, TRUE));
|
||||
default_route.metric = route_metric_with_penalty (self, default_route_metric);
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_ip4_config_add_route (composite, &default_route, &priv->default_route4);
|
||||
|
||||
if (!( gateway == 0
|
||||
|| nm_ip4_config_destination_is_direct (composite, gateway, 32)
|
||||
|| nm_ip4_config_get_direct_route_for_host (composite, gateway))) {
|
||||
/* add a direct route to the gateway */
|
||||
default_route.network = gateway;
|
||||
default_route.plen = 32;
|
||||
default_route.gateway = 0;
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
nm_ip4_config_add_route (composite, &default_route, &priv->default_routegw4);
|
||||
}
|
||||
|
||||
END_ADD_DEFAULT_ROUTE:
|
||||
|
||||
if (add_default_route) {
|
||||
if (priv->default_route4)
|
||||
nm_ip4_config_add_route (composite, NMP_OBJECT_CAST_IP4_ROUTE (priv->default_route4), NULL);
|
||||
if (priv->default_routegw4)
|
||||
nm_ip4_config_add_route (composite, NMP_OBJECT_CAST_IP4_ROUTE (priv->default_routegw4), NULL);
|
||||
if (priv->con_ip4_config) {
|
||||
nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
nm_ip4_config_add_device_routes (composite,
|
||||
nm_device_get_route_table (self, AF_INET, TRUE),
|
||||
default_route_metric,
|
||||
&ip4_dev_route_blacklist);
|
||||
nm_ip4_config_add_dependent_routes (composite,
|
||||
nm_device_get_route_table (self, AF_INET, TRUE),
|
||||
nm_device_get_route_metric (self, AF_INET),
|
||||
&ip4_dev_route_blacklist);
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
|
|
@ -6481,15 +6422,11 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
NMConnection *connection;
|
||||
gboolean success;
|
||||
NMIP6Config *composite;
|
||||
const guint32 default_route_metric = nm_device_get_route_metric (self, AF_INET6);
|
||||
const struct in6_addr *gateway;
|
||||
gboolean connection_has_default_route, connection_is_never_default;
|
||||
gboolean ignore_auto_routes = FALSE;
|
||||
gboolean ignore_auto_dns = FALSE;
|
||||
gboolean ignore_default_routes = FALSE;
|
||||
const char *token = NULL;
|
||||
GSList *iter;
|
||||
NMPlatformIP6Route default_route;
|
||||
gboolean add_default_route = TRUE;
|
||||
|
||||
/* Apply ignore-auto-routes and ignore-auto-dns settings */
|
||||
connection = nm_device_get_applied_connection (self);
|
||||
|
|
@ -6501,6 +6438,7 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
|
||||
ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6);
|
||||
ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6);
|
||||
ignore_default_routes = nm_setting_ip_config_get_never_default (s_ip6);
|
||||
|
||||
if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64)
|
||||
token = nm_setting_ip6_config_get_token (ip6);
|
||||
|
|
@ -6520,23 +6458,30 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
ensure_con_ip6_config (self);
|
||||
}
|
||||
|
||||
if (commit)
|
||||
priv->default_route_metric_penalty_ip6_has = default_route_metric_penalty_detect (self);
|
||||
|
||||
/* Merge all the IP configs into the composite config */
|
||||
if (priv->ac_ip6_config) {
|
||||
nm_ip6_config_merge (composite, priv->ac_ip6_config,
|
||||
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
|
||||
| (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->dhcp6.ip6_config) {
|
||||
nm_ip6_config_merge (composite, priv->dhcp6.ip6_config,
|
||||
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
|
||||
| (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
|
||||
for (iter = priv->vpn6_configs; iter; iter = iter->next)
|
||||
nm_ip6_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip6_config_merge (composite, iter->data, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
|
||||
if (priv->ext_ip6_config)
|
||||
nm_ip6_config_merge (composite, priv->ext_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip6_config_merge (composite, priv->ext_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
|
||||
/* Merge WWAN config *last* to ensure modem-given settings overwrite
|
||||
* any external stuff set by pppd or other scripts.
|
||||
|
|
@ -6544,7 +6489,9 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
if (priv->wwan_ip6_config) {
|
||||
nm_ip6_config_merge (composite, priv->wwan_ip6_config,
|
||||
(ignore_auto_routes ? NM_IP_CONFIG_MERGE_NO_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0));
|
||||
| (ignore_default_routes ? NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES : 0)
|
||||
| (ignore_auto_dns ? NM_IP_CONFIG_MERGE_NO_DNS : 0),
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
|
||||
if (priv->rt6_temporary_not_available) {
|
||||
|
|
@ -6561,78 +6508,15 @@ ip6_config_merge_and_apply (NMDevice *self,
|
|||
|
||||
/* Merge user overrides into the composite config. For assumed connections,
|
||||
* con_ip6_config is empty. */
|
||||
if (priv->con_ip6_config)
|
||||
nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
|
||||
/* Add the default route... */
|
||||
|
||||
if (!commit) {
|
||||
/* during a non-commit event, we always pickup whatever is configured. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
/* for external connections, we always pickup whatever is configured. */
|
||||
if (nm_device_sys_iface_state_is_external (self))
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
connection_has_default_route
|
||||
= nm_utils_connection_has_default_route (connection, AF_INET6, &connection_is_never_default);
|
||||
|
||||
if ( !priv->v6_commit_first_time
|
||||
&& connection_is_never_default) {
|
||||
/* If the connection is explicitly configured as never-default, we enforce the (absence of the)
|
||||
* default-route only once. That allows the user to configure a connection as never-default,
|
||||
* but he can add default routes externally (via a dispatcher script) and NM will not interfere. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
|
||||
if (!connection_has_default_route)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
if (!nm_ip6_config_get_num_addresses (composite)) {
|
||||
/* without addresses we can have no default route. */
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
}
|
||||
|
||||
gateway = nm_ip6_config_get_gateway (composite);
|
||||
if (!gateway)
|
||||
goto END_ADD_DEFAULT_ROUTE;
|
||||
|
||||
add_default_route = FALSE;
|
||||
|
||||
memset (&default_route, 0, sizeof (default_route));
|
||||
default_route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
default_route.gateway = *gateway;
|
||||
default_route.table_coerced = nm_platform_route_table_coerce (nm_device_get_route_table (self, AF_INET6, TRUE));
|
||||
default_route.metric = route_metric_with_penalty (self, default_route_metric);
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_ip6_config_add_route (composite, &default_route, &priv->default_route6);
|
||||
|
||||
if (!nm_ip6_config_get_direct_route_for_host (composite, gateway)) {
|
||||
/* add a direct route to the gateway */
|
||||
default_route.network = *gateway;
|
||||
default_route.plen = 128;
|
||||
default_route.gateway = in6addr_any;
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
nm_ip6_config_add_route (composite, &default_route, &priv->default_routegw6);
|
||||
}
|
||||
|
||||
END_ADD_DEFAULT_ROUTE:
|
||||
|
||||
if (add_default_route) {
|
||||
if (priv->default_route6)
|
||||
nm_ip6_config_add_route (composite, NMP_OBJECT_CAST_IP6_ROUTE (priv->default_route6), NULL);
|
||||
if (priv->default_routegw6)
|
||||
nm_ip6_config_add_route (composite, NMP_OBJECT_CAST_IP6_ROUTE (priv->default_routegw6), NULL);
|
||||
if (priv->con_ip6_config) {
|
||||
nm_ip6_config_merge (composite, priv->con_ip6_config, NM_IP_CONFIG_MERGE_DEFAULT,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
|
||||
if (commit) {
|
||||
nm_ip6_config_add_device_routes (composite,
|
||||
nm_device_get_route_table (self, AF_INET6, TRUE),
|
||||
default_route_metric);
|
||||
nm_ip6_config_add_dependent_routes (composite,
|
||||
nm_device_get_route_table (self, AF_INET6, TRUE),
|
||||
nm_device_get_route_metric (self, AF_INET6));
|
||||
}
|
||||
|
||||
/* Allow setting MTU etc */
|
||||
|
|
@ -7477,14 +7361,6 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
if (!priv->ac_ip6_config)
|
||||
priv->ac_ip6_config = _ip6_config_new (self);
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_GATEWAYS) {
|
||||
/* Use the first gateway as ordered in neighbor discovery cache. */
|
||||
if (rdata->gateways_n)
|
||||
nm_ip6_config_set_gateway (priv->ac_ip6_config, &rdata->gateways[0].address);
|
||||
else
|
||||
nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ADDRESSES) {
|
||||
guint8 plen;
|
||||
guint32 ifa_flags;
|
||||
|
|
@ -7510,8 +7386,11 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
ifa_flags);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ROUTES) {
|
||||
if (NM_FLAGS_ANY (changed, NM_NDISC_CONFIG_ROUTES
|
||||
| NM_NDISC_CONFIG_GATEWAYS)) {
|
||||
nm_ip6_config_reset_routes_ndisc (priv->ac_ip6_config,
|
||||
rdata->gateways,
|
||||
rdata->gateways_n,
|
||||
rdata->routes,
|
||||
rdata->routes_n,
|
||||
nm_device_get_route_table (self, AF_INET6, TRUE),
|
||||
|
|
@ -9016,8 +8895,6 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
_LOGD (LOGD_DEVICE, "clearing queued IP4 config change");
|
||||
priv->queued_ip4_config_pending = FALSE;
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
dhcp4_cleanup (self, cleanup_type, FALSE);
|
||||
arp_cleanup (self);
|
||||
dnsmasq_cleanup (self);
|
||||
|
|
@ -9035,8 +8912,6 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
_LOGD (LOGD_DEVICE, "clearing queued IP6 config change");
|
||||
priv->queued_ip6_config_pending = FALSE;
|
||||
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
g_clear_object (&priv->dad6_ip6_config);
|
||||
dhcp6_cleanup (self, cleanup_type, FALSE);
|
||||
linklocal6_cleanup (self);
|
||||
|
|
@ -10631,7 +10506,7 @@ nm_device_start_ip_check (NMDevice *self)
|
|||
NMSettingConnection *s_con;
|
||||
guint timeout = 0;
|
||||
const char *ping_binary = NULL;
|
||||
char buf[INET6_ADDRSTRLEN] = { 0 };
|
||||
char buf[NM_UTILS_INET_ADDRSTRLEN];
|
||||
NMLogDomain log_domain = LOGD_IP4;
|
||||
|
||||
/* Shouldn't be any active ping here, since IP_CHECK happens after the
|
||||
|
|
@ -10650,25 +10525,24 @@ nm_device_start_ip_check (NMDevice *self)
|
|||
g_assert (s_con);
|
||||
timeout = nm_setting_connection_get_gateway_ping_timeout (s_con);
|
||||
|
||||
buf[0] = '\0';
|
||||
if (timeout) {
|
||||
const NMPObject *gw;
|
||||
|
||||
if (priv->ip4_config && priv->ip4_state == IP_DONE) {
|
||||
guint gw = 0;
|
||||
|
||||
ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL);
|
||||
log_domain = LOGD_IP4;
|
||||
|
||||
gw = nm_ip4_config_get_gateway (priv->ip4_config);
|
||||
if (gw && !inet_ntop (AF_INET, &gw, buf, sizeof (buf)))
|
||||
buf[0] = '\0';
|
||||
gw = nm_ip4_config_best_default_route_get (priv->ip4_config);
|
||||
if (gw) {
|
||||
nm_utils_inet4_ntop (NMP_OBJECT_CAST_IP4_ROUTE (gw)->gateway, buf);
|
||||
ping_binary = nm_utils_find_helper ("ping", "/usr/bin/ping", NULL);
|
||||
log_domain = LOGD_IP4;
|
||||
}
|
||||
} else if (priv->ip6_config && priv->ip6_state == IP_DONE) {
|
||||
const struct in6_addr *gw = NULL;
|
||||
|
||||
ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL);
|
||||
log_domain = LOGD_IP6;
|
||||
|
||||
gw = nm_ip6_config_get_gateway (priv->ip6_config);
|
||||
if (gw && !inet_ntop (AF_INET6, gw, buf, sizeof (buf)))
|
||||
buf[0] = '\0';
|
||||
gw = nm_ip6_config_best_default_route_get (priv->ip6_config);
|
||||
if (gw) {
|
||||
nm_utils_inet6_ntop (&NMP_OBJECT_CAST_IP6_ROUTE (gw)->gateway, buf);
|
||||
ping_binary = nm_utils_find_helper ("ping6", "/usr/bin/ping6", NULL);
|
||||
log_domain = LOGD_IP6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10884,12 +10758,18 @@ find_ip4_lease_config (NMDevice *self,
|
|||
for (liter = leases; liter && !found; liter = liter->next) {
|
||||
NMIP4Config *lease_config = liter->data;
|
||||
const NMPlatformIP4Address *address = nm_ip4_config_get_first_address (lease_config);
|
||||
guint32 gateway = nm_ip4_config_get_gateway (lease_config);
|
||||
const NMPObject *gw1, *gw2;
|
||||
|
||||
g_assert (address);
|
||||
if (!nm_ip4_config_address_exists (ext_ip4_config, address))
|
||||
continue;
|
||||
if (gateway != nm_ip4_config_get_gateway (ext_ip4_config))
|
||||
gw1 = nm_ip4_config_best_default_route_get (lease_config);
|
||||
if (!gw1)
|
||||
continue;
|
||||
gw2 = nm_ip4_config_best_default_route_get (ext_ip4_config);
|
||||
if (!gw2)
|
||||
continue;
|
||||
if (NMP_OBJECT_CAST_IP4_ROUTE (gw1)->gateway != NMP_OBJECT_CAST_IP4_ROUTE (gw2)->gateway)
|
||||
continue;
|
||||
found = g_object_ref (lease_config);
|
||||
}
|
||||
|
|
@ -10999,37 +10879,39 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolea
|
|||
* (addresses,routes) that is no longer present externally from the internal
|
||||
* config. This way, we don't re-add addresses that were manually removed
|
||||
* by the user. */
|
||||
if (priv->con_ip4_config)
|
||||
nm_ip4_config_intersect (priv->con_ip4_config, priv->ext_ip4_config);
|
||||
if (priv->dev_ip4_config)
|
||||
nm_ip4_config_intersect (priv->dev_ip4_config, priv->ext_ip4_config);
|
||||
if (priv->wwan_ip4_config)
|
||||
nm_ip4_config_intersect (priv->wwan_ip4_config, priv->ext_ip4_config);
|
||||
if (priv->con_ip4_config) {
|
||||
nm_ip4_config_intersect (priv->con_ip4_config, priv->ext_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
if (priv->dev_ip4_config) {
|
||||
nm_ip4_config_intersect (priv->dev_ip4_config, priv->ext_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
if (priv->wwan_ip4_config) {
|
||||
nm_ip4_config_intersect (priv->wwan_ip4_config, priv->ext_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
for (iter = priv->vpn4_configs; iter; iter = iter->next)
|
||||
nm_ip4_config_intersect (iter->data, priv->ext_ip4_config);
|
||||
if ( priv->default_route4
|
||||
&& !nm_ip4_config_nmpobj_lookup (priv->ext_ip4_config, priv->default_route4))
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
if ( priv->default_routegw4
|
||||
&& !nm_ip4_config_nmpobj_lookup (priv->ext_ip4_config, priv->default_routegw4))
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
nm_ip4_config_intersect (iter->data, priv->ext_ip4_config, 0);
|
||||
}
|
||||
|
||||
/* Remove parts from ext_ip4_config to only contain the information that
|
||||
* was configured externally -- we already have the same configuration from
|
||||
* internal origins. */
|
||||
if (priv->con_ip4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->con_ip4_config);
|
||||
if (priv->dev_ip4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config);
|
||||
if (priv->wwan_ip4_config)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config);
|
||||
if (priv->con_ip4_config) {
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->con_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
if (priv->dev_ip4_config) {
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->dev_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
if (priv->wwan_ip4_config) {
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, priv->wwan_ip4_config,
|
||||
default_route_metric_penalty_get (self, AF_INET));
|
||||
}
|
||||
for (iter = priv->vpn4_configs; iter; iter = iter->next)
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, iter->data);
|
||||
if (priv->default_route4)
|
||||
nm_ip4_config_nmpobj_remove (priv->ext_ip4_config, priv->default_route4);
|
||||
if (priv->default_routegw4)
|
||||
nm_ip4_config_nmpobj_remove (priv->ext_ip4_config, priv->default_routegw4);
|
||||
nm_ip4_config_subtract (priv->ext_ip4_config, iter->data, 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -11051,41 +10933,47 @@ update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolea
|
|||
* (addresses,routes) that is no longer present externally from the internal
|
||||
* config. This way, we don't re-add addresses that were manually removed
|
||||
* by the user. */
|
||||
if (priv->con_ip6_config)
|
||||
nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config);
|
||||
if (priv->ac_ip6_config)
|
||||
nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config);
|
||||
if (priv->dhcp6.ip6_config)
|
||||
nm_ip6_config_intersect (priv->dhcp6.ip6_config, priv->ext_ip6_config);
|
||||
if (priv->wwan_ip6_config)
|
||||
nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config);
|
||||
if (priv->con_ip6_config) {
|
||||
nm_ip6_config_intersect (priv->con_ip6_config, priv->ext_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->ac_ip6_config) {
|
||||
nm_ip6_config_intersect (priv->ac_ip6_config, priv->ext_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->dhcp6.ip6_config) {
|
||||
nm_ip6_config_intersect (priv->dhcp6.ip6_config, priv->ext_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->wwan_ip6_config) {
|
||||
nm_ip6_config_intersect (priv->wwan_ip6_config, priv->ext_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
for (iter = priv->vpn6_configs; iter; iter = iter->next)
|
||||
nm_ip6_config_intersect (iter->data, priv->ext_ip6_config);
|
||||
if ( priv->default_route6
|
||||
&& !nm_ip6_config_nmpobj_lookup (priv->ext_ip6_config, priv->default_route6))
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
if ( priv->default_routegw6
|
||||
&& !nm_ip6_config_nmpobj_lookup (priv->ext_ip6_config, priv->default_routegw6))
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
nm_ip6_config_intersect (iter->data, priv->ext_ip6_config, 0);
|
||||
}
|
||||
|
||||
/* Remove parts from ext_ip6_config to only contain the information that
|
||||
* was configured externally -- we already have the same configuration from
|
||||
* internal origins. */
|
||||
if (priv->con_ip6_config)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config);
|
||||
if (priv->ac_ip6_config)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config);
|
||||
if (priv->dhcp6.ip6_config)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6.ip6_config);
|
||||
if (priv->wwan_ip6_config)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config);
|
||||
if (priv->con_ip6_config) {
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->con_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->ac_ip6_config) {
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->ac_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->dhcp6.ip6_config) {
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->dhcp6.ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
if (priv->wwan_ip6_config) {
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, priv->wwan_ip6_config,
|
||||
default_route_metric_penalty_get (self, AF_INET6));
|
||||
}
|
||||
for (iter = priv->vpn6_configs; iter; iter = iter->next)
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, iter->data);
|
||||
if (priv->default_route6)
|
||||
nm_ip6_config_nmpobj_remove (priv->ext_ip6_config, priv->default_route6);
|
||||
if (priv->default_routegw6)
|
||||
nm_ip6_config_nmpobj_remove (priv->ext_ip6_config, priv->default_routegw6);
|
||||
nm_ip6_config_subtract (priv->ext_ip6_config, iter->data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -12403,6 +12291,9 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
|
|||
priv->v4_route_table_initalized = FALSE;
|
||||
priv->v6_route_table_initalized = FALSE;
|
||||
|
||||
priv->default_route_metric_penalty_ip4_has = FALSE;
|
||||
priv->default_route_metric_penalty_ip6_has = FALSE;
|
||||
|
||||
priv->linklocal6_dad_counter = 0;
|
||||
|
||||
/* Clean up IP configs; this does not actually deconfigure the
|
||||
|
|
@ -12410,10 +12301,6 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
|
|||
*/
|
||||
nm_device_set_ip4_config (self, NULL, TRUE, NULL);
|
||||
nm_device_set_ip6_config (self, NULL, TRUE);
|
||||
nm_clear_nmp_object (&priv->default_route4);
|
||||
nm_clear_nmp_object (&priv->default_route6);
|
||||
nm_clear_nmp_object (&priv->default_routegw4);
|
||||
nm_clear_nmp_object (&priv->default_routegw6);
|
||||
g_clear_object (&priv->proxy_config);
|
||||
g_clear_object (&priv->con_ip4_config);
|
||||
g_clear_object (&priv->dev_ip4_config);
|
||||
|
|
|
|||
|
|
@ -912,8 +912,24 @@ static_stage3_ip4_done (NMModemBroadband *self)
|
|||
_LOGI (" address %s/%d", address_string, address.plen);
|
||||
|
||||
if (gw) {
|
||||
nm_ip4_config_set_gateway (config, gw);
|
||||
_LOGI (" gateway %s", gw_string);
|
||||
guint32 ip4_route_table, ip4_route_metric;
|
||||
|
||||
nm_modem_get_route_parameters (NM_MODEM (self),
|
||||
&ip4_route_table,
|
||||
&ip4_route_metric,
|
||||
NULL,
|
||||
NULL);
|
||||
{
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
|
||||
.gateway = gw,
|
||||
.table_coerced = nm_platform_route_table_coerce (ip4_route_table),
|
||||
.metric = ip4_route_metric,
|
||||
};
|
||||
|
||||
_LOGI (" gateway %s", gw_string);
|
||||
nm_ip4_config_add_route (config, &r, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* DNS servers */
|
||||
|
|
@ -1006,7 +1022,9 @@ stage3_ip6_done (NMModemBroadband *self)
|
|||
|
||||
address_string = mm_bearer_ip_config_get_gateway (self->_priv.ipv6_config);
|
||||
if (address_string) {
|
||||
if (!inet_pton (AF_INET6, address_string, (void *) &(address.address))) {
|
||||
guint32 ip6_route_table, ip6_route_metric;
|
||||
|
||||
if (inet_pton (AF_INET6, address_string, &address.address) != 1) {
|
||||
error = g_error_new (NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_INVALID_CONNECTION,
|
||||
"(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'",
|
||||
|
|
@ -1014,8 +1032,23 @@ stage3_ip6_done (NMModemBroadband *self)
|
|||
address_string);
|
||||
goto out;
|
||||
}
|
||||
_LOGI (" gateway %s", address_string);
|
||||
nm_ip6_config_set_gateway (config, &address.address);
|
||||
|
||||
nm_modem_get_route_parameters (NM_MODEM (self),
|
||||
NULL,
|
||||
NULL,
|
||||
&ip6_route_table,
|
||||
&ip6_route_metric);
|
||||
{
|
||||
const NMPlatformIP6Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
|
||||
.gateway = address.address,
|
||||
.table_coerced = nm_platform_route_table_coerce (ip6_route_table),
|
||||
.metric = ip6_route_metric,
|
||||
};
|
||||
|
||||
_LOGI (" gateway %s", address_string);
|
||||
nm_ip6_config_add_route (config, &r, NULL);
|
||||
}
|
||||
} else if (ip_method == NM_MODEM_IP_METHOD_STATIC) {
|
||||
/* Gateway required for the 'static' method */
|
||||
error = g_error_new (NM_DEVICE_ERROR,
|
||||
|
|
|
|||
|
|
@ -833,6 +833,7 @@ context_property_changed (GDBusProxy *proxy,
|
|||
const gchar *s, *addr_s;
|
||||
const gchar **array, **iter;
|
||||
guint32 address_network, gateway_network;
|
||||
guint32 ip4_route_table, ip4_route_metric;
|
||||
guint prefix = 0;
|
||||
|
||||
_LOGD ("PropertyChanged: %s", property);
|
||||
|
|
@ -938,16 +939,30 @@ context_property_changed (GDBusProxy *proxy,
|
|||
|
||||
nm_ip4_config_add_address (priv->ip4_config, &addr);
|
||||
|
||||
if (g_variant_lookup (v_dict, "Gateway", "&s", &s)) {
|
||||
if ( s
|
||||
&& nm_utils_parse_inaddr_bin (AF_INET, s, &gateway_network)) {
|
||||
_LOGI ("Gateway: %s", s);
|
||||
nm_ip4_config_set_gateway (priv->ip4_config, gateway_network);
|
||||
} else {
|
||||
if ( g_variant_lookup (v_dict, "Gateway", "&s", &s)
|
||||
&& s) {
|
||||
|
||||
if (!nm_utils_parse_inaddr_bin (AF_INET, s, &gateway_network)) {
|
||||
_LOGW ("invalid 'Gateway': %s", s);
|
||||
goto out;
|
||||
}
|
||||
nm_ip4_config_set_gateway (priv->ip4_config, gateway_network);
|
||||
|
||||
nm_modem_get_route_parameters (NM_MODEM (self),
|
||||
&ip4_route_table,
|
||||
&ip4_route_metric,
|
||||
NULL,
|
||||
NULL);
|
||||
{
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
|
||||
.gateway = gateway_network,
|
||||
.table_coerced = nm_platform_route_table_coerce (ip4_route_table),
|
||||
.metric = ip4_route_metric,
|
||||
};
|
||||
|
||||
_LOGI ("Gateway: %s", s);
|
||||
nm_ip4_config_add_route (priv->ip4_config, &r, NULL);
|
||||
}
|
||||
} else {
|
||||
_LOGW ("Settings 'Gateway' missing");
|
||||
goto out;
|
||||
|
|
@ -981,17 +996,23 @@ context_property_changed (GDBusProxy *proxy,
|
|||
_LOGI ("MessageProxy: %s", s);
|
||||
if ( s
|
||||
&& nm_utils_parse_inaddr_bin (AF_INET, s, &address_network)) {
|
||||
const NMPlatformIP4Route mms_route = {
|
||||
.network = address_network,
|
||||
.plen = 32,
|
||||
.gateway = gateway_network,
|
||||
.metric = 1,
|
||||
};
|
||||
nm_modem_get_route_parameters (NM_MODEM (self),
|
||||
&ip4_route_table,
|
||||
&ip4_route_metric,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* FIXME: does not handle ipv4.route-table setting and always adds the
|
||||
* route to RT_TABLE_MAIN table. */
|
||||
{
|
||||
const NMPlatformIP4Route mms_route = {
|
||||
.network = address_network,
|
||||
.plen = 32,
|
||||
.gateway = gateway_network,
|
||||
.table_coerced = nm_platform_route_table_coerce (ip4_route_table),
|
||||
.metric = ip4_route_metric,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (priv->ip4_config, &mms_route, NULL);
|
||||
nm_ip4_config_add_route (priv->ip4_config, &mms_route, NULL);
|
||||
}
|
||||
} else {
|
||||
_LOGW ("invalid MessageProxy: %s", s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "nm-core-internal.h"
|
||||
#include "platform/nm-platform.h"
|
||||
|
|
@ -97,6 +98,11 @@ typedef struct _NMModemPrivate {
|
|||
|
||||
guint32 mm_ip_timeout;
|
||||
|
||||
guint32 ip4_route_table;
|
||||
guint32 ip4_route_metric;
|
||||
guint32 ip6_route_table;
|
||||
guint32 ip6_route_metric;
|
||||
|
||||
/* PPP stats */
|
||||
guint32 in_bytes;
|
||||
guint32 out_bytes;
|
||||
|
|
@ -610,6 +616,14 @@ ppp_stage3_ip_config_start (NMModem *self,
|
|||
|
||||
priv->ppp_manager = nm_ppp_manager_create (priv->data_port, &error);
|
||||
|
||||
if (priv->ppp_manager) {
|
||||
nm_ppp_manager_set_route_parameters (priv->ppp_manager,
|
||||
priv->ip4_route_table,
|
||||
priv->ip4_route_metric,
|
||||
priv->ip6_route_table,
|
||||
priv->ip6_route_metric);
|
||||
}
|
||||
|
||||
if ( !priv->ppp_manager
|
||||
|| !nm_ppp_manager_start (priv->ppp_manager, req, ppp_name,
|
||||
ip_timeout, baud_override, &error)) {
|
||||
|
|
@ -706,6 +720,8 @@ nm_modem_ip4_pre_commit (NMModem *modem,
|
|||
{
|
||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (modem);
|
||||
|
||||
nm_modem_set_route_parameters_from_device (modem, device);
|
||||
|
||||
/* If the modem has an ethernet-type data interface (ie, not PPP and thus
|
||||
* not point-to-point) and IP config has a /32 prefix, then we assume that
|
||||
* ARP will be pointless and we turn it off.
|
||||
|
|
@ -1399,6 +1415,76 @@ nm_modem_get_iid (NMModem *self, NMUtilsIPv6IfaceId *out_iid)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_modem_get_route_parameters (NMModem *self,
|
||||
guint32 *out_ip4_route_table,
|
||||
guint32 *out_ip4_route_metric,
|
||||
guint32 *out_ip6_route_table,
|
||||
guint32 *out_ip6_route_metric)
|
||||
{
|
||||
NMModemPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_MODEM (self));
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
NM_SET_OUT (out_ip4_route_table, priv->ip4_route_table);
|
||||
NM_SET_OUT (out_ip4_route_metric, priv->ip4_route_metric);
|
||||
NM_SET_OUT (out_ip6_route_table, priv->ip6_route_table);
|
||||
NM_SET_OUT (out_ip6_route_metric, priv->ip6_route_metric);
|
||||
}
|
||||
|
||||
void
|
||||
nm_modem_set_route_parameters (NMModem *self,
|
||||
guint32 ip4_route_table,
|
||||
guint32 ip4_route_metric,
|
||||
guint32 ip6_route_table,
|
||||
guint32 ip6_route_metric)
|
||||
{
|
||||
NMModemPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_MODEM (self));
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
if ( priv->ip4_route_table != ip4_route_table
|
||||
|| priv->ip4_route_metric != ip4_route_metric
|
||||
|| priv->ip6_route_table != ip6_route_table
|
||||
|| priv->ip6_route_metric != ip6_route_metric) {
|
||||
priv->ip4_route_table = ip4_route_table;
|
||||
priv->ip4_route_metric = ip4_route_metric;
|
||||
priv->ip6_route_table = ip6_route_table;
|
||||
priv->ip6_route_metric = ip6_route_metric;
|
||||
|
||||
_LOGT ("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u",
|
||||
priv->ip4_route_table,
|
||||
priv->ip4_route_metric,
|
||||
priv->ip6_route_table,
|
||||
priv->ip6_route_metric);
|
||||
}
|
||||
|
||||
if (priv->ppp_manager) {
|
||||
nm_ppp_manager_set_route_parameters (priv->ppp_manager,
|
||||
priv->ip4_route_table,
|
||||
priv->ip4_route_metric,
|
||||
priv->ip6_route_table,
|
||||
priv->ip6_route_metric);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_modem_set_route_parameters_from_device (NMModem *self,
|
||||
NMDevice *device)
|
||||
{
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
|
||||
nm_modem_set_route_parameters (self,
|
||||
nm_device_get_route_table (device, AF_INET, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET),
|
||||
nm_device_get_route_table (device, AF_INET6, TRUE),
|
||||
nm_device_get_route_metric (device, AF_INET6));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_modem_get_capabilities (NMModem *self,
|
||||
NMDeviceModemCapabilities *modem_caps,
|
||||
|
|
@ -1533,7 +1619,15 @@ set_property (GObject *object, guint prop_id,
|
|||
static void
|
||||
nm_modem_init (NMModem *self)
|
||||
{
|
||||
NMModemPrivate *priv;
|
||||
|
||||
self->_priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_MODEM, NMModemPrivate);
|
||||
priv = self->_priv;
|
||||
|
||||
priv->ip4_route_table = RT_TABLE_MAIN;
|
||||
priv->ip4_route_metric = 700;
|
||||
priv->ip6_route_table = RT_TABLE_MAIN;
|
||||
priv->ip6_route_metric = 700;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -187,6 +187,21 @@ gboolean nm_modem_complete_connection (NMModem *self,
|
|||
const GSList *existing_connections,
|
||||
GError **error);
|
||||
|
||||
void nm_modem_get_route_parameters (NMModem *self,
|
||||
guint32 *out_ip4_route_table,
|
||||
guint32 *out_ip4_route_metric,
|
||||
guint32 *out_ip6_route_table,
|
||||
guint32 *out_ip6_route_metric);
|
||||
|
||||
void nm_modem_set_route_parameters (NMModem *self,
|
||||
guint32 ip4_route_table,
|
||||
guint32 ip4_route_metric,
|
||||
guint32 ip6_route_table,
|
||||
guint32 ip6_route_metric);
|
||||
|
||||
void nm_modem_set_route_parameters_from_device (NMModem *modem,
|
||||
NMDevice *device);
|
||||
|
||||
NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem,
|
||||
NMActRequest *req,
|
||||
NMDeviceStateReason *out_failure_reason);
|
||||
|
|
|
|||
|
|
@ -689,6 +689,8 @@ lease_validity_span (const char *str_expire, GDateTime *now)
|
|||
* @addr_family: whether to read IPv4 or IPv6 leases
|
||||
* @iface: the interface name to match leases with
|
||||
* @ifindex: interface index of @iface
|
||||
* @route_table: the route table for the default route.
|
||||
* @route_metric: the route metric for the default route.
|
||||
* @contents: the contents of a dhclient leasefile
|
||||
* @now: the current UTC date/time; pass %NULL to automatically use current
|
||||
* UTC time. Testcases may need a different value for 'now'
|
||||
|
|
@ -704,6 +706,8 @@ nm_dhcp_dhclient_read_lease_ip_configs (NMDedupMultiIndex *multi_idx,
|
|||
int addr_family,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
const char *contents,
|
||||
GDateTime *now)
|
||||
{
|
||||
|
|
@ -814,7 +818,17 @@ nm_dhcp_dhclient_read_lease_ip_configs (NMDedupMultiIndex *multi_idx,
|
|||
|
||||
ip4 = nm_ip4_config_new (multi_idx, ifindex);
|
||||
nm_ip4_config_add_address (ip4, &address);
|
||||
nm_ip4_config_set_gateway (ip4, gw);
|
||||
|
||||
{
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||
.gateway = gw,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (ip4, &r, NULL);
|
||||
}
|
||||
|
||||
value = g_hash_table_lookup (hash, "option domain-name-servers");
|
||||
if (value) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ GSList *nm_dhcp_dhclient_read_lease_ip_configs (struct _NMDedupMultiIndex *multi
|
|||
int addr_family,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
const char *contents,
|
||||
GDateTime *now);
|
||||
|
||||
|
|
|
|||
|
|
@ -167,9 +167,8 @@ nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx,
|
|||
guint32 route_table,
|
||||
guint32 route_metric)
|
||||
{
|
||||
char *contents = NULL;
|
||||
char *leasefile;
|
||||
GSList *leases = NULL;
|
||||
gs_free char *contents = NULL;
|
||||
gs_free char *leasefile = NULL;
|
||||
|
||||
leasefile = get_dhclient_leasefile (addr_family, iface, uuid, NULL);
|
||||
if (!leasefile)
|
||||
|
|
@ -178,13 +177,11 @@ nm_dhcp_dhclient_get_lease_ip_configs (NMDedupMultiIndex *multi_idx,
|
|||
if ( g_file_test (leasefile, G_FILE_TEST_EXISTS)
|
||||
&& g_file_get_contents (leasefile, &contents, NULL, NULL)
|
||||
&& contents
|
||||
&& contents[0])
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, addr_family, iface, ifindex, contents, NULL);
|
||||
|
||||
g_free (leasefile);
|
||||
g_free (contents);
|
||||
|
||||
return leases;
|
||||
&& contents[0]) {
|
||||
return nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, addr_family, iface, ifindex,
|
||||
route_table, route_metric, contents, NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
|
|||
gsize data_len;
|
||||
gboolean metered = FALSE;
|
||||
gboolean static_default_gateway = FALSE;
|
||||
gboolean gateway_has = FALSE;
|
||||
in_addr_t gateway = 0;
|
||||
|
||||
g_return_val_if_fail (lease != NULL, NULL);
|
||||
|
||||
|
|
@ -369,7 +371,8 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
|
|||
} else {
|
||||
if (!static_default_gateway) {
|
||||
static_default_gateway = TRUE;
|
||||
nm_ip4_config_set_gateway (ip4_config, route.gateway);
|
||||
gateway_has = TRUE;
|
||||
gateway = route.gateway;
|
||||
|
||||
s = nm_utils_inet4_ntop (route.gateway, NULL);
|
||||
LOG_LEASE (LOGD_DHCP4, "gateway %s", s);
|
||||
|
|
@ -390,13 +393,25 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
|
|||
if (!static_default_gateway) {
|
||||
r = sd_dhcp_lease_get_router (lease, &tmp_addr);
|
||||
if (r == 0) {
|
||||
nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr);
|
||||
gateway_has = TRUE;
|
||||
gateway = tmp_addr.s_addr;
|
||||
s = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL);
|
||||
LOG_LEASE (LOGD_DHCP4, "gateway %s", s);
|
||||
add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, s);
|
||||
}
|
||||
}
|
||||
|
||||
if (gateway_has) {
|
||||
const NMPlatformIP4Route rt = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||
.gateway = gateway,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (ip4_config, &rt, NULL);
|
||||
}
|
||||
|
||||
/* MTU */
|
||||
r = sd_dhcp_lease_get_mtu (lease, &mtu);
|
||||
if (r == 0 && mtu) {
|
||||
|
|
|
|||
|
|
@ -405,7 +405,8 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
|
|||
in_addr_t addr;
|
||||
NMPlatformIP4Address address;
|
||||
char *str = NULL;
|
||||
guint32 gwaddr = 0;
|
||||
gboolean gateway_has = FALSE;
|
||||
guint32 gateway = 0;
|
||||
guint8 plen = 0;
|
||||
|
||||
g_return_val_if_fail (options != NULL, NULL);
|
||||
|
|
@ -434,12 +435,12 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
|
|||
/* Routes: if the server returns classless static routes, we MUST ignore
|
||||
* the 'static_routes' option.
|
||||
*/
|
||||
if (!ip4_process_classless_routes (iface, options, route_table, route_metric, ip4_config, &gwaddr))
|
||||
if (!ip4_process_classless_routes (iface, options, route_table, route_metric, ip4_config, &gateway))
|
||||
process_classful_routes (iface, options, route_table, route_metric, ip4_config);
|
||||
|
||||
if (gwaddr) {
|
||||
_LOG2I (LOGD_DHCP4, iface, " gateway %s", nm_utils_inet4_ntop (gwaddr, NULL));
|
||||
nm_ip4_config_set_gateway (ip4_config, gwaddr);
|
||||
if (gateway) {
|
||||
_LOG2I (LOGD_DHCP4, iface, " gateway %s", nm_utils_inet4_ntop (gateway, NULL));
|
||||
gateway_has = TRUE;
|
||||
} else {
|
||||
/* If the gateway wasn't provided as a classless static route with a
|
||||
* subnet length of 0, try to find it using the old-style 'routers' option.
|
||||
|
|
@ -451,9 +452,9 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
|
|||
|
||||
for (s = routers; *s; s++) {
|
||||
/* FIXME: how to handle multiple routers? */
|
||||
if (inet_pton (AF_INET, *s, &gwaddr) > 0) {
|
||||
nm_ip4_config_set_gateway (ip4_config, gwaddr);
|
||||
if (inet_pton (AF_INET, *s, &gateway) > 0) {
|
||||
_LOG2I (LOGD_DHCP4, iface, " gateway %s", *s);
|
||||
gateway_has = TRUE;
|
||||
break;
|
||||
} else
|
||||
_LOG2W (LOGD_DHCP4, iface, "ignoring invalid gateway '%s'", *s);
|
||||
|
|
@ -462,6 +463,17 @@ nm_dhcp_utils_ip4_config_from_options (NMDedupMultiIndex *multi_idx,
|
|||
}
|
||||
}
|
||||
|
||||
if (gateway_has) {
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||
.gateway = gateway,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (ip4_config, &r, NULL);
|
||||
}
|
||||
|
||||
str = g_hash_table_lookup (options, "dhcp_lease_time");
|
||||
if (str) {
|
||||
address.lifetime = address.preferred = strtoul (str, NULL, 10);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "nm-utils/nm-dedup-multi.h"
|
||||
|
||||
|
|
@ -38,6 +39,8 @@
|
|||
#define DEBUG 1
|
||||
|
||||
static const int IFINDEX = 5;
|
||||
static const guint32 ROUTE_TABLE = RT_TABLE_MAIN;
|
||||
static const guint32 ROUTE_METRIC = 100;
|
||||
|
||||
static void
|
||||
test_config (const char *orig,
|
||||
|
|
@ -912,7 +915,7 @@ test_read_lease_ip4_config_basic (void)
|
|||
|
||||
/* Date from before the least expiration */
|
||||
now = g_date_time_new_utc (2013, 11, 1, 19, 55, 32);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, contents, now);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now);
|
||||
g_assert_cmpint (g_slist_length (leases), ==, 2);
|
||||
|
||||
/* IP4Config #1 */
|
||||
|
|
@ -929,7 +932,7 @@ test_read_lease_ip4_config_basic (void)
|
|||
|
||||
/* Gateway */
|
||||
expected_addr = nmtst_inet4_from_string ("192.168.1.1");
|
||||
g_assert_cmpint (nm_ip4_config_get_gateway (config), ==, expected_addr);
|
||||
g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr);
|
||||
|
||||
/* DNS */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 1);
|
||||
|
|
@ -952,7 +955,7 @@ test_read_lease_ip4_config_basic (void)
|
|||
|
||||
/* Gateway */
|
||||
expected_addr = nmtst_inet4_from_string ("10.77.52.254");
|
||||
g_assert_cmpint (nm_ip4_config_get_gateway (config), ==, expected_addr);
|
||||
g_assert_cmpint (nmtst_ip4_config_get_gateway (config), ==, expected_addr);
|
||||
|
||||
/* DNS */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_nameservers (config), ==, 2);
|
||||
|
|
@ -987,7 +990,7 @@ test_read_lease_ip4_config_expired (void)
|
|||
|
||||
/* Date from *after* the lease expiration */
|
||||
now = g_date_time_new_utc (2013, 12, 1, 19, 55, 32);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, contents, now);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now);
|
||||
g_assert (leases == NULL);
|
||||
|
||||
g_date_time_unref (now);
|
||||
|
|
@ -1010,7 +1013,7 @@ test_read_lease_ip4_config_expect_failure (gconstpointer user_data)
|
|||
|
||||
/* Date from before the least expiration */
|
||||
now = g_date_time_new_utc (2013, 11, 1, 1, 1, 1);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, contents, now);
|
||||
leases = nm_dhcp_dhclient_read_lease_ip_configs (multi_idx, AF_INET, "wlan0", IFINDEX, ROUTE_TABLE, ROUTE_METRIC, contents, now);
|
||||
g_assert (leases == NULL);
|
||||
|
||||
g_date_time_unref (now);
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ test_generic_options (void)
|
|||
|
||||
/* Gateway */
|
||||
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
|
||||
g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp);
|
||||
g_assert (nmtst_ip4_config_get_gateway (ip4_config) == tmp);
|
||||
|
||||
g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 0);
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ test_generic_options (void)
|
|||
g_assert (nm_ip4_config_get_nameserver (ip4_config, 1) == tmp);
|
||||
|
||||
/* Routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
|
||||
/* Route #1 */
|
||||
route = _nmtst_ip4_config_get_route (ip4_config, 0);
|
||||
|
|
@ -146,13 +146,17 @@ test_generic_options (void)
|
|||
|
||||
/* Route #2 */
|
||||
route = _nmtst_ip4_config_get_route (ip4_config, 1);
|
||||
g_assert (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0);
|
||||
g_assert (route->network == tmp);
|
||||
g_assert (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0);
|
||||
g_assert (route->gateway == tmp);
|
||||
g_assert (route->network == nmtst_inet4_from_string (expected_route2_dest));
|
||||
g_assert (route->gateway == nmtst_inet4_from_string (expected_route2_gw));
|
||||
g_assert_cmpint (route->plen, ==, 32);
|
||||
g_assert_cmpint (route->metric, ==, 0);
|
||||
|
||||
route = _nmtst_ip4_config_get_route (ip4_config, 2);
|
||||
g_assert (route->network == nmtst_inet4_from_string ("0.0.0.0"));
|
||||
g_assert (route->gateway == nmtst_inet4_from_string ("192.168.1.1"));
|
||||
g_assert_cmpint (route->plen, ==, 0);
|
||||
g_assert_cmpint (route->metric, ==, 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
|
|
@ -238,7 +242,7 @@ ip4_test_gateway (NMIP4Config *ip4_config, const char *expected_gw)
|
|||
|
||||
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
|
||||
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
|
||||
g_assert (nm_ip4_config_get_gateway (ip4_config) == tmp);
|
||||
g_assert (nmtst_ip4_config_get_gateway (ip4_config) == tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -261,9 +265,10 @@ test_classless_static_routes_1 (void)
|
|||
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -288,9 +293,10 @@ test_classless_static_routes_2 (void)
|
|||
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 8);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", expected_route1_gw, 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -316,9 +322,10 @@ test_fedora_dhclient_classless_static_routes (void)
|
|||
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 25);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 7);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", expected_route1_gw, 0);
|
||||
|
||||
/* Gateway */
|
||||
ip4_test_gateway (ip4_config, expected_gateway);
|
||||
|
|
@ -348,8 +355,9 @@ test_dhclient_invalid_classless_routes_1 (void)
|
|||
g_test_assert_expected_messages ();
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -380,9 +388,10 @@ test_dhcpcd_invalid_classless_routes_1 (void)
|
|||
/* Test falling back to old-style static routes if the classless static
|
||||
* routes are invalid.
|
||||
*/
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -412,9 +421,10 @@ test_dhclient_invalid_classless_routes_2 (void)
|
|||
/* Test falling back to old-style static routes if the classless static
|
||||
* routes are invalid.
|
||||
*/
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -446,9 +456,10 @@ test_dhcpcd_invalid_classless_routes_2 (void)
|
|||
*/
|
||||
|
||||
/* Routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 3);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route (ip4_config, 1, expected_route2_dest, expected_route2_gw, 32);
|
||||
ip4_test_route (ip4_config, 2, "0.0.0.0", "192.168.1.1", 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -474,8 +485,9 @@ test_dhclient_invalid_classless_routes_3 (void)
|
|||
g_test_assert_expected_messages ();
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -501,8 +513,9 @@ test_dhcpcd_invalid_classless_routes_3 (void)
|
|||
g_test_assert_expected_messages ();
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, "0.0.0.0", expected_route1_gw, 0);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -525,8 +538,9 @@ test_dhclient_gw_in_classless_routes (void)
|
|||
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, "0.0.0.0", "192.2.3.4", 0);
|
||||
|
||||
/* Gateway */
|
||||
ip4_test_gateway (ip4_config, expected_gateway);
|
||||
|
|
@ -552,8 +566,9 @@ test_dhcpcd_gw_in_classless_routes (void)
|
|||
ip4_config = _ip4_config_from_options (1, "eth0", options, 0);
|
||||
|
||||
/* IP4 routes */
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 1);
|
||||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
ip4_test_route (ip4_config, 0, expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route (ip4_config, 1, "0.0.0.0", "192.2.3.4", 0);
|
||||
|
||||
/* Gateway */
|
||||
ip4_test_gateway (ip4_config, expected_gateway);
|
||||
|
|
|
|||
|
|
@ -135,16 +135,6 @@ add_interface_configuration (NMDnsSystemdResolved *self,
|
|||
ic->configs = g_list_append (ic->configs, data->config);
|
||||
}
|
||||
|
||||
static void
|
||||
add_domain (GVariantBuilder *domains,
|
||||
const char *domain,
|
||||
gboolean never_default)
|
||||
{
|
||||
/* If this link is never the default (e.g. only used for resources on this
|
||||
* network) add a routing domain. */
|
||||
g_variant_builder_add (domains, "(sb)", domain, never_default);
|
||||
}
|
||||
|
||||
static void
|
||||
update_add_ip_config (NMDnsSystemdResolved *self,
|
||||
GVariantBuilder *dns,
|
||||
|
|
@ -154,7 +144,7 @@ update_add_ip_config (NMDnsSystemdResolved *self,
|
|||
int addr_family;
|
||||
gsize addr_size;
|
||||
guint i, n;
|
||||
gboolean never_default;
|
||||
gboolean route_only;
|
||||
|
||||
if (NM_IS_IP4_CONFIG (config))
|
||||
addr_family = AF_INET;
|
||||
|
|
@ -188,31 +178,33 @@ update_add_ip_config (NMDnsSystemdResolved *self,
|
|||
g_variant_builder_close (dns);
|
||||
}
|
||||
|
||||
never_default = addr_family == AF_INET
|
||||
? nm_ip4_config_get_never_default (config)
|
||||
: nm_ip6_config_get_never_default (config);
|
||||
/* If this link is never the default (e.g. only used for resources on this
|
||||
* network) add a routing domain. */
|
||||
route_only = addr_family == AF_INET
|
||||
? !nm_ip4_config_best_default_route_get (config)
|
||||
: !nm_ip6_config_best_default_route_get (config);
|
||||
|
||||
n = addr_family == AF_INET
|
||||
? nm_ip4_config_get_num_searches (config)
|
||||
: nm_ip6_config_get_num_searches (config);
|
||||
if (n > 0) {
|
||||
for (i = 0; i < n; i++) {
|
||||
add_domain (domains,
|
||||
addr_family == AF_INET
|
||||
? nm_ip4_config_get_search (config, i)
|
||||
: nm_ip6_config_get_search (config, i),
|
||||
never_default);
|
||||
g_variant_builder_add (domains, "(sb)",
|
||||
addr_family == AF_INET
|
||||
? nm_ip4_config_get_search (config, i)
|
||||
: nm_ip6_config_get_search (config, i),
|
||||
route_only);
|
||||
}
|
||||
} else {
|
||||
n = addr_family == AF_INET
|
||||
? nm_ip4_config_get_num_domains (config)
|
||||
: nm_ip6_config_get_num_domains (config);
|
||||
for (i = 0; i < n; i++) {
|
||||
add_domain (domains,
|
||||
addr_family == AF_INET
|
||||
? nm_ip4_config_get_domain (config, i)
|
||||
: nm_ip6_config_get_domain (config, i),
|
||||
never_default);
|
||||
g_variant_builder_add (domains, "(sb)",
|
||||
addr_family == AF_INET
|
||||
? nm_ip4_config_get_domain (config, i)
|
||||
: nm_ip6_config_get_domain (config, i),
|
||||
route_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ create_dm_cmd_line (const char *iface,
|
|||
nm_cmd_line_add_string (cmd, s->str);
|
||||
g_string_truncate (s, 0);
|
||||
|
||||
if (!nm_ip4_config_get_never_default (ip4_config)) {
|
||||
if (nm_ip4_config_best_default_route_get (ip4_config)) {
|
||||
g_string_append (s, "--dhcp-option=option:router,");
|
||||
g_string_append (s, localaddr);
|
||||
nm_cmd_line_add_string (cmd, s->str);
|
||||
|
|
|
|||
|
|
@ -62,12 +62,13 @@ typedef enum {
|
|||
NM_NDISC_PREFERENCE_HIGH
|
||||
} NMNDiscPreference;
|
||||
|
||||
typedef struct {
|
||||
struct _NMNDiscGateway {
|
||||
struct in6_addr address;
|
||||
guint32 timestamp;
|
||||
guint32 lifetime;
|
||||
NMNDiscPreference preference;
|
||||
} NMNDiscGateway;
|
||||
};
|
||||
typedef struct _NMNDiscGateway NMNDiscGateway;
|
||||
|
||||
struct _NMNDiscAddress {
|
||||
struct in6_addr address;
|
||||
|
|
|
|||
|
|
@ -169,6 +169,15 @@ nm_utils_ip_route_metric_normalize (int addr_family, guint32 metric)
|
|||
return addr_family == AF_INET6 ? nm_utils_ip6_route_metric_normalize (metric) : metric;
|
||||
}
|
||||
|
||||
static inline guint32
|
||||
nm_utils_ip_route_metric_penalize (int addr_family, guint32 metric, guint32 penalty)
|
||||
{
|
||||
metric = nm_utils_ip_route_metric_normalize (addr_family, metric);
|
||||
if (metric < G_MAXUINT32 - penalty)
|
||||
return metric + penalty;
|
||||
return G_MAXUINT32;
|
||||
}
|
||||
|
||||
int nm_utils_modprobe (GError **error, gboolean suppress_error_loggin, const char *arg1, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
guint64 nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid);
|
||||
|
|
|
|||
|
|
@ -124,9 +124,14 @@ dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
|
|||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
|
||||
first = TRUE;
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, ip4, &addr) {
|
||||
const NMPObject *default_route;
|
||||
|
||||
array[0] = addr->address;
|
||||
array[1] = addr->plen;
|
||||
array[2] = first ? nm_ip4_config_get_gateway (ip4) : 0;
|
||||
array[2] = ( first
|
||||
&& (default_route = nm_ip4_config_best_default_route_get (ip4)))
|
||||
? NMP_OBJECT_CAST_IP4_ROUTE (default_route)->gateway
|
||||
: (guint32) 0;
|
||||
g_variant_builder_add (&int_builder, "@au",
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
|
||||
array, 3, sizeof (guint32)));
|
||||
|
|
@ -197,12 +202,15 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
|
|||
|
||||
first = TRUE;
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, ip6, &addr) {
|
||||
const NMPObject *default_route;
|
||||
|
||||
ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
&addr->address,
|
||||
sizeof (struct in6_addr), 1);
|
||||
gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
first
|
||||
? (nm_ip6_config_get_gateway (ip6) ?: &in6addr_any)
|
||||
( first
|
||||
&& (default_route = nm_ip6_config_best_default_route_get (ip6)))
|
||||
? &NMP_OBJECT_CAST_IP6_ROUTE (default_route)->gateway
|
||||
: &in6addr_any,
|
||||
sizeof (struct in6_addr), 1);
|
||||
g_variant_builder_add (&int_builder, "(@ayu@ay)", ip, addr->plen, gw);
|
||||
|
|
|
|||
|
|
@ -122,13 +122,13 @@ dhcp4_state_changed (NMDhcpClient *client,
|
|||
existing = nm_ip4_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET),
|
||||
NM_PLATFORM_GET, gl.ifindex, FALSE);
|
||||
if (last_config)
|
||||
nm_ip4_config_subtract (existing, last_config);
|
||||
nm_ip4_config_subtract (existing, last_config, 0);
|
||||
|
||||
nm_ip4_config_merge (existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip4_config_add_device_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v4,
|
||||
&ip4_dev_route_blacklist);
|
||||
nm_ip4_config_merge (existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
nm_ip4_config_add_dependent_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v4,
|
||||
&ip4_dev_route_blacklist);
|
||||
if (!nm_ip4_config_commit (existing,
|
||||
NM_PLATFORM_GET,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN))
|
||||
|
|
@ -168,20 +168,12 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
existing = nm_ip6_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET),
|
||||
NM_PLATFORM_GET, gl.ifindex, FALSE, global_opt.tempaddr);
|
||||
if (ndisc_config)
|
||||
nm_ip6_config_subtract (existing, ndisc_config);
|
||||
nm_ip6_config_subtract (existing, ndisc_config, 0);
|
||||
else {
|
||||
ndisc_config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
|
||||
gl.ifindex);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_GATEWAYS) {
|
||||
/* Use the first gateway as ordered in neighbor discovery cache. */
|
||||
if (rdata->gateways_n)
|
||||
nm_ip6_config_set_gateway (ndisc_config, &rdata->gateways[0].address);
|
||||
else
|
||||
nm_ip6_config_set_gateway (ndisc_config, NULL);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ADDRESSES) {
|
||||
guint8 plen;
|
||||
guint32 ifa_flags;
|
||||
|
|
@ -207,8 +199,11 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
ifa_flags);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ROUTES) {
|
||||
if (NM_FLAGS_ANY (changed, NM_NDISC_CONFIG_ROUTES
|
||||
| NM_NDISC_CONFIG_GATEWAYS)) {
|
||||
nm_ip6_config_reset_routes_ndisc (ndisc_config,
|
||||
rdata->gateways,
|
||||
rdata->gateways_n,
|
||||
rdata->routes,
|
||||
rdata->routes_n,
|
||||
RT_TABLE_MAIN,
|
||||
|
|
@ -229,10 +224,10 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "mtu")), val);
|
||||
}
|
||||
|
||||
nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip6_config_add_device_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v6);
|
||||
nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
nm_ip6_config_add_dependent_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v6);
|
||||
if (!nm_ip6_config_commit (existing,
|
||||
NM_PLATFORM_GET,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
|
|
|
|||
|
|
@ -287,10 +287,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config,
|
|||
);
|
||||
|
||||
typedef struct {
|
||||
bool never_default:1;
|
||||
bool metered:1;
|
||||
bool has_gateway:1;
|
||||
guint32 gateway;
|
||||
guint32 mtu;
|
||||
int ifindex;
|
||||
NMIPConfigSource mtu_source;
|
||||
|
|
@ -489,6 +486,19 @@ _nm_ip4_config_best_default_route_find (const NMIP4Config *self)
|
|||
return new_best_default_route;
|
||||
}
|
||||
|
||||
in_addr_t
|
||||
nmtst_ip4_config_get_gateway (NMIP4Config *config)
|
||||
{
|
||||
const NMPObject *rt;
|
||||
|
||||
g_assert (NM_IS_IP4_CONFIG (config));
|
||||
|
||||
rt = nm_ip4_config_best_default_route_get (config);
|
||||
if (!rt)
|
||||
return 0;
|
||||
return NMP_OBJECT_CAST_IP4_ROUTE (rt)->gateway;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -575,9 +585,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
{
|
||||
NMIP4Config *self;
|
||||
NMIP4ConfigPrivate *priv;
|
||||
guint32 lowest_metric;
|
||||
guint32 old_gateway = 0;
|
||||
gboolean old_has_gateway = FALSE;
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
NMDedupMultiIter iter;
|
||||
const NMPObject *plobj = NULL;
|
||||
|
|
@ -614,6 +621,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
sort_captured_addresses,
|
||||
NULL);
|
||||
has_addresses = TRUE;
|
||||
_notify_addresses (self);
|
||||
}
|
||||
|
||||
head_entry = nm_platform_lookup_addrroute (platform,
|
||||
|
|
@ -621,31 +629,15 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
ifindex);
|
||||
|
||||
/* Extract gateway from default route */
|
||||
old_gateway = priv->gateway;
|
||||
old_has_gateway = priv->has_gateway;
|
||||
|
||||
lowest_metric = G_MAXUINT32;
|
||||
priv->has_gateway = FALSE;
|
||||
nmp_cache_iter_for_each (&iter, head_entry, &plobj) {
|
||||
const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (plobj);
|
||||
|
||||
if ( !route->table_coerced
|
||||
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)
|
||||
&& route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) {
|
||||
if (route->metric < lowest_metric) {
|
||||
priv->gateway = route->gateway;
|
||||
lowest_metric = route->metric;
|
||||
}
|
||||
priv->has_gateway = TRUE;
|
||||
}
|
||||
|
||||
nmp_cache_iter_for_each (&iter, head_entry, &plobj)
|
||||
_add_route (self, plobj, NULL, NULL);
|
||||
}
|
||||
|
||||
/* If the interface has the default route, and has IPv4 addresses, capture
|
||||
* nameservers from /etc/resolv.conf.
|
||||
*/
|
||||
if (has_addresses && priv->has_gateway && capture_resolv_conf) {
|
||||
if ( has_addresses
|
||||
&& priv->best_default_route
|
||||
&& capture_resolv_conf) {
|
||||
gs_free char *rc_contents = NULL;
|
||||
|
||||
if (g_file_get_contents (_PATH_RESCONF, &rc_contents, NULL, NULL)) {
|
||||
|
|
@ -657,25 +649,19 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
}
|
||||
}
|
||||
|
||||
/* actually, nobody should be connected to the signal, just to be sure, notify */
|
||||
_notify_addresses (self);
|
||||
_notify_routes (self);
|
||||
if ( priv->gateway != old_gateway
|
||||
|| priv->has_gateway != old_has_gateway)
|
||||
_notify (self, PROP_GATEWAY);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_add_device_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist)
|
||||
nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv;
|
||||
GPtrArray *ip4_dev_route_blacklist = NULL;
|
||||
const NMPlatformIP4Address *addr;
|
||||
const NMPlatformIP4Address *my_addr;
|
||||
const NMPlatformIP4Route *my_route;
|
||||
int ifindex;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
|
|
@ -689,18 +675,18 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
|
|||
/* For IPv6 slaac, we explicitly add the device-routes (onlink) to NMIP6Config.
|
||||
* As we don't do that for IPv4 (and manual IPv6 addresses), add them explicitly. */
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&iter, self, &addr) {
|
||||
nm_ip_config_iter_ip4_address_for_each (&iter, self, &my_addr) {
|
||||
nm_auto_nmpobj NMPObject *r = NULL;
|
||||
NMPlatformIP4Route *route;
|
||||
in_addr_t network;
|
||||
|
||||
if (addr->plen == 0)
|
||||
if (my_addr->plen == 0)
|
||||
continue;
|
||||
|
||||
nm_assert (addr->plen <= 32);
|
||||
nm_assert (my_addr->plen <= 32);
|
||||
|
||||
/* The destination network depends on the peer-address. */
|
||||
network = nm_utils_ip4_address_clear_host_address (addr->peer_address, addr->plen);
|
||||
network = nm_utils_ip4_address_clear_host_address (my_addr->peer_address, my_addr->plen);
|
||||
|
||||
if (_ipv4_is_zeronet (network)) {
|
||||
/* Kernel doesn't add device-routes for destinations that
|
||||
|
|
@ -714,8 +700,8 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
|
|||
route->ifindex = ifindex;
|
||||
route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
|
||||
route->network = network;
|
||||
route->plen = addr->plen;
|
||||
route->pref_src = addr->address;
|
||||
route->plen = my_addr->plen;
|
||||
route->pref_src = my_addr->address;
|
||||
route->table_coerced = nm_platform_route_table_coerce (route_table);
|
||||
route->metric = route_metric;
|
||||
route->scope_inv = nm_platform_route_scope_inv (NM_RT_SCOPE_LINK);
|
||||
|
|
@ -755,6 +741,27 @@ nm_ip4_config_add_device_routes (NMIP4Config *self,
|
|||
}
|
||||
}
|
||||
|
||||
again:
|
||||
nm_ip_config_iter_ip4_route_for_each (&iter, self, &my_route) {
|
||||
NMPlatformIP4Route rt;
|
||||
|
||||
if ( !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (my_route)
|
||||
|| my_route->gateway == 0
|
||||
|| NM_IS_IP_CONFIG_SOURCE_RTPROT (my_route->rt_source)
|
||||
|| nm_ip4_config_get_direct_route_for_host (self,
|
||||
my_route->gateway,
|
||||
nm_platform_route_table_uncoerce (my_route->table_coerced, TRUE)))
|
||||
continue;
|
||||
|
||||
rt = *my_route;
|
||||
rt.network = my_route->gateway;
|
||||
rt.plen = 32;
|
||||
rt.gateway = 0;
|
||||
_add_route (self, NULL, &rt, NULL);
|
||||
/* adding the route might have invalidated the iteration. Start again. */
|
||||
goto again;
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_ip4_dev_route_blacklist, ip4_dev_route_blacklist);
|
||||
}
|
||||
|
||||
|
|
@ -848,6 +855,8 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
|
|||
NMIP4ConfigPrivate *priv;
|
||||
guint naddresses, nroutes, nnameservers, nsearches;
|
||||
int i, priority;
|
||||
const char *gateway_str;
|
||||
guint32 gateway_bin;
|
||||
|
||||
if (!setting)
|
||||
return;
|
||||
|
|
@ -864,15 +873,18 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
|
|||
nsearches = nm_setting_ip_config_get_num_dns_searches (setting);
|
||||
|
||||
/* Gateway */
|
||||
if (nm_setting_ip_config_get_never_default (setting))
|
||||
nm_ip4_config_set_never_default (self, TRUE);
|
||||
else if (nm_setting_ip_config_get_ignore_auto_routes (setting))
|
||||
nm_ip4_config_set_never_default (self, FALSE);
|
||||
if (nm_setting_ip_config_get_gateway (setting)) {
|
||||
guint32 gateway;
|
||||
if ( !nm_setting_ip_config_get_never_default (setting)
|
||||
&& (gateway_str = nm_setting_ip_config_get_gateway (setting))
|
||||
&& inet_pton (AF_INET, gateway_str, &gateway_bin) == 1
|
||||
&& gateway_bin) {
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
||||
.gateway = gateway_bin,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
inet_pton (AF_INET, nm_setting_ip_config_get_gateway (setting), &gateway);
|
||||
nm_ip4_config_set_gateway (self, gateway);
|
||||
_add_route (self, NULL, &r, NULL);
|
||||
}
|
||||
|
||||
/* Addresses */
|
||||
|
|
@ -961,8 +973,8 @@ nm_ip4_config_merge_setting (NMIP4Config *self,
|
|||
NMSetting *
|
||||
nm_ip4_config_create_setting (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv;
|
||||
NMSettingIPConfig *s_ip4;
|
||||
guint32 gateway;
|
||||
guint nnameservers, nsearches, noptions;
|
||||
const char *method = NULL;
|
||||
int i;
|
||||
|
|
@ -979,7 +991,8 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
|
|||
return NM_SETTING (s_ip4);
|
||||
}
|
||||
|
||||
gateway = nm_ip4_config_get_gateway (self);
|
||||
priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nnameservers = nm_ip4_config_get_num_nameservers (self);
|
||||
nsearches = nm_ip4_config_get_num_searches (self);
|
||||
noptions = nm_ip4_config_get_num_dns_options (self);
|
||||
|
|
@ -1007,10 +1020,12 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
|
|||
}
|
||||
|
||||
/* Gateway */
|
||||
if ( nm_ip4_config_has_gateway (self)
|
||||
if ( priv->best_default_route
|
||||
&& nm_setting_ip_config_get_num_addresses (s_ip4) > 0) {
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet4_ntop (gateway, NULL),
|
||||
NM_SETTING_IP_CONFIG_GATEWAY,
|
||||
nm_utils_inet4_ntop (NMP_OBJECT_CAST_IP4_ROUTE (priv->best_default_route)->gateway,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1070,7 +1085,10 @@ nm_ip4_config_create_setting (const NMIP4Config *self)
|
|||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFlags merge_flags)
|
||||
nm_ip4_config_merge (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
NMIPConfigMergeFlags merge_flags,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP4ConfigPrivate *dst_priv;
|
||||
const NMIP4ConfigPrivate *src_priv;
|
||||
|
|
@ -1096,14 +1114,24 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
|
|||
nm_ip4_config_add_nameserver (dst, nm_ip4_config_get_nameserver (src, i));
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
if (nm_ip4_config_has_gateway (src))
|
||||
nm_ip4_config_set_gateway (dst, nm_ip4_config_get_gateway (src));
|
||||
|
||||
/* routes */
|
||||
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, NULL)
|
||||
const NMPlatformIP4Route *r_src;
|
||||
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r_src) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r_src)) {
|
||||
if (NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES))
|
||||
continue;
|
||||
if (default_route_metric_penalty) {
|
||||
NMPlatformIP4Route r = *r_src;
|
||||
|
||||
r.metric = nm_utils_ip_route_metric_penalize (AF_INET, r.metric, default_route_metric_penalty);
|
||||
_add_route (dst, NULL, &r, NULL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* domains */
|
||||
|
|
@ -1255,11 +1283,17 @@ _wins_get_index (const NMIP4Config *self, guint32 wins_server)
|
|||
* nm_ip4_config_subtract:
|
||||
* @dst: config from which to remove everything in @src
|
||||
* @src: config to remove from @dst
|
||||
* @default_route_metric_penalty: pretend that on source we applied
|
||||
* a route penalty on the default-route. It means, for default routes
|
||||
* we don't remove routes that match exactly, but those with a lower
|
||||
* metric (with the penalty removed).
|
||||
*
|
||||
* Removes everything in @src from @dst.
|
||||
*/
|
||||
void
|
||||
nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
||||
nm_ip4_config_subtract (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP4ConfigPrivate *dst_priv;
|
||||
guint i;
|
||||
|
|
@ -1296,23 +1330,31 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
nm_ip4_config_del_nameserver (dst, idx);
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
if ( (nm_ip4_config_has_gateway (src) == nm_ip4_config_has_gateway (dst))
|
||||
&& (nm_ip4_config_get_gateway (src) == nm_ip4_config_get_gateway (dst)))
|
||||
nm_ip4_config_unset_gateway (dst);
|
||||
|
||||
if (!nm_ip4_config_get_num_addresses (dst))
|
||||
nm_ip4_config_unset_gateway (dst);
|
||||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
changed_default_route = FALSE;
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
|
||||
const NMPObject *o_src = NMP_OBJECT_UP_CAST (r);
|
||||
NMPObject o_lookup_copy;
|
||||
const NMPObject *o_lookup;
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
|
||||
if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)
|
||||
&& default_route_metric_penalty) {
|
||||
NMPlatformIP4Route *rr;
|
||||
|
||||
/* the default route was penalized when merging it to the combined ip-config.
|
||||
* When subtracting the routes, we must re-do that process when comparing
|
||||
* the routes. */
|
||||
o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_src);
|
||||
rr = NMP_OBJECT_CAST_IP4_ROUTE (&o_lookup_copy);
|
||||
rr->metric = nm_utils_ip_route_metric_penalize (AF_INET, rr->metric, default_route_metric_penalty);
|
||||
} else
|
||||
o_lookup = o_src;
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
o_lookup,
|
||||
(gconstpointer *) &obj_old)) {
|
||||
if (dst_priv->best_default_route == obj_old) {
|
||||
nm_clear_nmp_object (&dst_priv->best_default_route);
|
||||
|
|
@ -1324,6 +1366,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
if (changed_default_route) {
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
|
||||
_nm_ip4_config_best_default_route_find (dst));
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
|
@ -1379,7 +1422,9 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
||||
nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP4ConfigPrivate *dst_priv;
|
||||
const NMIP4ConfigPrivate *src_priv;
|
||||
|
|
@ -1415,23 +1460,31 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
|||
|
||||
/* ignore nameservers */
|
||||
|
||||
/* default gateway */
|
||||
if ( !nm_ip4_config_get_num_addresses (dst)
|
||||
|| (nm_ip4_config_has_gateway (src) != nm_ip4_config_has_gateway (dst))
|
||||
|| (nm_ip4_config_get_gateway (src) != nm_ip4_config_get_gateway (dst))) {
|
||||
nm_ip4_config_unset_gateway (dst);
|
||||
}
|
||||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
new_best_default_route = NULL;
|
||||
nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
|
||||
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
|
||||
const NMPObject *o_dst = NMP_OBJECT_UP_CAST (r);
|
||||
const NMPObject *o_lookup;
|
||||
NMPObject o_lookup_copy;
|
||||
|
||||
if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)
|
||||
&& default_route_metric_penalty) {
|
||||
NMPlatformIP4Route *rr;
|
||||
|
||||
/* the default route was penalized when merging it to the combined ip-config.
|
||||
* When intersecting the routes, we must re-do that process when comparing
|
||||
* the routes. */
|
||||
o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_dst);
|
||||
rr = NMP_OBJECT_CAST_IP4_ROUTE (&o_lookup_copy);
|
||||
rr->metric = nm_utils_ip_route_metric_penalize (AF_INET, rr->metric, default_route_metric_penalty);
|
||||
} else
|
||||
o_lookup = o_dst;
|
||||
|
||||
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
|
||||
&src_priv->idx_ip4_routes,
|
||||
o)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
|
||||
o_lookup)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o_dst);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1440,8 +1493,10 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
|||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route)) {
|
||||
nm_assert (changed);
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
||||
|
|
@ -1502,22 +1557,6 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
has_minor_changes = TRUE;
|
||||
}
|
||||
|
||||
/* never_default */
|
||||
if (src_priv->never_default != dst_priv->never_default) {
|
||||
dst_priv->never_default = src_priv->never_default;
|
||||
has_minor_changes = TRUE;
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
if ( src_priv->gateway != dst_priv->gateway
|
||||
|| src_priv->has_gateway != dst_priv->has_gateway) {
|
||||
if (src_priv->has_gateway)
|
||||
nm_ip4_config_set_gateway (dst, src_priv->gateway);
|
||||
else
|
||||
nm_ip4_config_unset_gateway (dst);
|
||||
has_relevant_changes = TRUE;
|
||||
}
|
||||
|
||||
/* addresses */
|
||||
head_entry_src = nm_ip4_config_lookup_addresses (src);
|
||||
nm_dedup_multi_iter_init (&ipconf_iter_src, head_entry_src);
|
||||
|
|
@ -1615,7 +1654,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE);
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
_notify_routes (dst);
|
||||
}
|
||||
|
||||
|
|
@ -1794,12 +1834,6 @@ nm_ip4_config_dump (const NMIP4Config *self, const char *detail)
|
|||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address)
|
||||
g_message (" a: %s", nm_platform_ip4_address_to_string (address, NULL, 0));
|
||||
|
||||
/* default gateway */
|
||||
if (nm_ip4_config_has_gateway (self)) {
|
||||
tmp = nm_ip4_config_get_gateway (self);
|
||||
g_message (" gw: %s", nm_utils_inet4_ntop (tmp, NULL));
|
||||
}
|
||||
|
||||
/* nameservers */
|
||||
for (i = 0; i < nm_ip4_config_get_num_nameservers (self); i++) {
|
||||
tmp = nm_ip4_config_get_nameserver (self, i);
|
||||
|
|
@ -1840,102 +1874,9 @@ nm_ip4_config_dump (const NMIP4Config *self, const char *detail)
|
|||
g_message (" wins: %s", nm_utils_inet4_ntop (tmp, NULL));
|
||||
}
|
||||
|
||||
g_message (" n-dflt: %d", nm_ip4_config_get_never_default (self));
|
||||
g_message (" mtrd: %d", (int) nm_ip4_config_get_metered (self));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip4_config_destination_is_direct (const NMIP4Config *self, guint32 network, guint8 plen)
|
||||
{
|
||||
const NMPlatformIP4Address *item;
|
||||
in_addr_t peer_network;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&iter, self, &item) {
|
||||
if (item->plen > plen)
|
||||
continue;
|
||||
|
||||
peer_network = nm_utils_ip4_address_clear_host_address (item->peer_address, item->plen);
|
||||
if (_ipv4_is_zeronet (peer_network))
|
||||
continue;
|
||||
|
||||
if (peer_network != nm_utils_ip4_address_clear_host_address (network, item->plen))
|
||||
continue;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip4_config_set_never_default (NMIP4Config *self, gboolean never_default)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
priv->never_default = never_default;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip4_config_get_never_default (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return priv->never_default;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_set_gateway (NMIP4Config *self, guint32 gateway)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
if (priv->gateway != gateway || !priv->has_gateway) {
|
||||
priv->gateway = gateway;
|
||||
priv->has_gateway = TRUE;
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_unset_gateway (NMIP4Config *self)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
if (priv->has_gateway) {
|
||||
priv->gateway = 0;
|
||||
priv->has_gateway = FALSE;
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_ip4_config_has_gateway:
|
||||
* @self: the #NMIP4Config object
|
||||
*
|
||||
* NetworkManager's handling of default-routes is limited and usually a default-route
|
||||
* cannot have gateway 0.0.0.0. For peer-to-peer routes, we still want to
|
||||
* support that, so we need to differenciate between no-default-route and a
|
||||
* on-link-default route. Hence nm_ip4_config_has_gateway().
|
||||
*
|
||||
* Returns: whether the object has a gateway explicitly set. */
|
||||
gboolean
|
||||
nm_ip4_config_has_gateway (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return priv->has_gateway;
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_ip4_config_get_gateway (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return priv->gateway;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
|
|
@ -2077,7 +2018,8 @@ nm_ip4_config_reset_routes (NMIP4Config *self)
|
|||
|
||||
if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
|
||||
&priv->idx_ip4_routes) > 0) {
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
if (nm_clear_nmp_object (&priv->best_default_route))
|
||||
_notify (self, PROP_GATEWAY);
|
||||
_notify_routes (self);
|
||||
}
|
||||
}
|
||||
|
|
@ -2105,11 +2047,19 @@ _add_route (NMIP4Config *self,
|
|||
FALSE,
|
||||
&obj_old,
|
||||
&obj_new_2)) {
|
||||
gboolean changed_default_route = FALSE;
|
||||
|
||||
if ( priv->best_default_route == obj_old
|
||||
&& obj_old != obj_new_2)
|
||||
&& obj_old != obj_new_2) {
|
||||
changed_default_route = TRUE;
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
|
||||
}
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
if (_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2))
|
||||
changed_default_route = TRUE;
|
||||
|
||||
if (changed_default_route)
|
||||
_notify (self, PROP_GATEWAY);
|
||||
_notify_routes (self);
|
||||
} else
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
|
|
@ -2178,7 +2128,9 @@ _nmtst_ip4_config_get_route (const NMIP4Config *self, guint i)
|
|||
}
|
||||
|
||||
const NMPlatformIP4Route *
|
||||
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host)
|
||||
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self,
|
||||
in_addr_t host,
|
||||
guint32 route_table)
|
||||
{
|
||||
const NMPlatformIP4Route *best_route = NULL;
|
||||
const NMPlatformIP4Route *item;
|
||||
|
|
@ -2193,6 +2145,9 @@ nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host)
|
|||
if (best_route && best_route->plen > item->plen)
|
||||
continue;
|
||||
|
||||
if (nm_platform_route_table_uncoerce (item->table_coerced, TRUE) != route_table)
|
||||
continue;
|
||||
|
||||
if (nm_utils_ip4_address_clear_host_address (host, item->plen) != nm_utils_ip4_address_clear_host_address (item->network, item->plen))
|
||||
continue;
|
||||
|
||||
|
|
@ -2704,8 +2659,9 @@ nm_ip4_config_nmpobj_remove (NMIP4Config *self,
|
|||
break;
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
if (priv->best_default_route == obj_old) {
|
||||
_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip4_config_best_default_route_find (self));
|
||||
if (_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip4_config_best_default_route_find (self)))
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
_notify_routes (self);
|
||||
break;
|
||||
|
|
@ -2736,9 +2692,6 @@ nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only)
|
|||
g_return_if_fail (sum);
|
||||
|
||||
if (!dns_only) {
|
||||
hash_u32 (sum, nm_ip4_config_has_gateway (self));
|
||||
hash_u32 (sum, nm_ip4_config_get_gateway (self));
|
||||
|
||||
nm_ip_config_iter_ip4_address_for_each (&ipconf_iter, self, &address) {
|
||||
hash_u32 (sum, address->address);
|
||||
hash_u32 (sum, address->plen);
|
||||
|
|
@ -2893,7 +2846,10 @@ get_property (GObject *object, guint prop_id,
|
|||
const guint32 dbus_addr[3] = {
|
||||
address->address,
|
||||
address->plen,
|
||||
i == 0 ? priv->gateway : 0,
|
||||
( i == 0
|
||||
&& priv->best_default_route)
|
||||
? NMP_OBJECT_CAST_IP4_ROUTE (priv->best_default_route)->gateway
|
||||
: (guint32) 0,
|
||||
};
|
||||
|
||||
g_variant_builder_add (&builder_legacy, "@au",
|
||||
|
|
@ -2978,9 +2934,11 @@ out_routes_cached:
|
|||
priv->routes_variant);
|
||||
break;
|
||||
case PROP_GATEWAY:
|
||||
if (priv->has_gateway)
|
||||
g_value_set_string (value, nm_utils_inet4_ntop (priv->gateway, NULL));
|
||||
else
|
||||
if (priv->best_default_route) {
|
||||
g_value_set_string (value,
|
||||
nm_utils_inet4_ntop (NMP_OBJECT_CAST_IP4_ROUTE (priv->best_default_route)->gateway,
|
||||
NULL));
|
||||
} else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
case PROP_NAMESERVERS:
|
||||
|
|
|
|||
|
|
@ -80,12 +80,16 @@ nm_ip_config_best_default_route_is (const NMPObject *obj)
|
|||
{
|
||||
const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE (obj);
|
||||
|
||||
/* return whether @obj is considered a default-route, that is, a route
|
||||
* as added by NetworkManager. E.g. if the route is not in the main-table,
|
||||
* it's considered just like a regular route. */
|
||||
/* return whether @obj is considered a default-route.
|
||||
*
|
||||
* NMIP4Config/NMIP6Config tracks the (best) default-route explicitly, because
|
||||
* at various places we act differently depending on whether there is a default-route
|
||||
* configured.
|
||||
*
|
||||
* Note that this only considers the main routing table. */
|
||||
return r
|
||||
&& !r->table_coerced
|
||||
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r);
|
||||
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)
|
||||
&& nm_platform_route_table_is_main (r->table_coerced);
|
||||
}
|
||||
|
||||
const NMPObject *_nm_ip_config_best_default_route_find_better (const NMPObject *obj_cur, const NMPObject *obj_cmp);
|
||||
|
|
@ -151,10 +155,10 @@ NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
|
|||
|
||||
NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
|
||||
|
||||
void nm_ip4_config_add_device_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist);
|
||||
void nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist);
|
||||
|
||||
gboolean nm_ip4_config_commit (const NMIP4Config *self,
|
||||
NMPlatform *platform,
|
||||
|
|
@ -167,24 +171,24 @@ void nm_ip4_config_merge_setting (NMIP4Config *self,
|
|||
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *self);
|
||||
|
||||
|
||||
void nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFlags merge_flags);
|
||||
void nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src);
|
||||
void nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src);
|
||||
void nm_ip4_config_merge (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
NMIPConfigMergeFlags merge_flags,
|
||||
guint32 default_route_metric_penalty);
|
||||
void nm_ip4_config_subtract (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty);
|
||||
void nm_ip4_config_intersect (NMIP4Config *dst,
|
||||
const NMIP4Config *src,
|
||||
guint32 default_route_metric_penalty);
|
||||
gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relevant_changes);
|
||||
gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *self, guint32 dest, guint8 plen);
|
||||
void nm_ip4_config_dump (const NMIP4Config *self, const char *detail);
|
||||
|
||||
|
||||
void nm_ip4_config_set_never_default (NMIP4Config *self, gboolean never_default);
|
||||
gboolean nm_ip4_config_get_never_default (const NMIP4Config *self);
|
||||
void nm_ip4_config_set_gateway (NMIP4Config *self, guint32 gateway);
|
||||
void nm_ip4_config_unset_gateway (NMIP4Config *self);
|
||||
gboolean nm_ip4_config_has_gateway (const NMIP4Config *self);
|
||||
guint32 nm_ip4_config_get_gateway (const NMIP4Config *self);
|
||||
|
||||
const NMPObject *nm_ip4_config_best_default_route_get (const NMIP4Config *self);
|
||||
const NMPObject *_nm_ip4_config_best_default_route_find (const NMIP4Config *self);
|
||||
|
||||
in_addr_t nmtst_ip4_config_get_gateway (NMIP4Config *config);
|
||||
|
||||
const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self);
|
||||
void nm_ip4_config_reset_addresses (NMIP4Config *self);
|
||||
void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address);
|
||||
|
|
@ -203,7 +207,9 @@ void _nmtst_ip4_config_del_route (NMIP4Config *self, guint i);
|
|||
guint nm_ip4_config_get_num_routes (const NMIP4Config *self);
|
||||
const NMPlatformIP4Route *_nmtst_ip4_config_get_route (const NMIP4Config *self, guint i);
|
||||
|
||||
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host);
|
||||
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self,
|
||||
in_addr_t host,
|
||||
guint32 route_table);
|
||||
|
||||
void nm_ip4_config_reset_nameservers (NMIP4Config *self);
|
||||
void nm_ip4_config_add_nameserver (NMIP4Config *self, guint32 nameserver);
|
||||
|
|
|
|||
|
|
@ -58,11 +58,9 @@ _route_valid (const NMPlatformIP6Route *r)
|
|||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
bool never_default:1;
|
||||
int ifindex;
|
||||
int dns_priority;
|
||||
NMSettingIP6ConfigPrivacy privacy;
|
||||
struct in6_addr gateway;
|
||||
GArray *nameservers;
|
||||
GPtrArray *domains;
|
||||
GPtrArray *searches;
|
||||
|
|
@ -372,9 +370,6 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
{
|
||||
NMIP6Config *self;
|
||||
NMIP6ConfigPrivate *priv;
|
||||
guint32 lowest_metric = G_MAXUINT32;
|
||||
struct in6_addr old_gateway = IN6ADDR_ANY_INIT;
|
||||
gboolean has_gateway;
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
NMDedupMultiIter iter;
|
||||
const NMPObject *plobj = NULL;
|
||||
|
|
@ -411,37 +406,22 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
nm_dedup_multi_head_entry_sort (head_entry,
|
||||
sort_captured_addresses,
|
||||
GINT_TO_POINTER (use_temporary));
|
||||
_notify_addresses (self);
|
||||
}
|
||||
|
||||
head_entry = nm_platform_lookup_addrroute (platform,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
ifindex);
|
||||
|
||||
/* Extract gateway from default route */
|
||||
old_gateway = priv->gateway;
|
||||
|
||||
lowest_metric = G_MAXUINT32;
|
||||
has_gateway = FALSE;
|
||||
nmp_cache_iter_for_each (&iter, head_entry, &plobj) {
|
||||
const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (plobj);
|
||||
|
||||
if ( !route->table_coerced
|
||||
&& NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)
|
||||
&& route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) {
|
||||
if (route->metric < lowest_metric) {
|
||||
priv->gateway = route->gateway;
|
||||
lowest_metric = route->metric;
|
||||
}
|
||||
has_gateway = TRUE;
|
||||
}
|
||||
|
||||
nmp_cache_iter_for_each (&iter, head_entry, &plobj)
|
||||
_add_route (self, plobj, NULL, NULL);
|
||||
}
|
||||
|
||||
/* If the interface has the default route, and has IPv6 addresses, capture
|
||||
* nameservers from /etc/resolv.conf.
|
||||
*/
|
||||
if (has_addresses && has_gateway && capture_resolv_conf) {
|
||||
if ( has_addresses
|
||||
&& priv->best_default_route
|
||||
&& capture_resolv_conf) {
|
||||
gs_free char *rc_contents = NULL;
|
||||
|
||||
if (g_file_get_contents (_PATH_RESCONF, &rc_contents, NULL, NULL)) {
|
||||
|
|
@ -453,22 +433,17 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
}
|
||||
}
|
||||
|
||||
/* actually, nobody should be connected to the signal, just to be sure, notify */
|
||||
_notify_addresses (self);
|
||||
_notify_routes (self);
|
||||
if (!IN6_ARE_ADDR_EQUAL (&priv->gateway, &old_gateway))
|
||||
_notify (self, PROP_GATEWAY);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_add_device_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric)
|
||||
nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric)
|
||||
{
|
||||
const NMIP6ConfigPrivate *priv;
|
||||
const NMPlatformIP6Address *addr;
|
||||
const NMPlatformIP6Address *my_addr;
|
||||
const NMPlatformIP6Route *my_route;
|
||||
int ifindex;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
|
|
@ -484,21 +459,21 @@ nm_ip6_config_add_device_routes (NMIP6Config *self,
|
|||
*
|
||||
* For manually added IPv6 routes, add the device routes explicitly. */
|
||||
|
||||
nm_ip_config_iter_ip6_address_for_each (&iter, self, &addr) {
|
||||
nm_ip_config_iter_ip6_address_for_each (&iter, self, &my_addr) {
|
||||
NMPObject *r;
|
||||
NMPlatformIP6Route *route;
|
||||
gboolean has_peer;
|
||||
int routes_n, routes_i;
|
||||
|
||||
if (NM_FLAGS_HAS (addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
||||
if (NM_FLAGS_HAS (my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
||||
continue;
|
||||
|
||||
has_peer = !IN6_IS_ADDR_UNSPECIFIED (&addr->peer_address);
|
||||
has_peer = !IN6_IS_ADDR_UNSPECIFIED (&my_addr->peer_address);
|
||||
|
||||
/* If we have an IPv6 peer, we add two /128 routes
|
||||
* (unless, both addresses are identical). */
|
||||
routes_n = ( has_peer
|
||||
&& !IN6_ARE_ADDR_EQUAL (&addr->address, &addr->peer_address))
|
||||
&& !IN6_ARE_ADDR_EQUAL (&my_addr->address, &my_addr->peer_address))
|
||||
? 2 : 1;
|
||||
|
||||
for (routes_i = 0; routes_i < routes_n; routes_i++) {
|
||||
|
|
@ -513,13 +488,13 @@ nm_ip6_config_add_device_routes (NMIP6Config *self,
|
|||
|
||||
if (has_peer) {
|
||||
if (routes_i == 0)
|
||||
route->network = addr->address;
|
||||
route->network = my_addr->address;
|
||||
else
|
||||
route->network = addr->peer_address;
|
||||
route->network = my_addr->peer_address;
|
||||
route->plen = 128;
|
||||
} else {
|
||||
nm_utils_ip6_address_clear_host_address (&route->network, &addr->address, addr->plen);
|
||||
route->plen = addr->plen;
|
||||
nm_utils_ip6_address_clear_host_address (&route->network, &my_addr->address, my_addr->plen);
|
||||
route->plen = my_addr->plen;
|
||||
}
|
||||
|
||||
nm_platform_ip_route_normalize (AF_INET6, (NMPlatformIPRoute *) route);
|
||||
|
|
@ -533,6 +508,27 @@ nm_ip6_config_add_device_routes (NMIP6Config *self,
|
|||
_add_route (self, r, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
again:
|
||||
nm_ip_config_iter_ip6_route_for_each (&iter, self, &my_route) {
|
||||
NMPlatformIP6Route rt;
|
||||
|
||||
if ( !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (my_route)
|
||||
|| IN6_IS_ADDR_UNSPECIFIED (&my_route->gateway)
|
||||
|| NM_IS_IP_CONFIG_SOURCE_RTPROT (my_route->rt_source)
|
||||
|| nm_ip6_config_get_direct_route_for_host (self,
|
||||
&my_route->gateway,
|
||||
nm_platform_route_table_uncoerce (my_route->table_coerced, TRUE)))
|
||||
continue;
|
||||
|
||||
rt = *my_route;
|
||||
rt.network = my_route->gateway;
|
||||
rt.plen = 128;
|
||||
rt.gateway = in6addr_any;
|
||||
_add_route (self, NULL, &rt, NULL);
|
||||
/* adding the route might have invalidated the iteration. Start again. */
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -644,6 +640,7 @@ nm_ip6_config_merge_setting (NMIP6Config *self,
|
|||
NMIP6ConfigPrivate *priv;
|
||||
guint naddresses, nroutes, nnameservers, nsearches;
|
||||
const char *gateway_str;
|
||||
struct in6_addr gateway_bin;
|
||||
int i, priority;
|
||||
|
||||
if (!setting)
|
||||
|
|
@ -661,16 +658,18 @@ nm_ip6_config_merge_setting (NMIP6Config *self,
|
|||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
/* Gateway */
|
||||
if (nm_setting_ip_config_get_never_default (setting))
|
||||
nm_ip6_config_set_never_default (self, TRUE);
|
||||
else if (nm_setting_ip_config_get_ignore_auto_routes (setting))
|
||||
nm_ip6_config_set_never_default (self, FALSE);
|
||||
gateway_str = nm_setting_ip_config_get_gateway (setting);
|
||||
if (gateway_str) {
|
||||
struct in6_addr gateway;
|
||||
if ( !nm_setting_ip_config_get_never_default (setting)
|
||||
&& (gateway_str = nm_setting_ip_config_get_gateway (setting))
|
||||
&& inet_pton (AF_INET6, gateway_str, &gateway_bin) == 1
|
||||
&& !IN6_IS_ADDR_UNSPECIFIED (&gateway_bin)) {
|
||||
const NMPlatformIP6Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_USER,
|
||||
.gateway = gateway_bin,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
inet_pton (AF_INET6, gateway_str, &gateway);
|
||||
nm_ip6_config_set_gateway (self, &gateway);
|
||||
_add_route (self, NULL, &r, NULL);
|
||||
}
|
||||
|
||||
/* Addresses */
|
||||
|
|
@ -753,8 +752,8 @@ nm_ip6_config_merge_setting (NMIP6Config *self,
|
|||
NMSetting *
|
||||
nm_ip6_config_create_setting (const NMIP6Config *self)
|
||||
{
|
||||
const NMIP6ConfigPrivate *priv;
|
||||
NMSettingIPConfig *s_ip6;
|
||||
const struct in6_addr *gateway;
|
||||
guint nnameservers, nsearches, noptions;
|
||||
const char *method = NULL;
|
||||
int i;
|
||||
|
|
@ -771,7 +770,8 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
|
|||
return NM_SETTING (s_ip6);
|
||||
}
|
||||
|
||||
gateway = nm_ip6_config_get_gateway (self);
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nnameservers = nm_ip6_config_get_num_nameservers (self);
|
||||
nsearches = nm_ip6_config_get_num_searches (self);
|
||||
noptions = nm_ip6_config_get_num_dns_options (self);
|
||||
|
|
@ -803,10 +803,12 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
|
|||
}
|
||||
|
||||
/* Gateway */
|
||||
if ( gateway
|
||||
if ( priv->best_default_route
|
||||
&& nm_setting_ip_config_get_num_addresses (s_ip6) > 0) {
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP_CONFIG_GATEWAY, nm_utils_inet6_ntop (gateway, NULL),
|
||||
NM_SETTING_IP_CONFIG_GATEWAY,
|
||||
nm_utils_inet6_ntop (&NMP_OBJECT_CAST_IP6_ROUTE (priv->best_default_route)->gateway,
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
@ -869,7 +871,10 @@ nm_ip6_config_create_setting (const NMIP6Config *self)
|
|||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags)
|
||||
nm_ip6_config_merge (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
NMIPConfigMergeFlags merge_flags,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP6ConfigPrivate *dst_priv;
|
||||
const NMIP6ConfigPrivate *src_priv;
|
||||
|
|
@ -895,14 +900,24 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
|
|||
nm_ip6_config_add_nameserver (dst, nm_ip6_config_get_nameserver (src, i));
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
if (nm_ip6_config_get_gateway (src))
|
||||
nm_ip6_config_set_gateway (dst, nm_ip6_config_get_gateway (src));
|
||||
|
||||
/* routes */
|
||||
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, NULL)
|
||||
const NMPlatformIP6Route *r_src;
|
||||
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r_src) {
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r_src)) {
|
||||
if (NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES))
|
||||
continue;
|
||||
if (default_route_metric_penalty) {
|
||||
NMPlatformIP6Route r = *r_src;
|
||||
|
||||
r.metric = nm_utils_ip_route_metric_penalize (AF_INET6, r.metric, default_route_metric_penalty);
|
||||
_add_route (dst, NULL, &r, NULL);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_add_route (dst, ipconf_iter.current->obj, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* domains */
|
||||
|
|
@ -930,25 +945,6 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl
|
|||
g_object_thaw_notify (G_OBJECT (dst));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip6_config_destination_is_direct (const NMIP6Config *self, const struct in6_addr *network, guint8 plen)
|
||||
{
|
||||
const NMPlatformIP6Address *item;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
nm_assert (network);
|
||||
nm_assert (plen <= 128);
|
||||
|
||||
nm_ip_config_iter_ip6_address_for_each (&iter, self, &item) {
|
||||
if ( item->plen <= plen
|
||||
&& !NM_FLAGS_HAS (item->n_ifa_flags, IFA_F_NOPREFIXROUTE)
|
||||
&& nm_utils_ip6_address_same_prefix (&item->address, network, item->plen))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
|
|
@ -1017,11 +1013,17 @@ _dns_options_get_index (const NMIP6Config *self, const char *option)
|
|||
* nm_ip6_config_subtract:
|
||||
* @dst: config from which to remove everything in @src
|
||||
* @src: config to remove from @dst
|
||||
*
|
||||
* @default_route_metric_penalty: pretend that on source we applied
|
||||
* a route penalty on the default-route. It means, for default routes
|
||||
* we don't remove routes that match exactly, but those with a lower
|
||||
* metric (with the penalty removed).
|
||||
*
|
||||
* Removes everything in @src from @dst.
|
||||
*/
|
||||
void
|
||||
nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
||||
nm_ip6_config_subtract (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP6ConfigPrivate *dst_priv;
|
||||
guint i;
|
||||
|
|
@ -1029,7 +1031,6 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
const NMPlatformIP6Address *a;
|
||||
const NMPlatformIP6Route *r;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const struct in6_addr *dst_tmp, *src_tmp;
|
||||
gboolean changed;
|
||||
gboolean changed_default_route;
|
||||
|
||||
|
|
@ -1059,24 +1060,31 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
nm_ip6_config_del_nameserver (dst, idx);
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
src_tmp = nm_ip6_config_get_gateway (src);
|
||||
dst_tmp = nm_ip6_config_get_gateway (dst);
|
||||
if (src_tmp && dst_tmp && IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp))
|
||||
nm_ip6_config_set_gateway (dst, NULL);
|
||||
|
||||
if (!nm_ip6_config_get_num_addresses (dst))
|
||||
nm_ip6_config_set_gateway (dst, NULL);
|
||||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
changed_default_route = FALSE;
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &r) {
|
||||
const NMPObject *o_src = NMP_OBJECT_UP_CAST (r);
|
||||
NMPObject o_lookup_copy;
|
||||
const NMPObject *o_lookup;
|
||||
nm_auto_nmpobj const NMPObject *obj_old = NULL;
|
||||
|
||||
if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)
|
||||
&& default_route_metric_penalty) {
|
||||
NMPlatformIP6Route *rr;
|
||||
|
||||
/* the default route was penalized when merging it to the combined ip-config.
|
||||
* When subtracting the routes, we must re-do that process when comparing
|
||||
* the routes. */
|
||||
o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_src);
|
||||
rr = NMP_OBJECT_CAST_IP6_ROUTE (&o_lookup_copy);
|
||||
rr->metric = nm_utils_ip_route_metric_penalize (AF_INET6, rr->metric, default_route_metric_penalty);
|
||||
} else
|
||||
o_lookup = o_src;
|
||||
|
||||
if (nm_dedup_multi_index_remove_obj (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip6_routes,
|
||||
NMP_OBJECT_UP_CAST (r),
|
||||
o_lookup,
|
||||
(gconstpointer *) &obj_old)) {
|
||||
if (dst_priv->best_default_route == obj_old) {
|
||||
nm_clear_nmp_object (&dst_priv->best_default_route);
|
||||
|
|
@ -1088,6 +1096,7 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
if (changed_default_route) {
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route,
|
||||
_nm_ip6_config_best_default_route_find (dst));
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
|
@ -1121,11 +1130,12 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src)
|
|||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
|
||||
nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty)
|
||||
{
|
||||
NMIP6ConfigPrivate *dst_priv;
|
||||
const NMIP6ConfigPrivate *src_priv;
|
||||
const struct in6_addr *dst_tmp, *src_tmp;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP6Address *a;
|
||||
const NMPlatformIP6Route *r;
|
||||
|
|
@ -1158,26 +1168,31 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
|
|||
|
||||
/* ignore nameservers */
|
||||
|
||||
/* default gateway */
|
||||
dst_tmp = nm_ip6_config_get_gateway (dst);
|
||||
if (dst_tmp) {
|
||||
src_tmp = nm_ip6_config_get_gateway (src);
|
||||
if ( !nm_ip6_config_get_num_addresses (dst)
|
||||
|| !src_tmp
|
||||
|| !IN6_ARE_ADDR_EQUAL (src_tmp, dst_tmp))
|
||||
nm_ip6_config_set_gateway (dst, NULL);
|
||||
}
|
||||
|
||||
/* routes */
|
||||
changed = FALSE;
|
||||
new_best_default_route = NULL;
|
||||
nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, dst, &r) {
|
||||
const NMPObject *o = NMP_OBJECT_UP_CAST (r);
|
||||
const NMPObject *o_dst = NMP_OBJECT_UP_CAST (r);
|
||||
const NMPObject *o_lookup;
|
||||
NMPObject o_lookup_copy;
|
||||
|
||||
if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (r)
|
||||
&& default_route_metric_penalty) {
|
||||
NMPlatformIP6Route *rr;
|
||||
|
||||
/* the default route was penalized when merging it to the combined ip-config.
|
||||
* When intersecting the routes, we must re-do that process when comparing
|
||||
* the routes. */
|
||||
o_lookup = nmp_object_stackinit_obj (&o_lookup_copy, o_dst);
|
||||
rr = NMP_OBJECT_CAST_IP6_ROUTE (&o_lookup_copy);
|
||||
rr->metric = nm_utils_ip_route_metric_penalize (AF_INET6, rr->metric, default_route_metric_penalty);
|
||||
} else
|
||||
o_lookup = o_dst;
|
||||
|
||||
if (nm_dedup_multi_index_lookup_obj (src_priv->multi_idx,
|
||||
&src_priv->idx_ip6_routes,
|
||||
o)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o);
|
||||
o_lookup)) {
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, o_dst);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1186,8 +1201,10 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src)
|
|||
nm_assert_not_reached ();
|
||||
changed = TRUE;
|
||||
}
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route)) {
|
||||
nm_assert (changed);
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
}
|
||||
if (changed)
|
||||
_notify_routes (dst);
|
||||
|
||||
|
|
@ -1247,18 +1264,6 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
has_minor_changes = TRUE;
|
||||
}
|
||||
|
||||
/* never_default */
|
||||
if (src_priv->never_default != dst_priv->never_default) {
|
||||
dst_priv->never_default = src_priv->never_default;
|
||||
has_minor_changes = TRUE;
|
||||
}
|
||||
|
||||
/* default gateway */
|
||||
if (!IN6_ARE_ADDR_EQUAL (&src_priv->gateway, &dst_priv->gateway)) {
|
||||
nm_ip6_config_set_gateway (dst, &src_priv->gateway);
|
||||
has_relevant_changes = TRUE;
|
||||
}
|
||||
|
||||
/* addresses */
|
||||
head_entry_src = nm_ip6_config_lookup_addresses (src);
|
||||
nm_dedup_multi_iter_init (&ipconf_iter_src, head_entry_src);
|
||||
|
|
@ -1357,7 +1362,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE);
|
||||
_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route);
|
||||
if (_nm_ip_config_best_default_route_set (&dst_priv->best_default_route, new_best_default_route))
|
||||
_notify (dst, PROP_GATEWAY);
|
||||
_notify_routes (dst);
|
||||
}
|
||||
|
||||
|
|
@ -1484,11 +1490,6 @@ nm_ip6_config_dump (const NMIP6Config *self, const char *detail)
|
|||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address)
|
||||
g_message (" a: %s", nm_platform_ip6_address_to_string (address, NULL, 0));
|
||||
|
||||
/* default gateway */
|
||||
tmp = nm_ip6_config_get_gateway (self);
|
||||
if (tmp)
|
||||
g_message (" gw: %s", nm_utils_inet6_ntop (tmp, NULL));
|
||||
|
||||
/* nameservers */
|
||||
for (i = 0; i < nm_ip6_config_get_num_nameservers (self); i++) {
|
||||
tmp = nm_ip6_config_get_nameserver (self, i);
|
||||
|
|
@ -1512,51 +1513,6 @@ nm_ip6_config_dump (const NMIP6Config *self, const char *detail)
|
|||
g_message (" dnsopt: %s", nm_ip6_config_get_dns_option (self, i));
|
||||
|
||||
g_message (" dnspri: %d", nm_ip6_config_get_dns_priority (self));
|
||||
|
||||
g_message (" n-dflt: %d", nm_ip6_config_get_never_default (self));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip6_config_set_never_default (NMIP6Config *self, gboolean never_default)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
priv->never_default = never_default;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip6_config_get_never_default (const NMIP6Config *self)
|
||||
{
|
||||
const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return priv->never_default;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_set_gateway (NMIP6Config *self, const struct in6_addr *gateway)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
if (gateway) {
|
||||
if (IN6_ARE_ADDR_EQUAL (&priv->gateway, gateway))
|
||||
return;
|
||||
priv->gateway = *gateway;
|
||||
} else {
|
||||
if (IN6_IS_ADDR_UNSPECIFIED (&priv->gateway))
|
||||
return;
|
||||
memset (&priv->gateway, 0, sizeof (priv->gateway));
|
||||
}
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
|
||||
const struct in6_addr *
|
||||
nm_ip6_config_get_gateway (const NMIP6Config *self)
|
||||
{
|
||||
const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return IN6_IS_ADDR_UNSPECIFIED (&priv->gateway) ? NULL : &priv->gateway;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1809,6 +1765,8 @@ _lookup_route (const NMIP6Config *self,
|
|||
|
||||
void
|
||||
nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
||||
const NMNDiscGateway *gateways,
|
||||
guint gateways_n,
|
||||
const NMNDiscRoute *routes,
|
||||
guint routes_n,
|
||||
guint32 route_table,
|
||||
|
|
@ -1857,12 +1815,38 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
|||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
|
||||
if (_nm_ip_config_best_default_route_set (&priv->best_default_route, new_best_default_route))
|
||||
changed = TRUE;
|
||||
/* Use the first gateway as ordered in neighbor discovery cache. */
|
||||
if (gateways_n) {
|
||||
const NMPObject *obj_new;
|
||||
const NMPlatformIP6Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
|
||||
.ifindex = priv->ifindex,
|
||||
.gateway = gateways[0].address,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
};
|
||||
|
||||
if (_nm_ip_config_add_obj (priv->multi_idx,
|
||||
&priv->idx_ip6_routes_,
|
||||
priv->ifindex,
|
||||
NULL,
|
||||
(const NMPlatformObject *) &r,
|
||||
FALSE,
|
||||
TRUE,
|
||||
NULL,
|
||||
&obj_new))
|
||||
changed = TRUE;
|
||||
new_best_default_route = _nm_ip_config_best_default_route_find_better (new_best_default_route, obj_new);
|
||||
}
|
||||
|
||||
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)
|
||||
changed = TRUE;
|
||||
|
||||
if (_nm_ip_config_best_default_route_set (&priv->best_default_route, new_best_default_route)) {
|
||||
changed = TRUE;
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
_notify_routes (self);
|
||||
}
|
||||
|
|
@ -1874,7 +1858,8 @@ nm_ip6_config_reset_routes (NMIP6Config *self)
|
|||
|
||||
if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
|
||||
&priv->idx_ip6_routes) > 0) {
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
if (nm_clear_nmp_object (&priv->best_default_route))
|
||||
_notify (self, PROP_GATEWAY);
|
||||
_notify_routes (self);
|
||||
}
|
||||
}
|
||||
|
|
@ -1902,11 +1887,19 @@ _add_route (NMIP6Config *self,
|
|||
FALSE,
|
||||
&obj_old,
|
||||
&obj_new_2)) {
|
||||
gboolean changed_default_route = FALSE;
|
||||
|
||||
if ( priv->best_default_route == obj_old
|
||||
&& obj_old != obj_new_2)
|
||||
&& obj_old != obj_new_2) {
|
||||
changed_default_route = TRUE;
|
||||
nm_clear_nmp_object (&priv->best_default_route);
|
||||
_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2);
|
||||
}
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
if (_nm_ip_config_best_default_route_merge (&priv->best_default_route, obj_new_2))
|
||||
changed_default_route = TRUE;
|
||||
|
||||
if (changed_default_route)
|
||||
_notify (self, PROP_GATEWAY);
|
||||
_notify_routes (self);
|
||||
} else
|
||||
NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2));
|
||||
|
|
@ -1975,7 +1968,9 @@ _nmtst_ip6_config_get_route (const NMIP6Config *self, guint i)
|
|||
}
|
||||
|
||||
const NMPlatformIP6Route *
|
||||
nm_ip6_config_get_direct_route_for_host (const NMIP6Config *self, const struct in6_addr *host)
|
||||
nm_ip6_config_get_direct_route_for_host (const NMIP6Config *self,
|
||||
const struct in6_addr *host,
|
||||
guint32 route_table)
|
||||
{
|
||||
const NMPlatformIP6Route *best_route = NULL;
|
||||
const NMPlatformIP6Route *item;
|
||||
|
|
@ -1990,6 +1985,9 @@ nm_ip6_config_get_direct_route_for_host (const NMIP6Config *self, const struct i
|
|||
if (best_route && best_route->plen > item->plen)
|
||||
continue;
|
||||
|
||||
if (nm_platform_route_table_uncoerce (item->table_coerced, TRUE) != route_table)
|
||||
continue;
|
||||
|
||||
if (!nm_utils_ip6_address_same_prefix (host, &item->network, item->plen))
|
||||
continue;
|
||||
|
||||
|
|
@ -2357,8 +2355,9 @@ nm_ip6_config_nmpobj_remove (NMIP6Config *self,
|
|||
break;
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
if (priv->best_default_route == obj_old) {
|
||||
_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip6_config_best_default_route_find (self));
|
||||
if (_nm_ip_config_best_default_route_set (&priv->best_default_route,
|
||||
_nm_ip6_config_best_default_route_find (self)))
|
||||
_notify (self, PROP_GATEWAY);
|
||||
}
|
||||
_notify_routes (self);
|
||||
break;
|
||||
|
|
@ -2398,8 +2397,6 @@ nm_ip6_config_hash (const NMIP6Config *self, GChecksum *sum, gboolean dns_only)
|
|||
g_return_if_fail (sum);
|
||||
|
||||
if (dns_only == FALSE) {
|
||||
hash_in6addr (sum, nm_ip6_config_get_gateway (self));
|
||||
|
||||
nm_ip_config_iter_ip6_address_for_each (&ipconf_iter, self, &address) {
|
||||
hash_in6addr (sum, &address->address);
|
||||
hash_u32 (sum, address->plen);
|
||||
|
|
@ -2558,9 +2555,10 @@ get_property (GObject *object, guint prop_id,
|
|||
&address->address, 16, 1),
|
||||
address->plen,
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
|
||||
i == 0
|
||||
? (nm_ip6_config_get_gateway (self) ?: &in6addr_any)
|
||||
: &in6addr_any,
|
||||
( i == 0
|
||||
&& priv->best_default_route)
|
||||
? &NMP_OBJECT_CAST_IP6_ROUTE (priv->best_default_route)->gateway
|
||||
: &in6addr_any,
|
||||
16, 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -2636,9 +2634,11 @@ out_routes_cached:
|
|||
priv->routes_variant);
|
||||
break;
|
||||
case PROP_GATEWAY:
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED (&priv->gateway))
|
||||
g_value_set_string (value, nm_utils_inet6_ntop (&priv->gateway, NULL));
|
||||
else
|
||||
if (priv->best_default_route) {
|
||||
g_value_set_string (value,
|
||||
nm_utils_inet6_ntop (&NMP_OBJECT_CAST_IP6_ROUTE (priv->best_default_route)->gateway,
|
||||
NULL));
|
||||
} else
|
||||
g_value_set_string (value, NULL);
|
||||
break;
|
||||
case PROP_NAMESERVERS:
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ struct _NMDedupMultiIndex *nm_ip6_config_get_multi_idx (const NMIP6Config *self)
|
|||
NMIP6Config *nm_ip6_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex,
|
||||
gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary);
|
||||
|
||||
void nm_ip6_config_add_device_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric);
|
||||
void nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric);
|
||||
|
||||
gboolean nm_ip6_config_commit (const NMIP6Config *self,
|
||||
NMPlatform *platform,
|
||||
|
|
@ -123,19 +123,19 @@ void nm_ip6_config_merge_setting (NMIP6Config *self,
|
|||
NMSetting *nm_ip6_config_create_setting (const NMIP6Config *self);
|
||||
|
||||
|
||||
void nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags);
|
||||
void nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src);
|
||||
void nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src);
|
||||
void nm_ip6_config_merge (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
NMIPConfigMergeFlags merge_flags,
|
||||
guint32 default_route_metric_penalty);
|
||||
void nm_ip6_config_subtract (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty);
|
||||
void nm_ip6_config_intersect (NMIP6Config *dst,
|
||||
const NMIP6Config *src,
|
||||
guint32 default_route_metric_penalty);
|
||||
gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relevant_changes);
|
||||
int nm_ip6_config_destination_is_direct (const NMIP6Config *self, const struct in6_addr *dest, guint8 plen);
|
||||
void nm_ip6_config_dump (const NMIP6Config *self, const char *detail);
|
||||
|
||||
|
||||
void nm_ip6_config_set_never_default (NMIP6Config *self, gboolean never_default);
|
||||
gboolean nm_ip6_config_get_never_default (const NMIP6Config *self);
|
||||
void nm_ip6_config_set_gateway (NMIP6Config *self, const struct in6_addr *);
|
||||
const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *self);
|
||||
|
||||
const NMPObject *nm_ip6_config_best_default_route_get (const NMIP6Config *self);
|
||||
const NMPObject *_nm_ip6_config_best_default_route_find (const NMIP6Config *self);
|
||||
|
||||
|
|
@ -163,7 +163,9 @@ void _nmtst_ip6_config_del_route (NMIP6Config *self, guint i);
|
|||
guint nm_ip6_config_get_num_routes (const NMIP6Config *self);
|
||||
const NMPlatformIP6Route *_nmtst_ip6_config_get_route (const NMIP6Config *self, guint i);
|
||||
|
||||
const NMPlatformIP6Route *nm_ip6_config_get_direct_route_for_host (const NMIP6Config *self, const struct in6_addr *host);
|
||||
const NMPlatformIP6Route *nm_ip6_config_get_direct_route_for_host (const NMIP6Config *self,
|
||||
const struct in6_addr *host,
|
||||
guint32 route_table);
|
||||
const NMPlatformIP6Address *nm_ip6_config_get_subnet_for_host (const NMIP6Config *self, const struct in6_addr *host);
|
||||
|
||||
void nm_ip6_config_reset_nameservers (NMIP6Config *self);
|
||||
|
|
@ -210,7 +212,10 @@ void nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self,
|
|||
guint8 plen,
|
||||
guint32 ifa_flags);
|
||||
struct _NMNDiscRoute;
|
||||
struct _NMNDiscGateway;
|
||||
void nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
||||
const struct _NMNDiscGateway *gateways,
|
||||
guint gateways_n,
|
||||
const struct _NMNDiscRoute *routes,
|
||||
guint routes_n,
|
||||
guint32 route_table,
|
||||
|
|
|
|||
|
|
@ -194,7 +194,8 @@ typedef enum {
|
|||
typedef enum {
|
||||
NM_IP_CONFIG_MERGE_DEFAULT = 0,
|
||||
NM_IP_CONFIG_MERGE_NO_ROUTES = (1LL << 0),
|
||||
NM_IP_CONFIG_MERGE_NO_DNS = (1LL << 1),
|
||||
NM_IP_CONFIG_MERGE_NO_DEFAULT_ROUTES = (1LL << 1),
|
||||
NM_IP_CONFIG_MERGE_NO_DNS = (1LL << 2),
|
||||
} NMIPConfigMergeFlags;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,22 @@ nm_ppp_manager_create (const char *iface, GError **error)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ppp_manager_set_route_parameters (NMPPPManager *self,
|
||||
guint32 ip4_route_table,
|
||||
guint32 ip4_route_metric,
|
||||
guint32 ip6_route_table,
|
||||
guint32 ip6_route_metric)
|
||||
{
|
||||
g_return_if_fail (ppp_ops);
|
||||
|
||||
ppp_ops->set_route_parameters (self,
|
||||
ip4_route_table,
|
||||
ip4_route_metric,
|
||||
ip6_route_table,
|
||||
ip6_route_metric);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ppp_manager_start (NMPPPManager *self,
|
||||
NMActRequest *req,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@
|
|||
|
||||
NMPPPManager * nm_ppp_manager_create (const char *iface,
|
||||
GError **error);
|
||||
|
||||
void nm_ppp_manager_set_route_parameters (NMPPPManager *ppp_manager,
|
||||
guint32 ip4_route_table,
|
||||
guint32 ip4_route_metric,
|
||||
guint32 ip6_route_table,
|
||||
guint32 ip6_route_metric);
|
||||
|
||||
gboolean nm_ppp_manager_start (NMPPPManager *self,
|
||||
NMActRequest *req,
|
||||
const char *ppp_name,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#endif
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_ppp.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "platform/nm-platform.h"
|
||||
|
|
@ -105,6 +106,11 @@ typedef struct {
|
|||
char *ip_iface;
|
||||
int monitor_fd;
|
||||
guint monitor_id;
|
||||
|
||||
guint32 ip4_route_table;
|
||||
guint32 ip4_route_metric;
|
||||
guint32 ip6_route_table;
|
||||
guint32 ip6_route_metric;
|
||||
} NMPPPManagerPrivate;
|
||||
|
||||
struct _NMPPPManager {
|
||||
|
|
@ -132,6 +138,37 @@ static void _ppp_kill (NMPPPManager *manager);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_ppp_manager_set_route_paramters (NMPPPManager *self,
|
||||
guint32 ip4_route_table,
|
||||
guint32 ip4_route_metric,
|
||||
guint32 ip6_route_table,
|
||||
guint32 ip6_route_metric)
|
||||
{
|
||||
NMPPPManagerPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_PPP_MANAGER (self));
|
||||
|
||||
priv = NM_PPP_MANAGER_GET_PRIVATE (self);
|
||||
if ( priv->ip4_route_table != ip4_route_table
|
||||
|| priv->ip4_route_metric != ip4_route_metric
|
||||
|| priv->ip6_route_table != ip6_route_table
|
||||
|| priv->ip6_route_metric != ip6_route_metric) {
|
||||
priv->ip4_route_table = ip4_route_table;
|
||||
priv->ip4_route_metric = ip4_route_metric;
|
||||
priv->ip6_route_table = ip6_route_table;
|
||||
priv->ip6_route_metric = ip6_route_metric;
|
||||
|
||||
_LOGT ("route-parameters: table-v4: %u, metric-v4: %u, table-v6: %u, metric-v6: %u",
|
||||
priv->ip4_route_table,
|
||||
priv->ip4_route_metric,
|
||||
priv->ip6_route_table,
|
||||
priv->ip6_route_metric);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
monitor_cb (gpointer user_data)
|
||||
{
|
||||
|
|
@ -404,6 +441,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
|
|||
NMPlatformIP4Address address;
|
||||
guint32 u32, mtu;
|
||||
GVariantIter *iter;
|
||||
int ifindex;
|
||||
|
||||
_LOGI ("(IPv4 Config Get) reply received.");
|
||||
|
||||
|
|
@ -412,8 +450,11 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
|
|||
if (!set_ip_config_common (manager, config_dict, NM_PPP_IP4_CONFIG_INTERFACE, &mtu))
|
||||
goto out;
|
||||
|
||||
config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
|
||||
nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface));
|
||||
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface);
|
||||
if (ifindex <= 0)
|
||||
goto out;
|
||||
|
||||
config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET), ifindex);
|
||||
|
||||
if (mtu)
|
||||
nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_PPP);
|
||||
|
|
@ -425,7 +466,15 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager,
|
|||
address.address = u32;
|
||||
|
||||
if (g_variant_lookup (config_dict, NM_PPP_IP4_CONFIG_GATEWAY, "u", &u32)) {
|
||||
nm_ip4_config_set_gateway (config, u32);
|
||||
const NMPlatformIP4Route r = {
|
||||
.ifindex = ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_PPP,
|
||||
.gateway = u32,
|
||||
.table_coerced = nm_platform_route_table_coerce (priv->ip4_route_table),
|
||||
.metric = priv->ip4_route_metric,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (config, &r, NULL);
|
||||
address.peer_address = u32;
|
||||
} else
|
||||
address.peer_address = address.address;
|
||||
|
|
@ -500,6 +549,7 @@ impl_ppp_manager_set_ip6_config (NMPPPManager *manager,
|
|||
struct in6_addr a;
|
||||
NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT;
|
||||
gboolean has_peer = FALSE;
|
||||
int ifindex;
|
||||
|
||||
_LOGI ("(IPv6 Config Get) reply received.");
|
||||
|
||||
|
|
@ -508,14 +558,25 @@ impl_ppp_manager_set_ip6_config (NMPPPManager *manager,
|
|||
if (!set_ip_config_common (manager, config_dict, NM_PPP_IP6_CONFIG_INTERFACE, NULL))
|
||||
goto out;
|
||||
|
||||
config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
|
||||
nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface));
|
||||
ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, priv->ip_iface);
|
||||
if (ifindex <= 0)
|
||||
goto out;
|
||||
|
||||
config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET), ifindex);
|
||||
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.plen = 64;
|
||||
|
||||
if (iid_value_to_ll6_addr (config_dict, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) {
|
||||
nm_ip6_config_set_gateway (config, &a);
|
||||
const NMPlatformIP6Route r = {
|
||||
.ifindex = ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_PPP,
|
||||
.gateway = a,
|
||||
.table_coerced = nm_platform_route_table_coerce (priv->ip6_route_table),
|
||||
.metric = priv->ip6_route_metric,
|
||||
};
|
||||
|
||||
nm_ip6_config_add_route (config, &r, NULL);
|
||||
addr.peer_address = a;
|
||||
has_peer = TRUE;
|
||||
}
|
||||
|
|
@ -1167,7 +1228,7 @@ set_property (GObject *object, guint prop_id,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_PARENT_IFACE:
|
||||
g_free (priv->parent_iface);
|
||||
/* construct-only */
|
||||
priv->parent_iface = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1181,7 +1242,13 @@ set_property (GObject *object, guint prop_id,
|
|||
static void
|
||||
nm_ppp_manager_init (NMPPPManager *manager)
|
||||
{
|
||||
NM_PPP_MANAGER_GET_PRIVATE (manager)->monitor_fd = -1;
|
||||
NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
priv->monitor_fd = -1;
|
||||
priv->ip4_route_table = RT_TABLE_MAIN;
|
||||
priv->ip4_route_metric = 460;
|
||||
priv->ip6_route_table = RT_TABLE_MAIN;
|
||||
priv->ip6_route_metric = 460;
|
||||
}
|
||||
|
||||
static NMPPPManager *
|
||||
|
|
@ -1291,9 +1358,10 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class)
|
|||
}
|
||||
|
||||
NMPPPOps ppp_ops = {
|
||||
.create = _ppp_manager_new,
|
||||
.start = _ppp_manager_start,
|
||||
.stop_async = _ppp_manager_stop_async,
|
||||
.stop_finish = _ppp_manager_stop_finish,
|
||||
.stop_sync = _ppp_manager_stop_sync,
|
||||
.create = _ppp_manager_new,
|
||||
.set_route_parameters = _ppp_manager_set_route_paramters,
|
||||
.start = _ppp_manager_start,
|
||||
.stop_async = _ppp_manager_stop_async,
|
||||
.stop_finish = _ppp_manager_stop_finish,
|
||||
.stop_sync = _ppp_manager_stop_sync,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef __NM_PPP_MANAGER_H__
|
||||
#define __NM_PPP_MANAGER_H__
|
||||
|
||||
#define NM_PPP_MANAGER_PARENT_IFACE "parent-iface"
|
||||
#define NM_PPP_MANAGER_PARENT_IFACE "parent-iface"
|
||||
|
||||
#define NM_PPP_MANAGER_SIGNAL_STATE_CHANGED "state-changed"
|
||||
#define NM_PPP_MANAGER_SIGNAL_IP4_CONFIG "ip4-config"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@
|
|||
typedef const struct {
|
||||
NMPPPManager *(*create) (const char *iface);
|
||||
|
||||
void (*set_route_parameters) (NMPPPManager *manager,
|
||||
guint32 route_table_v4,
|
||||
guint32 route_metric_v4,
|
||||
guint32 route_table_v6,
|
||||
guint32 route_metric_v6);
|
||||
|
||||
gboolean (*start) (NMPPPManager *manager,
|
||||
NMActRequest *req,
|
||||
const char *ppp_name,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,16 @@ build_test_config (void)
|
|||
route = *nmtst_platform_ip4_route ("172.16.0.0", 16, "192.168.1.1");
|
||||
nm_ip4_config_add_route (config, &route, NULL);
|
||||
|
||||
nm_ip4_config_set_gateway (config, nmtst_inet4_from_string ("192.168.1.1"));
|
||||
{
|
||||
const NMPlatformIP4Route r = {
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||
.gateway = nmtst_inet4_from_string ("192.168.1.1"),
|
||||
.table_coerced = 0,
|
||||
.metric = 100,
|
||||
};
|
||||
|
||||
nm_ip4_config_add_route (config, &r, NULL);
|
||||
}
|
||||
|
||||
nm_ip4_config_add_nameserver (config, nmtst_inet4_from_string ("4.2.2.1"));
|
||||
nm_ip4_config_add_nameserver (config, nmtst_inet4_from_string ("4.2.2.2"));
|
||||
|
|
@ -106,7 +115,7 @@ test_subtract (void)
|
|||
|
||||
nm_ip4_config_set_mtu (dst, expected_mtu, NM_IP_CONFIG_SOURCE_UNKNOWN);
|
||||
|
||||
nm_ip4_config_subtract (dst, src);
|
||||
nm_ip4_config_subtract (dst, src, 0);
|
||||
|
||||
/* ensure what's left is what we expect */
|
||||
g_assert_cmpuint (nm_ip4_config_get_num_addresses (dst), ==, 1);
|
||||
|
|
@ -116,7 +125,8 @@ test_subtract (void)
|
|||
g_assert_cmpuint (test_addr->peer_address, ==, test_addr->address);
|
||||
g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen);
|
||||
|
||||
g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0);
|
||||
g_assert (!nm_ip4_config_best_default_route_get (dst));
|
||||
g_assert_cmpuint (nmtst_ip4_config_get_gateway (dst), ==, 0);
|
||||
|
||||
g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1);
|
||||
test_route = _nmtst_ip4_config_get_route (dst, 0);
|
||||
|
|
@ -278,15 +288,15 @@ test_merge_subtract_mtu (void)
|
|||
nm_ip4_config_set_mtu (cfg2, expected_mtu2, NM_IP_CONFIG_SOURCE_UNKNOWN);
|
||||
nm_ip4_config_set_mtu (cfg3, expected_mtu3, NM_IP_CONFIG_SOURCE_UNKNOWN);
|
||||
|
||||
nm_ip4_config_merge (cfg1, cfg2, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip4_config_merge (cfg1, cfg2, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
/* ensure MSS and MTU are in cfg1 */
|
||||
g_assert_cmpuint (nm_ip4_config_get_mtu (cfg1), ==, expected_mtu2);
|
||||
|
||||
nm_ip4_config_merge (cfg1, cfg3, NM_IP_CONFIG_MERGE_DEFAULT);
|
||||
nm_ip4_config_merge (cfg1, cfg3, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
/* ensure again the MSS and MTU in cfg1 got overridden */
|
||||
g_assert_cmpuint (nm_ip4_config_get_mtu (cfg1), ==, expected_mtu3);
|
||||
|
||||
nm_ip4_config_subtract (cfg1, cfg3);
|
||||
nm_ip4_config_subtract (cfg1, cfg3, 0);
|
||||
/* ensure MSS and MTU are zero in cfg1 */
|
||||
g_assert_cmpuint (nm_ip4_config_get_mtu (cfg1), ==, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ build_test_config (void)
|
|||
nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("abcd:1200::", 24, "abcd:1234:4321:cdde::2", NULL), NULL);
|
||||
nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("2001::", 16, "2001:abba::2234", NULL), NULL);
|
||||
|
||||
nm_ip6_config_set_gateway (config, nmtst_inet6_from_string ("3001:abba::3234"));
|
||||
nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("::", 0, "3001:abba::3234", NULL), NULL);
|
||||
|
||||
nm_ip6_config_add_nameserver (config, nmtst_inet6_from_string ("1:2:3:4::1"));
|
||||
nm_ip6_config_add_nameserver (config, nmtst_inet6_from_string ("1:2:3:4::2"));
|
||||
|
|
@ -84,7 +84,7 @@ test_subtract (void)
|
|||
nm_ip6_config_add_domain (dst, expected_domain);
|
||||
nm_ip6_config_add_search (dst, expected_search);
|
||||
|
||||
nm_ip6_config_subtract (dst, src);
|
||||
nm_ip6_config_subtract (dst, src, 0);
|
||||
|
||||
/* ensure what's left is what we expect */
|
||||
g_assert_cmpuint (nm_ip6_config_get_num_addresses (dst), ==, 1);
|
||||
|
|
@ -95,7 +95,7 @@ test_subtract (void)
|
|||
g_assert (memcmp (&test_addr->peer_address, &in6addr_any, sizeof (tmp)) == 0);
|
||||
g_assert_cmpuint (test_addr->plen, ==, expected_addr_plen);
|
||||
|
||||
g_assert (nm_ip6_config_get_gateway (dst) == NULL);
|
||||
g_assert (nm_ip6_config_best_default_route_get (dst) == NULL);
|
||||
|
||||
g_assert_cmpuint (nm_ip6_config_get_num_routes (dst), ==, 1);
|
||||
test_route = _nmtst_ip6_config_get_route (dst, 0);
|
||||
|
|
|
|||
|
|
@ -1018,9 +1018,6 @@ print_vpn_config (NMVpnConnection *self)
|
|||
nm_utils_inet4_ntop (route->gateway, buf));
|
||||
}
|
||||
|
||||
_LOGI ("Data: Forbid Default Route: %s",
|
||||
nm_ip4_config_get_never_default (priv->ip4_config) ? "yes" : "no");
|
||||
|
||||
num = nm_ip4_config_get_num_nameservers (priv->ip4_config);
|
||||
for (i = 0; i < num; i++) {
|
||||
_LOGI ("Data: Internal DNS: %s",
|
||||
|
|
@ -1055,9 +1052,6 @@ print_vpn_config (NMVpnConnection *self)
|
|||
nm_utils_inet6_ntop (&route->gateway, buf));
|
||||
}
|
||||
|
||||
_LOGI ("Data: Forbid Default Route: %s",
|
||||
nm_ip6_config_get_never_default (priv->ip6_config) ? "yes" : "no");
|
||||
|
||||
num = nm_ip6_config_get_num_nameservers (priv->ip6_config);
|
||||
for (i = 0; i < num; i++) {
|
||||
_LOGI ("Data: Internal DNS: %s",
|
||||
|
|
@ -1098,19 +1092,13 @@ apply_parent_device_config (NMVpnConnection *self)
|
|||
vpn4_parent_config = nm_ip4_config_new (nm_netns_get_multi_idx (priv->netns),
|
||||
ifindex);
|
||||
if (priv->ip_ifindex <= 0)
|
||||
nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config, NM_IP_CONFIG_MERGE_NO_DNS);
|
||||
nm_ip4_config_merge (vpn4_parent_config, priv->ip4_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
|
||||
}
|
||||
if (priv->ip6_config) {
|
||||
vpn6_parent_config = nm_ip6_config_new (nm_netns_get_multi_idx (priv->netns),
|
||||
ifindex);
|
||||
if (priv->ip_ifindex <= 0) {
|
||||
nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config, NM_IP_CONFIG_MERGE_NO_DNS);
|
||||
|
||||
/* Also clear the gateway. We don't configure the gateway as part of the
|
||||
* vpn-config. Instead we tell NMDefaultRouteManager directly about the
|
||||
* default route. */
|
||||
nm_ip6_config_set_gateway (vpn6_parent_config, NULL);
|
||||
}
|
||||
if (priv->ip_ifindex <= 0)
|
||||
nm_ip6_config_merge (vpn6_parent_config, priv->ip6_config, NM_IP_CONFIG_MERGE_NO_DNS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1479,6 +1467,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
gboolean b;
|
||||
int ip_ifindex;
|
||||
guint32 mss = 0;
|
||||
gboolean never_default = FALSE;
|
||||
|
||||
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
||||
|
||||
|
|
@ -1523,10 +1512,8 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
address.plen = 24;
|
||||
|
||||
/* Internal address of the VPN subnet's gateway */
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, "u", &u32)) {
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_INT_GATEWAY, "u", &u32))
|
||||
priv->ip4_internal_gw = u32;
|
||||
nm_ip4_config_set_gateway (config, priv->ip4_internal_gw);
|
||||
}
|
||||
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, "u", &u32))
|
||||
address.address = u32;
|
||||
|
|
@ -1625,7 +1612,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
}
|
||||
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_NEVER_DEFAULT, "b", &b))
|
||||
nm_ip4_config_set_never_default (config, b);
|
||||
never_default = b;
|
||||
|
||||
/* Merge in user overrides from the NMConnection's IPv4 setting */
|
||||
nm_ip4_config_merge_setting (config,
|
||||
|
|
@ -1633,11 +1620,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
route_table,
|
||||
route_metric);
|
||||
|
||||
if (!nm_ip4_config_get_never_default (config)) {
|
||||
if (!never_default) {
|
||||
const NMPlatformIP4Route r = {
|
||||
.ifindex = ip_ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.gateway = nm_ip4_config_get_gateway (config),
|
||||
.gateway = priv->ip4_internal_gw,
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
.mss = mss,
|
||||
|
|
@ -1648,10 +1635,10 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
|
||||
g_clear_pointer (&priv->ip4_dev_route_blacklist, g_ptr_array_unref);
|
||||
|
||||
nm_ip4_config_add_device_routes (config,
|
||||
route_table,
|
||||
nm_vpn_connection_get_ip4_route_metric (self),
|
||||
&priv->ip4_dev_route_blacklist);
|
||||
nm_ip4_config_add_dependent_routes (config,
|
||||
route_table,
|
||||
nm_vpn_connection_get_ip4_route_metric (self),
|
||||
&priv->ip4_dev_route_blacklist);
|
||||
|
||||
if (priv->ip4_config) {
|
||||
nm_ip4_config_replace (priv->ip4_config, config, NULL);
|
||||
|
|
@ -1679,6 +1666,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
gboolean b;
|
||||
int ip_ifindex;
|
||||
guint32 mss = 0;
|
||||
gboolean never_default = FALSE;
|
||||
|
||||
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
||||
|
||||
|
|
@ -1713,7 +1701,6 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
g_clear_pointer (&priv->ip6_internal_gw, g_free);
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_INT_GATEWAY, "@ay", &v)) {
|
||||
priv->ip6_internal_gw = ip6_addr_dup_from_variant (v);
|
||||
nm_ip6_config_set_gateway (config, priv->ip6_internal_gw);
|
||||
g_variant_unref (v);
|
||||
}
|
||||
|
||||
|
|
@ -1812,7 +1799,7 @@ next:
|
|||
}
|
||||
|
||||
if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_NEVER_DEFAULT, "b", &b))
|
||||
nm_ip6_config_set_never_default (config, b);
|
||||
never_default = b;
|
||||
|
||||
/* Merge in user overrides from the NMConnection's IPv6 setting */
|
||||
nm_ip6_config_merge_setting (config,
|
||||
|
|
@ -1820,11 +1807,11 @@ next:
|
|||
route_table,
|
||||
route_metric);
|
||||
|
||||
if (!nm_ip6_config_get_never_default (config)) {
|
||||
if (!never_default) {
|
||||
const NMPlatformIP6Route r = {
|
||||
.ifindex = ip_ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.gateway = *(nm_ip6_config_get_gateway (config) ?: &in6addr_any),
|
||||
.gateway = *(priv->ip6_internal_gw ?: &in6addr_any),
|
||||
.table_coerced = nm_platform_route_table_coerce (route_table),
|
||||
.metric = route_metric,
|
||||
.mss = mss,
|
||||
|
|
@ -1833,9 +1820,9 @@ next:
|
|||
nm_ip6_config_add_route (config, &r, NULL);
|
||||
}
|
||||
|
||||
nm_ip6_config_add_device_routes (config,
|
||||
route_table,
|
||||
route_metric);
|
||||
nm_ip6_config_add_dependent_routes (config,
|
||||
route_table,
|
||||
route_metric);
|
||||
|
||||
if (priv->ip6_config) {
|
||||
nm_ip6_config_replace (priv->ip6_config, config, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue