<para>Note that if IPv6 is enabled on the interface, and the MTU is chosen
below 1280 (the minimum MTU for IPv6) it will automatically be increased to this value.</para>
</listitem>
- </varlistentry>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>IPServiceType=</varname></term>
+ <listitem>
+ <para>Takes string; "CS6" or "CS4". Used to set IP service type to CS6 (network control)
+ or CS4 (Realtime). IPServiceType defaults to CS6 if nothing is specified.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
uint32_t xid, const uint8_t *mac_addr,
size_t mac_addr_len, uint16_t arp_type,
uint16_t port);
-int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port);
+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);
int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source, be32_t destination_addr,
- uint16_t destination, uint16_t len);
+ uint16_t destination, uint16_t len, int ip_service_type);
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum, uint16_t port);
bcast_addr, ð_mac, arp_type, dhcp_hlen, port);
}
-int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type) {
union sockaddr_union src = {
.in.sin_family = AF_INET,
.in.sin_port = htobe16(port),
if (s < 0)
return -errno;
- r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
+ if (ip_service_type >= 0)
+ r = setsockopt_int(s, IPPROTO_IP, IP_TOS, ip_service_type);
+ else
+ r = setsockopt_int(s, IPPROTO_IP, IP_TOS, IPTOS_CLASS_CS6);
+
if (r < 0)
return r;
void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
uint16_t source_port, be32_t destination_addr,
- uint16_t destination_port, uint16_t len) {
+ uint16_t destination_port, uint16_t len, int ip_service_type) {
packet->ip.version = IPVERSION;
packet->ip.ihl = DHCP_IP_SIZE / 4;
packet->ip.tot_len = htobe16(len);
- packet->ip.tos = IPTOS_CLASS_CS6;
+ if (ip_service_type >= 0)
+ packet->ip.tos = ip_service_type;
+ else
+ packet->ip.tos = IPTOS_CLASS_CS6;
packet->ip.protocol = IPPROTO_UDP;
packet->ip.saddr = source_addr;
void *userdata;
sd_dhcp_lease *lease;
usec_t start_delay;
+ int ip_service_type;
};
static const uint8_t default_req_opts[] = {
return 0;
}
+int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
+ assert_return(client, -EINVAL);
+
+ client->ip_service_type = type;
+
+ return 0;
+}
+
static int client_notify(sd_dhcp_client *client, int event) {
assert(client);
size_t len) {
dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
- INADDR_BROADCAST, DHCP_PORT_SERVER, len);
+ INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type);
return dhcp_network_send_raw_socket(client->fd, &client->link,
packet, len);
goto error;
}
- r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
+ r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
if (r < 0) {
log_dhcp_client(client, "could not bind UDP socket");
goto error;
.port = DHCP_PORT_CLIENT,
.anonymize = !!anonymize,
.max_attempts = (uint64_t) -1,
+ .ip_service_type = -1,
};
/* NOTE: this could be moved to a function. */
if (anonymize) {
dhcp_packet_append_ip_headers(packet, server->address, DHCP_PORT_SERVER,
packet->dhcp.yiaddr,
- DHCP_PORT_CLIENT, len);
+ DHCP_PORT_CLIENT, len, -1);
return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
}
}
server->fd_raw = r;
- r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER);
+ r = dhcp_network_bind_udp_socket(server->ifindex, INADDR_ANY, DHCP_PORT_SERVER, -1);
if (r < 0) {
sd_dhcp_server_stop(server);
return r;
return test_fd[0];
}
-int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port) {
+int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int ip_service_type) {
int fd;
fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
***/
#include <ctype.h>
+#include <netinet/ip.h>
#include "conf-parser.h"
#include "def.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-speed-meter.h"
+#include "networkd-dhcp4.h"
#include "string-table.h"
int manager_parse_config_file(Manager *m) {
ret->raw_data_len = count;
return 0;
}
+
+int config_parse_ip_service_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) {
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ if (streq(rvalue, "CS4"))
+ *((int *)data) = IPTOS_CLASS_CS4;
+ else if (streq(rvalue, "CS6"))
+ *((int *)data) = IPTOS_CLASS_CS6;
+ else
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Failed to parse IPServiceType type '%s', ignoring.", rvalue);
+
+ return 0;
+}
CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_service_type);
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set max attempts: %m");
}
- return dhcp4_set_client_identifier(link);
+ if (link->network->ip_service_type > 0) {
+ r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->ip_service_type);
+ if (r < 0)
+ return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ip service type: %m");
+ }
+ return dhcp4_set_client_identifier(link);
}
int config_parse_dhcp_max_attempts(
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
DHCPv4.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
+DHCPv4.IPServiceType, config_parse_ip_service_type, 0, offsetof(Network, ip_service_type)
DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns)
DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp)
DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
.can_triple_sampling = -1,
+ .ip_service_type = -1,
};
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
DHCPUseDomains dhcp_use_domains;
Set *dhcp_black_listed_ip;
Set *dhcp_request_options;
+ int ip_service_type;
/* DHCPv6 Client support*/
bool dhcp6_use_dns;
int sd_dhcp_client_get_lease(
sd_dhcp_client *client,
sd_dhcp_lease **ret);
+int sd_dhcp_client_set_service_type(
+ sd_dhcp_client *client,
+ int type);
int sd_dhcp_client_stop(sd_dhcp_client *client);
int sd_dhcp_client_start(sd_dhcp_client *client);
RequestOptions=
SendRelease=
MaxAttempts=
+IPServiceType=
[DHCPv6]
UseNTP=
UseDNS=