Idea for an alternate way to express network configuration
Being unsatisfied by existing network configuration methods for certain common distributions, I've decided I need to write something new to replace them and make network configuration more reliable and straightforward. I'm hoping this might be as simple as a replacement for an init startup script. But it might be beyond what a simple shell script could do.
My idea is to have a script or program that parses a network configuration file with a different arrangement of directives. I believe this structuring is closer to how real networks are organized. These directives would include: Code:
subnet <name> { { <IPaddr>/<prefix> | <IPaddr>&<netmask> | dhcp [hostname] } ... } This is the simple form. I would also add some ways to fine tune exceptions to this. But in most cases the simple form should do well. Example: Code:
subnet lan0 10.20.0.0/16 fcc0::/16 Among my needs includes the ability to be both interface name and MAC address independent. So that's why I am including the bus address capability. |
Just use this software of mine: http://code.google.com/p/badvpn/wiki/NCD
Works on all Linux distros and it much more powerful than anything else in existence, especially compared to a run-once script. A notable feature is proper handling of hotplugging. Quote:
Udev will assign persistent interface names based on the hardware MAC address; see this. This means that after a network card is first detected, it will be assigned a new name, and this name will be used in the future for this card, no matter where it's plugged in. If you for some reason want your network config to be done by bus address instead of by MAC address, you can override udev's persistent naming rules with your own. For example, create a file /etc/udev/rules.d/71-my-net.rules (the number overrides 70-persistent-net.rules): Code:
BUS=="pci", ID=="0000:06:00.0", NAME="eth33" EDIT: your rules may conflict with udev's persistent assigning - you have to prevent udev giving other interfaces those names you assign per bus ID. A quick hack is to add placeholder entries in /etc/udev/rules.d/70-persistent-net.rules which reference reserved names, but are never actually matched: Code:
# PCI device 0x1969:0x1063 (atl1c) You also have to manually remove other entries in /etc/udev/rules.d/70-persistent-net.rules which assign reserved names (eth33). |
Update: I've just added a "bus" variable to NCD's net.watch_interfaces(). This allows for easy per-bus-location configuration of interface, and doesn't require dealing with udev. See this example.
|
Quote:
Quote:
Quote:
Code:
#!/bin/bash 1. By interface name (the usual way) 2. By MAC address 3. By bus address I'm also looking at doing a 4th method which will be to use the subnet itself as the interface selector. What this would involve is a program that sniffs the traffic on the interfaces to detect subnets in some way. In promiscuous mode, it could detect the subnets by a few ways. A subnet configuration could have default routers and other hosts listed, and it would send ARP queries to see if there are responses. Or it could send a DHCP request and subsequently turn it down. This is all just to detect what subnets each interface has. It would allow more than one interface reaching a subnet (with ultimately the same or different IPs), and more than one subnet (and hence IP) per interface. And all this can be configured in one file, or an ordered concatenation of files from a subdirectory. It is this newer means of configuring the IP addresses that is my interest as a solution to both the udev issues (although mostly solved ... see the script above) and IP addressing issues (with my intention to gracefully allow multi-multi associations between subnets and interfaces). |
Quote:
|
Quote:
I do not understand why you want such a naming scheme. Why does the default MAC-address based scheme not work for you? The only reason I can think of is when you want to replace an existing card with another one - but then how hard is it to update the interface name in your config, or the persistent naming cache? What problem are you actually trying to solve here? Quote:
Quote:
Quote:
I don't think that the ARP probing is a good idea. Nowadays everything runs DHCP and you can use that to obtain the network config (and to identify it, like I said above). However, NCD is very modular, and you can implement an ARP probing statement if you like; see my DHCP client code for how to to link-layer traffic. Quote:
Quote:
Can you please give me some feedback about NCD? Is there some particular feature it's missing? I'm not fond of the idea of someone making a whole new network config system just to solve one particular problem. Also, it doesn't seem like your proposed system can do more than wired interfaces. It is my belief that any such simple declarative system for network config will have extreme extensibility and expressivity issues. NCD's power comes from its imperative nature, but with just the right amount of declarative style for the problem domain, in particular the reverse-execution thing. |
Quote:
Quote:
2. The whole motherboard or more is changed. More specifically, hard drives are moved from one machine in a rack to another. Perhaps this is because the machine they move from failed. 3. The system lives on a portable flash drive device, such as a USB memory stick. When the change happens at a remote location, where people executing these changes are less skill or less involved, making the needed network changes is not easy, if even possible. Something smarter in software can and should take over this role. This can even involve the USB memory stick, which might be the tool used to allow a remote admin to access the machine where no admins of sufficient skill to reconfigure the network are present on site. I'm wondering at this point how PXE can affect this. But that will need to wait until I get my feet wet with PXE. Quote:
If I had designed ethernet today, I'd simply have each NIC card generate a random 128-bit UUID on the fly each time it resets, and use that like the MAC. The only reason I wouldn't do that with today's ethernet is the MACs are only 48 bit. My point is, given enough bits, we really don't need to be assigning fixed addresses to specific hardware. That would cut some costs, too. Quote:
Quote:
Quote:
One concept I'm using in my configuration model is that an IP address is NOT considered associated with an interface, but rather, with a subnet. The association is strict in that it is only associated with a subnet that it is IN. There can be more than one IP address on this host in a subnet. It is the subnet itself that is associated with the interface. Once that association is established, all of this machine's IP addresses are associated with the interface ... or with all interfaces associated with that subnet. Organizing this way allows for the list of IPs, and the association of subnets, to be configured separately where desired (e.g. at least some of the IPs come from a web server). Quote:
Quote:
If course there can be potential issues with any system, declarative or imperative. That's one reason to ask for feedback. And yes, the idea I have is perhaps overly simplified. But I would want to have the ability, for a network that CAN be expressed in a simple way, to actually express it in such a simple way. I would not want the ability to do a very complex configuration to impose on simpler networks to express things any less simple than they need. My initial reading of NCD gives me that feeling that it is, at least in some major part, still based on the concept of "this IP belongs on this interface". I'd rather more have a case of "this IP (these IPs) are what I need to use, now please sort out for me which interfaces they need to go on". If the subnets for each are known, that sure simplifies it, as which subnet a given IP is in is certainly clear. Then you only need to associate a subnet and an interface (or establish all the many-to-many associations that really exist). In some cases, other programs may need to determine which IPs are used. The ability to express that needs to be simple from the other program's perspective. For NCD, it might be better for the other programs to store their IPs elsewhere, and have a script generate the NCD config from that. But NCD seems overly mechanical (in the imperative sense) to me. The configuration expresses "what to do" rather than "how it is to be". There's lots of logic in there. I'd rather avoid the logic on less complex networks. I'd rather express what the network is like, even including detection mechanisms like the ARP/DHCP tests (or others), and let the network config daemon figure out how to make it work, and achieve the desired state. |
1 Attachment(s)
Quote:
NOTE: you need the latest NCD from the SVN repo for this program. I should note that this NCD program I wrote is fully hotplug-aware. For instance, you can pull an USB NIC in and out as much as you like, or pull the network cable in and out, and the interface will be de/re-configured automatically. Actually, this ability is a key feature that is implied when using NCD for network config, provided you wrote the NCD program correctly. Quote:
Quote:
Quote:
Quote:
|
Quote:
I suspect lots of people won't want to create whole new NCD configs for what are otherwise simple (even if multiple interface and multiple IP) networks. It's not as bad as coding XML, but for the simple networks, I think my syntax idea is definitely simpler. But if someone has something complicated, like wanting to divide up IP address assignments among interfaces that otherwise reach the same subnet, more detail is needed in the config. And even that isn't very complex at all. NCD looks like it would handle all kinds of complicated things. I like the comparison with NetworkManager your web description makes. Among my beefs with NM was that it is essentially useless for servers. And that doesn't count the confusion it has with trying to do 2 subnets on one interface. NCD looks like the replacement. If there is a GUI to add on to NCD, then it NCD could replace NM even for those all-GUI environments used by people that want a GUI tool for everything, and still offer a programmable back-end as an alternative (don't try to do everything in a GUI). It would still be nice to have NCD be able to (at least allow the configuration programming to) deal with things like some newbie admin in a data center transposing the CAT5 connections. Having defined means (not assumed by NCD ... must be configured as policy by the admin) to identify networks that interfaces are connected to ... and the changes that happen (I count changing the NIC port connections as equivalent to hotplugging), would still be valuable. The "network detection policy" programming could allow the use of monitoring for various traffic types (DHCP, ARP, other broadcasts), or probing in certain ways (send DHCP request, send ARP request, send DNS query, and perhaps many other things) to figure out the network topology on the fly, but initially at startup, whenever events are detected (filterable), and on a timed schedule. I still believe ARP is a valid way to detect possible subnets. Many networks don't run DHCP or don't want to depend on it. ARP can be used by intentionally looking for a specific configured IP address just as if needing to send IP traffic there, or or just monitor for other hosts doing ARP queries, and the answers they get. One could also specifically query an IP address seen by another machine doing an ARP query and not getting an answer. Use NDP for IPv6. And this all needs to be policy configured, and not the default, since there are potential security implications like DoS. |
Quote:
Quote:
However, control itself is not enough. There should also be a simple way to permanently store such run-time configuration on disk, to load it into the daemon, and retrieve the current config from the daemon. Having said that, here's an idea for a particular way to implement run-time configuration.
A very simple example of a configuration follows. (it is not what you want, just demonstrates the form of the config). Here, list syntax is {value1, ... valueN} as NCD already implements, and map syntax is [key1 => value1, ..., keyN => valueN]. Code:
[ /interfaces/eth0/addrs (refers the the addresses list) /interfaces/eth0/addrs/0 (refers to the first address, probably that will never be used) Using this scheme, the "easy configuration for a dummy admin" would simply mean changing the configuration file and invoking the config client to upload the new configuration. The scheme also allows for GUI-based configuration, where a GUI would act as the config client, and it may or may not use the config file syntax used by the command line config client. Feel free to suggest improvements on this or an alternative. Quote:
Quote:
Quote:
|
Also, I think it would be useful to have a config operation that does not change the configuration, but resets a part of it. For example, resetting /interfaces/eth0 would be the same as uploading a new config without eth0, them immediately uploading the original config (atomically). The effect, in this case, would be to restart the eth0 interface entirely.
|
Quote:
An advantage of this approach is that the the parameters in question can be dynamic, e.g. an IP address obtained with DHCP. |
Quote:
Code:
process foo { |
In what way does that change the state? The use I'd have for ARP probe would be to add a subnet to the interface the ARP probe succeeded on. I'd want to send this probe on all, or maybe a list of, interfaces, to see where the subnet is. And the subnet may be on more than one interface. Upon success, if the interface is down, bring it up. Then add the IPs that are appropriate. And usually I would associate IPs with a subnet. Also, once the subnet is activated, new IP requests (for example a new vhost added to a web server) should know which interfaces (based on this subnet being active for them, now) to add them to. And those IPs should also be added to the subnet's list of IPs in case the network changes and interfaces go down, come up, or that newbie admin comes around and swaps the cables again (should trigger a lot of events to figure out how to adjust the configuration to work with that).
Sound complicated? |
Quote:
Code:
process my_interface { Quote:
Quote:
Quote:
Quote:
|
All times are GMT -5. The time now is 09:54 AM. |