mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
optionally set socket priority on DHCPv4 raw socket
This commit is contained in:
parent
c24b0bd1df
commit
ea57796854
7
NEWS
7
NEWS
@ -48,6 +48,13 @@ CHANGES WITH 253 in spe:
|
||||
* 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
|
||||
|
@ -1890,6 +1890,20 @@ allow my_server_t localnet_peer_t:peer recv;</programlisting>
|
||||
</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>
|
||||
|
@ -40,7 +40,9 @@ int dhcp_network_bind_raw_socket(
|
||||
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);
|
||||
|
@ -25,7 +25,9 @@ static int _bind_raw_socket(
|
||||
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);
|
||||
@ -113,6 +115,12 @@ static int _bind_raw_socket(
|
||||
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),
|
||||
@ -137,7 +145,9 @@ int dhcp_network_bind_raw_socket(
|
||||
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,
|
||||
@ -160,13 +170,13 @@ int dhcp_network_bind_raw_socket(
|
||||
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;
|
||||
}
|
||||
|
@ -16,7 +16,10 @@ int dhcp_network_bind_raw_socket(
|
||||
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);
|
||||
|
@ -121,6 +121,8 @@ struct sd_dhcp_client {
|
||||
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;
|
||||
@ -647,6 +649,16 @@ int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
|
||||
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);
|
||||
@ -1381,7 +1393,8 @@ static int client_start_delayed(sd_dhcp_client *client) {
|
||||
|
||||
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;
|
||||
@ -1429,7 +1442,8 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
|
||||
|
||||
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;
|
||||
|
@ -235,7 +235,10 @@ int dhcp_network_bind_raw_socket(
|
||||
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;
|
||||
|
@ -1499,6 +1499,12 @@ static int dhcp4_configure(Link *link) {
|
||||
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)
|
||||
@ -1701,6 +1707,42 @@ int config_parse_dhcp_ip_service_type(
|
||||
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,
|
||||
|
@ -29,6 +29,7 @@ int link_request_dhcp4_client(Link *link);
|
||||
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);
|
||||
|
@ -243,6 +243,7 @@ DHCPv4.SendDecline, config_parse_bool,
|
||||
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)
|
||||
|
@ -130,6 +130,8 @@ struct Network {
|
||||
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;
|
||||
|
@ -309,6 +309,9 @@ int sd_dhcp_client_get_lease(
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user