mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-19 20:10:33 +01:00
ndisc: add support for PREF64 option
This commit is contained in:
parent
b31d3e1eae
commit
0b3a7ca9d0
4 changed files with 59 additions and 0 deletions
|
|
@ -162,6 +162,7 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||
int offset;
|
||||
int hop_limit;
|
||||
guint32 val;
|
||||
gboolean pref64_found = FALSE;
|
||||
|
||||
/* Router discovery is subject to the following RFC documents:
|
||||
*
|
||||
|
|
@ -401,6 +402,35 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||
}
|
||||
}
|
||||
|
||||
/* PREF64 */
|
||||
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_PREF64) {
|
||||
struct in6_addr pref64_prefix = *ndp_msg_opt_pref64_prefix(msg, offset);
|
||||
guint8 pref64_length = ndp_msg_opt_pref64_prefix_length(msg, offset);
|
||||
gint64 expiry_msec =
|
||||
_nm_ndisc_lifetime_to_expiry(now_msec, ndp_msg_opt_pref64_lifetime(msg, offset));
|
||||
|
||||
/* Currently, only /96 is supported */
|
||||
if (pref64_length != 96) {
|
||||
_LOGW("Ignored PREF64 for unsupported prefix length: %d (only /96 is supported)",
|
||||
pref64_length);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Newer RA has more up to date information, prefer it: */
|
||||
if (!pref64_found) {
|
||||
pref64_found = TRUE;
|
||||
rdata->public.pref64.expiry_msec = 0;
|
||||
}
|
||||
|
||||
if (expiry_msec >= rdata->public.pref64.expiry_msec) {
|
||||
rdata->public.pref64.network = pref64_prefix;
|
||||
rdata->public.pref64.expiry_msec = expiry_msec;
|
||||
rdata->public.pref64.plen = pref64_length;
|
||||
rdata->public.pref64.valid = TRUE;
|
||||
changed |= NM_NDISC_CONFIG_PREF64;
|
||||
}
|
||||
}
|
||||
|
||||
nm_ndisc_ra_received(ndisc, now_msec, changed);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ struct _NMNDiscDataInternal {
|
|||
NMNDiscData public;
|
||||
GArray *gateways;
|
||||
GArray *addresses;
|
||||
GArray *clat_addresses;
|
||||
GArray *routes;
|
||||
GArray *dns_servers;
|
||||
GArray *dns_domains;
|
||||
|
|
|
|||
|
|
@ -212,6 +212,12 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx,
|
|||
for (i = 0; i < rdata->dns_domains_n; i++)
|
||||
nm_l3_config_data_add_search(l3cd, AF_INET6, rdata->dns_domains[i].domain);
|
||||
|
||||
if (rdata->pref64.valid) {
|
||||
nm_l3_config_data_set_pref64(l3cd, rdata->pref64.network, rdata->pref64.plen);
|
||||
} else {
|
||||
nm_l3_config_data_set_pref64_valid(l3cd, FALSE);
|
||||
}
|
||||
|
||||
nm_l3_config_data_set_ndisc_hop_limit(l3cd, rdata->hop_limit);
|
||||
nm_l3_config_data_set_ndisc_reachable_time_msec(l3cd, rdata->reachable_time_ms);
|
||||
nm_l3_config_data_set_ndisc_retrans_timer_msec(l3cd, rdata->retrans_timer_ms);
|
||||
|
|
@ -1528,6 +1534,17 @@ clean_routes(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64
|
|||
*changed |= NM_NDISC_CONFIG_ROUTES;
|
||||
}
|
||||
|
||||
static void
|
||||
clean_pref64(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64 *next_msec)
|
||||
{
|
||||
NMNDiscDataInternal *rdata = &NM_NDISC_GET_PRIVATE(ndisc)->rdata;
|
||||
|
||||
if (!rdata->public.pref64.valid)
|
||||
return;
|
||||
if (!expiry_next(now_msec, rdata->public.pref64.expiry_msec, next_msec))
|
||||
*changed |= NM_NDISC_CONFIG_PREF64;
|
||||
}
|
||||
|
||||
static void
|
||||
clean_dns_servers(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64 *next_msec)
|
||||
{
|
||||
|
|
@ -1604,6 +1621,7 @@ check_timestamps(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap changed)
|
|||
clean_gateways(ndisc, now_msec, &changed, &next_msec);
|
||||
clean_addresses(ndisc, now_msec, &changed, &next_msec);
|
||||
clean_routes(ndisc, now_msec, &changed, &next_msec);
|
||||
clean_pref64(ndisc, now_msec, &changed, &next_msec);
|
||||
clean_dns_servers(ndisc, now_msec, &changed, &next_msec);
|
||||
clean_dns_domains(ndisc, now_msec, &changed, &next_msec);
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,13 @@ typedef struct _NMNDiscRoute {
|
|||
bool duplicate : 1;
|
||||
} NMNDiscRoute;
|
||||
|
||||
typedef struct _NMNDiscPref64 {
|
||||
struct in6_addr network;
|
||||
gint64 expiry_msec;
|
||||
guint8 plen;
|
||||
bool valid : 1;
|
||||
} NMNDiscPref64;
|
||||
|
||||
typedef struct {
|
||||
struct in6_addr address;
|
||||
gint64 expiry_msec;
|
||||
|
|
@ -141,6 +148,7 @@ typedef enum {
|
|||
NM_NDISC_CONFIG_MTU = 1 << 7,
|
||||
NM_NDISC_CONFIG_REACHABLE_TIME = 1 << 8,
|
||||
NM_NDISC_CONFIG_RETRANS_TIMER = 1 << 9,
|
||||
NM_NDISC_CONFIG_PREF64 = 1 << 10,
|
||||
} NMNDiscConfigMap;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -196,6 +204,8 @@ typedef struct {
|
|||
const NMNDiscRoute *routes;
|
||||
const NMNDiscDNSServer *dns_servers;
|
||||
const NMNDiscDNSDomain *dns_domains;
|
||||
|
||||
NMNDiscPref64 pref64;
|
||||
} NMNDiscData;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue