mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 09:58:07 +02:00
merge: branch 'pr/1479'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1479
This commit is contained in:
commit
46f6e0bc29
3 changed files with 53 additions and 4 deletions
|
|
@ -211,6 +211,7 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
const NMNDiscRoute route = {
|
const NMNDiscRoute route = {
|
||||||
.network = r_network,
|
.network = r_network,
|
||||||
.plen = r_plen,
|
.plen = r_plen,
|
||||||
|
.on_link = TRUE,
|
||||||
.expiry_msec =
|
.expiry_msec =
|
||||||
_nm_ndisc_lifetime_to_expiry(now_msec,
|
_nm_ndisc_lifetime_to_expiry(now_msec,
|
||||||
ndp_msg_opt_prefix_valid_time(msg, offset)),
|
ndp_msg_opt_prefix_valid_time(msg, offset)),
|
||||||
|
|
@ -249,6 +250,7 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
.network = network,
|
.network = network,
|
||||||
.gateway = gateway_addr,
|
.gateway = gateway_addr,
|
||||||
.plen = plen,
|
.plen = plen,
|
||||||
|
.on_link = FALSE,
|
||||||
.expiry_msec =
|
.expiry_msec =
|
||||||
_nm_ndisc_lifetime_to_expiry(now_msec, ndp_msg_opt_route_lifetime(msg, offset)),
|
_nm_ndisc_lifetime_to_expiry(now_msec, ndp_msg_opt_route_lifetime(msg, offset)),
|
||||||
.preference = _route_preference_coerce(ndp_msg_opt_route_preference(msg, offset)),
|
.preference = _route_preference_coerce(ndp_msg_opt_route_preference(msg, offset)),
|
||||||
|
|
|
||||||
|
|
@ -161,8 +161,9 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
.table_coerced = 0,
|
.table_coerced = 0,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
.metric = 0,
|
/* Non-on_link routes get a small penalty */
|
||||||
.rt_pref = ndisc_route->preference,
|
.metric = ndisc_route->duplicate && !ndisc_route->on_link ? 5 : 0,
|
||||||
|
.rt_pref = ndisc_route->preference,
|
||||||
};
|
};
|
||||||
nm_assert((NMIcmpv6RouterPref) r.rt_pref == ndisc_route->preference);
|
nm_assert((NMIcmpv6RouterPref) r.rt_pref == ndisc_route->preference);
|
||||||
|
|
||||||
|
|
@ -349,12 +350,47 @@ _ASSERT_data_gateways(const NMNDiscDataInternal *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
static bool
|
||||||
|
is_duplicate_route(const NMNDiscRoute *r0, const NMNDiscRoute *r1)
|
||||||
|
{
|
||||||
|
return IN6_ARE_ADDR_EQUAL(&r0->network, &r1->network) && r0->plen == r1->plen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_data_complete_prepare_routes(GArray *routes)
|
||||||
|
{
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < routes->len; i++) {
|
||||||
|
NMNDiscRoute *r0 = &nm_g_array_index(routes, NMNDiscRoute, i);
|
||||||
|
|
||||||
|
r0->duplicate = FALSE;
|
||||||
|
}
|
||||||
|
for (i = 0; i < routes->len; i++) {
|
||||||
|
NMNDiscRoute *r0 = &nm_g_array_index(routes, NMNDiscRoute, i);
|
||||||
|
|
||||||
|
for (j = i + 1; j < routes->len; j++) {
|
||||||
|
NMNDiscRoute *r1 = &nm_g_array_index(routes, NMNDiscRoute, j);
|
||||||
|
|
||||||
|
if (!is_duplicate_route(r0, r1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
r0->duplicate = TRUE;
|
||||||
|
r1->duplicate = TRUE;
|
||||||
|
|
||||||
|
/* Maybe after index j, there is yet another duplicate. But we
|
||||||
|
* will find that later, when i becomes j. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const NMNDiscData *
|
static const NMNDiscData *
|
||||||
_data_complete(NMNDiscDataInternal *data)
|
_data_complete(NMNDiscDataInternal *data)
|
||||||
{
|
{
|
||||||
_ASSERT_data_gateways(data);
|
_ASSERT_data_gateways(data);
|
||||||
|
|
||||||
|
_data_complete_prepare_routes(data->routes);
|
||||||
#define _SET(data, field) \
|
#define _SET(data, field) \
|
||||||
G_STMT_START \
|
G_STMT_START \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -658,8 +694,17 @@ nm_ndisc_add_route(NMNDisc *ndisc, const NMNDiscRoute *new_item, gint64 now_msec
|
||||||
for (i = 0; i < rdata->routes->len;) {
|
for (i = 0; i < rdata->routes->len;) {
|
||||||
NMNDiscRoute *item = &nm_g_array_index(rdata->routes, NMNDiscRoute, i);
|
NMNDiscRoute *item = &nm_g_array_index(rdata->routes, NMNDiscRoute, i);
|
||||||
|
|
||||||
if (IN6_ARE_ADDR_EQUAL(&item->network, &new_item->network)
|
/*
|
||||||
&& item->plen == new_item->plen) {
|
* It is possible that two entries in rdata->routes have
|
||||||
|
* the same prefix as well as the same prefix length.
|
||||||
|
* One of them, however, refers to the on-link prefix,
|
||||||
|
* and the other one to a route from the route information field.
|
||||||
|
* Moreover, they might have different route preferences.
|
||||||
|
* Hence, if both routes differ in the on-link flag,
|
||||||
|
* comparison is aborted, and both routes are added.
|
||||||
|
*/
|
||||||
|
if (IN6_ARE_ADDR_EQUAL(&item->network, &new_item->network) && item->plen == new_item->plen
|
||||||
|
&& item->on_link == new_item->on_link) {
|
||||||
if (new_item->expiry_msec <= now_msec) {
|
if (new_item->expiry_msec <= now_msec) {
|
||||||
g_array_remove_index(rdata->routes, i);
|
g_array_remove_index(rdata->routes, i);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ typedef struct _NMNDiscRoute {
|
||||||
gint64 expiry_msec;
|
gint64 expiry_msec;
|
||||||
NMIcmpv6RouterPref preference;
|
NMIcmpv6RouterPref preference;
|
||||||
guint8 plen;
|
guint8 plen;
|
||||||
|
bool on_link : 1;
|
||||||
|
bool duplicate : 1;
|
||||||
} NMNDiscRoute;
|
} NMNDiscRoute;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue