network: ndisc - Honour CurHopLimit

RFC4861 Neighbor Discovery – Sections 4.2 and 6.3.4

From section 4.2. Router Advertisement Message Format:

Cur Hop Limit        8-bit unsigned integer.  The default value that
                     should be placed in the Hop Count field of the IP
                     header for outgoing IP packets.  A value of zero
                     means unspecified (by this router).
This commit is contained in:
Susant Sahani 2023-07-18 20:12:46 +05:30 committed by Luca Boccassi
parent 1a1f4a8092
commit f141b2c053
7 changed files with 28 additions and 0 deletions

View File

@ -2628,6 +2628,14 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>UseHopLimit=</varname></term>
<listitem>
<para>Takes a boolean. When true, the hop limit received in the Router Advertisement will be set to routes
configured based on the advertisement. See also <varname>IPv6HopLimit=</varname>. Defaults to true.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>UseGateway=</varname></term> <term><varname>UseGateway=</varname></term>
<listitem> <listitem>

View File

@ -168,6 +168,7 @@ static void ndisc_set_route_priority(Link *link, Route *route) {
static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
_cleanup_(route_freep) Route *route = in; _cleanup_(route_freep) Route *route = in;
struct in6_addr router; struct in6_addr router;
uint8_t hop_limit = 0;
uint32_t mtu = 0; uint32_t mtu = 0;
bool is_new; bool is_new;
int r; int r;
@ -187,6 +188,12 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
return log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m"); return log_link_warning_errno(link, r, "Failed to get default router MTU from RA: %m");
} }
if (link->network->ipv6_accept_ra_use_hop_limit) {
r = sd_ndisc_router_get_hop_limit(rt, &hop_limit);
if (r < 0 && r != -ENODATA)
return log_link_warning_errno(link, r, "Failed to get default router hop limit from RA: %m");
}
route->source = NETWORK_CONFIG_SOURCE_NDISC; route->source = NETWORK_CONFIG_SOURCE_NDISC;
route->provider.in6 = router; route->provider.in6 = router;
if (!route->table_set) if (!route->table_set)
@ -199,6 +206,9 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
if (route->mtu == 0) if (route->mtu == 0)
route->mtu = mtu; route->mtu = mtu;
if (route->hop_limit == 0)
route->hop_limit = hop_limit;
is_new = route_get(NULL, link, route, NULL) < 0; is_new = route_get(NULL, link, route, NULL) < 0;
r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages, r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages,

View File

@ -283,6 +283,7 @@ IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool,
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu) IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu)
IPv6AcceptRA.UseHopLimit, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_hop_limit)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client) IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET6, 0 IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET6, 0
IPv6AcceptRA.RouteMetric, config_parse_ipv6_accept_ra_route_metric, 0, 0 IPv6AcceptRA.RouteMetric, config_parse_ipv6_accept_ra_route_metric, 0, 0

View File

@ -484,6 +484,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_use_autonomous_prefix = true, .ipv6_accept_ra_use_autonomous_prefix = true,
.ipv6_accept_ra_use_onlink_prefix = true, .ipv6_accept_ra_use_onlink_prefix = true,
.ipv6_accept_ra_use_mtu = true, .ipv6_accept_ra_use_mtu = true,
.ipv6_accept_ra_use_hop_limit = true,
.ipv6_accept_ra_route_table = RT_TABLE_MAIN, .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
.ipv6_accept_ra_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH, .ipv6_accept_ra_route_metric_high = IPV6RA_ROUTE_METRIC_HIGH,
.ipv6_accept_ra_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM, .ipv6_accept_ra_route_metric_medium = IPV6RA_ROUTE_METRIC_MEDIUM,

View File

@ -319,6 +319,7 @@ struct Network {
bool ipv6_accept_ra_use_autonomous_prefix; bool ipv6_accept_ra_use_autonomous_prefix;
bool ipv6_accept_ra_use_onlink_prefix; bool ipv6_accept_ra_use_onlink_prefix;
bool ipv6_accept_ra_use_mtu; bool ipv6_accept_ra_use_mtu;
bool ipv6_accept_ra_use_hop_limit;
bool ipv6_accept_ra_quickack; bool ipv6_accept_ra_quickack;
bool ipv6_accept_ra_use_captive_portal; bool ipv6_accept_ra_use_captive_portal;
bool active_slave; bool active_slave;

View File

@ -1241,6 +1241,12 @@ static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link
return r; return r;
} }
if (route->hop_limit > 0) {
r = sd_netlink_message_append_u32(m, RTAX_HOPLIMIT, route->hop_limit);
if (r < 0)
return r;
}
r = sd_netlink_message_close_container(m); r = sd_netlink_message_close_container(m);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -50,6 +50,7 @@ struct Route {
uint32_t initcwnd; uint32_t initcwnd;
uint32_t initrwnd; uint32_t initrwnd;
uint32_t advmss; uint32_t advmss;
uint32_t hop_limit;
char *tcp_congestion_control_algo; char *tcp_congestion_control_algo;
unsigned char pref; unsigned char pref;
unsigned flags; unsigned flags;