mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 14:38:09 +02:00
nettools: reimport nettools' n-dhcp4 and rework logging
git subtree pull --prefix shared/n-dhcp4/ git@github.com:nettools/n-dhcp4.git master --squash
This commit is contained in:
commit
65b6fc7871
15 changed files with 313 additions and 132 deletions
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
rm -Rf "./ci-build"
|
||||
mkdir "./ci-build"
|
||||
cd "./ci-build"
|
||||
|
||||
${CHERRY_LIB_MESONSETUP} . "${CHERRY_LIB_SRCDIR}"
|
||||
${CHERRY_LIB_NINJABUILD}
|
||||
${CHERRY_LIB_MESONTEST}
|
||||
# no valgrind tests, since setns(2) is not supported by it
|
||||
50
shared/n-dhcp4/.github/workflows/ci.yml
vendored
Normal file
50
shared/n-dhcp4/.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: CI with Default Configuration
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
#
|
||||
# Prepare CI
|
||||
#
|
||||
# We cannot use the github-action of the `ci-c-util` project, because we
|
||||
# need privileges in the container. Therefore, fetch the CI sources and
|
||||
# build the container manually.
|
||||
#
|
||||
- name: Fetch CI
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: c-util/automation
|
||||
ref: v1
|
||||
path: automation
|
||||
- name: Build CI
|
||||
working-directory: automation/src/ci-c-util
|
||||
run: docker build --tag ci-c-util:v1 .
|
||||
|
||||
#
|
||||
# Run CI
|
||||
#
|
||||
# Take the CI image we built and run the CI with the default project
|
||||
# configuration. We do not use valgrind, since it falls-over with bpf(2)
|
||||
# syscalls.
|
||||
#
|
||||
- name: Fetch Sources
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: source
|
||||
- name: Run through C-Util CI
|
||||
run: |
|
||||
docker run \
|
||||
--privileged \
|
||||
-v "$(pwd)/source:/github/workspace" \
|
||||
"ci-c-util:v1" \
|
||||
"--m32=1" \
|
||||
"--source=/github/workspace"
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
os: linux
|
||||
dist: trusty
|
||||
language: c
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
before_install:
|
||||
- curl -O -L "https://raw.githubusercontent.com/cherry-pick/cherry-images/v1/scripts/vmrun"
|
||||
- curl -O -L "https://raw.githubusercontent.com/cherry-pick/cherry-ci/v1/scripts/cherryci"
|
||||
- chmod +x "./vmrun" "./cherryci"
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
script:
|
||||
- ./vmrun -- ../src/cherryci -d ../src/.cherryci -s c-util -m
|
||||
- script:
|
||||
- ./vmrun -T i686 -- ../src/cherryci -d ../src/.cherryci -s c-util
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
project(
|
||||
'n-dhcp4',
|
||||
'c',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
#
|
||||
# target: libndhcp4.so
|
||||
#
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
* @connection: connection to operate on
|
||||
* @client_config: client configuration to use
|
||||
* @probe_config: client probe configuration to use
|
||||
* @log_queue: the log queue for logging events
|
||||
* @fd_epoll: epoll context to attach to, or -1
|
||||
*
|
||||
* This initializes a new client connection using the configuration given in
|
||||
|
|
@ -47,11 +48,13 @@
|
|||
int n_dhcp4_c_connection_init(NDhcp4CConnection *connection,
|
||||
NDhcp4ClientConfig *client_config,
|
||||
NDhcp4ClientProbeConfig *probe_config,
|
||||
NDhcp4LogQueue *log_queue,
|
||||
int fd_epoll) {
|
||||
*connection = (NDhcp4CConnection)N_DHCP4_C_CONNECTION_NULL(*connection);
|
||||
connection->client_config = client_config;
|
||||
connection->probe_config = probe_config;
|
||||
connection->fd_epoll = fd_epoll;
|
||||
connection->log_queue = log_queue;
|
||||
|
||||
/*
|
||||
* We explicitly allow initializing connections with an invalid
|
||||
|
|
@ -1066,25 +1069,27 @@ static int n_dhcp4_c_connection_send_request(NDhcp4CConnection *connection,
|
|||
}
|
||||
|
||||
if (request->userdata.client_addr == INADDR_ANY) {
|
||||
n_dhcp4_c_log(connection->client_config, LOG_INFO,
|
||||
"send %s to %s%s",
|
||||
message_type_to_str(request->userdata.message_type),
|
||||
broadcast ?
|
||||
"255.255.255.255" :
|
||||
inet_ntop(AF_INET, &connection->server_ip,
|
||||
server_addr, sizeof(server_addr)),
|
||||
error_msg);
|
||||
n_dhcp4_log(connection->log_queue,
|
||||
LOG_INFO,
|
||||
"send %s to %s%s",
|
||||
message_type_to_str(request->userdata.message_type),
|
||||
broadcast ?
|
||||
"255.255.255.255" :
|
||||
inet_ntop(AF_INET, &connection->server_ip,
|
||||
server_addr, sizeof(server_addr)),
|
||||
error_msg);
|
||||
} else {
|
||||
n_dhcp4_c_log(connection->client_config, LOG_INFO,
|
||||
"send %s of %s to %s%s",
|
||||
message_type_to_str(request->userdata.message_type),
|
||||
inet_ntop(AF_INET, &request->userdata.client_addr,
|
||||
client_addr, sizeof(client_addr)),
|
||||
broadcast ?
|
||||
"255.255.255.255" :
|
||||
inet_ntop(AF_INET, &connection->server_ip,
|
||||
server_addr, sizeof(server_addr)),
|
||||
error_msg);
|
||||
n_dhcp4_log(connection->log_queue,
|
||||
LOG_INFO,
|
||||
"send %s of %s to %s%s",
|
||||
message_type_to_str(request->userdata.message_type),
|
||||
inet_ntop(AF_INET, &request->userdata.client_addr,
|
||||
client_addr, sizeof(client_addr)),
|
||||
broadcast ?
|
||||
"255.255.255.255" :
|
||||
inet_ntop(AF_INET, &connection->server_ip,
|
||||
server_addr, sizeof(server_addr)),
|
||||
error_msg);
|
||||
}
|
||||
|
||||
++request->userdata.n_send;
|
||||
|
|
@ -1207,19 +1212,21 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
|
|||
return N_DHCP4_E_AGAIN;
|
||||
|
||||
if (type == N_DHCP4_MESSAGE_OFFER || type == N_DHCP4_MESSAGE_ACK) {
|
||||
n_dhcp4_c_log(connection->client_config, LOG_INFO,
|
||||
"received %s of %s from %s",
|
||||
message_type_to_str(type),
|
||||
inet_ntop(AF_INET, &message->message.header.yiaddr,
|
||||
client_addr, sizeof(client_addr)),
|
||||
inet_ntop(AF_INET, &message->message.header.siaddr,
|
||||
serv_addr, sizeof(serv_addr)));
|
||||
n_dhcp4_log(connection->log_queue,
|
||||
LOG_INFO,
|
||||
"received %s of %s from %s",
|
||||
message_type_to_str(type),
|
||||
inet_ntop(AF_INET, &message->message.header.yiaddr,
|
||||
client_addr, sizeof(client_addr)),
|
||||
inet_ntop(AF_INET, &message->message.header.siaddr,
|
||||
serv_addr, sizeof(serv_addr)));
|
||||
} else {
|
||||
n_dhcp4_c_log(connection->client_config, LOG_INFO,
|
||||
"received %s from %s",
|
||||
message_type_to_str(type),
|
||||
inet_ntop(AF_INET, &message->message.header.siaddr,
|
||||
serv_addr, sizeof(serv_addr)));
|
||||
n_dhcp4_log(connection->log_queue,
|
||||
LOG_INFO,
|
||||
"received %s from %s",
|
||||
message_type_to_str(type),
|
||||
inet_ntop(AF_INET, &message->message.header.siaddr,
|
||||
serv_addr, sizeof(serv_addr)));
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
|
|
|||
|
|
@ -429,9 +429,13 @@ int n_dhcp4_client_probe_new(NDhcp4ClientProbe **probep,
|
|||
*/
|
||||
n_dhcp4_client_probe_config_initialize_random_seed(probe->config);
|
||||
|
||||
/* The new probe keeps a reference on @client. So we are sure that &client->log_queue
|
||||
* stays alive as long as we need it. */
|
||||
|
||||
r = n_dhcp4_c_connection_init(&probe->connection,
|
||||
client->config,
|
||||
probe->config,
|
||||
&client->log_queue,
|
||||
active ? client->fd_epoll : -1);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ int n_dhcp4_client_config_dup(NDhcp4ClientConfig *config, NDhcp4ClientConfig **d
|
|||
dup->n_mac = config->n_mac;
|
||||
memcpy(dup->broadcast_mac, config->broadcast_mac, sizeof(dup->broadcast_mac));
|
||||
dup->n_broadcast_mac = config->n_broadcast_mac;
|
||||
dup->log.level = config->log.level;
|
||||
dup->log.func = config->log.func;
|
||||
dup->log.data = config->log.data;
|
||||
|
||||
r = n_dhcp4_client_config_set_client_id(dup,
|
||||
config->client_id,
|
||||
|
|
@ -227,37 +224,64 @@ _c_public_ void n_dhcp4_client_config_set_broadcast_mac(NDhcp4ClientConfig *conf
|
|||
* n_dhcp4_client_config_set_client_id() - set client-id property
|
||||
* @config: client configuration to operate on
|
||||
* @id: client id
|
||||
* @n_id: length of the client id in bytes
|
||||
* @n_id: length of the client id in bytes. The length
|
||||
* must be from 2 up to 255 bytes. Set it to 0
|
||||
* to unset the client-id.
|
||||
*
|
||||
* This sets the client-id property of @config. It copies the entire client-id
|
||||
* buffer into the configuration.
|
||||
* See RFC 2132 (section 9.14) for the format of the Client Identifier.
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure.
|
||||
*/
|
||||
_c_public_ int n_dhcp4_client_config_set_client_id(NDhcp4ClientConfig *config, const uint8_t *id, size_t n_id) {
|
||||
uint8_t *t;
|
||||
|
||||
if (n_id == 0) {
|
||||
config->client_id = c_free(config->client_id);
|
||||
config->n_client_id = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (n_id < 2 || n_id > 255)
|
||||
return -EINVAL;
|
||||
|
||||
t = malloc(n_id + 1);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(t, id, n_id);
|
||||
t[n_id] = 0; /* safety 0 for debugging */
|
||||
|
||||
free(config->client_id);
|
||||
config->client_id = t;
|
||||
config->n_client_id = n_id;
|
||||
|
||||
memcpy(config->client_id, id, n_id);
|
||||
config->client_id[n_id] = 0; /* safety 0 for debugging */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_c_public_ void n_dhcp4_client_config_set_log_level(NDhcp4ClientConfig *config, int level) {
|
||||
config->log.level = level;
|
||||
}
|
||||
|
||||
_c_public_ void n_dhcp4_client_config_set_log_func(NDhcp4ClientConfig *config, NDhcp4LogFunc func, void *data) {
|
||||
config->log.func = func;
|
||||
config->log.data = data;
|
||||
/**
|
||||
* n_dhcp4_client_set_log_level() - set the logging level of the client
|
||||
* @client: the client to operate on
|
||||
* @level: the minimum syslog logging level that is
|
||||
* still logged. For example, set to LOG_NOTICE
|
||||
* to receive logging events with level LOG_NOTICE
|
||||
* and higher. Set to -1 to disable generating
|
||||
* logging events (which is also the default).
|
||||
*
|
||||
* By enabling logging, you can get N_DHCP4_CLIENT_EVENT_LOG events.
|
||||
*
|
||||
* From the logging event you may steal the message if (and only if) "allow_steal_message"
|
||||
* is true. In that case, clear the message field and free the message yourself.
|
||||
*
|
||||
* If a logging event cannot be logged due to out of memory, one message
|
||||
* gets logged that messages are missing. Until the event with that message
|
||||
* gets dropped, no further logging events will be queued.
|
||||
*
|
||||
* You may change the logging level at any time, but it does not affect
|
||||
* logging events that are already queued.
|
||||
*/
|
||||
_c_public_ void n_dhcp4_client_set_log_level(NDhcp4Client *client, int level) {
|
||||
client->log_queue.log_level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -313,6 +337,16 @@ NDhcp4CEventNode *n_dhcp4_c_event_node_free(NDhcp4CEventNode *node) {
|
|||
case N_DHCP4_CLIENT_EVENT_EXTENDED:
|
||||
node->event.extended.lease = n_dhcp4_client_lease_unref(node->event.extended.lease);
|
||||
break;
|
||||
case N_DHCP4_CLIENT_EVENT_LOG:
|
||||
if (_c_unlikely_(!node->event.log.allow_steal_message)) {
|
||||
/* @node is the static node "nomem_node". It must not be
|
||||
* freed. */
|
||||
c_list_unlink(&node->client_link);
|
||||
node->is_public = false;
|
||||
return NULL;
|
||||
}
|
||||
node->event.log.message = c_free((char *)node->event.log.message);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -395,8 +429,11 @@ _c_public_ int n_dhcp4_client_new(NDhcp4Client **clientp, NDhcp4ClientConfig *co
|
|||
|
||||
ev.data.u32 = N_DHCP4_CLIENT_EPOLL_TIMER;
|
||||
r = epoll_ctl(client->fd_epoll, EPOLL_CTL_ADD, client->fd_timer, &ev);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
close(client->fd_timer);
|
||||
client->fd_timer = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
*clientp = client;
|
||||
client = NULL;
|
||||
|
|
@ -486,6 +523,78 @@ int n_dhcp4_client_raise(NDhcp4Client *client, NDhcp4CEventNode **nodep, unsigne
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_dhcp4_log_queue_fmt() - add a logging event.
|
||||
* @client: the NDhcp4LogQueue to operate on
|
||||
* @level: the syslog logging level
|
||||
* @fmt: the format string for the message
|
||||
* @... printf arguments for logging
|
||||
*
|
||||
* Appends a logging event to the event queue if logging is
|
||||
* enabled and the logging level sufficiently high.
|
||||
*
|
||||
* Queuing a logging event might fail with out of memory.
|
||||
* In that case, a static event will be queued that informs
|
||||
* about lost messages.
|
||||
*/
|
||||
void n_dhcp4_log_queue_fmt(NDhcp4LogQueue *log_queue,
|
||||
int level,
|
||||
const char *fmt,
|
||||
...) {
|
||||
NDhcp4CEventNode *node;
|
||||
char *message;
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
if (level > log_queue->log_level)
|
||||
return;
|
||||
|
||||
/* Currently the logging queue is only implemented for
|
||||
* the client. Nobody would enable logging except a
|
||||
* client instance. */
|
||||
c_assert(log_queue->is_client);
|
||||
|
||||
if (!c_list_is_empty (&log_queue->nomem_node.client_link)) {
|
||||
/* we have the nomem_node queued after a recent out
|
||||
* of memory. This disables all logging messages until
|
||||
* the event gets popped.
|
||||
*
|
||||
* The reason is that we can only queue the nomem_node once,
|
||||
* so if we now try to append another event and succeed, the
|
||||
* user wouldn't know which messages got dropped. Instead,
|
||||
* just drop them all!! */
|
||||
return;
|
||||
}
|
||||
|
||||
r = n_dhcp4_c_event_node_new(&node);
|
||||
if (r < 0)
|
||||
goto handle_nomem;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = vasprintf(&message, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (r < 0) {
|
||||
n_dhcp4_c_event_node_free(node);
|
||||
goto handle_nomem;
|
||||
}
|
||||
|
||||
node->event = (NDhcp4ClientEvent) {
|
||||
.event = N_DHCP4_CLIENT_EVENT_LOG,
|
||||
.log = {
|
||||
.level = level,
|
||||
.message = message,
|
||||
.allow_steal_message = true,
|
||||
},
|
||||
};
|
||||
|
||||
c_list_link_tail(log_queue->event_list, &node->client_link);
|
||||
return;
|
||||
|
||||
handle_nomem:
|
||||
c_list_link_tail(log_queue->event_list, &log_queue->nomem_node.client_link);
|
||||
}
|
||||
|
||||
/**
|
||||
* n_dhcp4_client_arm_timer() - update timer
|
||||
* @client: client to operate on
|
||||
|
|
@ -682,9 +791,10 @@ _c_public_ int n_dhcp4_client_dispatch(NDhcp4Client *client) {
|
|||
/* continue normally */
|
||||
} else if (r) {
|
||||
if (r >= _N_DHCP4_E_INTERNAL) {
|
||||
n_dhcp4_c_log(client->config, LOG_ERR,
|
||||
"invalid internal error code %d after dispatch",
|
||||
r);
|
||||
n_dhcp4_log(&client->log_queue,
|
||||
LOG_ERR,
|
||||
"invalid internal error code %d after dispatch",
|
||||
r);
|
||||
return N_DHCP4_E_INTERNAL;
|
||||
}
|
||||
return r;
|
||||
|
|
@ -753,6 +863,8 @@ _c_public_ int n_dhcp4_client_dispatch(NDhcp4Client *client) {
|
|||
* the client attempted several incompatible
|
||||
* probes in parallel, then the most recent
|
||||
* ones will be cancelled asynchronously.
|
||||
* * N_DHCP4_CLIENT_EVENT_LOG: A logging event if n_dhcp4_client_set_log_level()
|
||||
* is enabled.
|
||||
*
|
||||
* Return: 0 on success, negative error code on failure.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ typedef struct NDhcp4Outgoing NDhcp4Outgoing;
|
|||
typedef struct NDhcp4SConnection NDhcp4SConnection;
|
||||
typedef struct NDhcp4SConnectionIp NDhcp4SConnectionIp;
|
||||
typedef struct NDhcp4SEventNode NDhcp4SEventNode;
|
||||
typedef struct NDhcp4LogQueue NDhcp4LogQueue;
|
||||
|
||||
/* specs */
|
||||
|
||||
|
|
@ -242,11 +243,6 @@ struct NDhcp4ClientConfig {
|
|||
size_t n_broadcast_mac;
|
||||
uint8_t *client_id;
|
||||
size_t n_client_id;
|
||||
struct {
|
||||
int level;
|
||||
NDhcp4LogFunc func;
|
||||
void *data;
|
||||
} log;
|
||||
};
|
||||
|
||||
#define N_DHCP4_CLIENT_CONFIG_NULL(_x) { \
|
||||
|
|
@ -290,9 +286,42 @@ struct NDhcp4CEventNode {
|
|||
.probe_link = C_LIST_INIT((_x).probe_link), \
|
||||
}
|
||||
|
||||
struct NDhcp4LogQueue {
|
||||
CList *event_list;
|
||||
NDhcp4CEventNode nomem_node;
|
||||
int log_level;
|
||||
bool is_client : 1;
|
||||
};
|
||||
|
||||
#define N_DHCP4_LOG_QUEUE_NULL_DEFUNCT() { \
|
||||
.log_level = -1, \
|
||||
.is_client = false, \
|
||||
}
|
||||
|
||||
#define N_DHCP4_LOG_QUEUE_NULL_CLIENT(client) { \
|
||||
.event_list = &((client).event_list), \
|
||||
.log_level = -1, \
|
||||
.is_client = true, \
|
||||
.nomem_node = { \
|
||||
.client_link = C_LIST_INIT((client).log_queue.nomem_node.client_link), \
|
||||
.probe_link = C_LIST_INIT((client).log_queue.nomem_node.probe_link), \
|
||||
.event = { \
|
||||
.event = N_DHCP4_CLIENT_EVENT_LOG, \
|
||||
.log = { \
|
||||
.level = LOG_CRIT, \
|
||||
.message = "one or more logging messages dropped due to out of memory", \
|
||||
.allow_steal_message = false, \
|
||||
}, \
|
||||
}, \
|
||||
.is_public = false, \
|
||||
}, \
|
||||
}
|
||||
|
||||
struct NDhcp4CConnection {
|
||||
NDhcp4ClientConfig *client_config;
|
||||
NDhcp4ClientProbeConfig *probe_config;
|
||||
NDhcp4LogQueue *log_queue;
|
||||
|
||||
int fd_epoll;
|
||||
|
||||
unsigned int state; /* current connection state */
|
||||
|
|
@ -324,6 +353,9 @@ struct NDhcp4Client {
|
|||
unsigned long n_refs;
|
||||
NDhcp4ClientConfig *config;
|
||||
CList event_list;
|
||||
|
||||
NDhcp4LogQueue log_queue;
|
||||
|
||||
int fd_epoll;
|
||||
int fd_timer;
|
||||
|
||||
|
|
@ -339,6 +371,7 @@ struct NDhcp4Client {
|
|||
.event_list = C_LIST_INIT((_x).event_list), \
|
||||
.fd_epoll = -1, \
|
||||
.fd_timer = -1, \
|
||||
.log_queue = N_DHCP4_LOG_QUEUE_NULL_CLIENT(_x), \
|
||||
}
|
||||
|
||||
struct NDhcp4ClientProbe {
|
||||
|
|
@ -570,6 +603,7 @@ NDhcp4CEventNode *n_dhcp4_c_event_node_free(NDhcp4CEventNode *node);
|
|||
int n_dhcp4_c_connection_init(NDhcp4CConnection *connection,
|
||||
NDhcp4ClientConfig *client_config,
|
||||
NDhcp4ClientProbeConfig *probe_config,
|
||||
NDhcp4LogQueue *log_queue,
|
||||
int fd_epoll);
|
||||
void n_dhcp4_c_connection_deinit(NDhcp4CConnection *connection);
|
||||
|
||||
|
|
@ -698,19 +732,28 @@ static inline uint64_t n_dhcp4_gettime(clockid_t clock) {
|
|||
return ts.tv_sec * 1000ULL * 1000ULL * 1000ULL + ts.tv_nsec;
|
||||
}
|
||||
|
||||
#define n_dhcp4_c_log(_config, _level, ...) \
|
||||
void n_dhcp4_log_queue_fmt(NDhcp4LogQueue *log_queue,
|
||||
int level,
|
||||
const char *fmt,
|
||||
...) _c_printf_(3, 4);
|
||||
|
||||
/**
|
||||
* n_dhcp4_log() - append a logging event
|
||||
* @x_log_queue: the logging event queue
|
||||
* @x_level: the syslog logging level for the message.
|
||||
* @...: the format string and arguments.
|
||||
*
|
||||
* Warning: this macro only evaluates the format arguments if the logging
|
||||
* level is enabled.
|
||||
*/
|
||||
#define n_dhcp4_log(x_log_queue, x_level, ...) \
|
||||
do { \
|
||||
const NDhcp4ClientConfig *__config = _config; \
|
||||
int __level = _level; \
|
||||
NDhcp4LogQueue *const _log_queue = (x_log_queue); \
|
||||
const int _level = (x_level); \
|
||||
\
|
||||
if (__level <= __config->log.level && __config->log.func) { \
|
||||
if (1) { \
|
||||
_config->log.func(__level, \
|
||||
__config->log.data, \
|
||||
__VA_ARGS__); \
|
||||
} else { \
|
||||
/* To have the compiler check arguments */ \
|
||||
printf(__VA_ARGS__); \
|
||||
} \
|
||||
if (_level <= _log_queue->log_level) { \
|
||||
n_dhcp4_log_queue_fmt(_log_queue, \
|
||||
_level, \
|
||||
__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ typedef struct NDhcp4ServerEvent NDhcp4ServerEvent;
|
|||
typedef struct NDhcp4ServerIp NDhcp4ServerIp;
|
||||
typedef struct NDhcp4ServerLease NDhcp4ServerLease;
|
||||
|
||||
typedef void (*NDhcp4LogFunc)(int level, void *data, const char *fmt, ...);
|
||||
|
||||
#define N_DHCP4_CLIENT_START_DELAY_RFC2131 (UINT64_C(9000))
|
||||
|
||||
enum {
|
||||
|
|
@ -63,6 +61,7 @@ enum {
|
|||
N_DHCP4_CLIENT_EVENT_EXTENDED,
|
||||
N_DHCP4_CLIENT_EVENT_EXPIRED,
|
||||
N_DHCP4_CLIENT_EVENT_CANCELLED,
|
||||
N_DHCP4_CLIENT_EVENT_LOG,
|
||||
_N_DHCP4_CLIENT_EVENT_N,
|
||||
};
|
||||
|
||||
|
|
@ -88,6 +87,14 @@ struct NDhcp4ClientEvent {
|
|||
struct {
|
||||
NDhcp4ClientProbe *probe;
|
||||
} retracted, expired, cancelled;
|
||||
struct {
|
||||
/* If allow_steal_message is true, then the user may steal the message when handling
|
||||
* the event. In that case, set the message field to %NULL and free it yourself
|
||||
* with free(). */
|
||||
const char *message;
|
||||
int level;
|
||||
bool allow_steal_message;
|
||||
} log;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -113,8 +120,6 @@ void n_dhcp4_client_config_set_request_broadcast(NDhcp4ClientConfig *config, boo
|
|||
void n_dhcp4_client_config_set_mac(NDhcp4ClientConfig *config, const uint8_t *mac, size_t n_mac);
|
||||
void n_dhcp4_client_config_set_broadcast_mac(NDhcp4ClientConfig *config, const uint8_t *mac, size_t n_mac);
|
||||
int n_dhcp4_client_config_set_client_id(NDhcp4ClientConfig *config, const uint8_t *id, size_t n_id);
|
||||
void n_dhcp4_client_config_set_log_level(NDhcp4ClientConfig *config, int level);
|
||||
void n_dhcp4_client_config_set_log_func(NDhcp4ClientConfig *config, NDhcp4LogFunc func, void *data);
|
||||
|
||||
/* client-probe configs */
|
||||
|
||||
|
|
@ -141,6 +146,8 @@ void n_dhcp4_client_get_fd(NDhcp4Client *client, int *fdp);
|
|||
int n_dhcp4_client_dispatch(NDhcp4Client *client);
|
||||
int n_dhcp4_client_pop_event(NDhcp4Client *client, NDhcp4ClientEvent **eventp);
|
||||
|
||||
void n_dhcp4_client_set_log_level(NDhcp4Client *client, int level);
|
||||
|
||||
int n_dhcp4_client_update_mtu(NDhcp4Client *client, uint16_t mtu);
|
||||
|
||||
int n_dhcp4_client_probe(NDhcp4Client *client,
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ static void test_connection(void) {
|
|||
NDhcp4CConnection connection_client = N_DHCP4_C_CONNECTION_NULL(connection_client);
|
||||
_c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *offer = NULL;
|
||||
_c_cleanup_(n_dhcp4_incoming_freep) NDhcp4Incoming *ack = NULL;
|
||||
NDhcp4LogQueue log_queue = N_DHCP4_LOG_QUEUE_NULL_DEFUNCT();
|
||||
|
||||
test_s_connection_init(ns_server, &connection_server, link_server.ifindex);
|
||||
n_dhcp4_s_connection_ip_init(&connection_server_ip, addr_server);
|
||||
|
|
@ -351,6 +352,7 @@ static void test_connection(void) {
|
|||
r = n_dhcp4_c_connection_init(&connection_client,
|
||||
client_config,
|
||||
probe_config,
|
||||
&log_queue,
|
||||
efd_client);
|
||||
c_assert(!r);
|
||||
test_c_connection_listen(ns_client, &connection_client);
|
||||
|
|
@ -358,13 +360,13 @@ static void test_connection(void) {
|
|||
test_discover(&connection_server, &connection_client, &addr_server, &addr_client, &offer);
|
||||
test_select(&connection_server, &connection_client, offer, &addr_server, &addr_client);
|
||||
test_reboot(&connection_server, &connection_client, &addr_server, &addr_client, &ack);
|
||||
test_rebind(&connection_server, &connection_client, &addr_server, &addr_client);
|
||||
test_decline(&connection_server, &connection_client, ack);
|
||||
|
||||
link_add_ip4(&link_client, &addr_client, 8);
|
||||
test_c_connection_connect(ns_client, &connection_client, &addr_client, &addr_server);
|
||||
|
||||
test_renew(&connection_server, &connection_client, &addr_server, &addr_client);
|
||||
test_rebind(&connection_server, &connection_client, &addr_server, &addr_client);
|
||||
test_release(&connection_server, &connection_client, &addr_server, &addr_client);
|
||||
|
||||
n_dhcp4_c_connection_deinit(&connection_client);
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 2e4b605c6217cd3c8a1ef773f82f5cc329ba650d
|
||||
Subproject commit 6c53ef1c0066a3b0d82e9e181e90114eacb7c4aa
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 7c42c592581906fef19458372b8db2b643278211
|
||||
Subproject commit 2d159c7da1d542f2b1fcbbefea6931bce242b943
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 11930d259212605a15430523472ef54e0c7654ee
|
||||
Subproject commit 8b8f941c57a790c277f49b099e73ed9f8ea141af
|
||||
|
|
@ -1056,6 +1056,18 @@ dhcp4_event_handle (NMDhcpNettools *self,
|
|||
case N_DHCP4_CLIENT_EVENT_DOWN:
|
||||
/* ignore down events, they are purely informational */
|
||||
break;
|
||||
case N_DHCP4_CLIENT_EVENT_LOG: {
|
||||
NMLogLevel nm_level;
|
||||
|
||||
nm_level = nm_log_level_from_syslog (event->log.level);
|
||||
if (nm_logging_enabled (nm_level, LOGD_DHCP4)) {
|
||||
nm_log (nm_level, LOGD_DHCP4, NULL , NULL,
|
||||
"dhcp4 (%s): %s",
|
||||
nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)),
|
||||
event->log.message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_LOGW ("unhandled DHCP event %d", event->event);
|
||||
break;
|
||||
|
|
@ -1096,27 +1108,6 @@ dhcp4_event_cb (int fd,
|
|||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
G_GNUC_PRINTF (3, 4)
|
||||
static void
|
||||
nettools_log (int level, void *data, const char *fmt, ...)
|
||||
{
|
||||
NMDhcpNettools *self = data;
|
||||
NMLogLevel nm_level;
|
||||
gs_free char *msg = NULL;
|
||||
va_list ap;
|
||||
|
||||
nm_level = nm_log_level_from_syslog (level);
|
||||
if (nm_logging_enabled (nm_level, LOGD_DHCP4)) {
|
||||
va_start (ap, fmt);
|
||||
msg = g_strdup_vprintf (fmt, ap);
|
||||
va_end (ap);
|
||||
nm_log (nm_level, LOGD_DHCP4, NULL , NULL,
|
||||
"dhcp4 (%s): %s",
|
||||
nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)),
|
||||
msg);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nettools_create (NMDhcpNettools *self,
|
||||
const char *dhcp_anycast_addr,
|
||||
|
|
@ -1186,8 +1177,6 @@ nettools_create (NMDhcpNettools *self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
n_dhcp4_client_config_set_log_level (config, nm_log_level_to_syslog (nm_logging_get_level (LOGD_DHCP4)));
|
||||
n_dhcp4_client_config_set_log_func (config, nettools_log, self);
|
||||
n_dhcp4_client_config_set_ifindex (config, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self)));
|
||||
n_dhcp4_client_config_set_transport (config, transport);
|
||||
n_dhcp4_client_config_set_mac (config, hwaddr_arr, hwaddr_len);
|
||||
|
|
@ -1209,6 +1198,8 @@ nettools_create (NMDhcpNettools *self,
|
|||
priv->client = client;
|
||||
client = NULL;
|
||||
|
||||
n_dhcp4_client_set_log_level (priv->client, nm_log_level_to_syslog (nm_logging_get_level (LOGD_DHCP4)));
|
||||
|
||||
n_dhcp4_client_get_fd (priv->client, &fd);
|
||||
|
||||
priv->event_source = nm_g_unix_fd_source_new (fd,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue