* systemd-fstab-generator now supports x-systemd.makefs option for
/sysroot (in the initrd).
+ * The [DHCPv4] section in .network file gained new SocketPriority=
+ setting that assigns the Linux socket priority used by the DHCPv4
+ raw socket. Can be used in conjuntion with the EgressQOSMaps=setting in
+ [VLAN] section of .netdev file to send the desired ethernet 802.1Q frame
+ priority for DHCPv4 initial packets. This cannot be achieved with
+ netfilter mangle tables because of the raw socket bypass.
+
Changes in udev:
* The new net naming scheme "v253" has been introduced. In the new
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>SocketPriority=</varname></term>
+ <listitem>
+ <para>The Linux socket option <constant>SO_PRIORITY</constant> applied to the raw IP socket used for
+ initial DHCPv4 messages. Unset by default. Usual values range from 0 to 6.
+ More details about <constant>SO_PRIORITY</constant> socket option in
+ <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+ Can be used in conjunction with [VLAN] section <varname>EgressQOSMaps=</varname> setting of .netdev
+ file to set the 802.1Q VLAN ethernet tagged header priority, see
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<!-- How to use the DHCP lease -->
<varlistentry>
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
- uint16_t port);
+ uint16_t port,
+ bool so_priority_set,
+ int so_priority);
int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type);
int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
const void *packet, size_t len);
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
- uint16_t port) {
+ uint16_t port,
+ bool so_priority_set,
+ int so_priority) {
assert(ifindex > 0);
assert(link);
if (r < 0)
return -errno;
+ if (so_priority_set) {
+ r = setsockopt_int(s, SOL_SOCKET, SO_PRIORITY, so_priority);
+ if (r < 0)
+ return r;
+ }
+
link->ll = (struct sockaddr_ll) {
.sll_family = AF_PACKET,
.sll_protocol = htobe16(ETH_P_IP),
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
uint16_t arp_type,
- uint16_t port) {
+ uint16_t port,
+ bool so_priority_set,
+ int so_priority) {
static struct hw_addr_data default_eth_bcast = {
.length = ETH_ALEN,
return _bind_raw_socket(ifindex, link, xid,
hw_addr,
(bcast_addr && !hw_addr_is_null(bcast_addr)) ? bcast_addr : &default_eth_bcast,
- arp_type, port);
+ arp_type, port, so_priority_set, so_priority);
case ARPHRD_INFINIBAND:
return _bind_raw_socket(ifindex, link, xid,
&HW_ADDR_NULL,
(bcast_addr && !hw_addr_is_null(bcast_addr)) ? bcast_addr : &default_ib_bcast,
- arp_type, port);
+ arp_type, port, so_priority_set, so_priority);
default:
return -EINVAL;
}
uint32_t id,
const struct hw_addr_data *hw_addr,
const struct hw_addr_data *bcast_addr,
- uint16_t arp_type, uint16_t port) {
+ uint16_t arp_type,
+ uint16_t port,
+ bool so_priority_set,
+ int so_priority) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
sd_dhcp_lease *lease;
usec_t start_delay;
int ip_service_type;
+ int socket_priority;
+ bool socket_priority_set;
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
bool test_mode;
return 0;
}
+int sd_dhcp_client_set_socket_priority(sd_dhcp_client *client, int socket_priority) {
+ assert_return(client, -EINVAL);
+ assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
+
+ client->socket_priority_set = true;
+ client->socket_priority = socket_priority;
+
+ return 0;
+}
+
int sd_dhcp_client_set_fallback_lease_lifetime(sd_dhcp_client *client, uint32_t fallback_lease_lifetime) {
assert_return(client, -EINVAL);
assert_return(!sd_dhcp_client_is_running(client), -EBUSY);
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
&client->hw_addr, &client->bcast_addr,
- client->arp_type, client->port);
+ client->arp_type, client->port,
+ client->socket_priority_set, client->socket_priority);
if (r < 0) {
client_stop(client, r);
return r;
r = dhcp_network_bind_raw_socket(client->ifindex, &client->link, client->xid,
&client->hw_addr, &client->bcast_addr,
- client->arp_type, client->port);
+ client->arp_type, client->port,
+ client->socket_priority_set, client->socket_priority);
if (r < 0) {
client_stop(client, r);
return 0;
uint32_t id,
const struct hw_addr_data *_hw_addr,
const struct hw_addr_data *_bcast_addr,
- uint16_t arp_type, uint16_t port) {
+ uint16_t arp_type,
+ uint16_t port,
+ bool so_priority_set,
+ int so_priority) {
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
return -errno;
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set IP service type: %m");
}
+ if (link->network->dhcp_socket_priority_set) {
+ r = sd_dhcp_client_set_socket_priority(link->dhcp_client, link->network->dhcp_socket_priority);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to set socket priority: %m");
+ }
+
if (link->network->dhcp_fallback_lease_lifetime > 0) {
r = sd_dhcp_client_set_fallback_lease_lifetime(link->dhcp_client, link->network->dhcp_fallback_lease_lifetime);
if (r < 0)
return 0;
}
+int config_parse_dhcp_socket_priority(
+ 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) {
+
+ Network *network = ASSERT_PTR(data);
+ int a, r;
+
+ assert(lvalue);
+ assert(rvalue);
+
+ if (isempty(rvalue)) {
+ network->dhcp_socket_priority_set = false;
+ return 0;
+ }
+
+ r = safe_atoi(rvalue, &a);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r,
+ "Failed to parse socket priority, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ network->dhcp_socket_priority_set = true;
+ network->dhcp_socket_priority = a;
+
+ return 0;
+}
+
int config_parse_dhcp_fallback_lease_lifetime(
const char *unit,
const char *filename,
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_socket_priority);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_fallback_lease_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_label);
DHCPv4.DenyList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_deny_listed_ip)
DHCPv4.AllowList, config_parse_in_addr_prefixes, AF_INET, offsetof(Network, dhcp_allow_listed_ip)
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, dhcp_ip_service_type)
+DHCPv4.SocketPriority, config_parse_dhcp_socket_priority, 0, 0
DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options)
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
DHCPv4.RouteMTUBytes, config_parse_mtu, AF_INET, offsetof(Network, dhcp_route_mtu)
uint16_t dhcp_client_port;
int dhcp_critical;
int dhcp_ip_service_type;
+ int dhcp_socket_priority;
+ bool dhcp_socket_priority_set;
bool dhcp_anonymize;
bool dhcp_send_hostname;
int dhcp_broadcast;
int sd_dhcp_client_set_service_type(
sd_dhcp_client *client,
int type);
+int sd_dhcp_client_set_socket_priority(
+ sd_dhcp_client *client,
+ int so_priority);
int sd_dhcp_client_set_fallback_lease_lifetime(
sd_dhcp_client *client,
uint32_t fallback_lease_lifetime);