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>
<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>
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)
*nexthop = (NextHop) {
.family = AF_UNSPEC,
+ .onlink = -1,
};
*ret = TAKE_PTR(nexthop);
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,
/* 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;
}
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;
+}
uint32_t id;
int family;
union in_addr_union gw;
+ int onlink;
} NextHop;
NextHop *nexthop_free(NextHop *nexthop);
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);
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);
Id=
Gateway=
Family=
+OnLink=
[QDisc]
Parent=
Handle=