On 21.02.2016 16:39, Thomas Haller
wrote:
On Sat, 2016-02-20 at 18:12 +0100, Stjepan Groš wrote:On 20.02.2016 00:39, Thomas Haller wrote:On Thu, 2016-02-04 at 12:21 +0100, Stjepan Groš wrote:Hi! Is anyone working on network namespaces support in NetworkManager? Or was thinking what is a "proper way" of implementing them? I'm experimenting with adding support to NM and what I implemented so far is: 1. Added objects NMNetnsController which would control all network namespaces managed by NM. 2. Each network namespace is represented with an object NMNetns and exposed on DBus. There are no methods so far but only a property name which contains network namespace's name on the filesystem. 3. NMNetnsController exposes object NetworkNamespacesController with methods AddNetworkNamepace and ListNetworkNamespaces. The first one take a name as an argument and creates a new (iproute2 compatible) network namespace, while the second one provides a list of existing namespaces. 4. When new network namespace is created (using AddNetworkNamepace method) a new, private, platform layer is instantiated and loopback interface within namespace activated. Note that new platform layer has to be created because once a socket is opened in one network namespace it is bound to the given namespace no matter which namespace is active so current singleton object wouldn't work without heavy refactoring! What I intend to do next is: 1. NM has to monitor devices/IP addresses in new network namespaces properly. 2. Methods that would allow an IPv4 or IPv6 address to be assigned in some network namespace. All the code is here: https://github.com/sgros/MIF_NetworkManager and since this is PoC, there are A LOT OF BUGS AND MISSING FEATURES. So, what do you think? Any comments, suggestions, critiques, etc? SG P.S. To be able to run patched NM you also need patched libndp library available here: https://github.com/sgros/MIF_libndpHi Sjepan, I think adding namespace support to platform needs to be more elaborate. There is also udev, ethtool, sysctl, which must be considered and the NMPlatform instance must transparently switch namespace as needed. I did that here: https://cgit.freedesktop.org/NetworkManager/NetworkManager/log/?h=t h/platform-netnsI agree that it should be a bit more thought out. That's the reason I still consider my approach to be experimental. If I got it right, you made NMPlatform object network namespace aware and you still have a single NMPlatform object (singleton)?NMPlatform is a singleton in the sense that there exists a nm_platform_get() function which returns a particular (singleton) instance and most callers use that function. But NMPlatform can already completely be used non-singleton-style. If any caller wishes to use a different platform instance then the "default" singleton, he can already do so. Yes, I changed the call nm_platform_get() (and NM_PLATFORM_GET) into nm_netns_get_platform(), which returns platform specific to some network namespace. The exception is NMManager object which manages root network namespace for which "singleton" (or main) is still valid. Also, there are few corner cases while objects are constructed that required me to change initialization process and in one case return main platform object if particular network namespace's platform object isn't fully initialized yet. I agree with your change to let NMDevice have distinct platform instances instead of using the singleton instance.Where do you intend to introduce management of network namespaces, e.g. where will you create/delete them?A NMPlatform instance entirely lives inside a namespace (because it basically wraps the platform cache and the netlink socket -- both contain information that is only relevant within one namespace. Theoretically, NMPlatform could be multi-namespace, but then it would need an entirely different (namespace aware) API and one cache per namespace. Which would make platform even more complex. It's cleaner and simpler to have NMPlatform not multi-namespace. Thus creating and management of namespaces should be done outside of NMPlatform. nm_platform_netns_create() is not so nice, because something *inside* the namespace should not create another namespace. Fully agree with this. On th/platform-netns, creation is done via nmp_netns_new(). Switching via nmp_netns_push()/nmp_netns_pop(), and deletion via nmp_netns_unref(). I didn't look at nmp object, and still don't know the exact purpose it is used for. It seemed to me as something internal to platform and thus also not appropriate for being network namespace aware. There is no nmp_netns_activate, because I think the API should force the caller to restore the previous namespace. Thus it's push/pop. But yeah, a nmp_netns_activate() function could be added. I agree that the caller should restore the previous namespace. Actually, other, non root, network namespaces are activated only sporadically and for a short periods of a time. This is how I try to make things and it works for now. The way how things are implemented within linux kernel allows for such behavior.
Maybe it's not so difficult. Namely, moving a device from one network namespace to another one generates two events via NMPlatform. One is removal of device in one (source) namespace, and another one is creation of a new device in a new (target) namespace. Also, it seems that there is no way that device, when moved to another network namespace, can keep its configuration data. This also makes moving device to another network namespace simpler to implement. Your NMNetnsController/NMNetns classes are exposed on D-Bus. Yes, they are. I introduced two new interfaces: org.freedesktop.NetworkManager.NetworkNamespacesController and org.freedesktop.NetworkManager.NetNsInstance. As I said, NMPlatform is strictly tied to a namespace, thus NMPlatform uses NMPNetns (not vice versa). I'm confused here. NMPlatform doesn't on network namespaces, we agree on that. But, NMPlatform can implement methods to switch network namespaces without being network namespace aware. Take for example methods to create new network namespace: https://github.com/sgros/MIF_NetworkManager/blob/master/src/platform/nm-linux-platform.c#L2658 or to switch to some other network namespace: https://github.com/sgros/MIF_NetworkManager/blob/master/src/platform/nm-linux-platform.c#L2731 all parameters need for implementing this are available via parameters passed to them, they don't need to store any internal information about network namespaces created, and finally, they don't depend on the current namespace being active. This last point means that you can use any NMPlatform object to switch/create/delete network namespaces. But what I did is that I use main NMPlatform object for that purpose (or at least try to). I think NMPlatform should not depend on anything D-Bus related. It's a lower layer. Thus, NMPNetns can also not be exposed on D-Bus. NMPlatform, as I implemente it, doesn't depend on D-Bus, nor it knows anything about D-Bus. SG Having your NMNetns class can be correct for managing and exposing namespaces on D-Bus. But you need the lower level NMPNetns too and NMNetns should call to NMPNetns/NMPlatform as needed. Thomas |
Attachment:
signature.asc
Description: OpenPGP digital signature