Closes #33929.
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>UnassignedSubnetPolicy=</varname></term>
+ <listitem>
+ <para>Takes <literal>none</literal>, or one of the reject types: <literal>unreachable</literal>,
+ <literal>prohibit</literal>, <literal>blackhole</literal>, or <literal>throw</literal>. If a reject
+ type is specified, the reject route corresponding to the acquired 6RD prefix will be configured.
+ For example, when <literal>unreachable</literal>,
+ <programlisting>unreachable 2001:db8::/56 dev lo proto dhcp metric 1024 pref medium</programlisting>
+ will be configured. See <ulink url="https://datatracker.ietf.org/doc/html/rfc7084">RFC 7084</ulink>.
+ If <literal>none</literal> is specified, such route will not be configured. This may be useful when
+ custom firewall rules that handle packets for unassigned subnets will be configured.
+ Defaults to <literal>unreachable</literal>.</para>
+
+ <xi:include href="version-info.xml" xpointer="v257"/>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>IPv6OnlyMode=</varname></term>
<listitem>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>UnassignedSubnetPolicy=</varname></term>
+ <listitem>
+ <para>Takes <literal>none</literal> or one of the reject types: <literal>unreachable</literal>,
+ <literal>prohibit</literal>, <literal>blackhole</literal>, or <literal>throw</literal>. If a reject
+ type is specified, the reject route corresponding to the delegated prefix will be configured.
+ For example, when <literal>unreachable</literal>,
+ <programlisting>unreachable 2001:db8::/56 dev lo proto dhcp metric 1024 pref medium</programlisting>
+ will be configured. See <ulink url="https://datatracker.ietf.org/doc/html/rfc7084">RFC 7084</ulink>.
+ If <literal>none</literal> is specified, such route will not be configured. This may be useful when
+ custom firewall rules that handle packets for unassigned subnets will be configured.
+ Defaults to <literal>unreachable</literal>.</para>
+
+ <xi:include href="version-info.xml" xpointer="v257"/>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>RapidCommit=</varname></term>
<listitem>
#include "networkd-manager.h"
#include "networkd-queue.h"
#include "networkd-radv.h"
+#include "networkd-route-util.h"
#include "networkd-route.h"
#include "networkd-setlink.h"
#include "parse-util.h"
usec_t lifetime_usec,
NetworkConfigSource source,
const union in_addr_union *server_address,
+ uint8_t type, /* RTN_* */
unsigned *counter,
route_netlink_handler_t callback,
bool *configured) {
assert(addr);
assert(IN_SET(source, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6));
assert(server_address);
+ assert(type == RTN_UNSPEC || route_type_is_reject(type));
assert(counter);
assert(callback);
assert(configured);
+ if (type == RTN_UNSPEC)
+ return 0; /* Disabled. */
+
if (prefixlen >= 64) {
log_link_debug(link, "Not adding a blocking route for DHCP delegated prefix %s since the prefix has length >= 64.",
IN6_ADDR_PREFIX_TO_STRING(addr, prefixlen));
route->family = AF_INET6;
route->dst.in6 = *addr;
route->dst_prefixlen = prefixlen;
- route->type = RTN_UNREACHABLE;
+ route->type = type;
route->protocol = RTPROT_DHCP;
route->priority = IP6_RT_PRIO_USER;
route->lifetime_usec = lifetime_usec;
usec_t lifetime_usec,
const union in_addr_union *server_address) {
+ assert(link);
+ assert(link->network);
+
return dhcp_request_unreachable_route(link, addr, prefixlen, lifetime_usec,
NETWORK_CONFIG_SOURCE_DHCP4, server_address,
+ link->network->dhcp_6rd_prefix_route_type,
&link->dhcp4_messages, dhcp4_unreachable_route_handler,
&link->dhcp4_configured);
}
usec_t lifetime_usec,
const union in_addr_union *server_address) {
+ assert(link);
+ assert(link->network);
+
return dhcp_request_unreachable_route(link, addr, prefixlen, lifetime_usec,
NETWORK_CONFIG_SOURCE_DHCP6, server_address,
+ link->network->dhcp6_pd_prefix_route_type,
&link->dhcp6_messages, dhcp6_unreachable_route_handler,
&link->dhcp6_configured);
}
return 0;
}
+
+int config_parse_dhcp_pd_prefix_route_type(
+ 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) {
+
+ uint8_t *p = ASSERT_PTR(data);
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ *p = RTN_UNREACHABLE; /* Defaults to unreachable. */
+ return 0;
+ }
+
+ if (streq(rvalue, "none")) {
+ *p = RTN_UNSPEC; /* Indicate that the route is disabled. */
+ return 0;
+ }
+
+ r = route_type_from_string(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse %s=, ignoring assignment: %s",
+ lvalue, rvalue);
+ return 0;
+ }
+
+ if (!route_type_is_reject(r)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Invalid route type is specified to %s=, ignoring assignment: %s",
+ lvalue, rvalue);
+ return 0;
+ }
+
+ *p = r;
+ return 0;
+}
int dhcp_pd_reconfigure_address(Address *address, Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_pd_subnet_id);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_pd_prefix_route_type);
DHCPv4.InitialAdvertisedReceiveWindow, config_parse_tcp_window, 0, offsetof(Network, dhcp_advertised_receive_window)
DHCPv4.FallbackLeaseLifetimeSec, config_parse_dhcp_fallback_lease_lifetime, 0, 0
DHCPv4.Use6RD, config_parse_bool, 0, offsetof(Network, dhcp_use_6rd)
+DHCPv4.UnassignedSubnetPolicy, config_parse_dhcp_pd_prefix_route_type, 0, offsetof(Network, dhcp_6rd_prefix_route_type)
DHCPv4.IPv6OnlyMode, config_parse_tristate, 0, offsetof(Network, dhcp_ipv6_only_mode)
DHCPv4.NetLabel, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp_netlabel)
DHCPv4.NFTSet, config_parse_nft_set, NFT_SET_PARSE_NETWORK, offsetof(Network, dhcp_nft_set_context)
DHCPv6.VendorClass, config_parse_dhcp_user_or_vendor_class, AF_INET6, offsetof(Network, dhcp6_vendor_class)
DHCPv6.SendVendorOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_vendor_options)
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_prefix_hint, 0, 0
+DHCPv6.UnassignedSubnetPolicy, config_parse_dhcp_pd_prefix_route_type, 0, offsetof(Network, dhcp6_pd_prefix_route_type)
DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_client_start_mode)
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
DHCPv6.IAID, config_parse_iaid, AF_INET6, 0
.dhcp_ip_service_type = -1,
.dhcp_broadcast = -1,
.dhcp_ipv6_only_mode = -1,
+ .dhcp_6rd_prefix_route_type = RTN_UNREACHABLE,
.dhcp6_use_address = true,
.dhcp6_use_pd_prefix = true,
.dhcp6_duid.type = _DUID_TYPE_INVALID,
.dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,
.dhcp6_send_release = true,
+ .dhcp6_pd_prefix_route_type = RTN_UNREACHABLE,
.dhcp_pd = -1,
.dhcp_pd_announce = true,
bool dhcp_use_timezone;
bool dhcp_use_hostname;
bool dhcp_use_6rd;
+ uint8_t dhcp_6rd_prefix_route_type;
bool dhcp_send_release;
bool dhcp_send_decline;
UseDomains dhcp_use_domains;
DUID dhcp6_duid;
uint8_t dhcp6_pd_prefix_length;
struct in6_addr dhcp6_pd_prefix_hint;
+ uint8_t dhcp6_pd_prefix_route_type;
char *dhcp6_hostname;
char *dhcp6_mudurl;
char **dhcp6_user_class;