ndisc: rename NMNDiscPreference to NMIcmpv6RouterPref

We encounter the same enum in 3 forms:

  - NMNDiscPreference in NetworkManager
  - "enum ndp_route_preference" in <ndp.h>
  - ICMPV6_ROUTER_PREF_* in <linux/icmpv6.h>

Move our enum to nm-core-utils.h, so that it can be used
by platform code as well (platform code should not include
ndisc/nm-ndisc.h).

Also, NMNDiscPreference was not numerically identical to their
native values (meaning: it shuffled the names and numbers).
Make them all numerically equal, so that they can be used in
the same context.
This means, while previously we could compare NMNDiscPreference
directly according to their priority, we now need _preference_to_priority().
On the other hand, we could omit translate_preference() -- but actually,
we still have _route_preference_coerce() because pref comes from libndp
and is thus untrusted. We still have to range check it.
This commit is contained in:
Thomas Haller 2017-10-09 11:56:51 +02:00
parent 7d59641d00
commit 32142a63e8
8 changed files with 88 additions and 45 deletions

View file

@ -51,7 +51,7 @@ typedef struct {
guint32 timestamp;
guint32 lifetime;
guint32 preferred;
NMNDiscPreference preference;
NMIcmpv6RouterPref preference;
} FakePrefix;
/*****************************************************************************/
@ -145,7 +145,7 @@ nm_fake_ndisc_add_gateway (NMFakeNDisc *self,
const char *addr,
guint32 timestamp,
guint32 lifetime,
NMNDiscPreference preference)
NMIcmpv6RouterPref preference)
{
NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self);
FakeRa *ra = find_ra (priv->ras, ra_id);
@ -169,7 +169,7 @@ nm_fake_ndisc_add_prefix (NMFakeNDisc *self,
guint32 timestamp,
guint32 lifetime,
guint32 preferred,
NMNDiscPreference preference)
NMIcmpv6RouterPref preference)
{
NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self);
FakeRa *ra = find_ra (priv->ras, ra_id);

View file

@ -50,7 +50,7 @@ void nm_fake_ndisc_add_gateway (NMFakeNDisc *self,
const char *addr,
guint32 timestamp,
guint32 lifetime,
NMNDiscPreference preference);
NMIcmpv6RouterPref preference);
void nm_fake_ndisc_add_prefix (NMFakeNDisc *self,
guint ra_id,
@ -60,7 +60,7 @@ void nm_fake_ndisc_add_prefix (NMFakeNDisc *self,
guint32 timestamp,
guint32 lifetime,
guint32 preferred,
NMNDiscPreference preference);
NMIcmpv6RouterPref preference);
void nm_fake_ndisc_add_dns_server (NMFakeNDisc *self,
guint ra_id,

View file

@ -93,12 +93,20 @@ send_rs (NMNDisc *ndisc, GError **error)
return TRUE;
}
_NM_UTILS_LOOKUP_DEFINE (static, translate_preference, enum ndp_route_preference, NMNDiscPreference,
NM_UTILS_LOOKUP_DEFAULT (NM_NDISC_PREFERENCE_INVALID),
NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_LOW, NM_NDISC_PREFERENCE_LOW),
NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_MEDIUM, NM_NDISC_PREFERENCE_MEDIUM),
NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_HIGH, NM_NDISC_PREFERENCE_HIGH),
);
static NMIcmpv6RouterPref
_route_preference_coerce (enum ndp_route_preference pref)
{
switch (pref) {
case NDP_ROUTE_PREF_LOW:
return NM_ICMPV6_ROUTER_PREF_LOW;
case NDP_ROUTE_PREF_MEDIUM:
return NM_ICMPV6_ROUTER_PREF_MEDIUM;
case NDP_ROUTE_PREF_HIGH:
return NM_ICMPV6_ROUTER_PREF_HIGH;
}
/* unexpected value must be treated as MEDIUM (RFC 4191). */
return NM_ICMPV6_ROUTER_PREF_MEDIUM;
}
static int
receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
@ -165,7 +173,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
.address = gateway_addr,
.timestamp = now,
.lifetime = ndp_msgra_router_lifetime (msgra),
.preference = translate_preference (ndp_msgra_route_preference (msgra)),
.preference = _route_preference_coerce (ndp_msgra_route_preference (msgra)),
};
if (nm_ndisc_add_gateway (ndisc, &gateway))
@ -218,7 +226,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
.plen = ndp_msg_opt_route_prefix_len (msg, offset),
.timestamp = now,
.lifetime = ndp_msg_opt_route_lifetime (msg, offset),
.preference = translate_preference (ndp_msg_opt_route_preference (msg, offset)),
.preference = _route_preference_coerce (ndp_msg_opt_route_preference (msg, offset)),
};
if (route.plen == 0 || route.plen > 128)

View file

@ -106,6 +106,24 @@ static void _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed);
/*****************************************************************************/
static guint8
_preference_to_priority (NMIcmpv6RouterPref pref)
{
switch (pref) {
case NM_ICMPV6_ROUTER_PREF_LOW:
return 1;
case NM_ICMPV6_ROUTER_PREF_MEDIUM:
return 2;
case NM_ICMPV6_ROUTER_PREF_HIGH:
return 3;
case NM_ICMPV6_ROUTER_PREF_INVALID:
break;
}
return 0;
}
/*****************************************************************************/
NMPNetns *
nm_ndisc_netns_get (NMNDisc *self)
{
@ -216,7 +234,7 @@ nm_ndisc_add_gateway (NMNDisc *ndisc, const NMNDiscGateway *new)
}
/* Put before less preferable gateways. */
if ( item->preference < new->preference
if ( _preference_to_priority (item->preference) < _preference_to_priority (new->preference)
&& insert_idx == G_MAXUINT)
insert_idx = i;
@ -375,7 +393,7 @@ nm_ndisc_add_route (NMNDisc *ndisc, const NMNDiscRoute *new)
}
/* Put before less preferable routes. */
if ( item->preference < new->preference
if ( _preference_to_priority (item->preference) < _preference_to_priority (new->preference)
&& insert_idx == G_MAXUINT)
insert_idx = i;
@ -840,6 +858,7 @@ _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed)
guint i;
char changedstr[CONFIG_MAP_MAX_STR];
char addrstr[INET6_ADDRSTRLEN];
char str_pref[35];
if (!_LOGD_ENABLED ())
return;
@ -854,7 +873,9 @@ _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed)
NMNDiscGateway *gateway = &g_array_index (rdata->gateways, NMNDiscGateway, i);
inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr));
_LOGD (" gateway %s pref %d exp %d", addrstr, gateway->preference, get_expiry (gateway));
_LOGD (" gateway %s pref %s exp %d", addrstr,
nm_icmpv6_router_pref_to_string (gateway->preference, str_pref, sizeof (str_pref)),
get_expiry (gateway));
}
for (i = 0; i < rdata->addresses->len; i++) {
NMNDiscAddress *address = &g_array_index (rdata->addresses, NMNDiscAddress, i);
@ -866,8 +887,9 @@ _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed)
NMNDiscRoute *route = &g_array_index (rdata->routes, NMNDiscRoute, i);
inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr));
_LOGD (" route %s/%u via %s pref %d exp %d", addrstr, (guint) route->plen,
nm_utils_inet6_ntop (&route->gateway, NULL), route->preference,
_LOGD (" route %s/%u via %s pref %s exp %d", addrstr, (guint) route->plen,
nm_utils_inet6_ntop (&route->gateway, NULL),
nm_icmpv6_router_pref_to_string (route->preference, str_pref, sizeof (str_pref)),
get_expiry (route));
}
for (i = 0; i < rdata->dns_servers->len; i++) {

View file

@ -55,20 +55,13 @@ typedef enum {
NM_NDISC_DHCP_LEVEL_MANAGED
} NMNDiscDHCPLevel;
typedef enum {
NM_NDISC_PREFERENCE_INVALID,
NM_NDISC_PREFERENCE_LOW,
NM_NDISC_PREFERENCE_MEDIUM,
NM_NDISC_PREFERENCE_HIGH
} NMNDiscPreference;
#define NM_NDISC_INFINITY G_MAXUINT32
struct _NMNDiscGateway {
struct in6_addr address;
guint32 timestamp;
guint32 lifetime;
NMNDiscPreference preference;
NMIcmpv6RouterPref preference;
};
typedef struct _NMNDiscGateway NMNDiscGateway;
@ -87,7 +80,7 @@ struct _NMNDiscRoute {
struct in6_addr gateway;
guint32 timestamp;
guint32 lifetime;
NMNDiscPreference preference;
NMIcmpv6RouterPref preference;
};
typedef struct _NMNDiscRoute NMNDiscRoute;

View file

@ -46,7 +46,7 @@ ndisc_new (void)
}
static void
match_gateway (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMNDiscPreference pref)
match_gateway (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMIcmpv6RouterPref pref)
{
const NMNDiscGateway *gw;
char buf[INET6_ADDRSTRLEN];
@ -82,7 +82,7 @@ match_address (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts
}
static void
match_route (const NMNDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMNDiscPreference pref)
match_route (const NMNDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMIcmpv6RouterPref pref)
{
const NMNDiscRoute *route;
char buf[INET6_ADDRSTRLEN];
@ -158,7 +158,7 @@ test_simple_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int
NM_NDISC_CONFIG_HOP_LIMIT |
NM_NDISC_CONFIG_MTU);
g_assert_cmpint (rdata->dhcp_level, ==, NM_NDISC_DHCP_LEVEL_OTHERCONF);
match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM);
match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_ICMPV6_ROUTER_PREF_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);
@ -179,7 +179,7 @@ test_simple (void)
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_OTHERCONF, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10);
nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 10);
nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 10);
@ -219,7 +219,7 @@ test_everything_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed
NM_NDISC_CONFIG_DNS_DOMAINS |
NM_NDISC_CONFIG_HOP_LIMIT |
NM_NDISC_CONFIG_MTU);
match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM);
match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_ICMPV6_ROUTER_PREF_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);
@ -232,7 +232,7 @@ test_everything_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed
NM_NDISC_CONFIG_DNS_DOMAINS);
g_assert_cmpint (rdata->gateways_n, ==, 1);
match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM);
match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_ICMPV6_ROUTER_PREF_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);
@ -260,7 +260,7 @@ test_everything (void)
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10);
nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 10);
nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 10);
@ -268,13 +268,13 @@ test_everything (void)
/* expire everything from the first RA in the second */
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 0, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 0, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 0, 0, 0);
nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 0);
nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 0);
/* and add some new stuff */
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", now, 10, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", now, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10);
nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::2", now, 10);
nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar2.com", now, 10);
@ -307,8 +307,8 @@ test_preference_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed
NM_NDISC_CONFIG_ADDRESSES |
NM_NDISC_CONFIG_ROUTES);
g_assert_cmpint (rdata->gateways_n, ==, 2);
match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_NDISC_PREFERENCE_MEDIUM);
match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_LOW);
match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_ICMPV6_ROUTER_PREF_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);
@ -321,8 +321,8 @@ test_preference_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed
NM_NDISC_CONFIG_ROUTES);
g_assert_cmpint (rdata->gateways_n, ==, 2);
match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_NDISC_PREFERENCE_HIGH);
match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_NDISC_PREFERENCE_MEDIUM);
match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_ICMPV6_ROUTER_PREF_HIGH);
match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_ICMPV6_ROUTER_PREF_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);
@ -352,17 +352,17 @@ test_preference (void)
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_LOW);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_ICMPV6_ROUTER_PREF_LOW);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 5);
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", ++now, 10, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", ++now, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10);
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", ++now, 10, NM_NDISC_PREFERENCE_HIGH);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", ++now, 10, NM_ICMPV6_ROUTER_PREF_HIGH);
nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 15);
g_signal_connect (ndisc,
@ -411,7 +411,7 @@ test_dns_solicit_loop_rs_sent (NMFakeNDisc *ndisc, TestData *data)
*/
id = nm_fake_ndisc_add_ra (ndisc, 0, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_ICMPV6_ROUTER_PREF_MEDIUM);
nm_fake_ndisc_emit_new_ras (ndisc);
} else if (data->rs_counter >= 6) {
@ -440,7 +440,7 @@ test_dns_solicit_loop (void)
id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500);
g_assert (id);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_LOW);
nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_ICMPV6_ROUTER_PREF_LOW);
nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 6);
g_signal_connect (ndisc,

View file

@ -4417,6 +4417,13 @@ nm_utils_format_con_diff_for_audit (GHashTable *diff)
/*****************************************************************************/
NM_UTILS_ENUM2STR_DEFINE (nm_icmpv6_router_pref_to_string, NMIcmpv6RouterPref,
NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_LOW, "low"),
NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_MEDIUM, "medium"),
NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_HIGH, "high"),
NM_UTILS_ENUM2STR (NM_ICMPV6_ROUTER_PREF_INVALID, "invalid"),
);
NM_UTILS_LOOKUP_STR_DEFINE (nm_activation_type_to_string, NMActivationType,
NM_UTILS_LOOKUP_DEFAULT_WARN ("(unknown)"),
NM_UTILS_LOOKUP_STR_ITEM (NM_ACTIVATION_TYPE_MANAGED, "managed"),

View file

@ -435,6 +435,19 @@ gboolean nm_utils_validate_plugin (const char *path, struct stat *stat, GError *
char **nm_utils_read_plugin_paths (const char *dirname, const char *prefix);
char *nm_utils_format_con_diff_for_audit (GHashTable *diff);
/*****************************************************************************/
/* this enum is compatible with ICMPV6_ROUTER_PREF_* (from <linux/icmpv6.h>,
* the values for netlink attribute RTA_PREF) and "enum ndp_route_preference"
* from <ndp.h>. */
typedef enum {
NM_ICMPV6_ROUTER_PREF_MEDIUM = 0x0, /* ICMPV6_ROUTER_PREF_MEDIUM */
NM_ICMPV6_ROUTER_PREF_LOW = 0x3, /* ICMPV6_ROUTER_PREF_LOW */
NM_ICMPV6_ROUTER_PREF_HIGH = 0x1, /* ICMPV6_ROUTER_PREF_HIGH */
NM_ICMPV6_ROUTER_PREF_INVALID = 0x2, /* ICMPV6_ROUTER_PREF_INVALID */
} NMIcmpv6RouterPref;
const char *nm_icmpv6_router_pref_to_string (NMIcmpv6RouterPref pref, char *buf, gsize len);
/*****************************************************************************/