From e68f7685a097f80c7bfb2e70c01b5069a4d6ccba Mon Sep 17 00:00:00 2001 From: Rowan-Ye Date: Fri, 5 Dec 2025 20:46:37 +0800 Subject: [PATCH] Add UPDATE_INETSK hook for inet address rewrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to support restoring processes on different nodes or subnets where the original socket IPs may no longer be valid. This change introduces a new plugin hook, CR_PLUGIN_HOOK__UPDATE_INETSK, and wires it into both the plugin API and the legacy descriptor autogen so that existing plugins remain compatible. The hook is invoked from collect_one_inetsk() before address validation, port reservation, or bind()/connect(). A plugin may rewrite the IPv4 or IPv6 src/dst address fields in InetSkEntry in‑place and return 0. Returning -ENOTSUP skips to the next plugin; any other negative value aborts the restore for that socket. Only the IP addresses may change — family, ports, ifname and length constraints remain enforced. This mechanism is mainly intended for cross‑node or Kubernetes‑style scenarios where the final IP is only known after the target network namespace is created and configured. Pre‑editing image files would be awkward or infeasible otherwise. Note: for established TCP connections, external coordination or preserving the original 4‑tuple is still required. This hook only adjusts addresses and does not modify TCP state. Signed-off-by: Rowan-Ye --- criu/include/criu-plugin.h | 4 ++++ criu/plugin.c | 1 + criu/sk-inet.c | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/criu/include/criu-plugin.h b/criu/include/criu-plugin.h index c3bea1385..fabc1d5ba 100644 --- a/criu/include/criu-plugin.h +++ b/criu/include/criu-plugin.h @@ -66,6 +66,8 @@ enum { CR_PLUGIN_HOOK__DUMP_DEVICES_LATE = 14, + CR_PLUGIN_HOOK__UPDATE_INETSK = 15, + CR_PLUGIN_HOOK__MAX }; @@ -87,6 +89,7 @@ DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__CHECKPOINT_DEVICES, int pid); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__POST_FORKING, void); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__RESTORE_INIT, void); DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__DUMP_DEVICES_LATE, int id); +DECLARE_PLUGIN_HOOK_ARGS(CR_PLUGIN_HOOK__UPDATE_INETSK, uint32_t family, uint32_t state, uint32_t src_ip, uint32_t dst_ip); enum { CR_PLUGIN_STAGE__DUMP, @@ -162,5 +165,6 @@ typedef int(cr_plugin_update_vma_map_t)(const char *path, const uint64_t addr, c uint64_t *new_pgoff, int *plugin_fd); typedef int(cr_plugin_resume_devices_late_t)(int pid); typedef int(cr_plugin_post_forking_t)(void); +typedef int(cr_plugin_update_inetsk_t)(uint32_t family, uint32_t state, uint32_t src_ip, uint32_t dst_ip); #endif /* __CRIU_PLUGIN_H__ */ diff --git a/criu/plugin.c b/criu/plugin.c index f9322a3c2..d21462847 100644 --- a/criu/plugin.c +++ b/criu/plugin.c @@ -62,6 +62,7 @@ static cr_plugin_desc_t *cr_gen_plugin_desc(void *h, char *path) __assign_hook(POST_FORKING, "cr_plugin_post_forking"); __assign_hook(RESTORE_INIT, "cr_plugin_restore_init"); __assign_hook(DUMP_DEVICES_LATE, "cr_plugin_dump_devices_late"); + __assign_hook(UPDATE_INETSK, "cr_plugin_update_inetsk"); #undef __assign_hook diff --git a/criu/sk-inet.c b/criu/sk-inet.c index 422edc656..2190a606a 100644 --- a/criu/sk-inet.c +++ b/criu/sk-inet.c @@ -35,6 +35,7 @@ #include "protobuf.h" #include "util.h" #include "namespaces.h" +#include "plugin.h" #include "images/inventory.pb-c.h" @@ -707,8 +708,14 @@ static inline int tcp_connection(InetSkEntry *ie) static int collect_one_inetsk(void *o, ProtobufCMessage *base, struct cr_img *i) { struct inet_sk_info *ii = o; + int ret; ii->ie = pb_msg(base, InetSkEntry); + + ret = run_plugins(UPDATE_INETSK, ii->ie->family, ii->ie->state, ii->ie->src_addr, ii->ie->dst_addr); + if (ret < 0 && ret != -ENOTSUP) + return -1; + if (tcp_connection(ii->ie)) tcp_locked_conn_add(ii);