From 95e6ebec66f173c8b958ebbbbfb745fa41d5f83c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 27 Sep 2022 18:05:51 +0200 Subject: [PATCH 1/5] glib-aux: add nm_utils_get_process_exit_status_desc_buf() helper --- src/libnm-glib-aux/nm-shared-utils.c | 39 +++++++++++++++++++++------- src/libnm-glib-aux/nm-shared-utils.h | 4 +++ 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 6f56a4fe95..e02803a6ea 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -6100,19 +6100,38 @@ nm_crypto_md5_hash(const guint8 *salt, /*****************************************************************************/ +const char * +nm_utils_get_process_exit_status_desc_buf(int status, char *buf, gsize buf_len) +{ + const char *buf0 = buf; + + nm_assert(buf_len == 0 || buf); + + /* This should give a partial sentence, it it can be combined with + * prinft("command XYZ %s.\n", desc) */ + + if (WIFEXITED(status)) + nm_strbuf_append(&buf, &buf_len, "exited with status %d", WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + nm_strbuf_append(&buf, &buf_len, "killed by signal %d", WTERMSIG(status)); + else if (WIFSTOPPED(status)) + nm_strbuf_append(&buf, &buf_len, "stopped by signal %d", WSTOPSIG(status)); + else if (WIFCONTINUED(status)) + nm_strbuf_append(&buf, &buf_len, "resumed by SIGCONT"); + else + nm_strbuf_append(&buf, &buf_len, "exited with unknown status 0x%x", status); + + return buf0; +} + char * nm_utils_get_process_exit_status_desc(int status) { - if (WIFEXITED(status)) - return g_strdup_printf("exited with status %d", WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - return g_strdup_printf("killed by signal %d", WTERMSIG(status)); - else if (WIFSTOPPED(status)) - return g_strdup_printf("stopped by signal %d", WSTOPSIG(status)); - else if (WIFCONTINUED(status)) - return g_strdup("resumed by SIGCONT)"); - else - return g_strdup_printf("exited with unknown status 0x%x", status); + char buf[NM_UTILS_GET_PROCESS_EXIT_STATUS_BUF_LEN]; + + nm_utils_get_process_exit_status_desc_buf(status, buf, sizeof(buf)); + + return g_strdup(buf); } /*****************************************************************************/ diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 3d32f0d21a..ce00a5e953 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -3067,6 +3067,10 @@ void nm_crypto_md5_hash(const guint8 *salt, /*****************************************************************************/ +#define NM_UTILS_GET_PROCESS_EXIT_STATUS_BUF_LEN 41 + +const char *nm_utils_get_process_exit_status_desc_buf(int status, char *buf, gsize buf_len); + char *nm_utils_get_process_exit_status_desc(int status); gboolean nm_utils_validate_hostname(const char *hostname); From a5f125f8cb5b38678953ef8dc2dd757c502f0a9e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 27 Sep 2022 18:06:05 +0200 Subject: [PATCH 2/5] glib-aux: add NM_UTILS_ERROR_COMMAND_FAILED error code --- src/libnm-glib-aux/nm-shared-utils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index ce00a5e953..3383e6d03f 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -960,6 +960,8 @@ typedef enum { NM_UTILS_ERROR_INVALID_ARGUMENT, /*< nick=InvalidArgument >*/ NM_UTILS_ERROR_NOT_READY, /*< nick=NotReady >*/ + NM_UTILS_ERROR_COMMAND_FAILED, /*< nick=CommandFailed >*/ + NM_UTILS_ERROR_AMBIGUOUS, /*< nick=Ambiguous >*/ /* the following codes have a special meaning and are exactly used for From 607a9544cb40eb384fda04418197ac31f3e718f6 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 28 Sep 2022 18:34:50 +0200 Subject: [PATCH 3/5] device: allow resetting the devip state via nm_device_devip_set_state() There is no reason to disallow resetting the state. --- src/core/devices/nm-device-private.h | 5 ++++- src/core/devices/nm-device.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index b54aed6a75..31424d5c2b 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -89,7 +89,10 @@ nm_device_devip_set_state(NMDevice *self, nm_assert(NM_IS_DEVICE(self)); nm_assert_addr_family_or_unspec(addr_family); nm_assert(!l3cd || NM_IS_L3_CONFIG_DATA(l3cd)); - nm_assert(NM_IN_SET(ip_state, NM_DEVICE_IP_STATE_PENDING, NM_DEVICE_IP_STATE_READY)); + nm_assert(NM_IN_SET(ip_state, + NM_DEVICE_IP_STATE_NONE, + NM_DEVICE_IP_STATE_PENDING, + NM_DEVICE_IP_STATE_READY)); nm_device_devip_set_state_full(self, addr_family, ip_state, l3cd, NM_DEVICE_STATE_REASON_NONE); } diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 5e503cda58..3a7009e6c2 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -9958,6 +9958,7 @@ nm_device_devip_set_state_full(NMDevice *self, nm_assert_addr_family_or_unspec(addr_family); nm_assert(NM_IN_SET(ip_state, + NM_DEVICE_IP_STATE_NONE, NM_DEVICE_IP_STATE_PENDING, NM_DEVICE_IP_STATE_READY, NM_DEVICE_IP_STATE_FAILED)); @@ -9965,7 +9966,7 @@ nm_device_devip_set_state_full(NMDevice *self, nm_assert((ip_state != NM_DEVICE_IP_STATE_FAILED) == (failed_reason == NM_DEVICE_STATE_REASON_NONE)); - nm_assert((ip_state != NM_DEVICE_IP_STATE_FAILED) || !l3cd); + nm_assert(NM_IN_SET(ip_state, NM_DEVICE_IP_STATE_PENDING, NM_DEVICE_IP_STATE_READY) || !l3cd); p = _dev_ipdev_data(self, addr_family); From 02feefb1df15dbd546f98f360196f3624e56b930 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 27 Sep 2022 18:07:01 +0200 Subject: [PATCH 4/5] firewall: fail from nm_firewall_nft_call() on non-zero exit code --- src/core/nm-firewall-utils.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c index 52f5113cb3..6ad789d37d 100644 --- a/src/core/nm-firewall-utils.c +++ b/src/core/nm-firewall-utils.c @@ -430,14 +430,21 @@ _fw_nft_call_communicate_cb(GObject *source, GAsyncResult *result, gpointer user } else if (g_subprocess_get_successful(call_data->subprocess)) { nm_log_dbg(LOGD_SHARING, "firewall: nft[%s]: command successful", call_data->identifier); } else { + char buf[NM_UTILS_GET_PROCESS_EXIT_STATUS_BUF_LEN]; gs_free char *ss_stdout = NULL; gs_free char *ss_stderr = NULL; gboolean print_stdout = (stdout_buf && g_bytes_get_size(stdout_buf) > 0); gboolean print_stderr = (stderr_buf && g_bytes_get_size(stderr_buf) > 0); + int status; + + status = g_subprocess_get_status(call_data->subprocess); + + nm_utils_get_process_exit_status_desc_buf(status, buf, sizeof(buf)); nm_log_warn(LOGD_SHARING, - "firewall: nft[%s]: command failed:%s%s%s%s%s%s%s", + "firewall: nft[%s]: command %s:%s%s%s%s%s%s%s", call_data->identifier, + buf, print_stdout || print_stderr ? "" : " unknown reason", NM_PRINT_FMT_QUOTED( print_stdout, @@ -455,6 +462,8 @@ _fw_nft_call_communicate_cb(GObject *source, GAsyncResult *result, gpointer user &ss_stderr), "\")", "")); + + nm_utils_error_set(&error, NM_UTILS_ERROR_COMMAND_FAILED, "nft command %s", buf); } _fw_nft_call_data_free(call_data, g_steal_pointer(&error)); From e796a67d6c0283d587d00ab6297c178e36a1b4c3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 27 Sep 2022 18:15:31 +0200 Subject: [PATCH 5/5] firewall: introduce helper function for add/flush/delete nft table command --- src/core/nm-firewall-utils.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c index 6ad789d37d..92c9fd814e 100644 --- a/src/core/nm-firewall-utils.c +++ b/src/core/nm-firewall-utils.c @@ -619,6 +619,14 @@ _fw_nft_call_sync(GBytes *stdin_buf, GError **error) #define _append(p_strbuf, fmt, ...) nm_str_buf_append_printf((p_strbuf), "" fmt "\n", ##__VA_ARGS__) +static void +_fw_nft_append_cmd_table(NMStrBuf *strbuf, const char *family, const char *table_name, gboolean up) +{ + /* Either delete the table, or create/flush it. */ + _append(strbuf, "add table %s %s", family, table_name); + _append(strbuf, "%s table %s %s", up ? "flush" : "delete", family, table_name); +} + static GBytes * _fw_nft_set_shared_construct(gboolean up, const char *ip_iface, in_addr_t addr, guint8 plen) { @@ -630,8 +638,7 @@ _fw_nft_set_shared_construct(gboolean up, const char *ip_iface, in_addr_t addr, _share_iptables_subnet_to_str(str_subnet, addr, plen); - _append(&strbuf, "add table ip %s", table_name); - _append(&strbuf, "%s table ip %s", up ? "flush" : "delete", table_name); + _fw_nft_append_cmd_table(&strbuf, "ip", table_name, up); if (up) { _append(&strbuf,