]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nss-resolve: add env var to specify resolved ifindex
authorPopax21 <popax@popax21.dev>
Tue, 9 Dec 2025 01:56:01 +0000 (02:56 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 18 Dec 2025 09:53:27 +0000 (10:53 +0100)
Adds a new `SYSTEMD_NSS_RESOLVE_INTERFACE` environment variable to the nss-resolve module, whose value is subsequently passed down to the `ifindex` resolved lookup option.
This allows name lookups to be constrained to a just single interface for e.g. captive portal browsers.

man/nss-resolve.xml
src/nss-resolve/nss-resolve.c

index 39d4405b2722b5f996651fdf8148b08de9f21c20..d2fef03c58075b4a98eaf2dccdabe0647317626c 100644 (file)
         <xi:include href="version-info.xml" xpointer="v250"/></listitem>
       </varlistentry>
     </variablelist>
+
+    <variablelist class='environment-variables'>
+      <varlistentry>
+        <term><varname>$SYSTEMD_NSS_RESOLVE_INTERFACE</varname></term>
+
+        <listitem><para>Takes an interface name or index as an argument. When specified, answers will only be
+        obtained from name servers belonging to the specified interface.</para>
+
+        <xi:include href="version-info.xml" xpointer="v260"/></listitem>
+      </varlistentry>
+    </variablelist>
   </refsect1>
 
   <refsect1>
index f842e0cf579c692c3a7ce31c1896b91077aa662b..ea60727e906d93c6bb95dc4b1a9f53f9a75953dc 100644 (file)
@@ -12,6 +12,7 @@
 #include "glyph-util.h"
 #include "in-addr-util.h"
 #include "json-util.h"
+#include "netlink-util.h"
 #include "nss-util.h"
 #include "resolved-def.h"
 #include "signal-util.h"
@@ -188,6 +189,23 @@ static uint64_t query_flags(void) {
                 query_flag("SYSTEMD_NSS_RESOLVE_NETWORK", 0, SD_RESOLVED_NO_NETWORK);
 }
 
+static int query_ifindex(void) {
+        int ifindex;
+        const char *e;
+
+        e = secure_getenv("SYSTEMD_NSS_RESOLVE_INTERFACE");
+        if (!e)
+                return 0;
+
+        ifindex = rtnl_resolve_interface(/* rtnl= */ NULL, e);
+        if (ifindex < 0) {
+                log_debug_errno(ifindex, "Failed to resolve $SYSTEMD_NSS_RESOLVE_INTERFACE, ignoring: %m");
+                ifindex = 0;
+        }
+
+        return ifindex;
+}
+
 enum nss_status _nss_resolve_gethostbyname4_r(
                 const char *name,
                 struct gaih_addrtuple **pat,
@@ -217,7 +235,8 @@ enum nss_status _nss_resolve_gethostbyname4_r(
         r = sd_json_buildo(
                         &cparams,
                         SD_JSON_BUILD_PAIR_STRING("name", name),
-                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
+                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
+                        SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
         if (r < 0)
                 goto fail;
 
@@ -386,7 +405,8 @@ enum nss_status _nss_resolve_gethostbyname3_r(
                         &cparams,
                         SD_JSON_BUILD_PAIR_STRING("name", name),
                         SD_JSON_BUILD_PAIR_INTEGER("family", af),
-                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
+                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
+                        SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
         if (r < 0)
                 goto fail;
 
@@ -606,7 +626,8 @@ enum nss_status _nss_resolve_gethostbyaddr2_r(
                         &cparams,
                         SD_JSON_BUILD_PAIR_BYTE_ARRAY("address", addr, len),
                         SD_JSON_BUILD_PAIR_INTEGER("family", af),
-                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()));
+                        SD_JSON_BUILD_PAIR_UNSIGNED("flags", query_flags()),
+                        SD_JSON_BUILD_PAIR_UNSIGNED("ifindex", query_ifindex()));
         if (r < 0)
                 goto fail;