summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-07-08 12:35:29 +0200
committerThomas Haller <thaller@redhat.com>2016-07-08 12:35:29 +0200
commit79c48a559f6e24820bb51b1328b9d2ac85214637 (patch)
treeb89ac186603e4fb27e2474c2be7c2a146465a8fb
parent10c53528552d1f0df8c28326a8f0bd2a31b9fa46 (diff)
parenta9524509e8737f93f7ab78509367efca406539b0 (diff)
downloadNetworkManager-79c48a559f6e24820bb51b1328b9d2ac85214637.tar.gz
rdisc: merge branch 'th/rdisc-cleanup-bgo768521'
https://bugzilla.gnome.org/show_bug.cgi?id=768521
-rw-r--r--src/Makefile.am4
-rw-r--r--src/devices/nm-device.c63
-rw-r--r--src/nm-core-utils.h2
-rw-r--r--src/nm-iface-helper.c49
-rw-r--r--src/rdisc/nm-fake-rdisc.c44
-rw-r--r--src/rdisc/nm-lndp-rdisc.c133
-rw-r--r--src/rdisc/nm-lndp-rdisc.h19
-rw-r--r--src/rdisc/nm-rdisc-private.h30
-rw-r--r--src/rdisc/nm-rdisc.c580
-rw-r--r--src/rdisc/nm-rdisc.h70
-rw-r--r--src/rdisc/tests/Makefile.am2
-rw-r--r--src/rdisc/tests/test-rdisc-fake.c179
12 files changed, 748 insertions, 427 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5e289d9363..04b8b694fc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -332,8 +332,6 @@ libNetworkManager_la_SOURCES = \
platform/wifi/wifi-utils.c \
platform/wifi/wifi-utils.h \
\
- rdisc/nm-fake-rdisc.c \
- rdisc/nm-fake-rdisc.h \
rdisc/nm-lndp-rdisc.c \
rdisc/nm-lndp-rdisc.h \
rdisc/nm-rdisc.c \
@@ -553,8 +551,6 @@ libnm_iface_helper_la_SOURCES = \
platform/wifi/wifi-utils.c \
platform/wifi/wifi-utils.h \
\
- rdisc/nm-fake-rdisc.c \
- rdisc/nm-fake-rdisc.h \
rdisc/nm-lndp-rdisc.c \
rdisc/nm-lndp-rdisc.h \
rdisc/nm-rdisc.c \
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 93d63a0411..f98ab0ec73 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -6097,8 +6097,9 @@ nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu)
}
static void
-rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
+rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, NMDevice *self)
{
+ NMRDiscConfigMap changed = changed_int;
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
int i;
int system_support;
@@ -6128,11 +6129,9 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
if (changed & NM_RDISC_CONFIG_GATEWAYS) {
/* Use the first gateway as ordered in router discovery cache. */
- if (rdisc->gateways->len) {
- NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
-
- nm_ip6_config_set_gateway (priv->ac_ip6_config, &gateway->address);
- } else
+ 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);
}
@@ -6145,8 +6144,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
* also counts static and temporary addresses when checking
* max_addresses.
**/
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ for (i = 0; i < rdata->addresses_n; i++) {
+ const NMRDiscAddress *discovered_address = &rdata->addresses[i];
NMPlatformIP6Address address;
memset (&address, 0, sizeof (address));
@@ -6168,25 +6167,17 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
/* Rebuild route list from router discovery cache. */
nm_ip6_config_reset_routes (priv->ac_ip6_config);
- for (i = 0; i < rdisc->routes->len; i++) {
- NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
- NMPlatformIP6Route route;
+ for (i = 0; i < rdata->routes_n; i++) {
+ const NMRDiscRoute *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_RDISC,
+ .metric = nm_device_get_ip6_route_metric (self),
+ };
- /* Only accept non-default routes. The router has no idea what the
- * local configuration or user preferences are, so sending routes
- * with a prefix length of 0 is quite rude and thus ignored.
- */
- if (discovered_route->plen > 0) {
- memset (&route, 0, sizeof (route));
- route.network = discovered_route->network;
- nm_assert (discovered_route->plen <= 128);
- route.plen = discovered_route->plen;
- route.gateway = discovered_route->gateway;
- route.rt_source = NM_IP_CONFIG_SOURCE_RDISC;
- route.metric = nm_device_get_ip6_route_metric (self);
-
- nm_ip6_config_add_route (priv->ac_ip6_config, &route);
- }
+ nm_ip6_config_add_route (priv->ac_ip6_config, &route);
}
}
@@ -6194,28 +6185,22 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
/* Rebuild DNS server list from router discovery cache. */
nm_ip6_config_reset_nameservers (priv->ac_ip6_config);
- for (i = 0; i < rdisc->dns_servers->len; i++) {
- NMRDiscDNSServer *discovered_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
-
- nm_ip6_config_add_nameserver (priv->ac_ip6_config, &discovered_server->address);
- }
+ for (i = 0; i < rdata->dns_servers_n; i++)
+ nm_ip6_config_add_nameserver (priv->ac_ip6_config, &rdata->dns_servers[i].address);
}
if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) {
/* Rebuild domain list from router discovery cache. */
nm_ip6_config_reset_domains (priv->ac_ip6_config);
- for (i = 0; i < rdisc->dns_domains->len; i++) {
- NMRDiscDNSDomain *discovered_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
-
- nm_ip6_config_add_domain (priv->ac_ip6_config, discovered_domain->domain);
- }
+ for (i = 0; i < rdata->dns_domains_n; i++)
+ nm_ip6_config_add_domain (priv->ac_ip6_config, rdata->dns_domains[i].domain);
}
if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) {
dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE);
- priv->dhcp6.mode = rdisc->dhcp_level;
+ priv->dhcp6.mode = rdata->dhcp_level;
if (priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE) {
NMDeviceStateReason reason;
@@ -6232,10 +6217,10 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *self)
}
if (changed & NM_RDISC_CONFIG_HOP_LIMIT)
- nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdisc->hop_limit);
+ nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdata->hop_limit);
if (changed & NM_RDISC_CONFIG_MTU)
- priv->ip6_mtu = rdisc->mtu;
+ priv->ip6_mtu = rdata->mtu;
nm_device_activate_schedule_ip6_config_result (self);
}
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index bfba35f575..90a4c23e6d 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -359,7 +359,7 @@ gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
guint dev_id,
NMUtilsIPv6IfaceId *out_iid);
-typedef enum {
+typedef enum { /*< skip >*/
NM_UTILS_STABLE_TYPE_UUID = 0,
NM_UTILS_STABLE_TYPE_STABLE_ID = 1,
} NMUtilsStableType;
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index e7f4b85434..49672cf565 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -130,8 +130,9 @@ dhcp4_state_changed (NMDhcpClient *client,
}
static void
-rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_data)
+rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, gpointer user_data)
{
+ NMRDiscConfigMap changed = changed_int;
static NMIP6Config *rdisc_config = NULL;
NMIP6Config *existing;
static int system_support = -1;
@@ -166,11 +167,9 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
if (changed & NM_RDISC_CONFIG_GATEWAYS) {
/* Use the first gateway as ordered in router discovery cache. */
- if (rdisc->gateways->len) {
- NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, 0);
-
- nm_ip6_config_set_gateway (rdisc_config, &gateway->address);
- } else
+ if (rdata->gateways_n)
+ nm_ip6_config_set_gateway (rdisc_config, &rdata->gateways[0].address);
+ else
nm_ip6_config_set_gateway (rdisc_config, NULL);
}
@@ -183,8 +182,8 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
* also counts static and temporary addresses when checking
* max_addresses.
**/
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ for (i = 0; i < rdata->addresses_n; i++) {
+ const NMRDiscAddress *discovered_address = &rdata->addresses[i];
NMPlatformIP6Address address;
memset (&address, 0, sizeof (address));
@@ -206,25 +205,17 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
/* Rebuild route list from router discovery cache. */
nm_ip6_config_reset_routes (rdisc_config);
- for (i = 0; i < rdisc->routes->len; i++) {
- NMRDiscRoute *discovered_route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
- NMPlatformIP6Route route;
-
- /* Only accept non-default routes. The router has no idea what the
- * local configuration or user preferences are, so sending routes
- * with a prefix length of 0 is quite rude and thus ignored.
- */
- if ( discovered_route->plen > 0
- && discovered_route->plen <= 128) {
- memset (&route, 0, sizeof (route));
- route.network = discovered_route->network;
- route.plen = discovered_route->plen;
- route.gateway = discovered_route->gateway;
- route.rt_source = NM_IP_CONFIG_SOURCE_RDISC;
- route.metric = global_opt.priority_v6;
-
- nm_ip6_config_add_route (rdisc_config, &route);
- }
+ for (i = 0; i < rdata->routes_n; i++) {
+ const NMRDiscRoute *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_RDISC,
+ .metric = global_opt.priority_v6,
+ };
+
+ nm_ip6_config_add_route (rdisc_config, &route);
}
}
@@ -233,12 +224,12 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, gpointer user_da
}
if (changed & NM_RDISC_CONFIG_HOP_LIMIT)
- nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdisc->hop_limit);
+ nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdata->hop_limit);
if (changed & NM_RDISC_CONFIG_MTU) {
char val[16];
- g_snprintf (val, sizeof (val), "%d", rdisc->mtu);
+ g_snprintf (val, sizeof (val), "%d", rdata->mtu);
nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val);
}
diff --git a/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c
index 6a1585b31f..46f2b08cf1 100644
--- a/src/rdisc/nm-fake-rdisc.c
+++ b/src/rdisc/nm-fake-rdisc.c
@@ -233,15 +233,20 @@ receive_ra (gpointer user_data)
NMFakeRDisc *self = user_data;
NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self);
NMRDisc *rdisc = NM_RDISC (self);
+ NMRDiscDataInternal *rdata = rdisc->rdata;
FakeRa *ra = priv->ras->data;
NMRDiscConfigMap changed = 0;
guint32 now = nm_utils_get_monotonic_timestamp_s ();
guint i;
+ NMRDiscDHCPLevel dhcp_level;
priv->receive_ra_id = 0;
- if (rdisc->dhcp_level != ra->dhcp_level) {
- rdisc->dhcp_level = ra->dhcp_level;
+ /* preserve the "most managed" level on updates. */
+ dhcp_level = MAX (rdata->public.dhcp_level, ra->dhcp_level);
+
+ if (rdata->public.dhcp_level != dhcp_level) {
+ rdata->public.dhcp_level = dhcp_level;
changed |= NM_RDISC_CONFIG_DHCP_LEVEL;
}
@@ -263,6 +268,8 @@ receive_ra (gpointer user_data)
.preference = item->preference,
};
+ g_assert (route.plen > 0 && route.plen <= 128);
+
if (nm_rdisc_add_route (rdisc, &route))
changed |= NM_RDISC_CONFIG_ROUTES;
@@ -294,13 +301,13 @@ receive_ra (gpointer user_data)
changed |= NM_RDISC_CONFIG_DNS_DOMAINS;
}
- if (rdisc->mtu != ra->mtu) {
- rdisc->mtu = ra->mtu;
+ if (rdata->public.mtu != ra->mtu) {
+ rdata->public.mtu = ra->mtu;
changed |= NM_RDISC_CONFIG_MTU;
}
- if (rdisc->hop_limit != ra->hop_limit) {
- rdisc->hop_limit = ra->hop_limit;
+ if (rdata->public.hop_limit != ra->hop_limit) {
+ rdata->public.hop_limit = ra->hop_limit;
changed |= NM_RDISC_CONFIG_HOP_LIMIT;
}
@@ -344,15 +351,10 @@ nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self)
NMRDisc *
nm_fake_rdisc_new (int ifindex, const char *ifname)
{
- NMRDisc *rdisc = g_object_new (NM_TYPE_FAKE_RDISC, NULL);
-
- rdisc->ifindex = ifindex;
- rdisc->ifname = g_strdup (ifname);
- rdisc->max_addresses = NM_RDISC_MAX_ADDRESSES_DEFAULT;
- rdisc->rtr_solicitations = NM_RDISC_RTR_SOLICITATIONS_DEFAULT;
- rdisc->rtr_solicitation_interval = NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT;
-
- return rdisc;
+ return g_object_new (NM_TYPE_FAKE_RDISC,
+ NM_RDISC_IFINDEX, ifindex,
+ NM_RDISC_IFNAME, ifname,
+ NULL);
}
static void
@@ -385,10 +387,10 @@ nm_fake_rdisc_class_init (NMFakeRDiscClass *klass)
rdisc_class->start = start;
rdisc_class->send_rs = send_rs;
- signals[RS_SENT] = g_signal_new (
- NM_FAKE_RDISC_RS_SENT,
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
+ signals[RS_SENT] =
+ g_signal_new (NM_FAKE_RDISC_RS_SENT,
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 0);
}
diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c
index fca61f79ad..12c2e30d94 100644
--- a/src/rdisc/nm-lndp-rdisc.c
+++ b/src/rdisc/nm-lndp-rdisc.c
@@ -20,39 +20,65 @@
#include "nm-default.h"
+#include "nm-lndp-rdisc.h"
+
#include <string.h>
#include <arpa/inet.h>
/* stdarg.h included because of a bug in ndp.h */
#include <stdarg.h>
#include <ndp.h>
-#include "nm-lndp-rdisc.h"
#include "nm-rdisc-private.h"
-
#include "NetworkManagerUtils.h"
#include "nm-platform.h"
#include "nmp-netns.h"
#define _NMLOG_PREFIX_NAME "rdisc-lndp"
+/*****************************************************************************/
+
typedef struct {
struct ndp *ndp;
GIOChannel *event_channel;
guint event_id;
guint ra_timeout_id; /* first RA timeout */
-} NMLNDPRDiscPrivate;
+} NMLndpRDiscPrivate;
+
+/*****************************************************************************/
-#define NM_LNDP_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LNDP_RDISC, NMLNDPRDiscPrivate))
+struct _NMLndpRDisc {
+ NMRDisc parent;
+ NMLndpRDiscPrivate _priv;
+};
-G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC)
+struct _NMLndpRDiscClass {
+ NMRDiscClass parent;
+};
-/******************************************************************/
+/*****************************************************************************/
+
+G_DEFINE_TYPE (NMLndpRDisc, nm_lndp_rdisc, NM_TYPE_RDISC)
+
+#define NM_LNDP_RDISC_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMLndpRDisc *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_LNDP_RDISC (_self)); \
+ &_self->_priv; \
+ })
+
+/*****************************************************************************/
static gboolean
send_rs (NMRDisc *rdisc, GError **error)
{
- NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+ NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc);
struct ndp_msg *msg;
int errsv;
@@ -63,7 +89,7 @@ send_rs (NMRDisc *rdisc, GError **error)
"cannot create router solicitation");
return FALSE;
}
- ndp_msg_ifindex_set (msg, rdisc->ifindex);
+ ndp_msg_ifindex_set (msg, nm_rdisc_get_ifindex (rdisc));
errsv = ndp_msg_send (priv->ndp, msg);
ndp_msg_destroy (msg);
@@ -89,6 +115,7 @@ static int
receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
{
NMRDisc *rdisc = (NMRDisc *) user_data;
+ NMRDiscDataInternal *rdata = rdisc->rdata;
NMRDiscConfigMap changed = 0;
struct ndp_msgra *msgra = ndp_msgra (msg);
struct in6_addr gateway_addr;
@@ -125,8 +152,14 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
else
dhcp_level = NM_RDISC_DHCP_LEVEL_NONE;
- if (dhcp_level != rdisc->dhcp_level) {
- rdisc->dhcp_level = dhcp_level;
+ /* when receiving multiple RA (possibly from different routers),
+ * let's keep the "most managed" level. */
+ G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_MANAGED > NM_RDISC_DHCP_LEVEL_OTHERCONF);
+ G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_OTHERCONF > NM_RDISC_DHCP_LEVEL_NONE);
+ dhcp_level = MAX (dhcp_level, rdata->public.dhcp_level);
+
+ if (dhcp_level != rdata->public.dhcp_level) {
+ rdata->public.dhcp_level = dhcp_level;
changed |= NM_RDISC_CONFIG_DHCP_LEVEL;
}
}
@@ -255,8 +288,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
}
hop_limit = ndp_msgra_curhoplimit (msgra);
- if (rdisc->hop_limit != hop_limit) {
- rdisc->hop_limit = hop_limit;
+ if (rdata->public.hop_limit != hop_limit) {
+ rdata->public.hop_limit = hop_limit;
changed |= NM_RDISC_CONFIG_HOP_LIMIT;
}
@@ -264,8 +297,10 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_MTU) {
guint32 mtu = ndp_msg_opt_mtu(msg, offset);
if (mtu >= 1280) {
- rdisc->mtu = mtu;
- changed |= NM_RDISC_CONFIG_MTU;
+ if (rdata->public.mtu != mtu) {
+ rdata->public.mtu = mtu;
+ changed |= NM_RDISC_CONFIG_MTU;
+ }
} else {
/* All sorts of bad things would happen if we accepted this.
* Kernel would set it, but would flush out all IPv6 addresses away
@@ -283,7 +318,7 @@ static gboolean
event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
- NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+ NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc);
_LOGD ("processing libndp events");
@@ -297,7 +332,7 @@ event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc)
static void
start (NMRDisc *rdisc)
{
- NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+ NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc);
int fd = ndp_get_eventfd (priv->ndp);
priv->event_channel = g_io_channel_unix_new (fd);
@@ -306,15 +341,25 @@ start (NMRDisc *rdisc)
/* Flush any pending messages to avoid using obsolete information */
event_ready (priv->event_channel, 0, rdisc);
- ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, rdisc->ifindex, rdisc);
+ ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc);
}
-/******************************************************************/
+/*****************************************************************************/
-static inline gint32
-ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, gint32 defval)
+static inline int
+ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval)
+{
+ return (int) nm_platform_sysctl_get_int_checked (platform,
+ nm_utils_ip6_property_path (ifname, property),
+ 10,
+ min,
+ max,
+ defval);
+}
+
+static void
+nm_lndp_rdisc_init (NMLndpRDisc *lndp_rdisc)
{
- return nm_platform_sysctl_get_int32 (platform, nm_utils_ip6_property_path (ifname, property), defval);
}
NMRDisc *
@@ -328,7 +373,7 @@ nm_lndp_rdisc_new (NMPlatform *platform,
{
nm_auto_pop_netns NMPNetns *netns = NULL;
NMRDisc *rdisc;
- NMLNDPRDiscPrivate *priv;
+ NMLndpRDiscPrivate *priv;
int errsv;
g_return_val_if_fail (NM_IS_PLATFORM (platform), NULL);
@@ -339,22 +384,23 @@ nm_lndp_rdisc_new (NMPlatform *platform,
rdisc = g_object_new (NM_TYPE_LNDP_RDISC,
NM_RDISC_PLATFORM, platform,
+ NM_RDISC_STABLE_TYPE, (int) stable_type,
+ NM_RDISC_IFINDEX, ifindex,
+ NM_RDISC_IFNAME, ifname,
+ NM_RDISC_NETWORK_ID, network_id,
+ NM_RDISC_ADDR_GEN_MODE, (int) addr_gen_mode,
+ NM_RDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname,
+ "max_addresses",
+ 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT),
+ NM_RDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname,
+ "router_solicitations",
+ 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT),
+ NM_RDISC_ROUTER_SOLICITATION_INTERVAL, ipv6_sysctl_get (platform, ifname,
+ "router_solicitation_interval",
+ 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT),
NULL);
- rdisc->ifindex = ifindex;
- rdisc->ifname = g_strdup (ifname);
- rdisc->stable_type = stable_type;
- rdisc->network_id = g_strdup (network_id);
- rdisc->addr_gen_mode = addr_gen_mode;
-
- rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
- NM_RDISC_MAX_ADDRESSES_DEFAULT);
- rdisc->rtr_solicitations = ipv6_sysctl_get (platform, ifname, "router_solicitations",
- NM_RDISC_RTR_SOLICITATIONS_DEFAULT);
- rdisc->rtr_solicitation_interval = ipv6_sysctl_get (platform, ifname, "router_solicitation_interval",
- NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT);
-
- priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+ priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc);
errsv = ndp_open (&priv->ndp);
@@ -370,21 +416,16 @@ nm_lndp_rdisc_new (NMPlatform *platform,
}
static void
-nm_lndp_rdisc_init (NMLNDPRDisc *lndp_rdisc)
-{
-}
-
-static void
dispose (GObject *object)
{
- NMLNDPRDisc *rdisc = NM_LNDP_RDISC (object);
- NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+ NMRDisc *rdisc = (NMRDisc *) object;
+ NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc);
nm_clear_g_source (&priv->event_id);
g_clear_pointer (&priv->event_channel, g_io_channel_unref);
if (priv->ndp) {
- ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, NM_RDISC (rdisc)->ifindex, rdisc);
+ ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc);
ndp_close (priv->ndp);
priv->ndp = NULL;
}
@@ -393,13 +434,11 @@ dispose (GObject *object)
}
static void
-nm_lndp_rdisc_class_init (NMLNDPRDiscClass *klass)
+nm_lndp_rdisc_class_init (NMLndpRDiscClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
NMRDiscClass *rdisc_class = NM_RDISC_CLASS (klass);
- g_type_class_add_private (klass, sizeof (NMLNDPRDiscPrivate));
-
object_class->dispose = dispose;
rdisc_class->start = start;
rdisc_class->send_rs = send_rs;
diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h
index 51290089ec..e2b47c0400 100644
--- a/src/rdisc/nm-lndp-rdisc.h
+++ b/src/rdisc/nm-lndp-rdisc.h
@@ -25,23 +25,14 @@
#include "nm-core-utils.h"
#define NM_TYPE_LNDP_RDISC (nm_lndp_rdisc_get_type ())
-#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDisc))
-#define NM_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_RDISC, NMLNDPRDiscClass))
+#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDisc))
+#define NM_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass))
#define NM_IS_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LNDP_RDISC))
#define NM_IS_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_LNDP_RDISC))
-#define NM_LNDP_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_RDISC, NMLNDPRDiscClass))
+#define NM_LNDP_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass))
-/******************************************************************/
-
-typedef struct {
- NMRDisc parent;
-} NMLNDPRDisc;
-
-typedef struct {
- NMRDiscClass parent;
-} NMLNDPRDiscClass;
-
-/******************************************************************/
+typedef struct _NMLndpRDisc NMLndpRDisc;
+typedef struct _NMLndpRDiscClass NMLndpRDiscClass;
GType nm_lndp_rdisc_get_type (void);
diff --git a/src/rdisc/nm-rdisc-private.h b/src/rdisc/nm-rdisc-private.h
index c0ec739aba..abc5a399b9 100644
--- a/src/rdisc/nm-rdisc-private.h
+++ b/src/rdisc/nm-rdisc-private.h
@@ -25,6 +25,17 @@
/* Functions only used by rdisc implementations */
+struct _NMRDiscDataInternal {
+ NMRDiscData public;
+ GArray *gateways;
+ GArray *addresses;
+ GArray *routes;
+ GArray *dns_servers;
+ GArray *dns_domains;
+};
+
+typedef struct _NMRDiscDataInternal NMRDiscDataInternal;
+
void nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed);
gboolean nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new);
@@ -44,19 +55,20 @@ gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDoma
const NMLogDomain __domain = (domain); \
\
if (nm_logging_enabled (__level, __domain)) { \
+ NMRDisc *const __self = (self); \
char __prefix[64]; \
- const char *__p_prefix = _NMLOG_PREFIX_NAME; \
- const NMRDisc *const __self = (self); \
\
- if (__self) { \
- g_snprintf (__prefix, sizeof (__prefix), "%s[%p,%s%s%s]", \
- _NMLOG_PREFIX_NAME, __self, \
- NM_PRINT_FMT_QUOTE_STRING (__self->ifname)); \
- __p_prefix = __prefix; \
- } \
_nm_log (__level, __domain, 0, \
"%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
- __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
+ (__self \
+ ? ({ \
+ const char *__ifname = nm_rdisc_get_ifname (__self); \
+ nm_sprintf_buf (__prefix, "%s[%p,%s%s%s]", \
+ _NMLOG_PREFIX_NAME, __self, \
+ NM_PRINT_FMT_QUOTE_STRING (__ifname)); \
+ }) \
+ : _NMLOG_PREFIX_NAME) \
+ _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
} \
} G_STMT_END
diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
index c11557d943..cf993bc311 100644
--- a/src/rdisc/nm-rdisc.c
+++ b/src/rdisc/nm-rdisc.c
@@ -20,36 +20,61 @@
#include "nm-default.h"
+#include "nm-rdisc.h"
+
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
-#include "nm-rdisc.h"
-#include "nm-rdisc-private.h"
+#include "nm-setting-ip6-config.h"
+#include "nm-rdisc-private.h"
#include "nm-utils.h"
#include "nm-platform.h"
#include "nmp-netns.h"
-#include <nm-setting-ip6-config.h>
-
#define _NMLOG_PREFIX_NAME "rdisc"
-typedef struct {
- int solicitations_left;
+/*****************************************************************************/
+
+struct _NMRDiscPrivate {
+ /* this *must* be the first field. */
+ NMRDiscDataInternal rdata;
+
+ gint32 solicitations_left;
guint send_rs_id;
- gint64 last_rs;
+ gint32 last_rs;
guint ra_timeout_id; /* first RA timeout */
guint timeout_id; /* prefix/dns/etc lifetime timeout */
char *last_send_rs_error;
-} NMRDiscPrivate;
-
-#define NM_RDISC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_RDISC, NMRDiscPrivate))
+ NMUtilsIPv6IfaceId iid;
+
+ /* immutable values: */
+ int ifindex;
+ char *ifname;
+ char *network_id;
+ NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+ NMUtilsStableType stable_type;
+ gint32 max_addresses;
+ gint32 router_solicitations;
+ gint32 router_solicitation_interval;
+
+ NMPlatform *platform;
+ NMPNetns *netns;
+};
-G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT)
+typedef struct _NMRDiscPrivate NMRDiscPrivate;
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_PLATFORM,
+ PROP_IFINDEX,
+ PROP_IFNAME,
+ PROP_STABLE_TYPE,
+ PROP_NETWORK_ID,
+ PROP_ADDR_GEN_MODE,
+ PROP_MAX_ADDRESSES,
+ PROP_ROUTER_SOLICITATIONS,
+ PROP_ROUTER_SOLICITATION_INTERVAL,
);
enum {
@@ -60,49 +85,120 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-/******************************************************************/
+G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT)
+
+#define NM_RDISC_GET_PRIVATE(self) \
+ ({ \
+ /* preserve the const-ness of self. Unfortunately, that
+ * way, @self cannot be a void pointer */ \
+ typeof (self) _self = (self); \
+ \
+ /* Get compiler error if variable is of wrong type */ \
+ _nm_unused const NMRDisc *_self2 = (_self); \
+ \
+ nm_assert (NM_IS_RDISC (_self)); \
+ _self->_priv; \
+ })
+
+/*****************************************************************************/
+
+static void _config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed);
+
+/*****************************************************************************/
NMPNetns *
nm_rdisc_netns_get (NMRDisc *self)
{
g_return_val_if_fail (NM_IS_RDISC (self), NULL);
- return self->_netns;
+ return NM_RDISC_GET_PRIVATE (self)->netns;
}
gboolean
nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns)
{
+ NMRDiscPrivate *priv;
+
g_return_val_if_fail (NM_IS_RDISC (self), FALSE);
- if ( self->_netns
- && !nmp_netns_push (self->_netns)) {
+ priv = NM_RDISC_GET_PRIVATE (self);
+ if ( priv->netns
+ && !nmp_netns_push (priv->netns)) {
NM_SET_OUT (netns, NULL);
return FALSE;
}
- NM_SET_OUT (netns, self->_netns);
+ NM_SET_OUT (netns, priv->netns);
return TRUE;
}
-/******************************************************************/
+/*****************************************************************************/
+
+int
+nm_rdisc_get_ifindex (NMRDisc *self)
+{
+ g_return_val_if_fail (NM_IS_RDISC (self), 0);
+
+ return NM_RDISC_GET_PRIVATE (self)->ifindex;
+}
+
+const char *
+nm_rdisc_get_ifname (NMRDisc *self)
+{
+ g_return_val_if_fail (NM_IS_RDISC (self), NULL);
+
+ return NM_RDISC_GET_PRIVATE (self)->ifname;
+}
+
+/*****************************************************************************/
+
+static const NMRDiscData *
+_data_complete (NMRDiscDataInternal *data)
+{
+#define _SET(data, field) \
+ G_STMT_START { \
+ if ((data->public.field##_n = data->field->len) > 0) \
+ data->public.field = (gpointer) data->field->data; \
+ else \
+ data->public.field = NULL; \
+ } G_STMT_END
+ _SET (data, gateways);
+ _SET (data, addresses);
+ _SET (data, routes);
+ _SET (data, dns_servers);
+ _SET (data, dns_domains);
+#undef _SET
+ return &data->public;
+}
+
+static void
+_emit_config_change (NMRDisc *self, NMRDiscConfigMap changed)
+{
+ _config_changed_log (self, changed);
+ g_signal_emit (self, signals[CONFIG_CHANGED], 0,
+ _data_complete (&NM_RDISC_GET_PRIVATE (self)->rdata),
+ (guint) changed);
+}
+
+/*****************************************************************************/
gboolean
nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new)
{
+ NMRDiscDataInternal *rdata = &NM_RDISC_GET_PRIVATE(rdisc)->rdata;
int i, insert_idx = -1;
- for (i = 0; i < rdisc->gateways->len; i++) {
- NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i);
+ for (i = 0; i < rdata->gateways->len; i++) {
+ NMRDiscGateway *item = &g_array_index (rdata->gateways, NMRDiscGateway, i);
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
if (new->lifetime == 0) {
- g_array_remove_index (rdisc->gateways, i--);
+ g_array_remove_index (rdata->gateways, i--);
return TRUE;
}
if (item->preference != new->preference) {
- g_array_remove_index (rdisc->gateways, i--);
+ g_array_remove_index (rdata->gateways, i--);
continue;
}
@@ -116,7 +212,7 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new)
}
if (new->lifetime)
- g_array_insert_val (rdisc->gateways, MAX (insert_idx, 0), *new);
+ g_array_insert_val (rdata->gateways, MAX (insert_idx, 0), *new);
return !!new->lifetime;
}
@@ -137,13 +233,17 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new)
static gboolean
complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
{
+ NMRDiscPrivate *priv;
GError *error = NULL;
- if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
- if (!nm_utils_ipv6_addr_set_stable_privacy (rdisc->stable_type,
+ g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE);
+
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
+ if (!nm_utils_ipv6_addr_set_stable_privacy (priv->stable_type,
&addr->address,
- rdisc->ifname,
- rdisc->network_id,
+ priv->ifname,
+ priv->network_id,
addr->dad_counter++,
&error)) {
_LOGW ("complete-address: failed to generate an stable-privacy address: %s",
@@ -155,14 +255,14 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
return TRUE;
}
- if (!rdisc->iid.id) {
+ if (!priv->iid.id) {
_LOGW ("complete-address: can't generate an EUI-64 address: no interface identifier");
return FALSE;
}
if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) {
_LOGD ("complete-address: adding an EUI-64 address");
- nm_utils_ipv6_addr_set_interface_identifier (&addr->address, rdisc->iid);
+ nm_utils_ipv6_addr_set_interface_identifier (&addr->address, priv->iid);
return TRUE;
}
@@ -173,19 +273,24 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr)
gboolean
nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
int i;
if (!complete_address (rdisc, new))
return FALSE;
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
+
+ for (i = 0; i < rdata->addresses->len; i++) {
+ NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i);
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
gboolean changed;
if (new->lifetime == 0) {
- g_array_remove_index (rdisc->addresses, i--);
+ g_array_remove_index (rdata->addresses, i--);
return TRUE;
}
@@ -200,33 +305,46 @@ nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new)
* what the kernel does, because it considers *all* addresses (including
* static and other temporary addresses).
**/
- if (rdisc->max_addresses && rdisc->addresses->len >= rdisc->max_addresses)
+ if (priv->max_addresses && rdata->addresses->len >= priv->max_addresses)
return FALSE;
if (new->lifetime)
- g_array_insert_val (rdisc->addresses, i, *new);
+ g_array_insert_val (rdata->addresses, i, *new);
return !!new->lifetime;
}
gboolean
nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
int i, insert_idx = -1;
- if (new->plen == 0 || new->plen > 128)
- return FALSE;
+ if (new->plen == 0 || new->plen > 128) {
+ /* Only expect non-default routes. The router has no idea what the
+ * local configuration or user preferences are, so sending routes
+ * with a prefix length of 0 must be ignored by NMRDisc.
+ *
+ * Also, upper layers also don't expect that NMRDisc exposes routes
+ * with a plen or zero or larger then 128.
+ */
+ g_return_val_if_reached (FALSE);
+ }
+
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
- for (i = 0; i < rdisc->routes->len; i++) {
- NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i);
+ for (i = 0; i < rdata->routes->len; i++) {
+ NMRDiscRoute *item = &g_array_index (rdata->routes, NMRDiscRoute, i);
if (IN6_ARE_ADDR_EQUAL (&item->network, &new->network) && item->plen == new->plen) {
if (new->lifetime == 0) {
- g_array_remove_index (rdisc->routes, i--);
+ g_array_remove_index (rdata->routes, i--);
return TRUE;
}
if (item->preference != new->preference) {
- g_array_remove_index (rdisc->routes, i--);
+ g_array_remove_index (rdata->routes, i--);
continue;
}
@@ -240,21 +358,26 @@ nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new)
}
if (new->lifetime)
- g_array_insert_val (rdisc->routes, CLAMP (insert_idx, 0, G_MAXINT), *new);
+ g_array_insert_val (rdata->routes, CLAMP (insert_idx, 0, G_MAXINT), *new);
return !!new->lifetime;
}
gboolean
nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
int i;
- for (i = 0; i < rdisc->dns_servers->len; i++) {
- NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
+
+ for (i = 0; i < rdata->dns_servers->len; i++) {
+ NMRDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i);
if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) {
if (new->lifetime == 0) {
- g_array_remove_index (rdisc->dns_servers, i);
+ g_array_remove_index (rdata->dns_servers, i);
return TRUE;
}
if (item->timestamp != new->timestamp || item->lifetime != new->lifetime) {
@@ -266,7 +389,7 @@ nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new)
}
if (new->lifetime)
- g_array_insert_val (rdisc->dns_servers, i, *new);
+ g_array_insert_val (rdata->dns_servers, i, *new);
return !!new->lifetime;
}
@@ -274,17 +397,22 @@ nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new)
gboolean
nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
NMRDiscDNSDomain *item;
int i;
- for (i = 0; i < rdisc->dns_domains->len; i++) {
- item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
+
+ for (i = 0; i < rdata->dns_domains->len; i++) {
+ item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i);
if (!g_strcmp0 (item->domain, new->domain)) {
gboolean changed;
if (new->lifetime == 0) {
- g_array_remove_index (rdisc->dns_domains, i);
+ g_array_remove_index (rdata->dns_domains, i);
return TRUE;
}
@@ -299,8 +427,8 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new)
}
if (new->lifetime) {
- g_array_insert_val (rdisc->dns_domains, i, *new);
- item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
+ g_array_insert_val (rdata->dns_domains, i, *new);
+ item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i);
item->domain = g_strdup (new->domain);
}
return !!new->lifetime;
@@ -330,18 +458,24 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new)
gboolean
nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
+
g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE);
- if (rdisc->iid.id != iid.id) {
- rdisc->iid = iid;
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
- if (rdisc->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)
+ if (priv->iid.id != iid.id) {
+ priv->iid = iid;
+
+ if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)
return FALSE;
- if (rdisc->addresses->len) {
+ if (rdata->addresses->len) {
_LOGD ("IPv6 interface identifier changed, flushing addresses");
- g_array_remove_range (rdisc->addresses, 0, rdisc->addresses->len);
- g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, NM_RDISC_CONFIG_ADDRESSES);
+ g_array_remove_range (rdata->addresses, 0, rdata->addresses->len);
+ _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES);
}
return TRUE;
}
@@ -350,13 +484,15 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid)
}
static gboolean
-send_rs (NMRDisc *rdisc)
+send_rs_timeout (NMRDisc *rdisc)
{
nm_auto_pop_netns NMPNetns *netns = NULL;
NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
GError *error = NULL;
+ priv->send_rs_id = 0;
+
if (!nm_rdisc_netns_push (rdisc, &netns))
return G_SOURCE_REMOVE;
@@ -380,13 +516,12 @@ send_rs (NMRDisc *rdisc)
priv->last_rs = nm_utils_get_monotonic_timestamp_s ();
if (priv->solicitations_left > 0) {
_LOGD ("scheduling router solicitation retry in %d seconds.",
- rdisc->rtr_solicitation_interval);
- priv->send_rs_id = g_timeout_add_seconds (rdisc->rtr_solicitation_interval,
- (GSourceFunc) send_rs, rdisc);
+ (int) priv->router_solicitation_interval);
+ priv->send_rs_id = g_timeout_add_seconds (priv->router_solicitation_interval,
+ (GSourceFunc) send_rs_timeout, rdisc);
} else {
_LOGD ("did not receive a router advertisement after %d solicitations.",
- rdisc->rtr_solicitations);
- priv->send_rs_id = 0;
+ (int) priv->router_solicitations);
}
return G_SOURCE_REMOVE;
@@ -396,17 +531,20 @@ static void
solicit (NMRDisc *rdisc)
{
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
- guint32 now = nm_utils_get_monotonic_timestamp_s ();
- gint64 next;
+ gint64 next, now;
+
+ if (priv->send_rs_id)
+ return;
- if (!priv->send_rs_id) {
- priv->solicitations_left = rdisc->rtr_solicitations;
+ now = nm_utils_get_monotonic_timestamp_s ();
- next = CLAMP (priv->last_rs + rdisc->rtr_solicitation_interval - now, 0, G_MAXINT32);
- _LOGD ("scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.",
- next);
- priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs, rdisc);
- }
+ priv->solicitations_left = priv->router_solicitations;
+
+ next = (((gint64) priv->last_rs) + priv->router_solicitation_interval) - now;
+ next = CLAMP (next, 0, G_MAXINT32);
+ _LOGD ("scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.",
+ next);
+ priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, rdisc);
}
static gboolean
@@ -415,7 +553,7 @@ rdisc_ra_timeout_cb (gpointer user_data)
NMRDisc *rdisc = NM_RDISC (user_data);
NM_RDISC_GET_PRIVATE (rdisc)->ra_timeout_id = 0;
- g_signal_emit_by_name (rdisc, NM_RDISC_RA_TIMEOUT);
+ g_signal_emit (rdisc, signals[RA_TIMEOUT], 0);
return G_SOURCE_REMOVE;
}
@@ -425,19 +563,20 @@ nm_rdisc_start (NMRDisc *rdisc)
nm_auto_pop_netns NMPNetns *netns = NULL;
NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
- guint ra_wait_secs;
+ gint64 ra_wait_secs;
g_assert (klass->start);
- _LOGD ("starting router discovery: %d", rdisc->ifindex);
+ _LOGD ("starting router discovery: %d", priv->ifindex);
if (!nm_rdisc_netns_push (rdisc, &netns))
return;
nm_clear_g_source (&priv->ra_timeout_id);
- ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120);
+ ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1;
+ ra_wait_secs = CLAMP (ra_wait_secs, 30, 120);
priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc);
- _LOGD ("scheduling RA timeout in %d seconds", ra_wait_secs);
+ _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs);
if (klass->start)
klass->start (rdisc);
@@ -448,23 +587,26 @@ nm_rdisc_start (NMRDisc *rdisc)
void
nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address)
{
+ NMRDiscDataInternal *rdata;
int i;
gboolean changed = FALSE;
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
+
+ for (i = 0; i < rdata->addresses->len; i++) {
+ NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i);
if (!IN6_ARE_ADDR_EQUAL (&item->address, address))
continue;
_LOGD ("DAD failed for discovered address %s", nm_utils_inet6_ntop (address, NULL));
if (!complete_address (rdisc, item))
- g_array_remove_index (rdisc->addresses, i--);
+ g_array_remove_index (rdata->addresses, i--);
changed = TRUE;
}
if (changed)
- g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, NM_RDISC_CONFIG_ADDRESSES);
+ _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES);
}
#define CONFIG_MAP_MAX_STR 7
@@ -505,64 +647,73 @@ dhcp_level_to_string (NMRDiscDHCPLevel dhcp_level)
#define expiry(item) (item->timestamp + item->lifetime)
static void
-config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed)
+_config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed)
{
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
int i;
char changedstr[CONFIG_MAP_MAX_STR];
char addrstr[INET6_ADDRSTRLEN];
- if (_LOGD_ENABLED ()) {
- config_map_to_string (changed, changedstr);
- _LOGD ("router discovery configuration changed [%s]:", changedstr);
- _LOGD (" dhcp-level %s", dhcp_level_to_string (rdisc->dhcp_level));
- for (i = 0; i < rdisc->gateways->len; i++) {
- NMRDiscGateway *gateway = &g_array_index (rdisc->gateways, NMRDiscGateway, i);
+ if (!_LOGD_ENABLED ())
+ return;
- inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr));
- _LOGD (" gateway %s pref %d exp %u", addrstr, gateway->preference, expiry (gateway));
- }
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *address = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ priv = NM_RDISC_GET_PRIVATE (rdisc);
+ rdata = &priv->rdata;
- inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr));
- _LOGD (" address %s exp %u", addrstr, expiry (address));
- }
- for (i = 0; i < rdisc->routes->len; i++) {
- NMRDiscRoute *route = &g_array_index (rdisc->routes, NMRDiscRoute, i);
+ config_map_to_string (changed, changedstr);
+ _LOGD ("router discovery configuration changed [%s]:", changedstr);
+ _LOGD (" dhcp-level %s", dhcp_level_to_string (priv->rdata.public.dhcp_level));
+ for (i = 0; i < rdata->gateways->len; i++) {
+ NMRDiscGateway *gateway = &g_array_index (rdata->gateways, NMRDiscGateway, i);
- inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr));
- _LOGD (" route %s/%d via %s pref %d exp %u", addrstr, route->plen,
- nm_utils_inet6_ntop (&route->gateway, NULL), route->preference,
- expiry (route));
- }
- for (i = 0; i < rdisc->dns_servers->len; i++) {
- NMRDiscDNSServer *dns_server = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
+ inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr));
+ _LOGD (" gateway %s pref %d exp %u", addrstr, gateway->preference, expiry (gateway));
+ }
+ for (i = 0; i < rdata->addresses->len; i++) {
+ NMRDiscAddress *address = &g_array_index (rdata->addresses, NMRDiscAddress, i);
- inet_ntop (AF_INET6, &dns_server->address, addrstr, sizeof (addrstr));
- _LOGD (" dns_server %s exp %u", addrstr, expiry (dns_server));
- }
- for (i = 0; i < rdisc->dns_domains->len; i++) {
- NMRDiscDNSDomain *dns_domain = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
+ inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr));
+ _LOGD (" address %s exp %u", addrstr, expiry (address));
+ }
+ for (i = 0; i < rdata->routes->len; i++) {
+ NMRDiscRoute *route = &g_array_index (rdata->routes, NMRDiscRoute, i);
- _LOGD (" dns_domain %s exp %u", dns_domain->domain, expiry (dns_domain));
- }
+ inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr));
+ _LOGD (" route %s/%d via %s pref %d exp %u", addrstr, (int) route->plen,
+ nm_utils_inet6_ntop (&route->gateway, NULL), route->preference,
+ expiry (route));
+ }
+ for (i = 0; i < rdata->dns_servers->len; i++) {
+ NMRDiscDNSServer *dns_server = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i);
+
+ inet_ntop (AF_INET6, &dns_server->address, addrstr, sizeof (addrstr));
+ _LOGD (" dns_server %s exp %u", addrstr, expiry (dns_server));
+ }
+ for (i = 0; i < rdata->dns_domains->len; i++) {
+ NMRDiscDNSDomain *dns_domain = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i);
+
+ _LOGD (" dns_domain %s exp %u", dns_domain->domain, expiry (dns_domain));
}
}
static void
clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent)
{
- int i;
+ NMRDiscDataInternal *rdata;
+ guint i;
+
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
- for (i = 0; i < rdisc->gateways->len; i++) {
- NMRDiscGateway *item = &g_array_index (rdisc->gateways, NMRDiscGateway, i);
+ for (i = 0; i < rdata->gateways->len; i++) {
+ NMRDiscGateway *item = &g_array_index (rdata->gateways, NMRDiscGateway, i);
guint64 expiry = (guint64) item->timestamp + item->lifetime;
if (item->lifetime == G_MAXUINT32)
continue;
if (now >= expiry) {
- g_array_remove_index (rdisc->gateways, i--);
+ g_array_remove_index (rdata->gateways, i--);
*changed |= NM_RDISC_CONFIG_GATEWAYS;
} else if (*nextevent > expiry)
*nextevent = expiry;
@@ -572,17 +723,20 @@ clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32
static void
clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent)
{
- int i;
+ NMRDiscDataInternal *rdata;
+ guint i;
+
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
- for (i = 0; i < rdisc->addresses->len; i++) {
- NMRDiscAddress *item = &g_array_index (rdisc->addresses, NMRDiscAddress, i);
+ for (i = 0; i < rdata->addresses->len; i++) {
+ NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i);
guint64 expiry = (guint64) item->timestamp + item->lifetime;
if (item->lifetime == G_MAXUINT32)
continue;
if (now >= expiry) {
- g_array_remove_index (rdisc->addresses, i--);
+ g_array_remove_index (rdata->addresses, i--);
*changed |= NM_RDISC_CONFIG_ADDRESSES;
} else if (*nextevent > expiry)
*nextevent = expiry;
@@ -592,17 +746,20 @@ clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32
static void
clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent)
{
- int i;
+ NMRDiscDataInternal *rdata;
+ guint i;
+
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
- for (i = 0; i < rdisc->routes->len; i++) {
- NMRDiscRoute *item = &g_array_index (rdisc->routes, NMRDiscRoute, i);
+ for (i = 0; i < rdata->routes->len; i++) {
+ NMRDiscRoute *item = &g_array_index (rdata->routes, NMRDiscRoute, i);
guint64 expiry = (guint64) item->timestamp + item->lifetime;
if (item->lifetime == G_MAXUINT32)
continue;
if (now >= expiry) {
- g_array_remove_index (rdisc->routes, i--);
+ g_array_remove_index (rdata->routes, i--);
*changed |= NM_RDISC_CONFIG_ROUTES;
} else if (*nextevent > expiry)
*nextevent = expiry;
@@ -612,10 +769,13 @@ clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *n
static void
clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent)
{
- int i;
+ NMRDiscDataInternal *rdata;
+ guint i;
- for (i = 0; i < rdisc->dns_servers->len; i++) {
- NMRDiscDNSServer *item = &g_array_index (rdisc->dns_servers, NMRDiscDNSServer, i);
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
+
+ for (i = 0; i < rdata->dns_servers->len; i++) {
+ NMRDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i);
guint64 expiry = (guint64) item->timestamp + item->lifetime;
guint64 refresh = (guint64) item->timestamp + item->lifetime / 2;
@@ -623,7 +783,7 @@ clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint
continue;
if (now >= expiry) {
- g_array_remove_index (rdisc->dns_servers, i--);
+ g_array_remove_index (rdata->dns_servers, i--);
*changed |= NM_RDISC_CONFIG_DNS_SERVERS;
} else if (now >= refresh)
solicit (rdisc);
@@ -635,10 +795,13 @@ clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint
static void
clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent)
{
- int i;
+ NMRDiscDataInternal *rdata;
+ guint i;
+
+ rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata;
- for (i = 0; i < rdisc->dns_domains->len; i++) {
- NMRDiscDNSDomain *item = &g_array_index (rdisc->dns_domains, NMRDiscDNSDomain, i);
+ for (i = 0; i < rdata->dns_domains->len; i++) {
+ NMRDiscDNSDomain *item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i);
guint64 expiry = (guint64) item->timestamp + item->lifetime;
guint64 refresh = (guint64) item->timestamp + item->lifetime / 2;
@@ -646,7 +809,7 @@ clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint
continue;
if (now >= expiry) {
- g_array_remove_index (rdisc->dns_domains, i--);
+ g_array_remove_index (rdata->dns_domains, i--);
*changed |= NM_RDISC_CONFIG_DNS_DOMAINS;
} else if (now >= refresh)
solicit (rdisc);
@@ -674,7 +837,7 @@ check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed)
clean_dns_domains (rdisc, now, &changed, &nextevent);
if (changed)
- g_signal_emit_by_name (rdisc, NM_RDISC_CONFIG_CHANGED, changed);
+ _emit_config_change (rdisc, changed);
if (nextevent != never) {
g_return_if_fail (nextevent > now);
@@ -687,8 +850,10 @@ check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed)
static gboolean
timeout_cb (gpointer user_data)
{
- NM_RDISC_GET_PRIVATE (user_data)->timeout_id = 0;
- check_timestamps (NM_RDISC (user_data), nm_utils_get_monotonic_timestamp_s (), 0);
+ NMRDisc *self = user_data;
+
+ NM_RDISC_GET_PRIVATE (self)->timeout_id = 0;
+ check_timestamps (self, nm_utils_get_monotonic_timestamp_s (), 0);
return G_SOURCE_REMOVE;
}
@@ -716,21 +881,56 @@ set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMRDisc *self = NM_RDISC (object);
+ NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (self);
switch (prop_id) {
case PROP_PLATFORM:
/* construct-only */
- self->_platform = g_value_get_object (value) ? : NM_PLATFORM_GET;
- if (!self->_platform)
+ priv->platform = g_value_get_object (value) ? : NM_PLATFORM_GET;
+ if (!priv->platform)
g_return_if_reached ();
- g_object_ref (self->_platform);
+ g_object_ref (priv->platform);
- self->_netns = nm_platform_netns_get (self->_platform);
- if (self->_netns)
- g_object_ref (self->_netns);
+ priv->netns = nm_platform_netns_get (priv->platform);
+ if (priv->netns)
+ g_object_ref (priv->netns);
- g_return_if_fail (!self->_netns || self->_netns == nmp_netns_get_current ());
+ g_return_if_fail (!priv->netns || priv->netns == nmp_netns_get_current ());
+ break;
+ case PROP_IFINDEX:
+ /* construct-only */
+ priv->ifindex = g_value_get_int (value);
+ g_return_if_fail (priv->ifindex > 0);
+ break;
+ case PROP_IFNAME:
+ /* construct-only */
+ priv->ifname = g_value_dup_string (value);
+ g_return_if_fail (priv->ifname && priv->ifname[0]);
+ break;
+ case PROP_STABLE_TYPE:
+ /* construct-only */
+ priv->stable_type = g_value_get_int (value);
+ break;
+ case PROP_NETWORK_ID:
+ /* construct-only */
+ priv->network_id = g_value_dup_string (value);
+ break;
+ case PROP_ADDR_GEN_MODE:
+ /* construct-only */
+ priv->addr_gen_mode = g_value_get_int (value);
+ break;
+ case PROP_MAX_ADDRESSES:
+ /* construct-only */
+ priv->max_addresses = g_value_get_int (value);
+ break;
+ case PROP_ROUTER_SOLICITATIONS:
+ /* construct-only */
+ priv->router_solicitations = g_value_get_int (value);
+ break;
+ case PROP_ROUTER_SOLICITATION_INTERVAL:
+ /* construct-only */
+ priv->router_solicitation_interval = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -741,17 +941,23 @@ set_property (GObject *object, guint prop_id,
static void
nm_rdisc_init (NMRDisc *rdisc)
{
- NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
+ NMRDiscPrivate *priv;
+ NMRDiscDataInternal *rdata;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (rdisc, NM_TYPE_RDISC, NMRDiscPrivate);
+ rdisc->_priv = priv;
- rdisc->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway));
- rdisc->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress));
- rdisc->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute));
- rdisc->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer));
- rdisc->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain));
- g_array_set_clear_func (rdisc->dns_domains, dns_domain_free);
- rdisc->hop_limit = 64;
+ rdata = &priv->rdata;
- /* Start at very low number so that last_rs - rtr_solicitation_interval
+ rdata->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway));
+ rdata->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress));
+ rdata->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute));
+ rdata->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer));
+ rdata->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain));
+ g_array_set_clear_func (rdata->dns_domains, dns_domain_free);
+ priv->rdata.public.hop_limit = 64;
+
+ /* Start at very low number so that last_rs - router_solicitation_interval
* is much lower than nm_utils_get_monotonic_timestamp_s() at startup.
*/
priv->last_rs = G_MININT32;
@@ -776,17 +982,20 @@ static void
finalize (GObject *object)
{
NMRDisc *rdisc = NM_RDISC (object);
+ NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
+ NMRDiscDataInternal *rdata = &priv->rdata;
+
+ g_free (priv->ifname);
+ g_free (priv->network_id);
- g_free (rdisc->ifname);
- g_free (rdisc->network_id);
- g_array_unref (rdisc->gateways);
- g_array_unref (rdisc->addresses);
- g_array_unref (rdisc->routes);
- g_array_unref (rdisc->dns_servers);
- g_array_unref (rdisc->dns_domains);
+ g_array_unref (rdata->gateways);
+ g_array_unref (rdata->addresses);
+ g_array_unref (rdata->routes);
+ g_array_unref (rdata->dns_servers);
+ g_array_unref (rdata->dns_domains);
- g_clear_object (&rdisc->_netns);
- g_clear_object (&rdisc->_platform);
+ g_clear_object (&priv->netns);
+ g_clear_object (&priv->platform);
G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object);
}
@@ -801,7 +1010,6 @@ nm_rdisc_class_init (NMRDiscClass *klass)
object_class->set_property = set_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
- klass->config_changed = config_changed;
obj_properties[PROP_PLATFORM] =
g_param_spec_object (NM_RDISC_PLATFORM, "", "",
@@ -809,20 +1017,68 @@ nm_rdisc_class_init (NMRDiscClass *klass)
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_IFINDEX] =
+ g_param_spec_int (NM_RDISC_IFINDEX, "", "",
+ 0, G_MAXINT, 0,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_IFNAME] =
+ g_param_spec_string (NM_RDISC_IFNAME, "", "",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_STABLE_TYPE] =
+ g_param_spec_int (NM_RDISC_STABLE_TYPE, "", "",
+ NM_UTILS_STABLE_TYPE_UUID, NM_UTILS_STABLE_TYPE_STABLE_ID, NM_UTILS_STABLE_TYPE_UUID,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_NETWORK_ID] =
+ g_param_spec_string (NM_RDISC_NETWORK_ID, "", "",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_ADDR_GEN_MODE] =
+ g_param_spec_int (NM_RDISC_ADDR_GEN_MODE, "", "",
+ NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_MAX_ADDRESSES] =
+ g_param_spec_int (NM_RDISC_MAX_ADDRESSES, "", "",
+ 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_ROUTER_SOLICITATIONS] =
+ g_param_spec_int (NM_RDISC_ROUTER_SOLICITATIONS, "", "",
+ 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_ROUTER_SOLICITATION_INTERVAL] =
+ g_param_spec_int (NM_RDISC_ROUTER_SOLICITATION_INTERVAL, "", "",
+ 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
signals[CONFIG_CHANGED] =
g_signal_new (NM_RDISC_CONFIG_CHANGED,
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMRDiscClass, config_changed),
+ 0,
NULL, NULL, NULL,
- G_TYPE_NONE, 1, G_TYPE_INT);
+ G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT);
signals[RA_TIMEOUT] =
g_signal_new (NM_RDISC_RA_TIMEOUT,
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMRDiscClass, ra_timeout),
+ 0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h
index 8c14576bcb..9e5e9349bc 100644
--- a/src/rdisc/nm-rdisc.h
+++ b/src/rdisc/nm-rdisc.h
@@ -35,6 +35,15 @@
#define NM_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass))
#define NM_RDISC_PLATFORM "platform"
+#define NM_RDISC_IFINDEX "ifindex"
+#define NM_RDISC_IFNAME "ifname"
+#define NM_RDISC_NETWORK_ID "network-id"
+#define NM_RDISC_ADDR_GEN_MODE "addr-gen-mode"
+#define NM_RDISC_STABLE_TYPE "stable-type"
+#define NM_RDISC_MAX_ADDRESSES "max-addresses"
+#define NM_RDISC_ROUTER_SOLICITATIONS "router-solicitations"
+#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval"
+
#define NM_RDISC_CONFIG_CHANGED "config-changed"
#define NM_RDISC_RA_TIMEOUT "ra-timeout"
@@ -69,7 +78,7 @@ typedef struct {
typedef struct {
struct in6_addr network;
- int plen;
+ guint8 plen;
struct in6_addr gateway;
guint32 timestamp;
guint32 lifetime;
@@ -100,41 +109,42 @@ typedef enum {
} NMRDiscConfigMap;
#define NM_RDISC_MAX_ADDRESSES_DEFAULT 16
-#define NM_RDISC_RTR_SOLICITATIONS_DEFAULT 3
-#define NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT 4
+#define NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT 3
+#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4
+
+struct _NMRDiscPrivate;
+struct _NMRDiscDataInternal;
+
+typedef struct {
+ NMRDiscDHCPLevel dhcp_level;
+ guint32 mtu;
+ int hop_limit;
+
+ guint gateways_n;
+ guint addresses_n;
+ guint routes_n;
+ guint dns_servers_n;
+ guint dns_domains_n;
+
+ const NMRDiscGateway *gateways;
+ const NMRDiscAddress *addresses;
+ const NMRDiscRoute *routes;
+ const NMRDiscDNSServer *dns_servers;
+ const NMRDiscDNSDomain *dns_domains;
+} NMRDiscData;
/**
* NMRDisc:
- * @ifindex: Interface index
*
* Interface-specific structure that handles incoming router advertisements,
* caches advertised items and removes them when they are obsolete.
*/
typedef struct {
GObject parent;
-
- NMPlatform *_platform;
- NMPNetns *_netns;
-
- NMUtilsStableType stable_type;
-
- int ifindex;
- char *ifname;
- char *network_id;
- NMSettingIP6ConfigAddrGenMode addr_gen_mode;
- NMUtilsIPv6IfaceId iid;
- gint32 max_addresses;
- gint32 rtr_solicitations;
- gint32 rtr_solicitation_interval;
-
- NMRDiscDHCPLevel dhcp_level;
- GArray *gateways;
- GArray *addresses;
- GArray *routes;
- GArray *dns_servers;
- GArray *dns_domains;
- int hop_limit;
- guint32 mtu;
+ union {
+ struct _NMRDiscPrivate *_priv;
+ struct _NMRDiscDataInternal *rdata;
+ };
} NMRDisc;
typedef struct {
@@ -142,13 +152,13 @@ typedef struct {
void (*start) (NMRDisc *rdisc);
gboolean (*send_rs) (NMRDisc *rdisc, GError **error);
- void (*config_changed) (NMRDisc *rdisc, NMRDiscConfigMap changed);
- void (*ra_process) (NMRDisc *rdisc);
- void (*ra_timeout) (NMRDisc *rdisc);
} NMRDiscClass;
GType nm_rdisc_get_type (void);
+int nm_rdisc_get_ifindex (NMRDisc *self);
+const char *nm_rdisc_get_ifname (NMRDisc *self);
+
gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid);
void nm_rdisc_start (NMRDisc *rdisc);
void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address);
diff --git a/src/rdisc/tests/Makefile.am b/src/rdisc/tests/Makefile.am
index 65191734ef..4e71fac4b5 100644
--- a/src/rdisc/tests/Makefile.am
+++ b/src/rdisc/tests/Makefile.am
@@ -27,6 +27,8 @@ test_rdisc_linux_LDADD = \
$(top_builddir)/src/libNetworkManager.la
test_rdisc_fake_SOURCES = \
+ $(srcdir)/../nm-fake-rdisc.c \
+ $(srcdir)/../nm-fake-rdisc.h \
test-rdisc-fake.c
test_rdisc_fake_LDADD = \
$(top_builddir)/src/libNetworkManager.la
diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/rdisc/tests/test-rdisc-fake.c
index dec698d6bf..02ffb5100e 100644
--- a/src/rdisc/tests/test-rdisc-fake.c
+++ b/src/rdisc/tests/test-rdisc-fake.c
@@ -46,11 +46,17 @@ rdisc_new (void)
}
static void
-match_gateway (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref)
+match_gateway (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref)
{
- NMRDiscGateway *gw = &g_array_index (array, NMRDiscGateway, idx);
+ const NMRDiscGateway *gw;
char buf[INET6_ADDRSTRLEN];
+ g_assert (rdata);
+ g_assert_cmpint (idx, <, rdata->gateways_n);
+ g_assert (rdata->gateways);
+
+ gw = &rdata->gateways[idx];
+
g_assert_cmpstr (inet_ntop (AF_INET6, &gw->address, buf, sizeof (buf)), ==, addr);
g_assert_cmpint (gw->timestamp, ==, ts);
g_assert_cmpint (gw->lifetime, ==, lt);
@@ -58,11 +64,17 @@ match_gateway (GArray *array, guint idx, const char *addr, guint32 ts, guint32 l
}
static void
-match_address (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred)
+match_address (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred)
{
- NMRDiscAddress *a = &g_array_index (array, NMRDiscAddress, idx);
+ const NMRDiscAddress *a;
char buf[INET6_ADDRSTRLEN];
+ g_assert (rdata);
+ g_assert_cmpint (idx, <, rdata->addresses_n);
+ g_assert (rdata->addresses);
+
+ a = &rdata->addresses[idx];
+
g_assert_cmpstr (inet_ntop (AF_INET6, &a->address, buf, sizeof (buf)), ==, addr);
g_assert_cmpint (a->timestamp, ==, ts);
g_assert_cmpint (a->lifetime, ==, lt);
@@ -70,13 +82,20 @@ match_address (GArray *array, guint idx, const char *addr, guint32 ts, guint32 l
}
static void
-match_route (GArray *array, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref)
+match_route (const NMRDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref)
{
- NMRDiscRoute *route = &g_array_index (array, NMRDiscRoute, idx);
+ const NMRDiscRoute *route;
char buf[INET6_ADDRSTRLEN];
+ g_assert (rdata);
+ g_assert_cmpint (idx, <, rdata->routes_n);
+ g_assert (rdata->routes);
+ g_assert (plen > 0 && plen <= 128);
+
+ route = &rdata->routes[idx];
+
g_assert_cmpstr (inet_ntop (AF_INET6, &route->network, buf, sizeof (buf)), ==, nw);
- g_assert_cmpint (route->plen, ==, plen);
+ g_assert_cmpint ((int) route->plen, ==, plen);
g_assert_cmpstr (inet_ntop (AF_INET6, &route->gateway, buf, sizeof (buf)), ==, gw);
g_assert_cmpint (route->timestamp, ==, ts);
g_assert_cmpint (route->lifetime, ==, lt);
@@ -84,20 +103,32 @@ match_route (GArray *array, guint idx, const char *nw, int plen, const char *gw,
}
static void
-match_dns_server (GArray *array, guint idx, const char *addr, guint32 ts, guint32 lt)
+match_dns_server (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt)
{
- NMRDiscDNSServer *dns = &g_array_index (array, NMRDiscDNSServer, idx);
+ const NMRDiscDNSServer *dns;
char buf[INET6_ADDRSTRLEN];
+ g_assert (rdata);
+ g_assert_cmpint (idx, <, rdata->dns_servers_n);
+ g_assert (rdata->dns_servers);
+
+ dns = &rdata->dns_servers[idx];
+
g_assert_cmpstr (inet_ntop (AF_INET6, &dns->address, buf, sizeof (buf)), ==, addr);
g_assert_cmpint (dns->timestamp, ==, ts);
g_assert_cmpint (dns->lifetime, ==, lt);
}
static void
-match_dns_domain (GArray *array, guint idx, const char *domain, guint32 ts, guint32 lt)
+match_dns_domain (const NMRDiscData *rdata, guint idx, const char *domain, guint32 ts, guint32 lt)
{
- NMRDiscDNSDomain *dns = &g_array_index (array, NMRDiscDNSDomain, idx);
+ const NMRDiscDNSDomain *dns;
+
+ g_assert (rdata);
+ g_assert_cmpint (idx, <, rdata->dns_domains_n);
+ g_assert (rdata->dns_domains);
+
+ dns = &rdata->dns_domains[idx];
g_assert_cmpstr (dns->domain, ==, domain);
g_assert_cmpint (dns->timestamp, ==, ts);
@@ -114,8 +145,10 @@ typedef struct {
} TestData;
static void
-test_simple_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data)
+test_simple_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data)
{
+ NMRDiscConfigMap changed = changed_int;
+
g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL |
NM_RDISC_CONFIG_GATEWAYS |
NM_RDISC_CONFIG_ADDRESSES |
@@ -124,12 +157,12 @@ test_simple_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data)
NM_RDISC_CONFIG_DNS_DOMAINS |
NM_RDISC_CONFIG_HOP_LIMIT |
NM_RDISC_CONFIG_MTU);
- g_assert_cmpint (rdisc->dhcp_level, ==, NM_RDISC_DHCP_LEVEL_OTHERCONF);
- match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
- match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
- match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10);
- match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::1", data->timestamp1, 10);
- match_dns_domain (rdisc->dns_domains, 0, "foobar.com", data->timestamp1, 10);
+ g_assert_cmpint (rdata->dhcp_level, ==, NM_RDISC_DHCP_LEVEL_OTHERCONF);
+ match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
+ match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
+ match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10);
+ match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10);
+ match_dns_domain (rdata, 0, "foobar.com", data->timestamp1, 10);
g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc)));
data->counter++;
@@ -172,40 +205,42 @@ test_everything_rs_sent (NMRDisc *rdisc, TestData *data)
}
static void
-test_everything_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data)
+test_everything_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data)
{
+ NMRDiscConfigMap changed = changed_int;
+
if (data->counter == 0) {
g_assert_cmpint (data->rs_counter, ==, 1);
g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL |
- NM_RDISC_CONFIG_GATEWAYS |
- NM_RDISC_CONFIG_ADDRESSES |
- NM_RDISC_CONFIG_ROUTES |
- NM_RDISC_CONFIG_DNS_SERVERS |
- NM_RDISC_CONFIG_DNS_DOMAINS |
- NM_RDISC_CONFIG_HOP_LIMIT |
- NM_RDISC_CONFIG_MTU);
- match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
- match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
- match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10);
- match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::1", data->timestamp1, 10);
- match_dns_domain (rdisc->dns_domains, 0, "foobar.com", data->timestamp1, 10);
+ NM_RDISC_CONFIG_GATEWAYS |
+ NM_RDISC_CONFIG_ADDRESSES |
+ NM_RDISC_CONFIG_ROUTES |
+ NM_RDISC_CONFIG_DNS_SERVERS |
+ NM_RDISC_CONFIG_DNS_DOMAINS |
+ NM_RDISC_CONFIG_HOP_LIMIT |
+ NM_RDISC_CONFIG_MTU);
+ match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
+ match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
+ match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10);
+ match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10);
+ match_dns_domain (rdata, 0, "foobar.com", data->timestamp1, 10);
} else if (data->counter == 1) {
g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS |
- NM_RDISC_CONFIG_ADDRESSES |
- NM_RDISC_CONFIG_ROUTES |
- NM_RDISC_CONFIG_DNS_SERVERS |
- NM_RDISC_CONFIG_DNS_DOMAINS);
-
- g_assert_cmpint (rdisc->gateways->len, ==, 1);
- match_gateway (rdisc->gateways, 0, "fe80::2", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
- g_assert_cmpint (rdisc->addresses->len, ==, 1);
- match_address (rdisc->addresses, 0, "2001:db8:a:b::1", data->timestamp1, 10, 10);
- g_assert_cmpint (rdisc->routes->len, ==, 1);
- match_route (rdisc->routes, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1, 10, 10);
- g_assert_cmpint (rdisc->dns_servers->len, ==, 1);
- match_dns_server (rdisc->dns_servers, 0, "2001:db8:c:c::2", data->timestamp1, 10);
- g_assert_cmpint (rdisc->dns_domains->len, ==, 1);
- match_dns_domain (rdisc->dns_domains, 0, "foobar2.com", data->timestamp1, 10);
+ NM_RDISC_CONFIG_ADDRESSES |
+ NM_RDISC_CONFIG_ROUTES |
+ NM_RDISC_CONFIG_DNS_SERVERS |
+ NM_RDISC_CONFIG_DNS_DOMAINS);
+
+ g_assert_cmpint (rdata->gateways_n, ==, 1);
+ match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM);
+ g_assert_cmpint (rdata->addresses_n, ==, 1);
+ match_address (rdata, 0, "2001:db8:a:b::1", data->timestamp1, 10, 10);
+ g_assert_cmpint (rdata->routes_n, ==, 1);
+ match_route (rdata, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1, 10, 10);
+ g_assert_cmpint (rdata->dns_servers_n, ==, 1);
+ match_dns_server (rdata, 0, "2001:db8:c:c::2", data->timestamp1, 10);
+ g_assert_cmpint (rdata->dns_domains_n, ==, 1);
+ match_dns_domain (rdata, 0, "foobar2.com", data->timestamp1, 10);
g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc)));
g_main_loop_quit (data->loop);
@@ -263,35 +298,37 @@ test_everything (void)
}
static void
-test_preference_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data)
+test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data)
{
+ NMRDiscConfigMap changed = changed_int;
+
if (data->counter == 1) {
g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS |
- NM_RDISC_CONFIG_ADDRESSES |
- NM_RDISC_CONFIG_ROUTES);
- g_assert_cmpint (rdisc->gateways->len, ==, 2);
- match_gateway (rdisc->gateways, 0, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM);
- match_gateway (rdisc->gateways, 1, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_LOW);
- g_assert_cmpint (rdisc->addresses->len, ==, 2);
- match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
- match_address (rdisc->addresses, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10);
- g_assert_cmpint (rdisc->routes->len, ==, 2);
- match_route (rdisc->routes, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10);
- match_route (rdisc->routes, 1, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 5);
+ NM_RDISC_CONFIG_ADDRESSES |
+ NM_RDISC_CONFIG_ROUTES);
+ g_assert_cmpint (rdata->gateways_n, ==, 2);
+ match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM);
+ match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_LOW);
+ g_assert_cmpint (rdata->addresses_n, ==, 2);
+ match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10);
+ match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10);
+ g_assert_cmpint (rdata->routes_n, ==, 2);
+ match_route (rdata, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10);
+ match_route (rdata, 1, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 5);
} else if (data->counter == 2) {
g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS |
- NM_RDISC_CONFIG_ADDRESSES |
- NM_RDISC_CONFIG_ROUTES);
-
- g_assert_cmpint (rdisc->gateways->len, ==, 2);
- match_gateway (rdisc->gateways, 0, "fe80::1", data->timestamp1 + 2, 10, NM_RDISC_PREFERENCE_HIGH);
- match_gateway (rdisc->gateways, 1, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM);
- g_assert_cmpint (rdisc->addresses->len, ==, 2);
- match_address (rdisc->addresses, 0, "2001:db8:a:a::1", data->timestamp1 + 2, 10, 10);
- match_address (rdisc->addresses, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10);
- g_assert_cmpint (rdisc->routes->len, ==, 2);
- match_route (rdisc->routes, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1 + 2, 10, 15);
- match_route (rdisc->routes, 1, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10);
+ NM_RDISC_CONFIG_ADDRESSES |
+ NM_RDISC_CONFIG_ROUTES);
+
+ g_assert_cmpint (rdata->gateways_n, ==, 2);
+ match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_RDISC_PREFERENCE_HIGH);
+ match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM);
+ g_assert_cmpint (rdata->addresses_n, ==, 2);
+ match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1 + 2, 10, 10);
+ match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10);
+ g_assert_cmpint (rdata->routes_n, ==, 2);
+ match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1 + 2, 10, 15);
+ match_route (rdata, 1, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10);
g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc)));
g_main_loop_quit (data->loop);
@@ -342,7 +379,7 @@ test_preference (void)
}
static void
-test_dns_solicit_loop_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, TestData *data)
+test_dns_solicit_loop_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data)
{
data->counter++;
}