Squashed 'src/n-dhcp4/' changes from 2707213e3e..0d4dcc9bb4

0d4dcc9bb4 n-dhcp4: introduce n_dhcp4_c_connection_clear_client_ip() helper
433c57ab2e n-dhcp4: Do not set ciaddr in DISCOVER state.
feacc2cccd n-dhcp4: change the default DSCP value to 0
b64e2c62e8 n-dhcp4: support setting the DSCP value
6cfa9d84d0 n-dhcp4: set xid of the DHCP header for RELEASE and DECLINE message

git-subtree-dir: src/n-dhcp4
git-subtree-split: 0d4dcc9bb45d5a63d53a787289ad79823343e624
This commit is contained in:
Jan Vaclav 2025-10-22 20:09:23 +02:00
parent 90b0404e8d
commit 2f35c94628
10 changed files with 60 additions and 13 deletions

View file

@ -191,7 +191,8 @@ int n_dhcp4_c_connection_connect(NDhcp4CConnection *connection,
r = n_dhcp4_c_socket_udp_new(&fd_udp,
connection->client_config->ifindex,
client,
server);
server,
connection->probe_config->dscp);
if (r)
return r;
@ -378,6 +379,10 @@ void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
*timeoutp = timeout;
}
void n_dhcp4_c_connection_clear_client_ip(NDhcp4CConnection *connection) {
connection->client_ip = INADDR_ANY;
}
static int n_dhcp4_c_connection_packet_broadcast(NDhcp4CConnection *connection,
NDhcp4Outgoing *message) {
int r;
@ -388,6 +393,7 @@ static int n_dhcp4_c_connection_packet_broadcast(NDhcp4CConnection *connection,
connection->client_config->ifindex,
connection->client_config->broadcast_mac,
connection->client_config->n_broadcast_mac,
connection->probe_config->dscp,
message);
if (r)
return r;
@ -1027,13 +1033,13 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
case N_DHCP4_C_MESSAGE_REBOOT:
case N_DHCP4_C_MESSAGE_REBIND:
case N_DHCP4_C_MESSAGE_RENEW:
case N_DHCP4_C_MESSAGE_DECLINE:
case N_DHCP4_C_MESSAGE_RELEASE:
request->userdata.base_time = timestamp;
n_dhcp4_outgoing_set_xid(request, n_dhcp4_client_probe_config_get_random(connection->probe_config));
break;
case N_DHCP4_C_MESSAGE_SELECT:
case N_DHCP4_C_MESSAGE_DECLINE:
case N_DHCP4_C_MESSAGE_RELEASE:
break;
default:
c_assert(0);

View file

@ -118,6 +118,7 @@ int n_dhcp4_client_probe_config_dup(NDhcp4ClientProbeConfig *config,
dup->init_reboot = config->init_reboot;
dup->requested_ip = config->requested_ip;
dup->ms_start_delay = config->ms_start_delay;
dup->dscp = config->dscp;
for (unsigned int i = 0; i < config->n_request_parameters; ++i)
dup->request_parameters[dup->n_request_parameters++] = config->request_parameters[i];
@ -190,6 +191,19 @@ _c_public_ void n_dhcp4_client_probe_config_set_init_reboot(NDhcp4ClientProbeCon
config->init_reboot = init_reboot;
}
/**
* n_dhcp4_client_probe_config_set_dscp() - set the IP DSCP value
* @config: configuration to operate on
* @dscp: value to set
*
* This sets the DSCP property of the configuration object, which specifies
* the DSCP value to set in the first six bits of the DS field in the IPv4
* header. If this function is not called, the DSCP will be set to CS0 (0).
*/
_c_public_ void n_dhcp4_client_probe_config_set_dscp(NDhcp4ClientProbeConfig *config, uint8_t dscp) {
config->dscp = dscp & 0x3F;
}
/**
* n_dhcp4_client_probe_config_set_requested_ip() - set requested-ip property
* @config: configuration to operate on
@ -689,6 +703,8 @@ static int n_dhcp4_client_probe_transition_deferred(NDhcp4ClientProbe *probe, ui
switch (probe->state) {
case N_DHCP4_CLIENT_PROBE_STATE_INIT:
/* reset client IP (CIADDR) */
n_dhcp4_c_connection_clear_client_ip(&probe->connection);
r = n_dhcp4_c_connection_listen(&probe->connection);
if (r)
return r;

View file

@ -7,6 +7,7 @@
#include <endian.h>
#include <inttypes.h>
#include <limits.h>
#include <netinet/ip.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
@ -34,6 +35,7 @@ typedef struct NDhcp4LogQueue NDhcp4LogQueue;
#define N_DHCP4_NETWORK_CLIENT_PORT (68)
#define N_DHCP4_MESSAGE_MAGIC ((uint32_t)(0x63825363))
#define N_DHCP4_MESSAGE_FLAG_BROADCAST (htons(0x8000))
#define N_DHCP4_DSCP_DEFAULT (IPTOS_CLASS_CS0 >> 2)
enum {
N_DHCP4_OP_BOOTREQUEST = 1,
@ -263,6 +265,7 @@ struct NDhcp4ClientProbeOption {
struct NDhcp4ClientProbeConfig {
bool inform_only;
bool init_reboot;
uint8_t dscp;
struct in_addr requested_ip;
unsigned short int entropy[3];
uint64_t ms_start_delay; /* max ms to wait before starting probe */
@ -273,6 +276,7 @@ struct NDhcp4ClientProbeConfig {
#define N_DHCP4_CLIENT_PROBE_CONFIG_NULL(_x) { \
.ms_start_delay = N_DHCP4_CLIENT_START_DELAY_RFC2131, \
.dscp = N_DHCP4_DSCP_DEFAULT, \
}
struct NDhcp4CEventNode {
@ -536,7 +540,8 @@ int n_dhcp4_c_socket_packet_new(int *sockfdp, int ifindex);
int n_dhcp4_c_socket_udp_new(int *sockfdp,
int ifindex,
const struct in_addr *client_addr,
const struct in_addr *server_addr);
const struct in_addr *server_addr,
uint8_t dscp);
int n_dhcp4_s_socket_packet_new(int *sockfdp);
int n_dhcp4_s_socket_udp_new(int *sockfdp, int ifindex);
@ -544,6 +549,7 @@ int n_dhcp4_c_socket_packet_send(int sockfd,
int ifindex,
const unsigned char *dest_haddr,
unsigned char halen,
uint8_t dscp,
NDhcp4Outgoing *message);
int n_dhcp4_c_socket_udp_send(int sockfd, NDhcp4Outgoing *message);
int n_dhcp4_c_socket_udp_broadcast(int sockfd, NDhcp4Outgoing *message);
@ -553,6 +559,7 @@ int n_dhcp4_s_socket_packet_send(int sockfd,
const unsigned char *dest_haddr,
unsigned char halen,
const struct in_addr *dest_inaddr,
uint8_t dscp,
NDhcp4Outgoing *message);
int n_dhcp4_s_socket_udp_send(int sockfd,
const struct in_addr *inaddr_src,
@ -610,6 +617,8 @@ void n_dhcp4_c_connection_close(NDhcp4CConnection *connection);
void n_dhcp4_c_connection_get_timeout(NDhcp4CConnection *connection,
uint64_t *timeoutp);
void n_dhcp4_c_connection_clear_client_ip(NDhcp4CConnection *connection);
int n_dhcp4_c_connection_discover_new(NDhcp4CConnection *connection,
NDhcp4Outgoing **request);
int n_dhcp4_c_connection_select_new(NDhcp4CConnection *connection,

View file

@ -202,6 +202,7 @@ int n_dhcp4_s_connection_send_reply(NDhcp4SConnection *connection,
header->chaddr,
header->hlen,
&(struct in_addr){header->yiaddr},
N_DHCP4_DSCP_DEFAULT,
message);
if (r)
return r;

View file

@ -133,6 +133,7 @@ int n_dhcp4_c_socket_packet_new(int *sockfdp, int ifindex) {
* @ifindex: interface index to bind to
* @client_addr: client address to bind to
* @server_addr: server address to connect to
* @dscp: the DSCP value
*
* Create a new AF_INET/SOCK_DGRAM socket usable to listen to and send DHCP client
* packets.
@ -145,7 +146,8 @@ int n_dhcp4_c_socket_packet_new(int *sockfdp, int ifindex) {
int n_dhcp4_c_socket_udp_new(int *sockfdp,
int ifindex,
const struct in_addr *client_addr,
const struct in_addr *server_addr) {
const struct in_addr *server_addr,
uint8_t dscp) {
_c_cleanup_(c_closep) int sockfd = -1;
struct sock_filter filter[] = {
/*
@ -189,7 +191,8 @@ int n_dhcp4_c_socket_udp_new(int *sockfdp,
.sin_addr = *server_addr,
.sin_port = htons(N_DHCP4_NETWORK_SERVER_PORT),
};
int r, tos = IPTOS_CLASS_CS6, on = 1;
int r, on = 1;
int tos = dscp << 2;
sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
if (sockfd < 0)
@ -340,6 +343,7 @@ static int n_dhcp4_socket_packet_send(int sockfd,
const unsigned char *dest_haddr,
unsigned char halen,
const struct sockaddr_in *dest_paddr,
uint8_t dscp,
NDhcp4Outgoing *message) {
struct packet_sockaddr_ll haddr = {
.sll_family = AF_PACKET,
@ -357,7 +361,7 @@ static int n_dhcp4_socket_packet_send(int sockfd,
n_buf = n_dhcp4_outgoing_get_raw(message, &buf);
r = packet_sendto_udp(sockfd, buf, n_buf, &len, src_paddr, &haddr, dest_paddr);
r = packet_sendto_udp(sockfd, buf, n_buf, &len, src_paddr, &haddr, dest_paddr, dscp);
if (r < 0) {
if (r == -EAGAIN || r == -ENOBUFS)
return N_DHCP4_E_DROPPED;
@ -379,6 +383,7 @@ int n_dhcp4_c_socket_packet_send(int sockfd,
int ifindex,
const unsigned char *dest_haddr,
unsigned char halen,
uint8_t dscp,
NDhcp4Outgoing *message) {
struct sockaddr_in src_paddr = {
.sin_family = AF_INET,
@ -397,6 +402,7 @@ int n_dhcp4_c_socket_packet_send(int sockfd,
dest_haddr,
halen,
&dest_paddr,
dscp,
message);
}
@ -468,6 +474,7 @@ int n_dhcp4_s_socket_packet_send(int sockfd,
const unsigned char *dest_haddr,
unsigned char halen,
const struct in_addr *dest_inaddr,
uint8_t dscp,
NDhcp4Outgoing *message) {
struct sockaddr_in src_paddr = {
.sin_family = AF_INET,
@ -486,6 +493,7 @@ int n_dhcp4_s_socket_packet_send(int sockfd,
dest_haddr,
halen,
&dest_paddr,
dscp,
message);
}

View file

@ -128,6 +128,7 @@ NDhcp4ClientProbeConfig *n_dhcp4_client_probe_config_free(NDhcp4ClientProbeConfi
void n_dhcp4_client_probe_config_set_inform_only(NDhcp4ClientProbeConfig *config, bool inform_only);
void n_dhcp4_client_probe_config_set_init_reboot(NDhcp4ClientProbeConfig *config, bool init_reboot);
void n_dhcp4_client_probe_config_set_dscp(NDhcp4ClientProbeConfig *config, uint8_t dscp);
void n_dhcp4_client_probe_config_set_requested_ip(NDhcp4ClientProbeConfig *config, struct in_addr ip);
void n_dhcp4_client_probe_config_set_start_delay(NDhcp4ClientProbeConfig *config, uint64_t msecs);
void n_dhcp4_client_probe_config_request_option(NDhcp4ClientProbeConfig *config, uint8_t option);

View file

@ -46,7 +46,7 @@ static void test_client_udp_socket_new(Link *link,
netns_get(&oldns);
netns_set(link->netns);
r = n_dhcp4_c_socket_udp_new(skp, link->ifindex, addr_client, addr_server);
r = n_dhcp4_c_socket_udp_new(skp, link->ifindex, addr_client, addr_server, N_DHCP4_DSCP_DEFAULT);
c_assert(r >= 0);
netns_set(oldns);
@ -95,6 +95,7 @@ static void test_client_server_packet(Link *link_server, Link *link_client) {
link_client->ifindex,
(const unsigned char[]){0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
ETH_ALEN,
-1,
outgoing);
c_assert(!r);
@ -178,6 +179,7 @@ static void test_server_client_packet(Link *link_server, Link *link_client) {
link_client->mac.ether_addr_octet,
ETH_ALEN,
&addr_client,
N_DHCP4_DSCP_DEFAULT,
outgoing);
c_assert(!r);
r = n_dhcp4_s_socket_packet_send(sk_server,
@ -188,6 +190,7 @@ static void test_server_client_packet(Link *link_server, Link *link_client) {
},
ETH_ALEN,
&addr_client,
N_DHCP4_DSCP_DEFAULT,
outgoing);
c_assert(!r);

View file

@ -150,6 +150,7 @@ uint16_t packet_internet_checksum_udp(const struct in_addr *src_addr,
* @src_paddr: source protocol address, see ip(7)
* @dest_haddr: destination hardware address, see packet(7)
* @dest_paddr: destination protocol address, see ip(7)
* @dscp: the DSCP value
*
* Sends an UDP packet on a AF_PACKET socket directly to a hardware
* address. The difference between this and sendto() on an AF_INET
@ -165,11 +166,12 @@ int packet_sendto_udp(int sockfd,
size_t *n_transmittedp,
const struct sockaddr_in *src_paddr,
const struct packet_sockaddr_ll *dest_haddr,
const struct sockaddr_in *dest_paddr) {
const struct sockaddr_in *dest_paddr,
uint8_t dscp) {
struct iphdr ip_hdr = {
.version = IPVERSION,
.ihl = sizeof(ip_hdr) / 4, /* Length of header in multiples of four bytes */
.tos = IPTOS_CLASS_CS6, /* Class Selector for network control */
.tos = dscp << 2,
.tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr) + n_buf),
.frag_off = htons(IP_DF), /* Do not fragment */
.ttl = IPDEFTTL,

View file

@ -42,7 +42,8 @@ int packet_sendto_udp(int sockfd,
size_t *n_transmittedp,
const struct sockaddr_in *src_paddr,
const struct packet_sockaddr_ll *dest_haddr,
const struct sockaddr_in *dest_paddr);
const struct sockaddr_in *dest_paddr,
uint8_t dscp);
int packet_recvfrom_udp(int sockfd,
void *buf,
size_t n_buf,

View file

@ -123,7 +123,7 @@ static void test_packet_unicast(int ifindex, int sk, void *buf, size_t n_buf,
memcpy(addr.sll_addr, haddr_dst, ETH_ALEN);
r = packet_sendto_udp(sk, buf, n_buf, &len, paddr_src, &addr, paddr_dst);
r = packet_sendto_udp(sk, buf, n_buf, &len, paddr_src, &addr, paddr_dst, N_DHCP4_DSCP_DEFAULT);
c_assert(!r);
c_assert(len == n_buf);
}
@ -142,7 +142,7 @@ static void test_packet_broadcast(int ifindex, int sk, void *buf, size_t n_buf,
memcpy(addr.sll_addr, (unsigned char[]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, ETH_ALEN);
r = packet_sendto_udp(sk, buf, n_buf, &len, paddr_src, &addr, paddr_dst);
r = packet_sendto_udp(sk, buf, n_buf, &len, paddr_src, &addr, paddr_dst, N_DHCP4_DSCP_DEFAULT);
c_assert(!r);
c_assert(len == n_buf);
}