Overview of ADSL
The 3 main modes of DSL that Linux supports are PPP over ATM (pppoa), PPP over Ethernet (pppoe), and Routed IP (ipoatm). Initially the first two modes (PPPoA and PPPoE) will be implemented as they are the most common, and Routed IP support will follow. NetworkManager already has well-developed and robust PPP and PPPoE support, which can be used to simplify the task of adding support for ADSL devices.
Good ADSL support requires a few things in the kernel. Prior to 2.6.38, ATM devices [http://www.spinics.net/lists/linux-usb/msg39850.html | did not properly export themselves] in sysfs, causing problems detecting new ADSL modems. Second, prior to 2.6.38 the ueagle-atm driver had a [http://kerneltrap.org/mailarchive/linux-netdev/2010/12/19/6292145 | race condition] that sometimes causes the carrier signal to be set even when no phone line was connected to the modem, which will prevent correct automatic connections in NetworkManager. Patches for both these issues have been submitted and thus 2.6.38 should work correctly.
The first thing to do when adding support for a new type of device to NetworkManager is to determine what configuration is necessary. In the case of ADSL, we appear to require:
VPI and VCI: usually given by your ISP, but there are [http://faq.eagle-usb.org/wakka.php?wiki=ListConfigADSL | lists out there we can use]
- Encapsulation: "llc" or "vcmux", depending on your ISP; we can use the same VPI/VCI list for encapsulation too
- Type: "pppoe", "pppoatm", or "ipoatm"
- Username and Password
Given this information, we now create an NMSetting subclass in libnm-util/ called NMSettingAdsl and add the configuration items above as the object's properties. We then implement the verify() method to check the values of each property and ensure they are supported. Make sure to add the nm-setting-adsl.c and nm-setting-adsl.h to Makefile.am, and also add each public function that NMSettingAdsl exports to libnm-util.ver to make these functions visible.
Now on to the actual implementation. Every type of device in NetworkManager is a subclass of NMDevice, so we need to create NMDeviceAdsl. It's probably best to copy NMDeviceEthernet and use that as a starting point, since it already has carrier handling that could be adapted to ADSL. Unfortunately the kernel ATM stack doesn't appear to send netlink events on carrier change, so we'll need to revert to polling the 'carrier' attribute in sysfs. That can be done by using g_timeout_add_seconds() in the NMDeviceAdsl's constructor() function, and removing that timeout with g_source_remove() in the dispose() function.
We'll also need to figure out what properties this object should have. We should only add things that are properties of the hardware itself, not configuration. So we'll want things like 'carrier', 'hw-address' (MAC address for PPPoE), and anything else that client applications might need when showing device details.
We'll also need to update a few things to listen for hotplug events for ATM devices. This would be handled in nm-udev-manager.c, where we'll need to listen for add/remove events on devices in the "atm" subsystem, and also in nm-manager.c where we'll need to call nm_device_adsl_new() and add the returned object to the internal device list.
This library is used by the GNOME applet, connection editor, and other programs to easily interface with NetworkManager. The objects defined here are simple GObject wrappers around the NM D-Bus API, providing GObject subclasses for each object NM exports over D-Bus (like devices, access points, the main NM object itself, etc). We'll need to create an NMObject subclass called NMDeviceAdsl here too, and like before using NMDeviceEthernet as the base is probably easiest.
We'll need to add support for ADSL devices to the applet and connection editor. For the applet, we create a new applet-device-adsl.c file that controls what the applet shows in the menu for ADSL devices. We'll need to identify an icon to show as the main applet icon when ADSL is connected. Next we'll need to add the bits for the connection editor; there's already a DSL tab we can re-use, though currently it only contains stuff for generic PPPoE. To do this, we create a new GtkBuilder .ui file (ce-page-adsl.ui) that contains UI elements for editing all the ATM specific stuff like VPI, VCI, Encapsulation, etc. Then we implement that UI by creating a CEPage subclass called page-adsl.c (and the corresponding header page-dsl.h) and filling in the UI logic. It should be pretty apparent from the other page-* files what needs to happen. A few other places need to be fixed up to accommodate ADSL too, like in nm-connection-editor.c where each options page is actually instantiated based on the contents of the given connection being edited.
One issue here is how to deal with the existing PPPoE support. Ideally, we rename page-dsl.c to page-pppoe.c since that's what it really is, and since it's only meant for Ethernet and WiFi PPPoE use-cases. I don't think we should re-use it for ADSL since all the ADSL options should be contained on one UI page.