mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-08 19:40:34 +01:00
core: move setting NDisc addresses/routes to NMIP6Config
Add an utility function for resetting addresses/routes of NMIP6Config from NMNDisc data. For one, this de-duplicates code in device and nm-iface-helper. Also, we no longer first reset (delete) all addresses and add them anew. Instead, we first mark all entries as dirty for deletion, merge (append) the new entires, and delete the remaining dirty entires. This saves a extra work, in the expected case where NMIP6Config already contains several of the new entries.
This commit is contained in:
parent
1b3a0208d9
commit
057b63979e
5 changed files with 140 additions and 85 deletions
|
|
@ -7420,49 +7420,18 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ADDRESSES) {
|
||||
/* Rebuild address list from neighbor discovery cache. */
|
||||
nm_ip6_config_reset_addresses (priv->ac_ip6_config);
|
||||
|
||||
/* ndisc->addresses contains at most max_addresses entries.
|
||||
* This is different from what the kernel does, which
|
||||
* also counts static and temporary addresses when checking
|
||||
* max_addresses.
|
||||
**/
|
||||
for (i = 0; i < rdata->addresses_n; i++) {
|
||||
const NMNDiscAddress *discovered_address = &rdata->addresses[i];
|
||||
NMPlatformIP6Address address;
|
||||
|
||||
memset (&address, 0, sizeof (address));
|
||||
address.address = discovered_address->address;
|
||||
address.plen = system_support ? 64 : 128;
|
||||
address.timestamp = discovered_address->timestamp;
|
||||
address.lifetime = discovered_address->lifetime;
|
||||
address.preferred = discovered_address->preferred;
|
||||
if (address.preferred > address.lifetime)
|
||||
address.preferred = address.lifetime;
|
||||
address.addr_source = NM_IP_CONFIG_SOURCE_NDISC;
|
||||
address.n_ifa_flags = ifa_flags;
|
||||
|
||||
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
|
||||
}
|
||||
nm_ip6_config_reset_addresses_ndisc (priv->ac_ip6_config,
|
||||
rdata->addresses,
|
||||
rdata->addresses_n,
|
||||
system_support ? 64 : 128,
|
||||
ifa_flags);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ROUTES) {
|
||||
/* Rebuild route list from neighbor discovery cache. */
|
||||
nm_ip6_config_reset_routes (priv->ac_ip6_config);
|
||||
|
||||
for (i = 0; i < rdata->routes_n; i++) {
|
||||
const NMNDiscRoute *discovered_route = &rdata->routes[i];
|
||||
const NMPlatformIP6Route route = {
|
||||
.network = discovered_route->network,
|
||||
.plen = discovered_route->plen,
|
||||
.gateway = discovered_route->gateway,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
|
||||
.metric = nm_device_get_ip6_route_metric (self),
|
||||
};
|
||||
|
||||
nm_ip6_config_add_route (priv->ac_ip6_config, &route);
|
||||
}
|
||||
nm_ip6_config_reset_routes_ndisc (priv->ac_ip6_config,
|
||||
rdata->routes,
|
||||
rdata->routes_n,
|
||||
nm_device_get_ip6_route_metric (self));
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_DNS_SERVERS) {
|
||||
|
|
|
|||
|
|
@ -69,22 +69,24 @@ typedef struct {
|
|||
NMNDiscPreference preference;
|
||||
} NMNDiscGateway;
|
||||
|
||||
typedef struct {
|
||||
struct _NMNDiscAddress {
|
||||
struct in6_addr address;
|
||||
guint8 dad_counter;
|
||||
guint32 timestamp;
|
||||
guint32 lifetime;
|
||||
guint32 preferred;
|
||||
} NMNDiscAddress;
|
||||
};
|
||||
typedef struct _NMNDiscAddress NMNDiscAddress;
|
||||
|
||||
typedef struct {
|
||||
struct _NMNDiscRoute {
|
||||
struct in6_addr network;
|
||||
guint8 plen;
|
||||
struct in6_addr gateway;
|
||||
guint32 timestamp;
|
||||
guint32 lifetime;
|
||||
NMNDiscPreference preference;
|
||||
} NMNDiscRoute;
|
||||
};
|
||||
typedef struct _NMNDiscRoute NMNDiscRoute;
|
||||
|
||||
typedef struct {
|
||||
struct in6_addr address;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
NMIP6Config *existing;
|
||||
int system_support;
|
||||
guint32 ifa_flags = 0x00;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Check, whether kernel is recent enough, to help user space handling RA.
|
||||
|
|
@ -194,49 +193,18 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ADDRESSES) {
|
||||
/* Rebuild address list from neighbor discovery cache. */
|
||||
nm_ip6_config_reset_addresses (ndisc_config);
|
||||
|
||||
/* ndisc->addresses contains at most max_addresses entries.
|
||||
* This is different from what the kernel does, which
|
||||
* also counts static and temporary addresses when checking
|
||||
* max_addresses.
|
||||
**/
|
||||
for (i = 0; i < rdata->addresses_n; i++) {
|
||||
const NMNDiscAddress *discovered_address = &rdata->addresses[i];
|
||||
NMPlatformIP6Address address;
|
||||
|
||||
memset (&address, 0, sizeof (address));
|
||||
address.address = discovered_address->address;
|
||||
address.plen = system_support ? 64 : 128;
|
||||
address.timestamp = discovered_address->timestamp;
|
||||
address.lifetime = discovered_address->lifetime;
|
||||
address.preferred = discovered_address->preferred;
|
||||
if (address.preferred > address.lifetime)
|
||||
address.preferred = address.lifetime;
|
||||
address.addr_source = NM_IP_CONFIG_SOURCE_NDISC;
|
||||
address.n_ifa_flags = ifa_flags;
|
||||
|
||||
nm_ip6_config_add_address (ndisc_config, &address);
|
||||
}
|
||||
nm_ip6_config_reset_addresses_ndisc (ndisc_config,
|
||||
rdata->addresses,
|
||||
rdata->addresses_n,
|
||||
system_support ? 64 : 128,
|
||||
ifa_flags);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_ROUTES) {
|
||||
/* Rebuild route list from neighbor discovery cache. */
|
||||
nm_ip6_config_reset_routes (ndisc_config);
|
||||
|
||||
for (i = 0; i < rdata->routes_n; i++) {
|
||||
const NMNDiscRoute *discovered_route = &rdata->routes[i];
|
||||
const NMPlatformIP6Route route = {
|
||||
.network = discovered_route->network,
|
||||
.plen = discovered_route->plen,
|
||||
.gateway = discovered_route->gateway,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_NDISC,
|
||||
.metric = global_opt.priority_v6,
|
||||
};
|
||||
|
||||
nm_ip6_config_add_route (ndisc_config, &route);
|
||||
}
|
||||
nm_ip6_config_reset_routes_ndisc (ndisc_config,
|
||||
rdata->routes,
|
||||
rdata->routes_n,
|
||||
global_opt.priority_v6);
|
||||
}
|
||||
|
||||
if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "nm-core-internal.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "ndisc/nm-ndisc.h"
|
||||
|
||||
#include "introspection/org.freedesktop.NetworkManager.IP6Config.h"
|
||||
|
||||
|
|
@ -1189,6 +1190,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
|
|||
dst_priv = NM_IP6_CONFIG_GET_PRIVATE (dst);
|
||||
src_priv = NM_IP6_CONFIG_GET_PRIVATE (src);
|
||||
|
||||
g_return_val_if_fail (src_priv->ifindex > 0, FALSE);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (dst));
|
||||
|
||||
/* ifindex */
|
||||
|
|
@ -1520,6 +1523,58 @@ nm_ip6_config_get_route_metric (const NMIP6Config *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self,
|
||||
const NMNDiscAddress *addresses,
|
||||
guint addresses_n,
|
||||
guint8 plen,
|
||||
guint32 ifa_flags)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv;
|
||||
guint i;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (self));
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv->ifindex > 0);
|
||||
|
||||
nm_dedup_multi_index_dirty_set_idx (priv->multi_idx, &priv->idx_ip6_addresses);
|
||||
|
||||
for (i = 0; i < addresses_n; i++) {
|
||||
const NMNDiscAddress *ndisc_addr = &addresses[i];
|
||||
NMPObject obj;
|
||||
NMPlatformIP6Address *a;
|
||||
|
||||
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ADDRESS, NULL);
|
||||
a = NMP_OBJECT_CAST_IP6_ADDRESS (&obj);
|
||||
a->ifindex = priv->ifindex;
|
||||
a->address = ndisc_addr->address;
|
||||
a->plen = plen;
|
||||
a->timestamp = ndisc_addr->timestamp;
|
||||
a->lifetime = ndisc_addr->lifetime;
|
||||
a->preferred = MIN (ndisc_addr->lifetime, ndisc_addr->preferred);
|
||||
a->addr_source = NM_IP_CONFIG_SOURCE_NDISC;
|
||||
a->n_ifa_flags = ifa_flags;
|
||||
|
||||
if (_nm_ip_config_add_obj (priv->multi_idx,
|
||||
&priv->idx_ip6_addresses_,
|
||||
priv->ifindex,
|
||||
&obj,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE))
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_addresses, FALSE) > 0)
|
||||
changed = TRUE;
|
||||
|
||||
if (changed)
|
||||
_notify_addresses (self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_reset_addresses (NMIP6Config *self)
|
||||
{
|
||||
|
|
@ -1698,6 +1753,55 @@ nm_ip6_config_has_any_dad_pending (const NMIP6Config *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
||||
const NMNDiscRoute *routes,
|
||||
guint routes_n,
|
||||
guint32 metric)
|
||||
{
|
||||
NMIP6ConfigPrivate *priv;
|
||||
guint i;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_CONFIG (self));
|
||||
|
||||
priv = NM_IP6_CONFIG_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv->ifindex > 0);
|
||||
|
||||
nm_dedup_multi_index_dirty_set_idx (priv->multi_idx, &priv->idx_ip6_routes);
|
||||
|
||||
for (i = 0; i < routes_n; i++) {
|
||||
const NMNDiscRoute *ndisc_route = &routes[i];
|
||||
NMPObject obj;
|
||||
NMPlatformIP6Route *r;
|
||||
|
||||
nmp_object_stackinit (&obj, NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
|
||||
r = NMP_OBJECT_CAST_IP6_ROUTE (&obj);
|
||||
r->ifindex = priv->ifindex;
|
||||
r->network = ndisc_route->network;
|
||||
r->plen = ndisc_route->plen;
|
||||
r->gateway = ndisc_route->gateway;
|
||||
r->rt_source = NM_IP_CONFIG_SOURCE_NDISC;
|
||||
r->metric = metric;
|
||||
|
||||
if (_nm_ip_config_add_obj (priv->multi_idx,
|
||||
&priv->idx_ip6_routes_,
|
||||
priv->ifindex,
|
||||
&obj,
|
||||
NULL,
|
||||
FALSE,
|
||||
TRUE))
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (nm_dedup_multi_index_dirty_remove_idx (priv->multi_idx, &priv->idx_ip6_routes, FALSE) > 0)
|
||||
changed = TRUE;
|
||||
|
||||
if (changed)
|
||||
_notify_routes (self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_reset_routes (NMIP6Config *self)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -191,6 +191,18 @@ gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b);
|
|||
|
||||
void nm_ip6_config_set_privacy (NMIP6Config *self, NMSettingIP6ConfigPrivacy privacy);
|
||||
|
||||
struct _NMNDiscAddress;
|
||||
void nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self,
|
||||
const struct _NMNDiscAddress *addresses,
|
||||
guint addresses_n,
|
||||
guint8 plen,
|
||||
guint32 ifa_flags);
|
||||
struct _NMNDiscRoute;
|
||||
void nm_ip6_config_reset_routes_ndisc (NMIP6Config *self,
|
||||
const struct _NMNDiscRoute *routes,
|
||||
guint routes_n,
|
||||
guint32 metric);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Testing-only functions */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue