mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-09 13:30:20 +01:00
ndisc: honor default route parameters from RA route options
RFC 4191 section-3.1 says: When processing a Router Advertisement, a type C host first updates a ::/0 route based on the Router Lifetime and Default Router Preference in the Router Advertisement message header. [...] The Router Preference and Lifetime values in a ::/0 Route Information Option override the preference and lifetime values in the Router Advertisement header. Fix the RA parsing so that the parameters from a default route option are applied to the gateway. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1666 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2072 Fixes:c3a4656a68('rdisc: libndp implementation') (cherry picked from commit6c18fda519)
This commit is contained in:
parent
3917235a2d
commit
d775c3d256
1 changed files with 32 additions and 19 deletions
|
|
@ -115,7 +115,8 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
NMNDisc *ndisc = (NMNDisc *) user_data;
|
NMNDisc *ndisc = (NMNDisc *) user_data;
|
||||||
NMNDiscDataInternal *rdata = ndisc->rdata;
|
NMNDiscDataInternal *rdata = ndisc->rdata;
|
||||||
NMNDiscConfigMap changed = 0;
|
NMNDiscConfigMap changed = 0;
|
||||||
struct ndp_msgra *msgra = ndp_msgra(msg);
|
NMNDiscGateway gateway;
|
||||||
|
struct ndp_msgra *msgra = ndp_msgra(msg);
|
||||||
struct in6_addr gateway_addr;
|
struct in6_addr gateway_addr;
|
||||||
const gint64 now_msec = nm_utils_get_monotonic_timestamp_msec();
|
const gint64 now_msec = nm_utils_get_monotonic_timestamp_msec();
|
||||||
int offset;
|
int offset;
|
||||||
|
|
@ -174,23 +175,17 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
* Subsequent router advertisements can represent new default gateways
|
* Subsequent router advertisements can represent new default gateways
|
||||||
* on the network. We should present all of them in router preference
|
* on the network. We should present all of them in router preference
|
||||||
* order.
|
* order.
|
||||||
*/
|
*
|
||||||
{
|
* https://tools.ietf.org/html/rfc2461#section-4.2 :
|
||||||
const NMNDiscGateway gateway = {
|
* A Lifetime of 0 indicates that the router is not a default router and
|
||||||
.address = gateway_addr,
|
* SHOULD NOT appear on the default router list.
|
||||||
.expiry_msec = _nm_ndisc_lifetime_to_expiry(now_msec, ndp_msgra_router_lifetime(msgra)),
|
*
|
||||||
.preference = _route_preference_coerce(ndp_msgra_route_preference(msgra)),
|
* We handle that by tracking a gateway that expires right now. */
|
||||||
};
|
gateway = (NMNDiscGateway) {
|
||||||
|
.address = gateway_addr,
|
||||||
/* https://tools.ietf.org/html/rfc2461#section-4.2
|
.expiry_msec = _nm_ndisc_lifetime_to_expiry(now_msec, ndp_msgra_router_lifetime(msgra)),
|
||||||
* > A Lifetime of 0 indicates that the router is not a
|
.preference = _route_preference_coerce(ndp_msgra_route_preference(msgra)),
|
||||||
* > default router and SHOULD NOT appear on the default
|
};
|
||||||
* > router list.
|
|
||||||
* We handle that by tracking a gateway that expires right now. */
|
|
||||||
|
|
||||||
if (nm_ndisc_add_gateway(ndisc, &gateway, now_msec))
|
|
||||||
changed |= NM_NDISC_CONFIG_GATEWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Addresses & Routes */
|
/* Addresses & Routes */
|
||||||
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_PREFIX) {
|
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_PREFIX) {
|
||||||
|
|
@ -240,9 +235,24 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
guint8 plen = ndp_msg_opt_route_prefix_len(msg, offset);
|
guint8 plen = ndp_msg_opt_route_prefix_len(msg, offset);
|
||||||
struct in6_addr network;
|
struct in6_addr network;
|
||||||
|
|
||||||
if (plen == 0 || plen > 128)
|
if (plen > 128)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (plen == 0) {
|
||||||
|
/* https://tools.ietf.org/html/rfc4191#section-3.1 :
|
||||||
|
* When processing a Router Advertisement, a type C host first updates a
|
||||||
|
* ::/0 route based on the Router Lifetime and Default Router Preference
|
||||||
|
* in the Router Advertisement message header. [...] The Router Preference
|
||||||
|
* and Lifetime values in a ::/0 Route Information Option override the
|
||||||
|
* preference and lifetime values in the Router Advertisement header.
|
||||||
|
*/
|
||||||
|
gateway.preference =
|
||||||
|
_route_preference_coerce(ndp_msg_opt_route_preference(msg, offset));
|
||||||
|
gateway.expiry_msec =
|
||||||
|
_nm_ndisc_lifetime_to_expiry(now_msec, ndp_msg_opt_route_lifetime(msg, offset));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
nm_ip6_addr_clear_host_address(&network, ndp_msg_opt_route_prefix(msg, offset), plen);
|
nm_ip6_addr_clear_host_address(&network, ndp_msg_opt_route_prefix(msg, offset), plen);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -262,6 +272,9 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nm_ndisc_add_gateway(ndisc, &gateway, now_msec))
|
||||||
|
changed |= NM_NDISC_CONFIG_GATEWAYS;
|
||||||
|
|
||||||
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_RDNSS) {
|
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_RDNSS) {
|
||||||
struct in6_addr *addr;
|
struct in6_addr *addr;
|
||||||
int addr_index;
|
int addr_index;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue