]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: expose the nsid in the GetNamespaceId() varlink call 30908/head
authorLennart Poettering <lennart@poettering.net>
Fri, 12 Jan 2024 10:47:45 +0000 (11:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 12 Jan 2024 20:43:34 +0000 (21:43 +0100)
Let's return both ids in the GetNamespaceID(), since they are pretty
much the same concept.

src/network/networkd-manager-varlink.c
src/shared/varlink-io.systemd.Network.c

index d9750d9b641f04133aaffc98cd64156bd3b36ac7..30aebb5d9e1a6ed621c667fbff3a504471b1f4da 100644 (file)
@@ -25,23 +25,35 @@ static int vl_method_get_states(Varlink *link, JsonVariant *parameters, VarlinkM
 }
 
 static int vl_method_get_namespace_id(Varlink *link, JsonVariant *parameters, VarlinkMethodFlags flags, void *userdata) {
-        uint64_t id;
+        uint64_t inode = 0;
+        uint32_t nsid = UINT32_MAX;
+        int r;
 
         assert(link);
 
         if (json_variant_elements(parameters) > 0)
                 return varlink_error_invalid_parameter(link, parameters);
 
+        /* Network namespaces have two identifiers: the inode number (which all namespace types have), and
+         * the "nsid" (aka the "cookie"), which only network namespaces know as a concept, and which is not
+         * assigned by default, but once it is, is fixed. Let's return both, to avoid any confusion which one
+         * this is. */
+
         struct stat st;
-        if (stat("/proc/self/ns/net", &st) < 0) {
+        if (stat("/proc/self/ns/net", &st) < 0)
                 log_warning_errno(errno, "Failed to stat network namespace, ignoring: %m");
-                id = 0;
-        } else
-                id = st.st_ino;
+        else
+                inode = st.st_ino;
+
+        r = netns_get_nsid(/* netnsfd= */ -EBADF, &nsid);
+        if (r < 0)
+                log_warning_errno(r, "Failed to query network nsid, ignoring: %m");
 
         return varlink_replyb(link,
                               JSON_BUILD_OBJECT(
-                                              JSON_BUILD_PAIR_UNSIGNED("NamespaceId", id)));
+                                              JSON_BUILD_PAIR_UNSIGNED("NamespaceId", inode),
+                                              JSON_BUILD_PAIR_CONDITION(nsid == UINT32_MAX, "NamespaceNSID", JSON_BUILD_NULL),
+                                              JSON_BUILD_PAIR_CONDITION(nsid != UINT32_MAX, "NamespaceNSID", JSON_BUILD_UNSIGNED(nsid))));
 }
 
 int manager_connect_varlink(Manager *m) {
index ec25e26e29591ce8b4994c2bbf5094dc82f3cb71..e2da5810e340a1b7f22b13282ebe40daff951ca4 100644 (file)
@@ -11,7 +11,8 @@ static VARLINK_DEFINE_METHOD(GetStates,
                              VARLINK_DEFINE_OUTPUT(OperationalState, VARLINK_STRING, 0));
 
 static VARLINK_DEFINE_METHOD(GetNamespaceId,
-                             VARLINK_DEFINE_OUTPUT(NamespaceId, VARLINK_INT, 0));
+                             VARLINK_DEFINE_OUTPUT(NamespaceId, VARLINK_INT, 0),
+                             VARLINK_DEFINE_OUTPUT(NamespaceNSID, VARLINK_INT, VARLINK_NULLABLE));
 
 VARLINK_DEFINE_INTERFACE(
                 io_systemd_Network,