network: nexthop: add OnLink= setting

This commit is contained in:
Yu Watanabe 2021-02-14 14:49:35 +09:00
parent 8e32f20d13
commit 2ddd52d1e2
6 changed files with 82 additions and 6 deletions

View file

@ -1340,6 +1340,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
to <literal>ipv4</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>OnLink=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the kernel does not have to check if the gateway is
reachable directly by the current machine (i.e., attached to the local network), so that we
can insert the nexthop in the kernel table without it being complained about. Defaults to
<literal>no</literal>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
@ -1361,9 +1370,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<term><varname>GatewayOnLink=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the kernel does not have to check if the gateway is
reachable directly by the current machine (i.e., the kernel does not need to check if the
gateway is attached to the local network), so that we can insert the route in the kernel
table without it being complained about. Defaults to <literal>no</literal>.</para>
reachable directly by the current machine (i.e., attached to the local network), so that we
can insert the route in the kernel table without it being complained about. Defaults to
<literal>no</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>

View file

@ -189,6 +189,7 @@ Route.NextHop, config_parse_route_nexthop,
NextHop.Id, config_parse_nexthop_id, 0, 0
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
NextHop.Family, config_parse_nexthop_family, 0, 0
NextHop.OnLink, config_parse_nexthop_onlink, 0, 0
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCPv4.UseDNS, config_parse_dhcp_use_dns, 0, 0
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)

View file

@ -47,6 +47,7 @@ static int nexthop_new(NextHop **ret) {
*nexthop = (NextHop) {
.family = AF_UNSPEC,
.onlink = -1,
};
*ret = TAKE_PTR(nexthop);
@ -360,6 +361,12 @@ static int nexthop_configure(const NextHop *nexthop, Link *link) {
r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw);
if (r < 0)
return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
if (nexthop->onlink > 0) {
r = sd_rtnl_message_nexthop_set_flags(req, RTNH_F_ONLINK);
if (r < 0)
return log_link_error_errno(link, r, "Failed to set RTNH_F_ONLINK flag: %m");
}
}
r = netlink_call_async(link->manager->rtnl, NULL, req, nexthop_handler,
@ -549,6 +556,16 @@ static int nexthop_section_verify(NextHop *nh) {
/* When no Gateway= is specified, assume IPv4. */
nh->family = AF_INET;
if (nh->onlink < 0 && in_addr_is_set(nh->family, &nh->gw) &&
ordered_hashmap_isempty(nh->network->addresses_by_section)) {
/* If no address is configured, in most cases the gateway cannot be reachable.
* TODO: we may need to improve the condition above. */
log_warning("%s: Gateway= without static address configured. "
"Enabling OnLink= option.",
nh->section->filename);
nh->onlink = true;
}
return 0;
}
@ -722,3 +739,48 @@ int config_parse_nexthop_family(
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_onlink(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
n->onlink = -1;
TAKE_PTR(n);
return 0;
}
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
n->onlink = r;
TAKE_PTR(n);
return 0;
}

View file

@ -27,6 +27,7 @@ typedef struct NextHop {
uint32_t id;
int family;
union in_addr_union gw;
int onlink;
} NextHop;
NextHop *nexthop_free(NextHop *nexthop);
@ -41,3 +42,4 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id);
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_gateway);
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_family);
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_onlink);

View file

@ -2743,9 +2743,10 @@ static int route_section_verify(Route *route, Network *network) {
if (route->family == AF_INET6 && route->priority == 0)
route->priority = IP6_RT_PRIO_USER;
if (ordered_hashmap_isempty(network->addresses_by_section) &&
in_addr_is_set(route->gw_family, &route->gw) &&
route->gateway_onlink < 0) {
if (route->gateway_onlink < 0 && in_addr_is_set(route->gw_family, &route->gw) &&
ordered_hashmap_isempty(network->addresses_by_section)) {
/* If no address is configured, in most cases the gateway cannot be reachable.
* TODO: we may need to improve the condition above. */
log_warning("%s: Gateway= without static address configured. "
"Enabling GatewayOnLink= option.",
network->filename);

View file

@ -352,6 +352,7 @@ SendVendorOption=
Id=
Gateway=
Family=
OnLink=
[QDisc]
Parent=
Handle=