diff --git a/metropolis/node/core/main.go b/metropolis/node/core/main.go
index 721482b..bd7f475 100644
--- a/metropolis/node/core/main.go
+++ b/metropolis/node/core/main.go
@@ -107,7 +107,8 @@
 		logger.Warningf("Failed to initialize TPM 2.0, attempting fallback to untrusted: %v", err)
 	}
 
-	networkSvc := network.New()
+	networkSvc := network.New(nil)
+	networkSvc.DHCPVendorClassID = "dev.monogon.metropolis.node.v1"
 	timeSvc := timesvc.New()
 
 	// This function initializes a headless Delve if this is a debug build or
diff --git a/metropolis/node/core/network/BUILD.bazel b/metropolis/node/core/network/BUILD.bazel
index 86ffda8..1500eff 100644
--- a/metropolis/node/core/network/BUILD.bazel
+++ b/metropolis/node/core/network/BUILD.bazel
@@ -2,19 +2,26 @@
 
 go_library(
     name = "network",
-    srcs = ["main.go"],
+    srcs = [
+        "main.go",
+        "static.go",
+    ],
     importpath = "source.monogon.dev/metropolis/node/core/network",
     visibility = ["//:__subpackages__"],
     deps = [
+        "//go/algorithm/toposort",
         "//metropolis/node/core/network/dhcp4c",
         "//metropolis/node/core/network/dhcp4c/callback",
         "//metropolis/node/core/network/dns",
         "//metropolis/pkg/event",
         "//metropolis/pkg/event/memory",
+        "//metropolis/pkg/logtree",
         "//metropolis/pkg/supervisor",
+        "//net/proto",
         "@com_github_google_nftables//:nftables",
         "@com_github_google_nftables//expr",
         "@com_github_insomniacslk_dhcp//dhcpv4",
         "@com_github_vishvananda_netlink//:netlink",
+        "@org_golang_x_sys//unix",
     ],
 )
diff --git a/metropolis/node/core/network/main.go b/metropolis/node/core/network/main.go
index 6fb01eb..466c076 100644
--- a/metropolis/node/core/network/main.go
+++ b/metropolis/node/core/network/main.go
@@ -22,6 +22,7 @@
 	"net"
 	"os"
 	"path"
+	"strconv"
 	"strings"
 
 	"github.com/google/nftables"
@@ -35,6 +36,7 @@
 	"source.monogon.dev/metropolis/pkg/event"
 	"source.monogon.dev/metropolis/pkg/event/memory"
 	"source.monogon.dev/metropolis/pkg/supervisor"
+	netpb "source.monogon.dev/net/proto"
 )
 
 // Service is the network service for this node. It maintains all
@@ -43,6 +45,13 @@
 // via New, it can be started and restarted arbitrarily, but the service object
 // itself must be long-lived.
 type Service struct {
+	// If set, use the given static network configuration instead of relying on
+	// autoconfiguration.
+	StaticConfig *netpb.Net
+
+	// Vendor Class identifier of the system
+	DHCPVendorClassID string
+
 	dnsReg chan *dns.ExtraDirective
 	dnsSvc *dns.Service
 
@@ -58,12 +67,16 @@
 	status memory.Value[*Status]
 }
 
-func New() *Service {
+// New instantiates a new network service. If autoconfiguration is desired,
+// staticConfig must be set to nil. If staticConfig is set to a non-nil value,
+// it will be used instead of autoconfiguration.
+func New(staticConfig *netpb.Net) *Service {
 	dnsReg := make(chan *dns.ExtraDirective)
 	dnsSvc := dns.New(dnsReg)
 	return &Service{
-		dnsReg: dnsReg,
-		dnsSvc: dnsSvc,
+		dnsReg:       dnsReg,
+		dnsSvc:       dnsSvc,
+		StaticConfig: staticConfig,
 	}
 }
 
@@ -134,7 +147,7 @@
 	if err != nil {
 		return fmt.Errorf("failed to create DHCP client on interface %v: %w", iface.Attrs().Name, err)
 	}
-	s.dhcp.VendorClassIdentifier = "dev.monogon.metropolis.node.v1"
+	s.dhcp.VendorClassIdentifier = s.DHCPVendorClassID
 	s.dhcp.RequestedOptions = []dhcpv4.OptionCode{dhcpv4.OptionRouter, dhcpv4.OptionDomainNameServer, dhcpv4.OptionClasslessStaticRoute}
 	s.dhcp.LeaseCallback = dhcpcb.Compose(dhcpcb.ManageIP(iface), dhcpcb.ManageRoutes(iface), s.statusCallback, func(old, new *dhcp4c.Lease) error {
 		if old == nil || !old.AssignedIP.Equal(new.AssignedIP) {
@@ -190,10 +203,38 @@
 	return nil
 }
 
+// RFC2474 Section 4.2.2.1 with reference to RFC791 Section 3.1 (Network
+// Control Precedence)
+const dscpCS7 = 0x7 << 3
+
 func (s *Service) Run(ctx context.Context) error {
 	logger := supervisor.Logger(ctx)
 	supervisor.Run(ctx, "dns", s.dnsSvc.Run)
-	supervisor.Run(ctx, "interfaces", s.runInterfaces)
+
+	earlySysctlOpts := sysctlOptions{
+		// Enable strict reverse path filtering on all interfaces (important
+		// for spoofing prevention from Pods with CAP_NET_ADMIN)
+		"net.ipv4.conf.all.rp_filter": "1",
+		// Disable source routing
+		"net.ipv4.conf.all.accept_source_route": "0",
+		// By default no interfaces should accept router advertisements.
+		// This will be selectively enabled on the appropriate interfaces.
+		"net.ipv6.conf.all.accept_ra": "0",
+		// Make static IPs stick around, otherwise we have to configure them
+		// again after carrier loss events.
+		"net.ipv6.conf.all.keep_addr_on_down": "1",
+		// Make neighbor discovery use DSCP CS7 without ECN
+		"net.ipv6.conf.all.ndisc_tclass": strconv.Itoa(dscpCS7 << 2),
+	}
+	if err := earlySysctlOpts.apply(); err != nil {
+		logger.Fatalf("Error configuring early sysctl options: %v", err)
+	}
+	// Choose between autoconfig and static config runnables
+	if s.StaticConfig == nil {
+		supervisor.Run(ctx, "dynamic", s.runDynamicConfig)
+	} else {
+		supervisor.Run(ctx, "static", s.runStaticConfig)
+	}
 
 	s.natTable = s.nftConn.AddTable(&nftables.Table{
 		Family: nftables.TableFamilyIPv4,
@@ -214,11 +255,6 @@
 	sysctlOpts := sysctlOptions{
 		// Enable IP forwarding for our pods
 		"net.ipv4.ip_forward": "1",
-		// Enable strict reverse path filtering on all interfaces (important
-		// for spoofing prevention from Pods with CAP_NET_ADMIN)
-		"net.ipv4.conf.all.rp_filter": "1",
-		// Disable source routing
-		"net.ipv4.conf.all.accept_source_route": "0",
 
 		// Increase Linux socket kernel buffer sizes to 16MiB (needed for fast
 		// datacenter networks)
@@ -236,7 +272,7 @@
 	return nil
 }
 
-func (s *Service) runInterfaces(ctx context.Context) error {
+func (s *Service) runDynamicConfig(ctx context.Context) error {
 	logger := supervisor.Logger(ctx)
 	logger.Info("Starting network interface management")
 
diff --git a/metropolis/node/core/network/static.go b/metropolis/node/core/network/static.go
new file mode 100644
index 0000000..45469df
--- /dev/null
+++ b/metropolis/node/core/network/static.go
@@ -0,0 +1,417 @@
+package network
+
+import (
+	"bytes"
+	"context"
+	"errors"
+	"fmt"
+	"net"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+
+	"github.com/insomniacslk/dhcp/dhcpv4"
+	"github.com/vishvananda/netlink"
+	"golang.org/x/sys/unix"
+
+	"source.monogon.dev/go/algorithm/toposort"
+	"source.monogon.dev/metropolis/node/core/network/dhcp4c"
+	dhcpcb "source.monogon.dev/metropolis/node/core/network/dhcp4c/callback"
+	"source.monogon.dev/metropolis/pkg/logtree"
+	"source.monogon.dev/metropolis/pkg/supervisor"
+	netpb "source.monogon.dev/net/proto"
+)
+
+var vlanProtoMap = map[netpb.VLAN_Protocol]netlink.VlanProtocol{
+	netpb.VLAN_CVLAN: netlink.VLAN_PROTOCOL_8021Q,
+	netpb.VLAN_SVLAN: netlink.VLAN_PROTOCOL_8021AD,
+}
+
+func (s *Service) runStaticConfig(ctx context.Context) error {
+	l := supervisor.Logger(ctx)
+	sortedInterfaces, err := getSortedIfaces(s)
+	if err != nil {
+		return err
+	}
+
+	hostDevices, err := listHostDeviceIfaces()
+	if err != nil {
+		return err
+	}
+
+	nameLinkMap := make(map[string]netlink.Link)
+
+	// interface name -> parent interface name
+	nameParentMap := make(map[string]string)
+
+	for _, i := range sortedInterfaces {
+		var newLink netlink.Link
+		var err error
+		switch it := i.Type.(type) {
+		case *netpb.Interface_Device:
+			newLink, err = deviceIfaceFromSpec(it, hostDevices, l)
+		case *netpb.Interface_Bond:
+			for _, m := range it.Bond.MemberInterface {
+				nameParentMap[m] = i.Name
+			}
+			newLink, err = bondIfaceFromSpec(it, i)
+		case *netpb.Interface_Vlan:
+			newLink = &netlink.Vlan{
+				VlanId:       int(it.Vlan.Id),
+				VlanProtocol: vlanProtoMap[it.Vlan.Protocol],
+				LinkAttrs:    netlink.NewLinkAttrs(),
+			}
+			newLink.Attrs().ParentIndex = nameLinkMap[it.Vlan.Parent].Attrs().Index
+		}
+		if err != nil {
+			return fmt.Errorf("interface %q: %w", i.Name, err)
+		}
+		newLink.Attrs().Name = i.Name
+		// Set link administratively up
+		newLink.Attrs().Flags |= unix.IFF_UP
+		if i.Mtu != 0 {
+			newLink.Attrs().MTU = int(i.Mtu)
+		}
+		if nameParentMap[i.Name] != "" {
+			newLink.Attrs().MasterIndex = nameLinkMap[nameParentMap[i.Name]].Attrs().Index
+		}
+		if newLink.Attrs().Index == -1 {
+			if err := netlink.LinkAdd(newLink); err != nil {
+				return fmt.Errorf("failed to add link %q: %w", i.Name, err)
+			}
+		} else {
+			if err := netlink.LinkModify(newLink); err != nil {
+				return fmt.Errorf("failed to modify link %q: %w", i.Name, err)
+			}
+		}
+		nameLinkMap[i.Name] = newLink
+		if i.Ipv4Autoconfig != nil {
+			if err := s.runDHCPv4(ctx, newLink); err != nil {
+				return fmt.Errorf("error enabling DHCPv4 on %q: %w", newLink.Attrs().Name, err)
+			}
+		}
+		if i.Ipv6Autoconfig != nil {
+			err := sysctlOptions{
+				"net.ipv6.conf." + newLink.Attrs().Name + ".accept_ra": "1",
+			}.apply()
+			if err != nil {
+				return fmt.Errorf("failed enabling accept_ra for interface %q: %w", newLink.Attrs().Name, err)
+			}
+			// TODO(lorenz): Actually implement DHCPv6/Managed flag
+		}
+		for _, a := range i.Address {
+			err := addAddrFromSpec(a, newLink)
+			if err != nil {
+				return fmt.Errorf("failed adding address %q to link: %w", a, err)
+			}
+		}
+		for _, r := range i.Route {
+			err := routeFromSpec(r, newLink)
+			if err != nil {
+				return fmt.Errorf("failed creating route on interface %q: %w", i.Name, err)
+			}
+		}
+		l.Infof("Configured interface %q", i.Name)
+	}
+	supervisor.Signal(ctx, supervisor.SignalHealthy)
+	supervisor.Signal(ctx, supervisor.SignalDone)
+	return nil
+}
+
+func (s *Service) runDHCPv4(ctx context.Context, lnk netlink.Link) error {
+	c, err := dhcp4c.NewClient(netlinkLinkToNetInterface(lnk))
+	if err != nil {
+		return fmt.Errorf("failed creating DHCPv4 client: %w", err)
+	}
+	c.RequestedOptions = []dhcpv4.OptionCode{dhcpv4.OptionRouter, dhcpv4.OptionDomainNameServer, dhcpv4.OptionClasslessStaticRoute}
+	c.LeaseCallback = dhcpcb.Compose(dhcpcb.ManageIP(lnk), dhcpcb.ManageRoutes(lnk), s.statusCallback)
+	return supervisor.Run(ctx, "dhcp-"+lnk.Attrs().Name, c.Run)
+}
+
+// getSortedIfaces returns a list of all interfaces to be configured in
+// an order which is valid to configure them in, ie. parent interfaces get
+// configured before child interfaces. It also validates that all interfaces
+// referenced do in fact exist in the configuration.
+func getSortedIfaces(s *Service) ([]*netpb.Interface, error) {
+	var depGraph toposort.Graph[string]
+	ifMap := make(map[string]*netpb.Interface)
+	for _, iface := range s.StaticConfig.Interface {
+		if err := isValidDevName(iface.Name); err != nil {
+			return nil, fmt.Errorf("invalid interface name %q: %w", iface.Name, err)
+		}
+		ifMap[iface.Name] = iface
+		depGraph.AddNode(iface.Name)
+		switch it := iface.Type.(type) {
+		case *netpb.Interface_Bond:
+			for _, depIf := range it.Bond.MemberInterface {
+				// Bond interfaces are set up with no children, their children
+				// are then added when they are configured. Thus this needs a
+				// reverse dependency.
+				depGraph.AddEdge(depIf, iface.Name)
+			}
+		case *netpb.Interface_Vlan:
+			depGraph.AddEdge(iface.Name, it.Vlan.Parent)
+		}
+	}
+	badRefs := depGraph.ImplicitNodeReferences()
+	if len(badRefs) > 0 {
+		var errMsgs []string
+		for n, refs := range badRefs {
+			var strRefs []string
+			for ref := range refs {
+				strRefs = append(strRefs, ref)
+			}
+			errMsgs = append(errMsgs, fmt.Sprintf("reference to undefined interface %q from interfaces %s", n, strings.Join(strRefs, ", ")))
+		}
+		return nil, errors.New(strings.Join(errMsgs, "; "))
+	}
+	interfaceOrder, err := depGraph.TopologicalOrder()
+	if err != nil {
+		return nil, fmt.Errorf("unable to calculate interface setup order: %w", err)
+	}
+	var sortedInterfaces []*netpb.Interface
+	for _, ifname := range interfaceOrder {
+		sortedInterfaces = append(sortedInterfaces, ifMap[ifname])
+	}
+	return sortedInterfaces, nil
+}
+
+type deviceIfData struct {
+	dev    *netlink.Device
+	driver string
+}
+
+func listHostDeviceIfaces() ([]deviceIfData, error) {
+	links, err := netlink.LinkList()
+	if err != nil {
+		return nil, fmt.Errorf("failed to list network links: %w", err)
+	}
+
+	var hostDevices []deviceIfData
+
+	for _, link := range links {
+		if link.Attrs().EncapType == "loopback" {
+			continue
+		}
+		d, ok := link.(*netlink.Device)
+		if !ok {
+			continue
+		}
+		var driver string
+		driverPath, err := os.Readlink("/sys/class/net/" + d.Name + "/device/driver")
+		if err == nil {
+			driver = filepath.Base(driverPath)
+		}
+		hostDevices = append(hostDevices, deviceIfData{
+			dev:    d,
+			driver: driver,
+		})
+	}
+	return hostDevices, nil
+}
+
+func deviceIfaceFromSpec(it *netpb.Interface_Device, hostDevices []deviceIfData, l logtree.LeveledLogger) (*netlink.Device, error) {
+	var matchedDevices []*netlink.Device
+	var err error
+	var parsedHWAddr net.HardwareAddr
+	if it.Device.HardwareAddress != "" {
+		parsedHWAddr, err = net.ParseMAC(it.Device.HardwareAddress)
+		if err != nil {
+			return nil, fmt.Errorf("unable to parse hardware address %q: %w", it.Device.HardwareAddress, err)
+		}
+	}
+
+	// This is O(N^2), but is bounded by the amount of physical NICs in the
+	// system. At this point we can reasonably assume N < 100.
+	for _, d := range hostDevices {
+		if len(parsedHWAddr) != 0 {
+			// If device has a permanent hardware address, it must match,
+			// otherwise the standard hardware address must match
+			if len(d.dev.PermHardwareAddr) > 0 {
+				if !bytes.Equal(d.dev.PermHardwareAddr, parsedHWAddr) {
+					l.V(1).Infof("mismatched perm hw addr %q: %s %s\n", d.dev.Name, d.dev.PermHardwareAddr, parsedHWAddr)
+					continue
+				}
+			} else if !bytes.Equal(d.dev.HardwareAddr, parsedHWAddr) {
+				l.V(1).Infof("mismatched fallback hw addr %q: %s %s\n", d.dev.Name, d.dev.HardwareAddr, parsedHWAddr)
+				continue
+			}
+		}
+		if it.Device.Driver != "" {
+			if it.Device.Driver != d.driver {
+				l.V(1).Infof("mismatched driver %q: %s %s\n", d.dev.Name, it.Device.Driver, d.driver)
+				continue
+			}
+		}
+		matchedDevices = append(matchedDevices, d.dev)
+	}
+	if len(matchedDevices) <= int(it.Device.Index) || it.Device.Index < 0 {
+		return nil, fmt.Errorf("there are %d matching host devices but requested device index is %d", len(matchedDevices), it.Device.Index)
+	}
+	dev := &netlink.Device{
+		LinkAttrs: netlink.NewLinkAttrs(),
+	}
+	dev.Index = matchedDevices[it.Device.Index].Index
+	return dev, nil
+}
+
+var lacpRateMap = map[netpb.Bond_LACP_Rate]netlink.BondLacpRate{
+	netpb.Bond_LACP_SLOW: netlink.BOND_LACP_RATE_SLOW,
+	netpb.Bond_LACP_FAST: netlink.BOND_LACP_RATE_FAST,
+}
+
+var lacpAdSelectMap = map[netpb.Bond_LACP_SelectionLogic]netlink.BondAdSelect{
+	netpb.Bond_LACP_STABLE:    netlink.BOND_AD_SELECT_STABLE,
+	netpb.Bond_LACP_BANDWIDTH: netlink.BOND_AD_SELECT_BANDWIDTH,
+	netpb.Bond_LACP_COUNT:     netlink.BOND_AD_SELECT_COUNT,
+}
+
+var xmitHashPolicyMap = map[netpb.Bond_TransmitHashPolicy]netlink.BondXmitHashPolicy{
+	netpb.Bond_LAYER2:         netlink.BOND_XMIT_HASH_POLICY_LAYER2,
+	netpb.Bond_LAYER2_3:       netlink.BOND_XMIT_HASH_POLICY_LAYER2_3,
+	netpb.Bond_LAYER3_4:       netlink.BOND_XMIT_HASH_POLICY_LAYER3_4,
+	netpb.Bond_ENCAP_LAYER2_3: netlink.BOND_XMIT_HASH_POLICY_ENCAP2_3,
+	netpb.Bond_ENCAP_LAYER3_4: netlink.BOND_XMIT_HASH_POLICY_ENCAP3_4,
+	// TODO(vishvananda/netlink#860): constant not in netlink yet
+	netpb.Bond_VLAN_SRCMAC: 5,
+}
+
+func bondIfaceFromSpec(it *netpb.Interface_Bond, i *netpb.Interface) (*netlink.Bond, error) {
+	newBond := netlink.NewLinkBond(netlink.NewLinkAttrs())
+	newBond.MinLinks = int(it.Bond.MinLinks)
+	newBond.XmitHashPolicy = xmitHashPolicyMap[it.Bond.TransmitHashPolicy]
+	switch bt := it.Bond.Mode.(type) {
+	case *netpb.Bond_Lacp:
+		newBond.Mode = netlink.BOND_MODE_802_3AD
+		newBond.LacpRate = lacpRateMap[bt.Lacp.Rate]
+		newBond.AdSelect = lacpAdSelectMap[bt.Lacp.SelectionLogic]
+		if bt.Lacp.ActorSystemMac != "" {
+			mac, err := net.ParseMAC(bt.Lacp.ActorSystemMac)
+			if err != nil {
+				return nil, fmt.Errorf("malformed LACP actor_system_mac for bond %q: %w", i.Name, err)
+			}
+			newBond.AdActorSystem = mac
+		}
+		if bt.Lacp.ActorSystemPriority != 0 {
+			newBond.AdActorSysPrio = int(bt.Lacp.ActorSystemPriority)
+		}
+		if bt.Lacp.UserPortKey != 0 {
+			newBond.AdUserPortKey = int(bt.Lacp.UserPortKey)
+		}
+	case *netpb.Bond_ActiveBackup_:
+		newBond.Mode = netlink.BOND_MODE_ACTIVE_BACKUP
+	default:
+		return nil, fmt.Errorf("unknown bond type %T", bt)
+	}
+	return newBond, nil
+}
+
+func addAddrFromSpec(a string, link netlink.Link) error {
+	var addr netlink.Addr
+	ipNet, err := addressOrPrefix(a)
+	if err != nil {
+		// Error already contains original string and enough wrapping
+		// is already done, so pass through directly.
+		return err
+	}
+	addr.IPNet = ipNet
+	if ones, size := addr.Mask.Size(); ones == size {
+		// If this is a single host IP, do not add a prefix route as it is
+		// not routable without a separate inteface route.
+		addr.Flags |= unix.IFA_F_NOPREFIXROUTE
+	}
+	addr.Flags |= unix.IFA_F_PERMANENT
+	// Kernel will add the on-link prefix for us in the routing
+	// table if required.
+	if err := netlink.AddrAdd(link, &addr); err != nil {
+		return fmt.Errorf("failed to add to kernel interface: %w", err)
+	}
+	return nil
+}
+
+func routeFromSpec(r *netpb.Interface_Route, link netlink.Link) error {
+	var route netlink.Route
+	dst, err := addressOrPrefix(r.Destination)
+	if err != nil {
+		return fmt.Errorf("destination invalid: %w", err)
+	}
+	if !dst.IP.Mask(dst.Mask).Equal(dst.IP) {
+		return fmt.Errorf("destination %v has bits in the mask set", r.Destination)
+	}
+	route.Dst = dst
+	route.Protocol = unix.RTPROT_STATIC
+	route.LinkIndex = link.Attrs().Index
+	route.Priority = int(r.Metric)
+	if r.SourceIp != "" {
+		srcIP := net.ParseIP(r.SourceIp)
+		if srcIP == nil {
+			return fmt.Errorf("failed parsing %q as IP", r.SourceIp)
+		}
+		route.Src = srcIP
+	}
+	if r.GatewayIp != "" {
+		gwIP := net.ParseIP(r.GatewayIp)
+		if gwIP == nil {
+			return fmt.Errorf("failed parsing %q as IP", r.GatewayIp)
+		}
+		route.Gw = gwIP
+
+		// These are all interface routes, if a gateway is present
+		// it is always treated as on-link.
+		route.Flags |= int(netlink.FLAG_ONLINK)
+	}
+	if err := netlink.RouteAdd(&route); err != nil {
+		return fmt.Errorf("failed creating kernel route %q: %w", r.Destination, err)
+	}
+	return nil
+}
+
+func addressOrPrefix(s string) (*net.IPNet, error) {
+	if strings.ContainsRune(s, '/') {
+		ip, prefix, err := net.ParseCIDR(s)
+		if err != nil {
+			// err already contains original string, no need to wrap
+			return nil, err
+		}
+		return &net.IPNet{IP: ip, Mask: prefix.Mask}, nil
+	} else {
+		ip := net.ParseIP(s)
+		if ip == nil {
+			return nil, fmt.Errorf("invalid IP: %v", ip)
+		}
+		var mask net.IPMask
+		if ip.To4() == nil {
+			mask = net.CIDRMask(128, 128) // IPv6 /128
+		} else {
+			mask = net.CIDRMask(32, 32) // IPv4 /32
+		}
+		return &net.IPNet{IP: ip, Mask: mask}, nil
+	}
+}
+
+func netlinkLinkToNetInterface(lnk netlink.Link) *net.Interface {
+	attrs := lnk.Attrs()
+	return &net.Interface{
+		Index:        attrs.Index,
+		MTU:          attrs.MTU,
+		Name:         attrs.Name,
+		HardwareAddr: attrs.HardwareAddr,
+		Flags:        attrs.Flags,
+	}
+}
+
+var validDevNameRegexp = regexp.MustCompile("^[^/:[:space:]]{1,15}$")
+
+func isValidDevName(name string) error {
+	if name == "." || name == ".." {
+		return errors.New("cannot be \".\" or \"..\"")
+	}
+	if strings.ContainsRune(name, '%') {
+		return errors.New("contains \"%\" sign which dynamically allocate names, this is disallowed")
+	}
+	if !validDevNameRegexp.MatchString(name) {
+		return errors.New("too short, too long or contains forward slashes, colons or spaces")
+	}
+	return nil
+}
