mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 01:47:58 +02:00
core: refactor NMIP4Config to use dedup-index for IPv4 routes
Eventually, every NMPlatformIP4Route, NMPlatformIP6Route, NMPlatformIP4Address and NMPlatformIP6Address should be shared an deduplicated via the global NMDedupMultiIndex instance. As first proof of concept, refactor NMIP4Config to track IPv4 routes via the shared multi_idx. There is later potential for improvement, when we pass (deduplicated) NMPObject instances around instead of plain NMPlatformIP4Route, which needs still a lot of comparing and cloning.
This commit is contained in:
parent
89385bd968
commit
935411e5c0
8 changed files with 408 additions and 186 deletions
|
|
@ -135,7 +135,7 @@ test_generic_options (void)
|
|||
g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2);
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
route = _nmtst_nm_ip4_config_get_route (ip4_config, 0);
|
||||
g_assert (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0);
|
||||
g_assert (route->network == tmp);
|
||||
g_assert (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0);
|
||||
|
|
@ -144,7 +144,7 @@ test_generic_options (void)
|
|||
g_assert_cmpint (route->metric, ==, 0);
|
||||
|
||||
/* Route #2 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 1);
|
||||
route = _nmtst_nm_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);
|
||||
|
|
@ -221,7 +221,7 @@ ip4_test_route (NMIP4Config *ip4_config,
|
|||
|
||||
g_assert (expected_prefix <= 32);
|
||||
|
||||
route = nm_ip4_config_get_route (ip4_config, route_num);
|
||||
route = _nmtst_nm_ip4_config_get_route (ip4_config, route_num);
|
||||
g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0);
|
||||
g_assert (route->network == tmp);
|
||||
g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
|
|||
{
|
||||
char **strv;
|
||||
GPtrArray *domains = NULL;
|
||||
int i;
|
||||
guint i;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
g_return_val_if_fail (ip4 != NULL, NULL);
|
||||
|
||||
|
|
@ -92,11 +94,8 @@ get_ip4_rdns_domains (NMIP4Config *ip4)
|
|||
nm_utils_get_reverse_dns_domains_ip4 (address->address, address->plen, domains);
|
||||
}
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (ip4, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route)
|
||||
nm_utils_get_reverse_dns_domains_ip4 (route->network, route->plen, domains);
|
||||
}
|
||||
|
||||
/* Terminating NULL so we can use g_strfreev() to free it */
|
||||
g_ptr_array_add (domains, NULL);
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ static void
|
|||
dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
|
||||
{
|
||||
GVariantBuilder int_builder;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
guint n, i;
|
||||
const NMPlatformIP4Address *addr;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
|
@ -163,9 +164,7 @@ dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
|
|||
|
||||
/* Static routes */
|
||||
g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aau"));
|
||||
n = nm_ip4_config_get_num_routes (ip4);
|
||||
for (i = 0; i < n; i++) {
|
||||
route = nm_ip4_config_get_route (ip4, i);
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &route) {
|
||||
array[0] = route->network;
|
||||
array[1] = route->plen;
|
||||
array[2] = route->gateway;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "nm-utils/nm-dedup-multi.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "platform/nmp-object.h"
|
||||
#include "platform/nm-platform.h"
|
||||
#include "platform/nm-platform-utils.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -45,6 +46,78 @@ G_STATIC_ASSERT (G_MAXUINT >= 0xFFFFFFFF);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_idx_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a,
|
||||
const NMPlatformIP4Route *r_b)
|
||||
{
|
||||
return r_a->network == r_b->network
|
||||
&& r_a->plen == r_b->plen;
|
||||
}
|
||||
|
||||
static guint
|
||||
_idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj)
|
||||
{
|
||||
const NMPObject *o = (NMPObject *) obj;
|
||||
guint h;
|
||||
|
||||
switch (NMP_OBJECT_GET_TYPE (o)) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||
g_return_val_if_reached (0);
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
h = 40303327;
|
||||
h = NM_HASH_COMBINE (h, o->ip4_route.network);
|
||||
h = NM_HASH_COMBINE (h, o->ip4_route.plen);
|
||||
break;
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
g_return_val_if_reached (0);
|
||||
default:
|
||||
g_return_val_if_reached (0);
|
||||
};
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_idx_obj_id_equal (const NMDedupMultiIdxType *idx_type,
|
||||
const NMDedupMultiObj *obj_a,
|
||||
const NMDedupMultiObj *obj_b)
|
||||
{
|
||||
const NMPObject *o_a = (NMPObject *) obj_a;
|
||||
const NMPObject *o_b = (NMPObject *) obj_b;
|
||||
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (o_a) == NMP_OBJECT_GET_TYPE (o_b));
|
||||
|
||||
switch (NMP_OBJECT_GET_TYPE (o_a)) {
|
||||
case NMP_OBJECT_TYPE_IP4_ADDRESS:
|
||||
case NMP_OBJECT_TYPE_IP6_ADDRESS:
|
||||
g_return_val_if_reached (FALSE);
|
||||
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
||||
return _idx_obj_id_equal_ip4_route (&o_a->ip4_route, &o_b->ip4_route);
|
||||
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
||||
g_return_val_if_reached (FALSE);
|
||||
default:
|
||||
g_return_val_if_reached (FALSE);
|
||||
};
|
||||
}
|
||||
|
||||
static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = {
|
||||
.idx_obj_id_hash = _idx_obj_id_hash,
|
||||
.idx_obj_id_equal = _idx_obj_id_equal,
|
||||
};
|
||||
|
||||
void
|
||||
nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type,
|
||||
NMPObjectType obj_type)
|
||||
{
|
||||
nm_dedup_multi_idx_type_init ((NMDedupMultiIdxType *) idx_type,
|
||||
&_dedup_multi_idx_type_class);
|
||||
idx_type->obj_type = obj_type;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config,
|
||||
PROP_MULTI_IDX,
|
||||
PROP_IFINDEX,
|
||||
|
|
@ -73,7 +146,6 @@ typedef struct {
|
|||
gint dns_priority;
|
||||
gint64 route_metric;
|
||||
GArray *addresses;
|
||||
GArray *routes;
|
||||
GArray *nameservers;
|
||||
GPtrArray *domains;
|
||||
GPtrArray *searches;
|
||||
|
|
@ -84,6 +156,7 @@ typedef struct {
|
|||
GVariant *address_data_variant;
|
||||
GVariant *addresses_variant;
|
||||
NMDedupMultiIndex *multi_idx;
|
||||
NMDedupMultiIdxType idx_ip4_routes;
|
||||
} NMIP4ConfigPrivate;
|
||||
|
||||
struct _NMIP4Config {
|
||||
|
|
@ -101,6 +174,10 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void _add_route (NMIP4Config *config, const NMPObject *o_new, const NMPlatformIP4Route *new);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
nm_ip4_config_get_ifindex (const NMIP4Config *config)
|
||||
{
|
||||
|
|
@ -124,6 +201,49 @@ _ipv4_is_zeronet (in_addr_t network)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const NMDedupMultiHeadEntry *
|
||||
_idx_ip4_routes (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
return nm_dedup_multi_index_lookup_head (priv->multi_idx,
|
||||
&priv->idx_ip4_routes,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const NMPlatformIP4Route *
|
||||
_entry_iter_get_ip4_route (const CList *iter)
|
||||
{
|
||||
const NMDedupMultiEntry *e = c_list_entry (iter, NMDedupMultiEntry, lst_entries);
|
||||
const NMPObject *o = (NMPObject *) e->box->obj;
|
||||
|
||||
nm_assert (o);
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (o) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
||||
return &o->ip4_route;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_iter_ip4_route_init (NMDedupMultiIter *ipconf_iter, const NMIP4Config *self)
|
||||
{
|
||||
g_return_if_fail (NM_IS_IP4_CONFIG (self));
|
||||
nm_dedup_multi_iter_init (ipconf_iter, _idx_ip4_routes (self));
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_ip4_config_iter_ip4_route_next (NMDedupMultiIter *ipconf_iter, const NMPlatformIP4Route **out_route)
|
||||
{
|
||||
gboolean has_next;
|
||||
|
||||
has_next = nm_dedup_multi_iter_next (ipconf_iter);
|
||||
if (has_next) {
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (ipconf_iter->current->box->obj) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
||||
NM_SET_OUT (out_route, &(((const NMPObject *) ipconf_iter->current->box->obj)->ip4_route));
|
||||
}
|
||||
return has_next;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_ip4_config_capture_resolv_conf():
|
||||
* @nameservers: array of guint32
|
||||
|
|
@ -196,13 +316,6 @@ addresses_are_duplicate (const NMPlatformIP4Address *a, const NMPlatformIP4Addre
|
|||
&& ((a->peer_address ^ b->peer_address) & nm_utils_ip4_prefix_to_netmask (a->plen)) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
routes_are_duplicate (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gboolean consider_gateway_and_metric)
|
||||
{
|
||||
return a->network == b->network && a->plen == b->plen &&
|
||||
(!consider_gateway_and_metric || (a->gateway == b->gateway && a->metric == b->metric));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gint
|
||||
|
|
@ -277,6 +390,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
guint32 lowest_metric = G_MAXUINT32;
|
||||
guint32 old_gateway = 0;
|
||||
gboolean old_has_gateway = FALSE;
|
||||
gs_unref_array GArray *routes = NULL;
|
||||
|
||||
/* Slaves have no IP configuration */
|
||||
if (nm_platform_link_get_master (platform, ifindex) > 0)
|
||||
|
|
@ -286,18 +400,17 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
g_array_unref (priv->addresses);
|
||||
g_array_unref (priv->routes);
|
||||
|
||||
priv->addresses = nm_platform_ip4_address_get_all (platform, ifindex);
|
||||
g_array_sort (priv->addresses, sort_captured_addresses);
|
||||
|
||||
priv->routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
|
||||
routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
|
||||
|
||||
/* Extract gateway from default route */
|
||||
old_gateway = priv->gateway;
|
||||
old_has_gateway = priv->has_gateway;
|
||||
for (i = 0; i < priv->routes->len; ) {
|
||||
const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
for (i = 0; i < routes->len; ) {
|
||||
const NMPlatformIP4Route *route = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) {
|
||||
if (route->metric < lowest_metric) {
|
||||
|
|
@ -306,7 +419,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
}
|
||||
priv->has_gateway = TRUE;
|
||||
/* Remove the default route from the list */
|
||||
g_array_remove_index_fast (priv->routes, i);
|
||||
g_array_remove_index_fast (routes, i);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
|
|
@ -320,18 +433,21 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i
|
|||
* automatically added by NetworkManager when needed.
|
||||
*/
|
||||
if (priv->has_gateway) {
|
||||
for (i = 0; i < priv->routes->len; i++) {
|
||||
const NMPlatformIP4Route *route = &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
for (i = 0; i < routes->len; i++) {
|
||||
const NMPlatformIP4Route *route = &g_array_index (routes, NMPlatformIP4Route, i);
|
||||
|
||||
if ( (route->plen == 32)
|
||||
&& (route->network == priv->gateway)
|
||||
&& (route->gateway == 0)) {
|
||||
g_array_remove_index (priv->routes, i);
|
||||
g_array_remove_index (routes, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < routes->len; i++)
|
||||
_add_route (config, NULL, &g_array_index (routes, NMPlatformIP4Route, i));
|
||||
|
||||
/* If the interface has the default route, and has IPv4 addresses, capture
|
||||
* nameservers from /etc/resolv.conf.
|
||||
*/
|
||||
|
|
@ -367,11 +483,15 @@ nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteMa
|
|||
|
||||
/* Routes */
|
||||
{
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
guint i;
|
||||
guint count = nm_ip4_config_get_num_routes (config);
|
||||
GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count);
|
||||
gboolean success;
|
||||
gs_unref_array GArray *routes = NULL;
|
||||
gs_unref_array GArray *device_route_purge_list = NULL;
|
||||
const CList *iter;
|
||||
|
||||
head_entry = _idx_ip4_routes (config);
|
||||
|
||||
routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), head_entry ? head_entry->len : 0);
|
||||
|
||||
if ( default_route_metric >= 0
|
||||
&& added_addresses) {
|
||||
|
|
@ -414,20 +534,15 @@ nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteMa
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
route = nm_ip4_config_get_route (config, i);
|
||||
/* duplicates in @routes are no problem as route-manager handles them
|
||||
* gracefully (by ignoring them). */
|
||||
g_array_append_vals (routes, route, 1);
|
||||
if (head_entry) {
|
||||
c_list_for_each (iter, &head_entry->lst_entries_head)
|
||||
g_array_append_vals (routes, _entry_iter_get_ip4_route (iter), 1);
|
||||
}
|
||||
|
||||
nm_route_manager_ip4_route_register_device_route_purge_list (route_manager, device_route_purge_list);
|
||||
|
||||
success = nm_route_manager_ip4_route_sync (route_manager, ifindex, routes, default_route_metric < 0, routes_full_sync);
|
||||
g_array_unref (routes);
|
||||
if (!success)
|
||||
if (!nm_route_manager_ip4_route_sync (route_manager, ifindex, routes,
|
||||
default_route_metric < 0, routes_full_sync))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +662,7 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu
|
|||
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
|
||||
merge_route_attributes (s_route, &route);
|
||||
nm_ip4_config_add_route (config, &route);
|
||||
_add_route (config, NULL, &route);
|
||||
}
|
||||
|
||||
/* DNS */
|
||||
|
|
@ -583,10 +698,12 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
|
|||
{
|
||||
NMSettingIPConfig *s_ip4;
|
||||
guint32 gateway;
|
||||
guint naddresses, nroutes, nnameservers, nsearches, noptions;
|
||||
guint naddresses, nnameservers, nsearches, noptions;
|
||||
const char *method = NULL;
|
||||
int i;
|
||||
gint64 route_metric;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ());
|
||||
|
||||
|
|
@ -599,7 +716,6 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
|
|||
|
||||
gateway = nm_ip4_config_get_gateway (config);
|
||||
naddresses = nm_ip4_config_get_num_addresses (config);
|
||||
nroutes = nm_ip4_config_get_num_routes (config);
|
||||
nnameservers = nm_ip4_config_get_num_nameservers (config);
|
||||
nsearches = nm_ip4_config_get_num_searches (config);
|
||||
noptions = nm_ip4_config_get_num_dns_options (config);
|
||||
|
|
@ -646,8 +762,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config)
|
|||
NULL);
|
||||
|
||||
/* Routes */
|
||||
for (i = 0; i < nroutes; i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
|
||||
NMIPRoute *s_route;
|
||||
|
||||
/* Ignore default route. */
|
||||
|
|
@ -700,6 +815,7 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
|
|||
NMIP4ConfigPrivate *dst_priv;
|
||||
const NMIP4ConfigPrivate *src_priv;
|
||||
guint32 i;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
|
|
@ -725,8 +841,10 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl
|
|||
|
||||
/* routes */
|
||||
if (!NM_FLAGS_HAS (merge_flags, NM_IP_CONFIG_MERGE_NO_ROUTES)) {
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (src); i++)
|
||||
nm_ip4_config_add_route (dst, nm_ip4_config_get_route (src, i));
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, src, &route)
|
||||
_add_route (dst, NMP_OBJECT_UP_CAST (route), NULL);
|
||||
}
|
||||
|
||||
if (dst_priv->route_metric == -1)
|
||||
|
|
@ -821,22 +939,6 @@ _nameservers_get_index (const NMIP4Config *self, guint32 ns)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_routes_get_index (const NMIP4Config *self, const NMPlatformIP4Route *route)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->routes->len; i++) {
|
||||
const NMPlatformIP4Route *r = &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
|
||||
if ( route->network == r->network
|
||||
&& route->plen == r->plen)
|
||||
return (int) i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
_domains_get_index (const NMIP4Config *self, const char *domain)
|
||||
{
|
||||
|
|
@ -924,12 +1026,17 @@ _wins_get_index (const NMIP4Config *self, guint32 wins_server)
|
|||
void
|
||||
nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
||||
{
|
||||
guint32 i;
|
||||
NMIP4ConfigPrivate *priv_dst;
|
||||
guint i;
|
||||
gint idx;
|
||||
const NMPlatformIP4Route *r;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
|
||||
priv_dst = NM_IP4_CONFIG_GET_PRIVATE (dst);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (dst));
|
||||
|
||||
/* addresses */
|
||||
|
|
@ -957,10 +1064,10 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
/* ignore route_metric */
|
||||
|
||||
/* routes */
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (src); i++) {
|
||||
idx = _routes_get_index (dst, nm_ip4_config_get_route (src, i));
|
||||
if (idx >= 0)
|
||||
nm_ip4_config_del_route (dst, idx);
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, src, &r) {
|
||||
nm_dedup_multi_index_remove_obj (priv_dst->multi_idx,
|
||||
&priv_dst->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r));
|
||||
}
|
||||
|
||||
/* domains */
|
||||
|
|
@ -1020,14 +1127,21 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src)
|
|||
void
|
||||
nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
||||
{
|
||||
guint32 i;
|
||||
NMIP4ConfigPrivate *priv_dst;
|
||||
const NMIP4ConfigPrivate *priv_src;
|
||||
guint i;
|
||||
gint idx;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *r;
|
||||
|
||||
g_return_if_fail (src != NULL);
|
||||
g_return_if_fail (dst != NULL);
|
||||
g_return_if_fail (src);
|
||||
g_return_if_fail (dst);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (dst));
|
||||
|
||||
priv_dst = NM_IP4_CONFIG_GET_PRIVATE (dst);
|
||||
priv_src = NM_IP4_CONFIG_GET_PRIVATE (src);
|
||||
|
||||
/* addresses */
|
||||
for (i = 0; i < nm_ip4_config_get_num_addresses (dst); ) {
|
||||
idx = _addresses_get_index (src, nm_ip4_config_get_address (dst, i));
|
||||
|
|
@ -1048,12 +1162,15 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src)
|
|||
}
|
||||
|
||||
/* routes */
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (dst); ) {
|
||||
idx = _routes_get_index (src, nm_ip4_config_get_route (dst, i));
|
||||
if (idx < 0)
|
||||
nm_ip4_config_del_route (dst, i);
|
||||
else
|
||||
i++;
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, dst, &r) {
|
||||
if (nm_dedup_multi_index_lookup_obj (priv_src->multi_idx,
|
||||
&priv_src->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r)))
|
||||
continue;
|
||||
|
||||
if (nm_dedup_multi_index_remove_entry (priv_dst->multi_idx,
|
||||
ipconf_iter.current) != 1)
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* ignore domains */
|
||||
|
|
@ -1091,7 +1208,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
NMIP4ConfigPrivate *dst_priv;
|
||||
const NMIP4ConfigPrivate *src_priv;
|
||||
const NMPlatformIP4Address *dst_addr, *src_addr;
|
||||
const NMPlatformIP4Route *dst_route, *src_route;
|
||||
NMDedupMultiIter ipconf_iter_src, ipconf_iter_dst;
|
||||
|
||||
g_return_val_if_fail (src != NULL, FALSE);
|
||||
g_return_val_if_fail (dst != NULL, FALSE);
|
||||
|
|
@ -1158,26 +1275,45 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
}
|
||||
|
||||
/* routes */
|
||||
num = nm_ip4_config_get_num_routes (src);
|
||||
are_equal = num == nm_ip4_config_get_num_routes (dst);
|
||||
if (are_equal) {
|
||||
for (i = 0; i < num; i++ ) {
|
||||
if (nm_platform_ip4_route_cmp (src_route = nm_ip4_config_get_route (src, i),
|
||||
dst_route = nm_ip4_config_get_route (dst, i))) {
|
||||
are_equal = FALSE;
|
||||
if (!routes_are_duplicate (src_route, dst_route, TRUE)) {
|
||||
has_relevant_changes = TRUE;
|
||||
break;
|
||||
}
|
||||
nm_ip4_config_iter_ip4_route_init (&ipconf_iter_src, src);
|
||||
nm_ip4_config_iter_ip4_route_init (&ipconf_iter_dst, dst);
|
||||
are_equal = TRUE;
|
||||
while (TRUE) {
|
||||
gboolean has;
|
||||
const NMPlatformIP4Route *r_src, *r_dst;
|
||||
|
||||
has = nm_ip4_config_iter_ip4_route_next (&ipconf_iter_src, &r_src);
|
||||
if (has != nm_ip4_config_iter_ip4_route_next (&ipconf_iter_dst, &r_dst)) {
|
||||
are_equal = FALSE;
|
||||
has_relevant_changes = TRUE;
|
||||
break;
|
||||
}
|
||||
if (!has)
|
||||
break;
|
||||
|
||||
if (nm_platform_ip4_route_cmp (r_src, r_dst) != 0) {
|
||||
are_equal = FALSE;
|
||||
if (!_idx_obj_id_equal_ip4_route (r_src, r_dst)) {
|
||||
has_relevant_changes = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
has_relevant_changes = TRUE;
|
||||
}
|
||||
if (!are_equal) {
|
||||
nm_ip4_config_reset_routes (dst);
|
||||
for (i = 0; i < num; i++)
|
||||
nm_ip4_config_add_route (dst, nm_ip4_config_get_route (src, i));
|
||||
const NMPlatformIP4Route *r_src;
|
||||
|
||||
has_minor_changes = TRUE;
|
||||
nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes);
|
||||
nm_dedup_multi_iter_rewind (&ipconf_iter_src);
|
||||
while (nm_ip4_config_iter_ip4_route_next (&ipconf_iter_src, &r_src)) {
|
||||
nm_dedup_multi_index_add (dst_priv->multi_idx,
|
||||
&dst_priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r_src),
|
||||
NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE);
|
||||
}
|
||||
|
||||
/* nameservers */
|
||||
|
|
@ -1339,8 +1475,11 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
|
|||
void
|
||||
nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
|
||||
{
|
||||
guint32 i, tmp;
|
||||
guint32 tmp;
|
||||
guint i;
|
||||
const char *str;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
g_message ("--------- NMIP4Config %p (%s)", config, detail);
|
||||
|
||||
|
|
@ -1370,8 +1509,8 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail)
|
|||
}
|
||||
|
||||
/* routes */
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++)
|
||||
g_message (" rt: %s", nm_platform_ip4_route_to_string (nm_ip4_config_get_route (config, i), NULL, 0));
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route)
|
||||
g_message (" rt: %s", nm_platform_ip4_route_to_string (route, NULL, 0));
|
||||
|
||||
/* domains */
|
||||
for (i = 0; i < nm_ip4_config_get_num_domains (config); i++)
|
||||
|
|
@ -1621,13 +1760,88 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
|
|||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
if (priv->routes->len != 0) {
|
||||
g_array_set_size (priv->routes, 0);
|
||||
if (nm_dedup_multi_index_remove_idx (priv->multi_idx,
|
||||
&priv->idx_ip4_routes) > 0) {
|
||||
_notify (config, PROP_ROUTE_DATA);
|
||||
_notify (config, PROP_ROUTES);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_add_route (NMIP4Config *config, const NMPObject *o_new, const NMPlatformIP4Route *new)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv;
|
||||
NMPObject o_new_storage;
|
||||
const NMDedupMultiBox *box_old;
|
||||
|
||||
nm_assert (NM_IS_IP4_CONFIG (config));
|
||||
|
||||
priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
nm_assert (priv->ifindex > 0);
|
||||
|
||||
/* we go through extra lengths to accept a full o_new object. That one,
|
||||
* can be reused by increasing the ref-count. */
|
||||
if (!o_new) {
|
||||
nm_assert (new);
|
||||
nm_assert (new->plen > 0 && new->plen <= 32);
|
||||
nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
(const NMPlatformObject *) new);
|
||||
o_new_storage.ip4_route.ifindex = priv->ifindex;
|
||||
o_new = &o_new_storage;
|
||||
} else {
|
||||
nm_assert (!new);
|
||||
nm_assert (NMP_OBJECT_GET_TYPE (o_new) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
||||
nm_assert (o_new->ip4_route.plen > 0 && o_new->ip4_route.plen <= 32);
|
||||
if (o_new->ip4_route.ifindex != priv->ifindex) {
|
||||
nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE, &o_new->object);
|
||||
o_new_storage.ip4_route.ifindex = priv->ifindex;
|
||||
o_new = &o_new_storage;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nm_dedup_multi_index_add (priv->multi_idx,
|
||||
&priv->idx_ip4_routes,
|
||||
o_new,
|
||||
NM_DEDUP_MULTI_IDX_MODE_APPEND,
|
||||
NULL,
|
||||
&box_old)) {
|
||||
if (box_old)
|
||||
nm_dedup_multi_box_unref (priv->multi_idx, box_old);
|
||||
return;
|
||||
}
|
||||
|
||||
if (box_old) {
|
||||
NMIPConfigSource old_source;
|
||||
|
||||
old_source = ((const NMPObject *) box_old->obj)->ip_route.rt_source;
|
||||
/* we want to keep the maximum rt_source. But since we expect
|
||||
* that usually we already add the maxiumum right away, we first try to
|
||||
* add the new route (replacing the old one). Only if we later
|
||||
* find out that rt_source is now lower, we fix it.
|
||||
*/
|
||||
if (o_new->ip_route.rt_source < old_source) {
|
||||
if (o_new != &o_new_storage) {
|
||||
nmp_object_stackinit (&o_new_storage, NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
&o_new->object);
|
||||
o_new = &o_new_storage;
|
||||
}
|
||||
o_new_storage.ip_route.rt_source = old_source;
|
||||
if (!nm_dedup_multi_index_add (priv->multi_idx,
|
||||
&priv->idx_ip4_routes,
|
||||
o_new,
|
||||
NM_DEDUP_MULTI_IDX_MODE_APPEND,
|
||||
NULL,
|
||||
NULL))
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
nm_dedup_multi_box_unref (priv->multi_idx, box_old);
|
||||
}
|
||||
|
||||
_notify (config, PROP_ROUTE_DATA);
|
||||
_notify (config, PROP_ROUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_ip4_config_add_route:
|
||||
* @config: the #NMIP4Config
|
||||
|
|
@ -1641,76 +1855,70 @@ nm_ip4_config_reset_routes (NMIP4Config *config)
|
|||
void
|
||||
nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *new)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
NMIPConfigSource old_source;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (new != NULL);
|
||||
g_return_if_fail (config);
|
||||
g_return_if_fail (new);
|
||||
g_return_if_fail (new->plen > 0 && new->plen <= 32);
|
||||
g_return_if_fail (priv->ifindex > 0);
|
||||
g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (config)->ifindex > 0);
|
||||
|
||||
for (i = 0; i < priv->routes->len; i++ ) {
|
||||
NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
|
||||
if (routes_are_duplicate (item, new, FALSE)) {
|
||||
if (nm_platform_ip4_route_cmp (item, new) == 0)
|
||||
return;
|
||||
old_source = item->rt_source;
|
||||
memcpy (item, new, sizeof (*item));
|
||||
/* Restore highest priority source */
|
||||
item->rt_source = MAX (old_source, new->rt_source);
|
||||
item->ifindex = priv->ifindex;
|
||||
goto NOTIFY;
|
||||
}
|
||||
}
|
||||
|
||||
g_array_append_val (priv->routes, *new);
|
||||
g_array_index (priv->routes, NMPlatformIP4Route, priv->routes->len - 1).ifindex = priv->ifindex;
|
||||
NOTIFY:
|
||||
_notify (config, PROP_ROUTE_DATA);
|
||||
_notify (config, PROP_ROUTES);
|
||||
_add_route (config, NULL, new);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_del_route (NMIP4Config *config, guint i)
|
||||
_nmtst_nm_ip4_config_del_route (NMIP4Config *self, guint i)
|
||||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
const NMPlatformIP4Route *r;
|
||||
|
||||
g_return_if_fail (i < priv->routes->len);
|
||||
r = _nmtst_nm_ip4_config_get_route (self, i);
|
||||
g_return_if_fail (r);
|
||||
|
||||
g_array_remove_index (priv->routes, i);
|
||||
_notify (config, PROP_ROUTE_DATA);
|
||||
_notify (config, PROP_ROUTES);
|
||||
if (nm_dedup_multi_index_remove_obj (priv->multi_idx,
|
||||
&priv->idx_ip4_routes,
|
||||
NMP_OBJECT_UP_CAST (r)) != 1)
|
||||
g_return_if_reached ();
|
||||
_notify (self, PROP_ROUTE_DATA);
|
||||
_notify (self, PROP_ROUTES);
|
||||
}
|
||||
|
||||
guint
|
||||
nm_ip4_config_get_num_routes (const NMIP4Config *config)
|
||||
nm_ip4_config_get_num_routes (const NMIP4Config *self)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
|
||||
return priv->routes->len;
|
||||
head_entry = _idx_ip4_routes (self);
|
||||
nm_assert ((head_entry ? head_entry->len : 0) == c_list_length (&head_entry->lst_entries_head));
|
||||
return head_entry ? head_entry->len : 0;
|
||||
}
|
||||
|
||||
const NMPlatformIP4Route *
|
||||
nm_ip4_config_get_route (const NMIP4Config *config, guint i)
|
||||
_nmtst_nm_ip4_config_get_route (const NMIP4Config *self, guint i)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
const NMDedupMultiHeadEntry *head_entry;
|
||||
CList *iter;
|
||||
guint j;
|
||||
|
||||
return &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
head_entry = _idx_ip4_routes (self);
|
||||
if (head_entry) {
|
||||
j = 0;
|
||||
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
||||
if (i == j)
|
||||
return _entry_iter_get_ip4_route (iter);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
const NMPlatformIP4Route *
|
||||
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host)
|
||||
nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host)
|
||||
{
|
||||
const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
guint i;
|
||||
NMPlatformIP4Route *best_route = NULL;
|
||||
const NMPlatformIP4Route *best_route = NULL;
|
||||
const NMPlatformIP4Route *item;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
|
||||
g_return_val_if_fail (host, NULL);
|
||||
|
||||
for (i = 0; i < priv->routes->len; i++) {
|
||||
NMPlatformIP4Route *item = &g_array_index (priv->routes, NMPlatformIP4Route, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, self, &item) {
|
||||
if (item->gateway != 0)
|
||||
continue;
|
||||
|
||||
|
|
@ -1725,7 +1933,6 @@ nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host
|
|||
|
||||
best_route = item;
|
||||
}
|
||||
|
||||
return best_route;
|
||||
}
|
||||
|
||||
|
|
@ -2193,6 +2400,8 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
|
|||
{
|
||||
guint i;
|
||||
const char *s;
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
g_return_if_fail (config);
|
||||
g_return_if_fail (sum);
|
||||
|
|
@ -2208,9 +2417,8 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only
|
|||
hash_u32 (sum, address->peer_address & nm_utils_ip4_prefix_to_netmask (address->plen));
|
||||
}
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (config); i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
|
||||
hash_u32 (sum, route->network);
|
||||
hash_u32 (sum, route->plen);
|
||||
hash_u32 (sum, route->gateway);
|
||||
|
|
@ -2295,6 +2503,9 @@ get_property (GObject *object, guint prop_id,
|
|||
{
|
||||
NMIP4Config *config = NM_IP4_CONFIG (object);
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
GVariantBuilder array_builder, addr_builder, route_builder;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
|
|
@ -2303,7 +2514,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_ADDRESS_DATA:
|
||||
case PROP_ADDRESSES:
|
||||
{
|
||||
GVariantBuilder array_builder, addr_builder;
|
||||
gs_unref_array GArray *new = NULL;
|
||||
guint naddr, i;
|
||||
|
||||
|
|
@ -2370,14 +2580,8 @@ return_cached:
|
|||
break;
|
||||
case PROP_ROUTE_DATA:
|
||||
{
|
||||
GVariantBuilder array_builder, route_builder;
|
||||
guint nroutes = nm_ip4_config_get_num_routes (config);
|
||||
guint i;
|
||||
|
||||
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}"));
|
||||
for (i = 0; i < nroutes; i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
|
||||
g_variant_builder_init (&route_builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_builder_add (&route_builder, "{sv}",
|
||||
"dest",
|
||||
|
|
@ -2402,13 +2606,8 @@ return_cached:
|
|||
break;
|
||||
case PROP_ROUTES:
|
||||
{
|
||||
GVariantBuilder array_builder;
|
||||
guint nroutes = nm_ip4_config_get_num_routes (config);
|
||||
guint i;
|
||||
|
||||
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau"));
|
||||
for (i = 0; i < nroutes; i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (config, i);
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, config, &route) {
|
||||
guint32 dbus_route[4];
|
||||
|
||||
/* legacy versions of nm_ip4_route_set_prefix() in libnm-util assert that the
|
||||
|
|
@ -2501,8 +2700,10 @@ nm_ip4_config_init (NMIP4Config *config)
|
|||
{
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config);
|
||||
|
||||
nm_ip_config_dedup_multi_idx_type_init ((NMIPConfigDedupMultiIdxType *) &priv->idx_ip4_routes,
|
||||
NMP_OBJECT_TYPE_IP4_ROUTE);
|
||||
|
||||
priv->addresses = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Address));
|
||||
priv->routes = g_array_new (FALSE, FALSE, sizeof (NMPlatformIP4Route));
|
||||
priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32));
|
||||
priv->domains = g_ptr_array_new_with_free_func (g_free);
|
||||
priv->searches = g_ptr_array_new_with_free_func (g_free);
|
||||
|
|
@ -2528,10 +2729,11 @@ finalize (GObject *object)
|
|||
NMIP4Config *self = NM_IP4_CONFIG (object);
|
||||
NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
nm_dedup_multi_index_remove_idx (priv->multi_idx, &priv->idx_ip4_routes);
|
||||
|
||||
nm_clear_g_variant (&priv->address_data_variant);
|
||||
nm_clear_g_variant (&priv->addresses_variant);
|
||||
g_array_unref (priv->addresses);
|
||||
g_array_unref (priv->routes);
|
||||
g_array_unref (priv->nameservers);
|
||||
g_ptr_array_unref (priv->domains);
|
||||
g_ptr_array_unref (priv->searches);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,27 @@
|
|||
#include "nm-exported-object.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
|
||||
#include "nm-utils/nm-dedup-multi.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMDedupMultiIdxType parent;
|
||||
NMPObjectType obj_type;
|
||||
} NMIPConfigDedupMultiIdxType;
|
||||
|
||||
void nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type, NMPObjectType obj_type);
|
||||
|
||||
void nm_ip4_config_iter_ip4_route_init (NMDedupMultiIter *iter, const NMIP4Config *self);
|
||||
gboolean nm_ip4_config_iter_ip4_route_next (NMDedupMultiIter *iter, const NMPlatformIP4Route **out_route);
|
||||
|
||||
#define nm_ip4_config_iter_ip4_route_for_each(iter, self, route) \
|
||||
for (nm_ip4_config_iter_ip4_route_init ((iter), (self)); \
|
||||
nm_ip4_config_iter_ip4_route_next ((iter), (route)); \
|
||||
)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_IP4_CONFIG (nm_ip4_config_get_type ())
|
||||
#define NM_IP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IP4_CONFIG, NMIP4Config))
|
||||
#define NM_IP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IP4_CONFIG, NMIP4ConfigClass))
|
||||
|
|
@ -55,14 +76,14 @@ typedef struct _NMIP4ConfigClass NMIP4ConfigClass;
|
|||
GType nm_ip4_config_get_type (void);
|
||||
|
||||
|
||||
NMIP4Config * nm_ip4_config_new (struct _NMDedupMultiIndex *multi_idx,
|
||||
NMIP4Config * nm_ip4_config_new (NMDedupMultiIndex *multi_idx,
|
||||
int ifindex);
|
||||
|
||||
int nm_ip4_config_get_ifindex (const NMIP4Config *config);
|
||||
|
||||
struct _NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
|
||||
NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
|
||||
|
||||
NMIP4Config *nm_ip4_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
|
||||
NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex, gboolean capture_resolv_conf);
|
||||
gboolean nm_ip4_config_commit (const NMIP4Config *config, NMPlatform *platform, NMRouteManager *route_manager, int ifindex, gboolean routes_full_sync, gint64 default_route_metric);
|
||||
void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric);
|
||||
NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config);
|
||||
|
|
@ -93,9 +114,9 @@ gboolean nm_ip4_config_address_exists (const NMIP4Config *config, const NMPlatfo
|
|||
|
||||
void nm_ip4_config_reset_routes (NMIP4Config *config);
|
||||
void nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *route);
|
||||
void nm_ip4_config_del_route (NMIP4Config *config, guint i);
|
||||
void _nmtst_nm_ip4_config_del_route (NMIP4Config *config, guint i);
|
||||
guint nm_ip4_config_get_num_routes (const NMIP4Config *config);
|
||||
const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint i);
|
||||
const NMPlatformIP4Route *_nmtst_nm_ip4_config_get_route (const NMIP4Config *config, guint i);
|
||||
|
||||
const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host);
|
||||
|
||||
|
|
|
|||
|
|
@ -168,8 +168,10 @@ add_proxy_config (GVariantBuilder *proxy_data, const NMProxyConfig *proxy_config
|
|||
static void
|
||||
get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
|
||||
{
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
char *cidr;
|
||||
int i;
|
||||
const NMPlatformIP4Route *routes;
|
||||
guint i;
|
||||
|
||||
/* Extract searches */
|
||||
for (i = 0; i < nm_ip4_config_get_num_searches (ip4); i++)
|
||||
|
|
@ -189,9 +191,7 @@ get_ip4_domains (GPtrArray *domains, NMIP4Config *ip4)
|
|||
g_ptr_array_add (domains, cidr);
|
||||
}
|
||||
|
||||
for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) {
|
||||
const NMPlatformIP4Route *routes = nm_ip4_config_get_route (ip4, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, ip4, &routes) {
|
||||
cidr = g_strdup_printf ("%s/%u",
|
||||
nm_utils_inet4_ntop (routes->network, NULL),
|
||||
routes->plen);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ test_subtract (void)
|
|||
g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0);
|
||||
|
||||
g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1);
|
||||
test_route = nm_ip4_config_get_route (dst, 0);
|
||||
test_route = _nmtst_nm_ip4_config_get_route (dst, 0);
|
||||
g_assert (test_route != NULL);
|
||||
g_assert_cmpuint (test_route->network, ==, nmtst_inet4_from_string (expected_route_dest));
|
||||
g_assert_cmpuint (test_route->plen, ==, expected_route_plen);
|
||||
|
|
@ -236,27 +236,27 @@ test_add_route_with_source (void)
|
|||
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
nm_ip4_config_add_route (a, &route);
|
||||
|
||||
test_route = nm_ip4_config_get_route (a, 0);
|
||||
test_route = _nmtst_nm_ip4_config_get_route (a, 0);
|
||||
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
|
||||
|
||||
route.rt_source = NM_IP_CONFIG_SOURCE_VPN;
|
||||
nm_ip4_config_add_route (a, &route);
|
||||
|
||||
test_route = nm_ip4_config_get_route (a, 0);
|
||||
test_route = _nmtst_nm_ip4_config_get_route (a, 0);
|
||||
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
|
||||
|
||||
/* Test that a lower priority address source is overwritten */
|
||||
nm_ip4_config_del_route (a, 0);
|
||||
_nmtst_nm_ip4_config_del_route (a, 0);
|
||||
route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
|
||||
nm_ip4_config_add_route (a, &route);
|
||||
|
||||
test_route = nm_ip4_config_get_route (a, 0);
|
||||
test_route = _nmtst_nm_ip4_config_get_route (a, 0);
|
||||
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL);
|
||||
|
||||
route.rt_source = NM_IP_CONFIG_SOURCE_USER;
|
||||
nm_ip4_config_add_route (a, &route);
|
||||
|
||||
test_route = nm_ip4_config_get_route (a, 0);
|
||||
test_route = _nmtst_nm_ip4_config_get_route (a, 0);
|
||||
g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER);
|
||||
|
||||
g_object_unref (a);
|
||||
|
|
|
|||
|
|
@ -942,6 +942,7 @@ print_vpn_config (NMVpnConnection *self)
|
|||
char *dns_domain = NULL;
|
||||
guint32 num, i;
|
||||
char buf[NM_UTILS_INET_ADDRSTRLEN];
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
|
||||
if (priv->ip4_external_gw) {
|
||||
_LOGI ("Data: VPN Gateway: %s",
|
||||
|
|
@ -954,6 +955,8 @@ print_vpn_config (NMVpnConnection *self)
|
|||
_LOGI ("Data: Tunnel Device: %s%s%s", NM_PRINT_FMT_QUOTE_STRING (priv->ip_iface));
|
||||
|
||||
if (priv->ip4_config) {
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
_LOGI ("Data: IPv4 configuration:");
|
||||
|
||||
address4 = nm_ip4_config_get_address (priv->ip4_config, 0);
|
||||
|
|
@ -965,10 +968,7 @@ print_vpn_config (NMVpnConnection *self)
|
|||
_LOGI ("Data: Internal Point-to-Point Address: %s", nm_utils_inet4_ntop (address4->peer_address, NULL));
|
||||
_LOGI ("Data: Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (priv->ip4_config));
|
||||
|
||||
num = nm_ip4_config_get_num_routes (priv->ip4_config);
|
||||
for (i = 0; i < num; i++) {
|
||||
const NMPlatformIP4Route *route = nm_ip4_config_get_route (priv->ip4_config, i);
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route) {
|
||||
_LOGI ("Data: Static Route: %s/%d Next Hop: %s",
|
||||
nm_utils_inet4_ntop (route->network, NULL),
|
||||
route->plen,
|
||||
|
|
@ -1404,7 +1404,6 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
const char *str;
|
||||
GVariant *v;
|
||||
gboolean b;
|
||||
guint i, n;
|
||||
int ip_ifindex;
|
||||
|
||||
g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT));
|
||||
|
|
@ -1505,9 +1504,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
if ( g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_PRESERVE_ROUTES, "b", &b)
|
||||
&& b) {
|
||||
if (priv->ip4_config) {
|
||||
n = nm_ip4_config_get_num_routes (priv->ip4_config);
|
||||
for (i = 0; i < n; i++)
|
||||
nm_ip4_config_add_route (config, nm_ip4_config_get_route (priv->ip4_config, i));
|
||||
NMDedupMultiIter ipconf_iter;
|
||||
const NMPlatformIP4Route *route;
|
||||
|
||||
nm_ip4_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route)
|
||||
nm_ip4_config_add_route (config, route);
|
||||
}
|
||||
} else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) {
|
||||
while (g_variant_iter_next (iter, "@au", &v)) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue