--- ./cloudinit/distros/aix.py	2026-06-30 08:10:31.933047467 -0500
+++ ./cloudinit/distros/aix.py	2026-06-30 08:10:48.904321393 -0500
@@ -23,6 +23,7 @@
 from cloudinit.distros import net_util
 from cloudinit.distros import rhel_util
 from cloudinit.distros import aix_util
+from cloudinit.distros import aix_network_state
 from cloudinit.settings import PER_INSTANCE
 
 from cloudinit.distros.parsers.hostname import HostnameConf
@@ -57,8 +58,19 @@
     def apply_network_config_names(self, netconfig):
         LOG.debug("AIX does not rename network interface, netconfig=%s", netconfig)
 
-    def _write_network_state(self, settings):
-        raise NotImplementedError()
+    def _write_network_state(self, network_state):
+        """
+        AIX implementation of _write_network_state.
+
+        This directly processes the network_state object (similar to Linux),
+        bypassing the deprecated ENI text conversion path.
+        """
+        LOG.debug("AIX: Using direct network_state processing")
+        dev_names = aix_network_state.write_network_state_aix(
+            network_state,
+            self.resolve_conf_fn
+        )
+        return dev_names
 
     def _write_network(self, settings):
         print("aix.py _write_network settings=%s" % settings)
--- ./cloudinit/distros/aix_util.py	2026-06-30 08:10:31.933047467 -0500
+++ ./cloudinit/distros/aix_util.py	2026-06-30 08:10:48.904321393 -0500
@@ -44,6 +44,47 @@
     else:
         return devname
 
+def bring_interface_down(aix_dev):
+    #Bring down an AIX network interface.
+
+    LOG.debug("AIX: Checking state of interface %s", aix_dev)
+    current_state = get_if_attr(aix_dev, "state")
+
+    if current_state == "down":
+        LOG.debug("AIX: Interface %s is already down", aix_dev)
+        time.sleep(1)
+        return True
+
+    LOG.debug("AIX: Bringing down interface %s using chdev", aix_dev)
+    cmd = ["/usr/sbin/chdev", "-l", aix_dev, "-a", "state=down"]
+    try:
+        (_out, err) = subp.subp(cmd, rcs=[0, 1])
+        time.sleep(1)
+        if len(err):
+            LOG.warning("AIX: Running %s resulted in stderr output: %s", cmd, err)
+        return True
+    except subp.ProcessExecutionError:
+        util.logexc(LOG, "AIX: Running interface command %s failed", cmd)
+        return False
+
+# Always bring interface UP using chdev.
+def bring_interface_up(aix_dev):
+    LOG.debug("AIX: Bringing up interface %s using chdev", aix_dev)
+    cmd = ['/usr/sbin/chdev', '-l', aix_dev, '-a', 'state=up']
+    try:
+        (_out, err) = subp.subp(cmd, rcs=[0, 1])
+        time.sleep(1)
+        if len(err):
+            LOG.warning("AIX: Running %s resulted in stderr output: %s", cmd, err)
+
+        return True
+        # Persist the bring-up command to /etc/rc.tcpip
+        #util.append_file("/etc/rc.tcpip",
+        #                 "%s\n" % (" ".join(bring_up_cmd)))
+    except subp.ProcessExecutionError:
+        util.logexc(LOG, "AIX: Running interface command %s failed", cmd)
+        return False
+
 # Call chdev to add route
 def add_route(network, route):
     # First, delete the route if it exists on the system
@@ -167,10 +208,10 @@
     util.append_file(tmpf, "{\n")
     if info.get('netmask'):
         util.append_file(tmpf, " option 1  %s\n" % (info.get('netmask')))
-    if interface == "en0":
-        if info.get('gateway'):
-            util.append_file(tmpf, " option 3  %s\n" % (info.get('gateway')))
+    if info.get('gateway'):
+        util.append_file(tmpf, " option 3  %s\n" % (info.get('gateway')))
     else:
+        # Reject gateway option for interfaces without a gateway
         util.append_file(tmpf, " reject 3\n")         
     if info.get('address'):
         util.append_file(tmpf, " option 50 %s\n" % (info.get('address')))
--- ./cloudinit/distros/networking.py	2026-06-30 08:10:31.943062441 -0500
+++ ./cloudinit/distros/networking.py	2026-06-30 08:10:48.914326446 -0500
@@ -196,6 +196,12 @@
         print("try_set_link_up devname %s" % devname)
         return self.is_up(devname)
 
+    def get_interfaces_by_mac(self) -> dict:
+        """Get interfaces by MAC address for AIX using netstat and lsattr."""
+        return net.get_interfaces_by_mac_on_aix(
+            blacklist_drivers=self.blacklist_drivers
+        )
+
 class BSDNetworking(Networking):
     """Implementation of networking functionality shared across BSDs."""
 
--- ./cloudinit/net/__init__.py	2026-06-30 08:10:31.963090022 -0500
+++ ./cloudinit/net/__init__.py	2026-06-30 08:10:48.934347362 -0500
@@ -866,6 +866,10 @@
         return get_interfaces_by_mac_on_openbsd(
             blacklist_drivers=blacklist_drivers
         )
+    elif util.is_AIX():
+        return get_interfaces_by_mac_on_aix(
+            blacklist_drivers=blacklist_drivers
+        )
     else:
         return get_interfaces_by_mac_on_linux(
             blacklist_drivers=blacklist_drivers
@@ -957,6 +961,69 @@
                 )
             ret[ib_mac] = name
     return ret
+
+def get_interfaces_by_mac_on_aix(blacklist_drivers=None) -> dict:
+    """Build a dictionary of tuples {mac: name} for AIX.
+
+    Uses lsdev to find all ethernet interfaces, then entstat to get their MACs.
+    This works for interfaces in any state (Defined, Available, Stopped).
+    """
+    LOG.debug("AIX: get_interfaces_by_mac_on_aix() called")
+    ret = {}
+
+    try:
+        # First, get list of all ethernet interfaces using lsdev
+        # Output format:
+        # en0 Defined    Standard Ethernet Network Interface
+        # en1 Available  Standard Ethernet Network Interface
+        (out, _) = subp.subp(["lsdev", "-Cc", "if"])
+        LOG.debug("AIX: lsdev -Cc if output:\n%s", out)
+
+        # Parse lsdev output to find en* interfaces
+        en_interfaces = []
+        for line in out.splitlines():
+            parts = line.split()
+            if len(parts) >= 2 and parts[0].startswith('en'):
+                ifname = parts[0]
+                en_interfaces.append(ifname)
+                LOG.debug("AIX: Found interface %s", ifname)
+
+        # For each interface, use entstat to get its MAC address
+        for ifname in en_interfaces:
+            try:
+                # entstat shows detailed interface statistics including MAC
+                # Hardware Address: fa:64:d0:0d:0c:20
+                (entstat_out, _) = subp.subp(["entstat", "-d", ifname])
+                LOG.debug("AIX: entstat -d %s output:\n%s", ifname, entstat_out)
+
+                # Look for "Hardware Address:" line
+                for line in entstat_out.splitlines():
+                    if "Hardware Address:" in line:
+                        # Extract MAC address
+                        parts = line.split(":")
+                        if len(parts) >= 2:
+                            # Get everything after "Hardware Address:"
+                            mac_part = ":".join(parts[1:]).strip()
+                            # MAC is already in colon notation from entstat
+                            mac_address = mac_part.lower()
+
+                            if mac_address:
+                                ret[mac_address] = ifname
+                                LOG.debug("AIX: Found interface %s with MAC %s",
+                                         ifname, mac_address)
+                        break
+            except subp.ProcessExecutionError as e:
+                LOG.debug("AIX: entstat failed for %s: %s", ifname, e)
+                continue
+
+    except subp.ProcessExecutionError as e:
+        LOG.warning("AIX: Failed to get interfaces via lsdev: %s", e)
+    except Exception as e:
+        LOG.warning("AIX: Unexpected error getting interfaces by MAC: %s", e)
+
+    LOG.debug("AIX: get_interfaces_by_mac_on_aix() returning: %s", ret)
+    return ret
+
 
 
 def get_interfaces(blacklist_drivers=None) -> list:
--- ./cloudinit/sources/DataSourceConfigDrive.py	2026-06-30 08:10:31.973095930 -0500
+++ ./cloudinit/sources/DataSourceConfigDrive.py	2026-06-30 08:10:48.954367147 -0500
@@ -163,15 +163,14 @@
     @property
     def network_config(self):
         if self._network_config is None:
-            if self.network_eni is not None:
-                LOG.debug("network config provided via converted eni data")
-                self._network_config = eni.convert_eni_data(self.network_eni)
-                print("self.network_eni=%s self._network_config=%s" % (self.network_eni, self._network_config))
-            elif self.network_json not in (None, sources.UNSET):
+            if self.network_json not in (None, sources.UNSET):
                 LOG.debug("network config provided via network_json")
                 self._network_config = openstack.convert_net_json(
                     self.network_json, known_macs=self.known_macs
                 )
+            elif self.network_eni is not None:
+                self._network_config = eni.convert_eni_data(self.network_eni)
+                LOG.debug("network config provided via converted eni data")
             else:
                 LOG.debug("no network configuration available")
         return self._network_config
--- ./cloudinit/util.py	2026-06-30 08:10:31.872953258 -0500
+++ ./cloudinit/util.py	2026-06-30 08:10:48.854267485 -0500
@@ -447,6 +447,10 @@
 def is_OpenBSD():
     return system_info()["variant"] == "openbsd"
 
+@lru_cache()
+def is_AIX():
+    return system_info()["system"].lower() == "aix"
+
 def get_cfg_option_bool(yobj, key, default=False):
     if key not in yobj:
         return default
--- /dev/null	2026-07-01 06:16:44.000262359 -0500
+++ ./cloudinit/distros/aix_network_state.py	2026-07-01 06:12:03.346824359 -0500
@@ -0,0 +1,330 @@
+# vi: ts=4 expandtab
+#
+# AIX-specific network state handling
+# This module provides direct network_state processing for AIX,
+# similar to how Linux distros use network renderers.
+
+import time
+from cloudinit import log as logging
+from cloudinit import subp, util
+from cloudinit.distros import aix_util
+from cloudinit.net.network_state import subnet_is_ipv6
+
+LOG = logging.getLogger(__name__)
+
+
+def write_network_state_aix(network_state, resolve_conf_fn):
+    """
+    AIX-specific implementation to write network configuration directly
+    from network_state object, bypassing ENI text conversion.
+
+    This is similar to how Linux distros use network renderers, but
+    adapted for AIX's chdev/ifconfig commands.
+
+    Args:
+        network_state: NetworkState object containing interfaces, routes, etc.
+        resolve_conf_fn: Path to resolv.conf file
+
+    Returns:
+        List of device names configured
+    """
+    LOG.debug("AIX: Writing network state directly from network_state object")
+
+    dev_names = []
+    nameservers = []
+    searchservers = []
+    create_dhcp_file = True
+    run_dhcpcd = False
+    run_autoconf6 = False
+    ipv6_interface = None
+
+    # First, make sure the services starts out uncommented in /etc/rc.tcpip
+    aix_util.disable_dhcpcd()
+    aix_util.disable_ndpd_host()
+    aix_util.disable_autoconf6()
+    aix_util.remove_resolve_conf_file(resolve_conf_fn)
+
+    # Remove the chdev ipv6 entries present in the /etc/rc.tcpip from earlier runs.
+    # Read the content of the file and filter out lines containing both words
+    with open('/etc/rc.tcpip', "r") as infile:
+        lines = [line for line in infile
+                if "chdev" not in line and "anetaddr6" not in line
+                and "cloud-init" not in line]
+
+    # Write the filtered lines back to the file
+    with open('/etc/rc.tcpip', "w") as outfile:
+        outfile.writelines(lines)
+
+    # Build gateway map from routes using iter_routes()
+    gateway_map = {}
+    LOG.debug("AIX: Extracting gateways from network_state routes")
+    for route in network_state.iter_routes():
+        LOG.debug("AIX: Processing route: %s", route)
+        # Look for default gateway routes (0.0.0.0/0 or ::/0)
+        if route.get('network') in ['0.0.0.0', '::'] or \
+           route.get('destination') in ['0.0.0.0/0', '::/0', 'default']:
+            interface = route.get('interface')
+            gateway = route.get('gateway')
+            if interface and gateway:
+                gateway_map[interface] = gateway
+                LOG.debug("AIX: Found gateway %s for interface %s from top-level routes",
+                         gateway, interface)
+
+    # Process each interface using iter_interfaces()
+    for iface in network_state.iter_interfaces():
+        iface_name = iface.get('name')
+        if iface_name == 'lo':
+            continue
+
+        dev_names.append(iface_name)
+        aix_dev = aix_util.translate_devname(iface_name)
+        LOG.debug("AIX: Configuring interface %s (AIX device: %s)",
+                 iface_name, aix_dev)
+
+        # Get subnets for this interface
+        subnets = iface.get('subnets', [])
+        if not subnets:
+            LOG.debug("AIX: No subnets found for %s", iface_name)
+            continue
+
+        # Static configuration
+        run_cmd = False
+        ipv6_present = False
+        chdev_cmd = ['/usr/sbin/chdev']
+
+        # Process each subnet
+        for subnet in subnets:
+            subnet_type = subnet.get('type')
+
+            # Check for DHCP
+            if subnet_type in ['dhcp', 'dhcp4', 'dhcp6']:
+                # Build info dict from subnet data for config_dhcp
+                # config_dhcp expects a dict with 'address', 'netmask', 'gateway' keys
+                info = {
+                   'address': subnet.get('address'),
+                   'netmask': subnet.get('netmask'),
+                   'gateway': subnet.get('gateway')
+                }
+                aix_util.config_dhcp(aix_dev, info, create_dhcp_file)
+                create_dhcp_file = False
+                run_dhcpcd = True
+                continue
+
+            chdev_cmd.extend(['-l', aix_dev])
+            # Static IPv6 configuration
+            if subnet_type == 'static6' and subnet_is_ipv6(subnet):
+                ipv6_address = subnet.get('address')
+                if ipv6_address:
+                    run_cmd = True
+                    ipv6_present = True
+                    run_autoconf6 = True
+                    addr_parts = ipv6_address.split('/')
+                    LOG.debug("AIX: Configuring IPv6 %s on %s", ipv6_address, aix_dev)
+                    chdev_cmd.append('-anetaddr6=' + addr_parts[0])
+                    if len(addr_parts) > 1:
+                        chdev_cmd.append('-aprefixlen=' + addr_parts[1])
+
+                    if ipv6_interface is None:
+                        ipv6_interface = aix_dev
+                    else:
+                        ipv6_interface = "any"
+
+            # Static IPv4 configuration
+            elif subnet_type == 'static' and not subnet_is_ipv6(subnet):
+                ipv4_address = subnet.get('address')
+                ipv4_netmask = subnet.get('netmask')
+                if ipv4_address:
+                    run_cmd = True
+                    ipv6_present = False
+                    LOG.debug("AIX: Configuring IPv4 %s/%s on %s",
+                              ipv4_address, ipv4_netmask, aix_dev)
+                    chdev_cmd.append('-anetaddr=' + ipv4_address)
+                    if ipv4_netmask:
+                        chdev_cmd.append('-anetmask=' + ipv4_netmask)
+
+            # Check for gateway in subnet routes
+            subnet_routes = subnet.get('routes', [])
+            for route in subnet_routes:
+                LOG.debug("AIX: Processing subnet route: %s", route)
+                if route.get('network') in ['0.0.0.0', '::'] or \
+                    route.get('destination') in ['0.0.0.0/0', '::/0', 'default'] or \
+                    route.get('netmask') == '0.0.0.0':
+                    gw = route.get('gateway')
+                    if gw and iface_name not in gateway_map:
+                        gateway_map[iface_name] = gw
+                        LOG.debug("AIX: Found gateway %s for %s from subnet routes",
+                                    gw, iface_name)
+
+            # Configure autoconf6 if needed
+            if run_autoconf6:
+                ifconfig_cmd = ['/etc/ifconfig', '-a']
+                (cmd_output, _) = subp.subp(ifconfig_cmd, rcs=[0, 1])
+                print("------------------------------------------------------------")
+                print("Output of "+" ".join(ifconfig_cmd))
+                print(cmd_output)
+                print("------------------------------------------------------------")
+                rmdev_cmd = ['/usr/sbin/rmdev', '-l', aix_dev]
+                (cmd_output, _) = subp.subp(rmdev_cmd, rcs=[0, 1])
+                print(" ".join(rmdev_cmd) + " executed")
+                print(cmd_output)
+                time.sleep(2)
+                ifconfig_cmd = ['/etc/ifconfig', '-a']
+                (cmd_output, _) = subp.subp(ifconfig_cmd, rcs=[0, 1])
+                print("------------------------------------------------------------")
+                print("Output of "+" ".join(ifconfig_cmd))
+                print(cmd_output)
+                print("------------------------------------------------------------")
+                netstat_cmd = ['/usr/bin/netstat', '-rn']
+                (cmd_output, _) = subp.subp(netstat_cmd, rcs=[0, 1])
+                print("------------------------------------------------------------")
+                print("Output of "+" ".join(netstat_cmd))
+                print(cmd_output)
+                print("------------------------------------------------------------")
+                autconf6_cmd = ['/usr/sbin/autoconf6', '-6', '-R', '-i', aix_dev]
+                (cmd_output, _) = subp.subp(autconf6_cmd, rcs=[0, 1])
+                print(" ".join(autconf6_cmd) + " executed")
+                if ipv6_present:
+                    util.append_file("/etc/rc.tcpip", "%s\n" % ("/usr/sbin/autoconf6 -6 -R -i " + aix_dev + "          #cloud-init"))
+                time.sleep(2)
+                netstat_cmd = ['/usr/bin/netstat', '-rn']
+                (cmd_output, _) = subp.subp(netstat_cmd, rcs=[0, 1])
+                print("------------------------------------------------------------")
+                print("Output of "+" ".join(netstat_cmd))
+                print(cmd_output)
+                print("------------------------------------------------------------")
+
+
+
+            # Execute chdev command
+            if run_cmd:
+                try:
+                    print("AIX: Running ", chdev_cmd)
+                    subp.subp(chdev_cmd, logstring=chdev_cmd)
+                    time.sleep(2)
+
+                    print(" ".join(chdev_cmd) + " executed")
+                    netstat_cmd = ['/usr/bin/netstat', '-rn']
+                    (cmd_output, _) = subp.subp(netstat_cmd, rcs=[0, 1])
+                    print("------------------------------------------------------------")
+                    print("Output of "+" ".join(netstat_cmd))
+                    print(cmd_output)
+                    print("------------------------------------------------------------")
+
+                    # Always persist chdev commands to /etc/rc.tcpip for reboot
+                    util.append_file("/etc/rc.tcpip",
+                                   "%s\n" % (" ".join(chdev_cmd)))
+                except Exception as e:
+                    LOG.error("AIX: Failed to configure %s: %s", aix_dev, e)
+                    raise
+
+                # MTU configuration
+                mtu = iface.get('mtu')
+                if mtu:
+                    if int(mtu) > 1500:
+                        subp.subp(["/etc/ifconfig", aix_dev, "down", "detach"],
+                                   capture=False, rcs=[0, 1])
+                        time.sleep(2)
+                        aix_adapter = aix_util.logical_adpt_name(aix_dev)
+                        subp.subp(["/usr/sbin/chdev", "-l", aix_adapter,
+                                   "-ajumbo_frames=yes"], capture=False, rcs=[0, 1])
+                        time.sleep(2)
+
+                    subp.subp(["/usr/sbin/chdev", "-l", aix_dev,
+                              "-amtu=" + str(mtu)], capture=False, rcs=[0, 1])
+                    time.sleep(2)
+
+                # This ensures clean state before bringing it up
+                aix_util.bring_interface_down(aix_dev)
+                # Always bring interface UP.
+                aix_util.bring_interface_up(aix_dev)
+
+                # Add gateway from routes
+                gateway = gateway_map.get(iface_name)
+                if gateway:
+                    LOG.debug("AIX: Adding gateway %s for %s", gateway, aix_dev)
+                    if run_autoconf6:
+                        aix_util.add_route("ipv6", gateway)
+                        #Modified 'command' from list to string. And stopped using the routine subp.subp()
+                        #Since, it has issues in passing multiple arguments at once. It considers them as
+                        #a single byte stream and thus throws the invalid arg errors.
+                        #startsrc_cmd = ['startsrc', '-s', 'ndpd-host', '-a "-g -p"']
+                        startsrc_cmd = 'startsrc -s ndpd-host -a "-g -p"'
+                        (cmd_output, _) = subp.subp(startsrc_cmd, shell=True, rcs=[0, 1])
+                        print("------------------------------------------------------------")
+                        print("Output of " + startsrc_cmd)
+                        print(cmd_output)
+                        print("------------------------------------------------------------")
+                        LOG.debug("AIX: Ran command: %s", startsrc_cmd)
+                        #need this delay, because ndpd-host was showing active if checked as soon as startsrc is run
+                        time.sleep(10)
+                        tmp_cmd = "lssrc -s ndpd-host | grep ndpd-host"
+                        (cmd_output, _) = subp.subp(tmp_cmd, shell=True, rcs=[0, 1])
+                        print("------------------------------------------------------------")
+                        print("Output of " + tmp_cmd)
+                        print(cmd_output)
+                        print("------------------------------------------------------------")
+                        if "inoperative" in cmd_output:
+                            LOG.debug(
+                                 "Running %s resulted in stderr output",
+                                tmp_cmd
+                            )
+                            LOG.debug("AIX: ndpd-host does not support option, p. Running it without option, p")
+                            #startsrc_cmd = ['startsrc', '-s' 'ndpd-host' '-a' '-g -v']
+                            startsrc_cmd = 'startsrc -s ndpd-host -a "-g -v"'
+                            (cmd_output, _) = subp.subp(startsrc_cmd, shell=True, rcs=[0, 1])
+                            print("------------------------------------------------------------")
+                            print("Output of " + startsrc_cmd)
+                            print(cmd_output)
+                            print("------------------------------------------------------------")
+                            LOG.debug("AIX: Ran command: %s", startsrc_cmd)
+                        print(startsrc_cmd + " executed")
+                         # startsrc_cmd is already a string, use it directly
+                        #util.append_file("/etc/rc.tcpip", "%s\n" % (startsrc_cmd + '          #cloud-init'))
+                        util.append_file("/etc/rc.tcpip", "%s\n" % (startsrc_cmd + '          #cloud-init'))
+                        netstat_cmd = ['/usr/bin/netstat', '-rn']
+                        (cmd_output, _) = subp.subp(netstat_cmd, rcs=[0, 1])
+                        print("------------------------------------------------------------")
+                        print("Output of "+" ".join(netstat_cmd))
+                        print(cmd_output)
+                        print("------------------------------------------------------------")
+                    else:
+                        aix_util.add_route("ipv4", gateway)
+
+                run_autoconf6 = False
+
+         # DNS configuration from subnets (per-interface / per-network entries)
+        for subnet in subnets:
+            for ns in subnet.get('dns_nameservers', []):
+                if ns not in nameservers:
+                    nameservers.append(ns)
+
+            for sd in subnet.get('dns_search', []):
+                if sd not in searchservers:
+                    searchservers.append(sd)
+
+    # Collect global DNS from top-level network_data.json "services" entries.
+    # These are stored in network_state.dns_nameservers / dns_searchdomains
+    # after being converted to "nameserver" config entries by convert_net_json().
+    for ns in network_state.dns_nameservers:
+        if ns not in nameservers:
+            nameservers.append(ns)
+    for sd in network_state.dns_searchdomains:
+        if sd not in searchservers:
+            searchservers.append(sd)
+
+    # Enable services
+    if run_dhcpcd:
+        aix_util.enable_dhcpcd()
+#As per the new tested order, we dont need these two steps here.
+#   if run_autoconf6:
+#       aix_util.enable_ndpd_host()
+#       aix_util.enable_autoconf6(ipv6_interface)
+
+    # Write DNS configuration
+    if nameservers or searchservers:
+        aix_util.update_resolve_conf_file(resolve_conf_fn,
+                                        nameservers, searchservers)
+
+    print("AIX: Returning", dev_names)
+    return dev_names
+
--- ./cloudinit/sources/helpers/openstack.py_orig	2026-07-01 06:13:10.580877683 -0500
+++ ./cloudinit/sources/helpers/openstack.py	2026-07-01 06:16:29.825473869 -0500
@@ -650,6 +650,26 @@
                 subnet["ipv4"] = True
             if network["type"] == "ipv6":
                 subnet["ipv6"] = True
+
+            # Look for either subnet or network specific DNS servers
+            # and add them as subnet level DNS entries.
+            # Subnet specific nameservers (from per-route services)
+            dns_nameservers = [
+                service["address"]
+                for route in network.get("routes", [])
+                for service in route.get("services", [])
+                if service.get("type") == "dns"
+            ]
+            # Network specific nameservers
+            for service in network.get("services", []):
+                if service.get("type") != "dns":
+                    continue
+                if service["address"] in dns_nameservers:
+                    continue
+                dns_nameservers.append(service["address"])
+            if dns_nameservers:
+                subnet["dns_nameservers"] = dns_nameservers
+
             subnets.append(subnet)
         cfg.update({"subnets": subnets})
         if link["type"] in ["bond"]:
@@ -751,7 +771,7 @@
                 cfg["type"] = "infiniband"
 
     for service in services:
-        cfg = service
+        cfg = copy.deepcopy(service)
         cfg.update({"type": "nameserver"})
         config.append(cfg)
 
