예제 #1
0
    def _render_subnet_routes(cls, iface_cfg, route_cfg, subnets, flavor):
        # TODO(rjschwei): route configuration on SUSE distro happens via
        # ifroute-* files, see lp#1812117. SUSE currently carries a local
        # patch in their package.
        if flavor == "suse":
            return
        for _, subnet in enumerate(subnets, start=len(iface_cfg.children)):
            subnet_type = subnet.get("type")
            for route in subnet.get("routes", []):
                is_ipv6 = subnet.get("ipv6") or is_ipv6_address(
                    route["gateway"]
                )

                # Any dynamic configuration method, slaac, dhcpv6-stateful/
                # stateless should get router information from router RA's.
                if (
                    _is_default_route(route)
                    and subnet_type not in IPV6_DYNAMIC_TYPES
                ):
                    if (
                        subnet.get("ipv4") and route_cfg.has_set_default_ipv4
                    ) or (
                        subnet.get("ipv6") and route_cfg.has_set_default_ipv6
                    ):
                        raise ValueError(
                            "Duplicate declaration of default "
                            "route found for interface '%s'" % (iface_cfg.name)
                        )
                    # NOTE that instead of defining the route0 settings,
                    # the owning interface provides the default route.

                    # TODO(harlowja): add validation that no other iface has
                    # also provided the default route?
                    iface_cfg["DEFROUTE"] = True
                    if iface_cfg["BOOTPROTO"] in ("dhcp", "dhcp4"):
                        iface_cfg["DHCLIENT_SET_DEFAULT_ROUTE"] = True
                    if "gateway" in route:
                        if is_ipv6:
                            iface_cfg["IPV6_DEFAULTGW"] = route["gateway"]
                            route_cfg.has_set_default_ipv6 = True
                        else:
                            iface_cfg["GATEWAY"] = route["gateway"]
                            route_cfg.has_set_default_ipv4 = True
                    if "metric" in route:
                        iface_cfg["METRIC"] = route["metric"]

                else:
                    # add default routes only to ifcfg files, not
                    # to route-* or route6-*
                    for old_key, new_name in [
                        ("gateway", "GATEWAY"),
                        ("metric", "METRIC"),
                        ("prefix", "PREFIX"),
                        ("netmask", "NETMASK"),
                        ("network", "ADDRESS"),
                    ]:
                        if old_key in route:
                            new_key = f"{new_name}{route_cfg.last_idx}"
                            route_cfg[new_key] = route[old_key]
                    route_cfg.last_idx += 1
예제 #2
0
    def handle_physical(self, command):
        """
        command = {
            'type': 'physical',
            'mac_address': 'c0:d6:9f:2c:e8:80',
            'name': 'eth0',
            'subnets': [
                {'type': 'dhcp4'}
             ],
            'accept-ra': 'true'
        }
        """

        interfaces = self._network_state.get("interfaces", {})
        iface = interfaces.get(command["name"], {})
        for param, val in command.get("params", {}).items():
            iface.update({param: val})

        # convert subnet ipv6 netmask to cidr as needed
        subnets = _normalize_subnets(command.get("subnets"))

        # automatically set 'use_ipv6' if any addresses are ipv6
        if not self.use_ipv6:
            for subnet in subnets:
                if subnet.get("type").endswith("6") or is_ipv6_address(
                    subnet.get("address")
                ):
                    self.use_ipv6 = True
                    break

        accept_ra = command.get("accept-ra", None)
        if accept_ra is not None:
            accept_ra = util.is_true(accept_ra)
        wakeonlan = command.get("wakeonlan", None)
        if wakeonlan is not None:
            wakeonlan = util.is_true(wakeonlan)
        iface.update(
            {
                "name": command.get("name"),
                "type": command.get("type"),
                "mac_address": command.get("mac_address"),
                "inet": "inet",
                "mode": "manual",
                "mtu": command.get("mtu"),
                "address": None,
                "gateway": None,
                "subnets": subnets,
                "accept-ra": accept_ra,
                "wakeonlan": wakeonlan,
            }
        )
        self._network_state["interfaces"].update({command.get("name"): iface})
        self.dump_network_state()
예제 #3
0
    def _add_nameserver(self, dns):
        """
        Extends the ipv[46].dns property with a name server.
        """

        # FIXME: the subnet contains IPv4 and IPv6 name server mixed
        # together. We might be getting an IPv6 name server while
        # we're dealing with an IPv4 subnet. Sort this out by figuring
        # out the correct family and making sure a valid section exist.
        family = "ipv6" if is_ipv6_address(dns) else "ipv4"
        self._set_default(family, "method", "disabled")

        self._set_default(family, "dns", "")
        self.config[family]["dns"] = self.config[family]["dns"] + dns + ";"
예제 #4
0
    def _render_subnets(cls, iface_cfg, subnets, has_default_route, flavor):
        # setting base values
        if flavor == "suse":
            iface_cfg["BOOTPROTO"] = "static"
            if "BRIDGE" in iface_cfg:
                iface_cfg["BOOTPROTO"] = "dhcp"
                iface_cfg.drop("BRIDGE")
        else:
            iface_cfg["BOOTPROTO"] = "none"

        # modifying base values according to subnets
        for i, subnet in enumerate(subnets, start=len(iface_cfg.children)):
            mtu_key = "MTU"
            subnet_type = subnet.get("type")
            if subnet_type == "dhcp6" or subnet_type == "ipv6_dhcpv6-stateful":
                if flavor == "suse":
                    # User wants dhcp for both protocols
                    if iface_cfg["BOOTPROTO"] == "dhcp4":
                        iface_cfg["BOOTPROTO"] = "dhcp"
                    else:
                        # Only IPv6 is DHCP, IPv4 may be static
                        iface_cfg["BOOTPROTO"] = "dhcp6"
                    iface_cfg["DHCLIENT6_MODE"] = "managed"
                # only if rhel AND dhcpv6 stateful
                elif (flavor == "rhel"
                      and subnet_type == "ipv6_dhcpv6-stateful"):
                    iface_cfg["BOOTPROTO"] = "dhcp"
                    iface_cfg["DHCPV6C"] = True
                    iface_cfg["IPV6INIT"] = True
                    iface_cfg["IPV6_AUTOCONF"] = False
                else:
                    iface_cfg["IPV6INIT"] = True
                    # Configure network settings using DHCPv6
                    iface_cfg["DHCPV6C"] = True
            elif subnet_type == "ipv6_dhcpv6-stateless":
                if flavor == "suse":
                    # User wants dhcp for both protocols
                    if iface_cfg["BOOTPROTO"] == "dhcp4":
                        iface_cfg["BOOTPROTO"] = "dhcp"
                    else:
                        # Only IPv6 is DHCP, IPv4 may be static
                        iface_cfg["BOOTPROTO"] = "dhcp6"
                    iface_cfg["DHCLIENT6_MODE"] = "info"
                else:
                    iface_cfg["IPV6INIT"] = True
                    # Configure network settings using SLAAC from RAs and
                    # optional info from dhcp server using DHCPv6
                    iface_cfg["IPV6_AUTOCONF"] = True
                    iface_cfg["DHCPV6C"] = True
                    # Use Information-request to get only stateless
                    # configuration parameters (i.e., without address).
                    iface_cfg["DHCPV6C_OPTIONS"] = "-S"
            elif subnet_type == "ipv6_slaac":
                if flavor == "suse":
                    # User wants dhcp for both protocols
                    if iface_cfg["BOOTPROTO"] == "dhcp4":
                        iface_cfg["BOOTPROTO"] = "dhcp"
                    else:
                        # Only IPv6 is DHCP, IPv4 may be static
                        iface_cfg["BOOTPROTO"] = "dhcp6"
                    iface_cfg["DHCLIENT6_MODE"] = "info"
                else:
                    iface_cfg["IPV6INIT"] = True
                    # Configure network settings using SLAAC from RAs
                    iface_cfg["IPV6_AUTOCONF"] = True
            elif subnet_type in ["dhcp4", "dhcp"]:
                bootproto_in = iface_cfg["BOOTPROTO"]
                iface_cfg["BOOTPROTO"] = "dhcp"
                if flavor == "suse" and subnet_type == "dhcp4":
                    # If dhcp6 is already specified the user wants dhcp
                    # for both protocols
                    if bootproto_in != "dhcp6":
                        # Only IPv4 is DHCP, IPv6 may be static
                        iface_cfg["BOOTPROTO"] = "dhcp4"
            elif subnet_type in ["static", "static6"]:
                # RH info
                # grep BOOTPROTO sysconfig.txt -A2 | head -3
                # BOOTPROTO=none|bootp|dhcp
                # 'bootp' or 'dhcp' cause a DHCP client
                # to run on the device. Any other
                # value causes any static configuration
                # in the file to be applied.
                if subnet_is_ipv6(subnet) and flavor != "suse":
                    mtu_key = "IPV6_MTU"
                    iface_cfg["IPV6INIT"] = True
                if "mtu" in subnet:
                    mtu_mismatch = bool(
                        mtu_key in iface_cfg
                        and subnet["mtu"] != iface_cfg[mtu_key])
                    if mtu_mismatch:
                        LOG.warning(
                            "Network config: ignoring %s device-level mtu:%s"
                            " because ipv4 subnet-level mtu:%s provided.",
                            iface_cfg.name,
                            iface_cfg[mtu_key],
                            subnet["mtu"],
                        )
                    if subnet_is_ipv6(subnet):
                        if flavor == "suse":
                            # TODO(rjschwei) write mtu setting to
                            # /etc/sysctl.d/
                            pass
                        else:
                            iface_cfg[mtu_key] = subnet["mtu"]
                    else:
                        iface_cfg[mtu_key] = subnet["mtu"]

                if subnet_is_ipv6(subnet) and flavor == "rhel":
                    iface_cfg["IPV6_FORCE_ACCEPT_RA"] = False
                    iface_cfg["IPV6_AUTOCONF"] = False
            elif subnet_type == "manual":
                if flavor == "suse":
                    LOG.debug('Unknown subnet type setting "%s"', subnet_type)
                else:
                    # If the subnet has an MTU setting, then ONBOOT=True
                    # to apply the setting
                    iface_cfg["ONBOOT"] = mtu_key in iface_cfg
            else:
                raise ValueError(
                    "Unknown subnet type '%s' found for interface '%s'" %
                    (subnet_type, iface_cfg.name))
            if subnet.get("control") == "manual":
                if flavor == "suse":
                    iface_cfg["STARTMODE"] = "manual"
                else:
                    iface_cfg["ONBOOT"] = False

        # set IPv4 and IPv6 static addresses
        ipv4_index = -1
        ipv6_index = -1
        for i, subnet in enumerate(subnets, start=len(iface_cfg.children)):
            subnet_type = subnet.get("type")
            # metric may apply to both dhcp and static config
            if "metric" in subnet:
                if flavor != "suse":
                    iface_cfg["METRIC"] = subnet["metric"]
            if subnet_type in ["dhcp", "dhcp4"]:
                # On SUSE distros 'DHCLIENT_SET_DEFAULT_ROUTE' is a global
                # setting in /etc/sysconfig/network/dhcp
                if flavor != "suse":
                    if has_default_route and iface_cfg["BOOTPROTO"] != "none":
                        iface_cfg["DHCLIENT_SET_DEFAULT_ROUTE"] = False
                continue
            elif subnet_type in IPV6_DYNAMIC_TYPES:
                continue
            elif subnet_type in ["static", "static6"]:
                if subnet_is_ipv6(subnet):
                    ipv6_index = ipv6_index + 1
                    ipv6_cidr = "%s/%s" % (subnet["address"], subnet["prefix"])
                    if ipv6_index == 0:
                        if flavor == "suse":
                            iface_cfg["IPADDR6"] = ipv6_cidr
                        else:
                            iface_cfg["IPV6ADDR"] = ipv6_cidr
                    elif ipv6_index == 1:
                        if flavor == "suse":
                            iface_cfg["IPADDR6_1"] = ipv6_cidr
                        else:
                            iface_cfg["IPV6ADDR_SECONDARIES"] = ipv6_cidr
                    else:
                        if flavor == "suse":
                            iface_cfg["IPADDR6_%d" % ipv6_index] = ipv6_cidr
                        else:
                            iface_cfg["IPV6ADDR_SECONDARIES"] += (" " +
                                                                  ipv6_cidr)
                else:
                    ipv4_index = ipv4_index + 1
                    suff = "" if ipv4_index == 0 else str(ipv4_index)
                    iface_cfg["IPADDR" + suff] = subnet["address"]
                    iface_cfg["NETMASK" + suff] = net_prefix_to_ipv4_mask(
                        subnet["prefix"])

                if "gateway" in subnet and flavor != "suse":
                    iface_cfg["DEFROUTE"] = True
                    if is_ipv6_address(subnet["gateway"]):
                        iface_cfg["IPV6_DEFAULTGW"] = subnet["gateway"]
                    else:
                        iface_cfg["GATEWAY"] = subnet["gateway"]

                if "dns_search" in subnet and flavor != "suse":
                    iface_cfg["DOMAIN"] = " ".join(subnet["dns_search"])

                if "dns_nameservers" in subnet and flavor != "suse":
                    if len(subnet["dns_nameservers"]) > 3:
                        # per resolv.conf(5) MAXNS sets this to 3.
                        LOG.debug(
                            "%s has %d entries in dns_nameservers. "
                            "Only 3 are used.",
                            iface_cfg.name,
                            len(subnet["dns_nameservers"]),
                        )
                    for i, k in enumerate(subnet["dns_nameservers"][:3], 1):
                        iface_cfg["DNS" + str(i)] = k