2011-03-08 21:24:27 +00:00
|
|
|
So you're interested in hacking on NetworkManager? Here's some cool
|
|
|
|
stuff you could do...
|
|
|
|
|
|
|
|
* Internet Connectivity Detection
|
|
|
|
|
|
|
|
This feature would consist of attempting to make an HTTP request to a known
|
|
|
|
DNS address and compare the response to a well-known string, like Windows does.
|
|
|
|
This feature and the server address should be configurable via an option in the
|
|
|
|
/etc/NetworkManager/NetworkManager.conf config file.
|
|
|
|
|
|
|
|
Once the device has successfully gotten an IPv4 or IPv6 address, it should
|
|
|
|
enter the state NM_DEVICE_STATE_IP_CHECK, where this HTTP request would be
|
|
|
|
performed. After the check was done, the device would set a property in
|
|
|
|
NMDevicePrivate to indicate whether Internet access was successful or not, and
|
|
|
|
advance to the NM_DEVICE_STATE_ACTIVATED state.
|
|
|
|
|
|
|
|
The NMManager object, when determining the overall NM_STATE_* state in the
|
|
|
|
nm_manager_update_state() function, would query this property and set
|
|
|
|
NM_STATE_CONNECTED_LOCAL, NM_STATE_CONNECTED_SITE, or NM_STATE_CONNECTED_GLOBAL
|
|
|
|
based on it and the device's state.
|
|
|
|
|
|
|
|
Ideally this feature would not require linking to an HTTP library like libcurl,
|
|
|
|
but would use open-coded simple HTTP or libsoup for the request. The request
|
|
|
|
must be done asynchronously, of course.
|
|
|
|
|
|
|
|
|
|
|
|
* ADSL support
|
|
|
|
|
|
|
|
NetworkManager should natively support ADSL modems using one of the 3 main
|
|
|
|
connection methods, PPP over ATM (pppoa), PPP over Ethernet (pppoe), or
|
|
|
|
IP over ATM (ipoatm). Initial support could be targeted at just pppoa and
|
|
|
|
pppoe, and there is some code in NetworkManager already for pppoe. More info
|
|
|
|
about ADSL configuration on Linux in general is here:
|
|
|
|
|
|
|
|
http://atm.eagle-usb.org/wakka.php?wiki=UeagleAtmDoc
|
|
|
|
|
|
|
|
hicham started code for the configuration settings here:
|
|
|
|
|
|
|
|
https://github.com/hicham-haouari/NetworkManager-ADSL-Support/commits/adsl
|
|
|
|
|
|
|
|
After the libnm-util pieces, internally NM needs to be modified for ADSL
|
|
|
|
support, of course. That involves adding a new NM_DEVICE_TYPE_ADSL in
|
|
|
|
NetworkManager.h, and then creating a new NMDeviceAdsl subclass in src/. It's
|
|
|
|
probably easiest to copy the nm-device-ethernet.c file and strip out stuff
|
|
|
|
that's not required. Like the nm-device-ethernet.c file handles the 'carrier'
|
|
|
|
state though, the ADSL code should periodically poll the sysfs 'carrier'
|
|
|
|
attribute of the DSL modem to detect when the modem has a link with the remote
|
|
|
|
DSL concentrator, and only activate connections when the link is present.
|
|
|
|
|
|
|
|
Detection of ADSL modems should be handled in nm-udev-manager.c checking for
|
|
|
|
the "atm" subsystem.
|
|
|
|
|
|
|
|
Code to manage br2684ctl will likely be required to be written for the PPPoE
|
|
|
|
case before PPPoE is started on the bridge-created link "nasX". There are
|
|
|
|
quite a few examples of daemon management code in NetworkManager (dnsmasq,
|
|
|
|
avahi-autoipd, ppp, dhclient, etc) so there should be a lot of code to
|
|
|
|
copy and paste from.
|
|
|
|
|
|
|
|
|
|
|
|
* Convert WEXT code to nl80211
|
|
|
|
|
|
|
|
There's still some WEXT code in NetworkManager for signal strength reporting,
|
|
|
|
mode, frequency, BSSID, etc. This should all get converted to nl80211 code,
|
|
|
|
possibly using libnl as a base. It's not particularly hard, but some
|
|
|
|
investigation on how to talk to netlink and how to use nl80211 and netlink
|
|
|
|
attributes will need to be done. Tools like 'iw' already do much of this work,
|
|
|
|
but we *cannot* copy & paste code from them since the 'iw' license is not
|
|
|
|
compatible with NetworkManager's GPL license. For exmaple, the following code
|
|
|
|
does the job, but should be reworked a bit to use the internal synchronous
|
|
|
|
netlink connection from src/nm-netlink-manager.c instead of doing the
|
|
|
|
netlink communication on its own with genl_connect() and such:
|
|
|
|
|
|
|
|
http://mail.gnome.org/archives/networkmanager-list/2009-September/msg00214.html
|
|
|
|
|
|
|
|
The same approach should be taken for signal strength reporting, etc.
|
|
|
|
|
|
|
|
|
|
|
|
* Real Access Point mode support
|
|
|
|
|
|
|
|
Now that NetworkManager requires wpa_supplicant 0.7.x or later, we can add
|
|
|
|
full Access Point (AP) mode support. NetworkManager currently implements
|
|
|
|
connection sharing via AdHoc mode support, which has some limitations. Instead,
|
|
|
|
we should check whether the wifi device supports AP mode, and if so, use
|
|
|
|
that mode instead. wpa_supplicant has support for a "lightweight AP" mode which
|
|
|
|
we should use. Witold Sowa started this support a while ago and wrote the new
|
|
|
|
D-Bus API for wpa_supplicant that makes all this possible, but some NM pieces
|
|
|
|
are still missing. If the wifi driver supports AP mode, then in
|
|
|
|
src/supplicant-manager/ NM should send an AP-mode config instead of sending
|
|
|
|
the adhoc config.
|
|
|
|
|
2011-05-24 00:13:55 +00:00
|
|
|
Note that some devices (airo, ipw2100, ipw2200, iwl3945, iwl4965, atmel, zd1201)
|
|
|
|
will never support AP mode due to firmware limitations, so we clearly must still
|
|
|
|
provide Ad-Hoc connection sharing support for those devices and switch between
|
|
|
|
Ad-Hoc and AP mode depending on device capabilities.
|
|
|
|
|
2011-03-08 21:24:27 +00:00
|
|
|
|
|
|
|
* On-Demand WiFi Scan support
|
|
|
|
|
|
|
|
Single-user and embedded devices often use a continuous wifi scan when the
|
|
|
|
networking configuration interface is open to quickly allow users to find their
|
|
|
|
wifi network. NM periodically scans, but this could take as long as 2 mintues
|
|
|
|
to update the list. Note that WiFi scans require 2 - 10 seconds to complete,
|
|
|
|
and during this time normal traffic (video, VOIP, streaming music, downloads,
|
|
|
|
etc) is not transmitted, so a WiFi scan is a disruptive operation to the user.
|
|
|
|
|
|
|
|
A D-Bus method should be added to the NMDeviceWifi device to allow user
|
|
|
|
applications to request a scan. This request should be rate-limited to no
|
|
|
|
more than once every 10 seconds to give time for traffic to resume when the
|
|
|
|
scan is done, and to lessen the effect of any DDoS by malicious user
|
|
|
|
applications. This request should also be restricted by one or more PolicyKit
|
|
|
|
permissions like org.freedesktop.NetworkManager.network-control.
|
|
|
|
|
|
|
|
To begin, a new method definition should be added to the
|
|
|
|
introspection/nm-device-wifi.xml for a method called "RequestScan" which takes
|
|
|
|
an argument called "options" of type of "a{sv}". This argument will be used
|
|
|
|
later. An annotation (like the other functions have) should be added so that
|
|
|
|
the method will be called "impl_device_request_scan".
|
|
|
|
|
|
|
|
Next, the corresponding method implementation should be added to
|
|
|
|
src/nm-device-wifi.c by adding the prototype for impl_device_request_scan
|
|
|
|
near the top of the file, and implementing it below. The implementation will
|
|
|
|
recieve a GHashTable corresponding to the "a{sv}" argument list from the XML
|
|
|
|
file, but we can ignore that for now.
|
|
|
|
|
|
|
|
The incoming request should be authenticated using nm_auth_get_caller_uid()
|
|
|
|
and additionally starting a PolicyKit authentication check with
|
|
|
|
with nm_auth_chain_new(). See the function manager_device_disconnect_request()
|
|
|
|
in src/nm-manager.c for an example of this.
|
|
|
|
|
|
|
|
Only after the caller is authorized to scan should the request be checked
|
|
|
|
against the last scan timestamp, and if the last scan was 10 seconds or more
|
|
|
|
ago, a new scan should be requested.
|
|
|
|
|
|
|
|
|
|
|
|
* Implement NM_DEVICE_STATE_DISCONNECTING
|
|
|
|
|
|
|
|
To allow for "pre-down" scenarios, this state should be implemented before a
|
|
|
|
device is taken down while it still has connectivity. If the device is
|
|
|
|
taken down because it's ethernet carrier was dropped, or because the WiFi
|
|
|
|
connection was terminated by the supplicant, this state is pointless and should
|
|
|
|
be skipped. But if the user requested a manual "disconnect", or NM is dropping
|
|
|
|
connections on exit, etc, then this state should be entered. In the future
|
|
|
|
this state should hook into a new dispatcher action in src/NetworkManagerUtils.c
|
|
|
|
to exectue dispatcher scripts during the disconnection, and to wait a limited
|
|
|
|
amount of time for each script to complete before allowing the device to
|
|
|
|
proceed to the NM_DEVICE_STATE_DISCONNECTED state, fully implementing pre-down.
|
|
|
|
|
|
|
|
|
|
|
|
* VPN re-connect
|
|
|
|
|
|
|
|
NM should remember whether a VPN was connected if a connection disconnects
|
|
|
|
(like WiFi drops out or short carrier drop) or if the laptop goes to sleep.
|
|
|
|
Upon reconnect, if the same Connection is again active, the previously
|
|
|
|
connected VPN should be activated again as well. Basically, don't just drop
|
|
|
|
the VPN because WiFi choked for 10 seconds, but reconnect the VPN if it was
|
|
|
|
connected before the drop.
|
|
|
|
|
|
|
|
|
|
|
|
* VPN autoconnect
|
|
|
|
|
|
|
|
We should add a property to the NMSettingConnection object in
|
|
|
|
libnm-util/nm-setting-connection.c called "vpns" that is a string list,
|
|
|
|
containing a list of Connection UUIDs that should be activated when the base
|
|
|
|
connection itself is activated. This will allow a VPN connection to be
|
|
|
|
started every time another connection is started, so that if you choose you're
|
|
|
|
always on the VPN in your favorite coffee shop.
|
|
|
|
|
|
|
|
The NM_DEVICE_STATE_SECONDARIES state was added specifically for cases like
|
|
|
|
this. Thus, after the base device has IP connectivity, but before it has
|
|
|
|
signaled that it's fully activated, the device should enter the SECONDARIES
|
|
|
|
state and kick off activation of the given VPN connection. Only after this
|
|
|
|
VPN connection has successfully connected should the base device to the
|
|
|
|
NM_DEVICE_STATE_ACTIVATED state.
|
|
|
|
|
|
|
|
|
|
|
|
* VPN and IPv6
|
|
|
|
|
|
|
|
The internal VPN capability should support IPv6. Essentially, the D-Bus
|
|
|
|
interface between NetworkManager and the VPN service daemons should be extended
|
|
|
|
with an IP6Config signal that passes up the IPv6 addressing and routing details
|
|
|
|
if the VPN daemon is IPv6 capable. NM should then process those details like it
|
|
|
|
does with IPv4. include/NetworkManagerVPN.h should be updated with key/value
|
|
|
|
pairs defining the various IPv6 attributes much like the IPv4 ones are defined.
|
|
|
|
|
|
|
|
|
|
|
|
* VPN IP Methods
|
|
|
|
|
|
|
|
Some VPNs (openvpn with TAP for example) require that DHCP is run on a
|
|
|
|
pseudo-ethernet device to obtain addressing information. This is not currently
|
|
|
|
possible, but NM already has all the code for DHCP. Thus, a new "method"
|
|
|
|
key should be defined in include/NetworkManagerVPN.h to allow for DHCP to
|
|
|
|
be performed if the VPN service daemon requests it in the IP4Config or IP6Config
|
|
|
|
signals. A patch here:
|
|
|
|
|
|
|
|
http://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?h=vpn-ip-method
|
|
|
|
|
|
|
|
shows that, but internally NM needs to process this request, and instead of
|
|
|
|
applying given IPv4 or IPv6 configuration (since there isn't any yet) it should
|
|
|
|
kick off a DHCP request and wait for the request to finish. When it does
|
|
|
|
finish it should apply the configuration to the interface. Most of the DHCP
|
|
|
|
code is already written, but src/vpn-manager/nm-vpn-connection.c would need
|
|
|
|
updates to recognize the new "method" property of the IP4Config signal and
|
|
|
|
handle the DHCP lifetime after that. The base NMDevice class in nm-device.c
|
|
|
|
has code for handling the DHCP lifetime, connecting to NMDHCPManager signals
|
|
|
|
for renew and failure processing, etc, and could be used as an example.
|
2004-07-27 20:49:11 +00:00
|
|
|
|
2011-03-14 04:49:02 +00:00
|
|
|
|
|
|
|
* WPS
|
|
|
|
|
|
|
|
wpa_supplicant has support for WPS (Wifi Protected Setup, basically Bluetooth-
|
|
|
|
like PIN codes for setting up a wifi connection) and we should add support for
|
|
|
|
this to NetworkManager too. APs that support WPS will say so in their beacon
|
|
|
|
IEs which are contained in the "WPA" and "RSN" properties of the BSS object
|
|
|
|
exported by the supplicant, and can be processed in src/nm-wifi-ap.c's
|
|
|
|
foreach_property_cb() function. We should add some private fields to the
|
|
|
|
NMAccessPoint object (defined in nm-wifi-ap.c) to remember whether a specific
|
|
|
|
AP supports WPS and what WPS methods it supports, and expose that over D-Bus to
|
|
|
|
GUI clients as well.
|
|
|
|
|
|
|
|
There are two common WPS setup methods: PIN and button. For PIN, the router
|
|
|
|
either displays a random PIN on an LCD or the router's web UI, or a static PIN
|
|
|
|
is printed on the router itself. The user enters that PIN instead of a PSK
|
|
|
|
when connecting. For the "button" method, the router has a physical button that
|
|
|
|
when pushed, allows any client to connect for a short period of time.
|
|
|
|
|
|
|
|
We'll then need to add some properties to the NMSettingWirelessSecurity setting
|
|
|
|
for the WPS PIN code so that when the user enters it through the GUI, it can
|
|
|
|
be passed back to NM. And we'll need to figure out some mechanism for passing
|
|
|
|
back an indication that the user pushed the button on the router for the
|
|
|
|
pushbutton method.
|
|
|
|
|
|
|
|
When connecting to a new access point that supports WPS, the GUI client would
|
|
|
|
call the AddAndActivateConnection method and wait for NM to request secrets.
|
|
|
|
NM would determine that the AP supports WPS, and request WPS secrets from the
|
|
|
|
applet. The applet would ask the user for a PIN, or to push the button on the
|
|
|
|
AP, instead of asking for a passphrase or PSK. When the user has entered the
|
|
|
|
PIN or pushed the button, the applet returns this information to NM, which
|
|
|
|
proceeds with the connection.
|
|
|
|
|
|
|
|
NM sends the correct wpa_supplicant config for WPS to the supplicant, and waits
|
|
|
|
for the connection to occur. WPS can only be used the *first* time, so after a
|
|
|
|
first successfull connection, NM must request the actual hexadecimal PSK from
|
|
|
|
wpa_supplicant via D-Bus, and store that PSK in the connection, clear any WPS
|
|
|
|
PIN code from the connection, and save the connection to backing storage.
|
|
|
|
|
|
|
|
Any applet GUI should also allow the user to enter the PSK instead of completing
|
|
|
|
association using WPS, since quite a few routers out there are broken, or
|
|
|
|
because the user has no physical access to the router itself, but has been given
|
|
|
|
as passphrase/PSK instead.
|
|
|
|
|
2011-05-24 00:44:32 +00:00
|
|
|
|
|
|
|
* Proxies
|
|
|
|
|
|
|
|
HTTP and other proxies are per-connection configuration. It's highly unlikely
|
|
|
|
that the same proxy you need to use at work is used at home or in a coffee shop.
|
|
|
|
Thus, it makes sense that which proxy settings to use should be updated when
|
|
|
|
network connections change. NetworkManager is a perfect place to do this since
|
|
|
|
it tracks which network connections are active, and it already queries the
|
|
|
|
network for automatic proxy configuration via DHCP and WPAD.
|
|
|
|
|
|
|
|
We should add a new NMSetting subclass called NMSettingProxy that holds
|
|
|
|
necessary proxy configuration. The properties of this setting should be a
|
|
|
|
superset of what is provided in the Firefox proxy configuration screen and the
|
|
|
|
various desktop environment proxy configuration tools like the GNOME Network
|
|
|
|
Proxy control panel; this should include at a minimum:
|
|
|
|
|
|
|
|
method: "auto", "manual", "none"
|
|
|
|
default-proxy: string
|
|
|
|
default-proxy-port: uint
|
|
|
|
default-always: boolean (use default proxy for all protocols)
|
|
|
|
ssl-proxy: string
|
|
|
|
ssl-proxy-port: uint
|
|
|
|
ftp-proxy: string
|
|
|
|
ftp-proxy-port: uint
|
|
|
|
socks-proxy: string
|
|
|
|
socks-proxy-port: uint
|
|
|
|
socks-version: uint, either 4 or 5
|
|
|
|
no-proxy-for: array of strings (things not to use the proxy for, ie ".foobar.com",
|
|
|
|
"192.168.0.1/24", an IPv6 address, etc)
|
|
|
|
pac-url: string (URL of PAC file, overrides DHCP-provided WPAD value)
|
|
|
|
(FIXME: proxy authentication? do we need separate user/pass properties for
|
|
|
|
each protocol type? should NM handle proxy auth or should it be punted
|
|
|
|
to each application?)
|
|
|
|
|
|
|
|
After completing IP configuration but still during the NM_DEVICE_STATE_IP_CONFIG
|
|
|
|
activation stage, NetworkManager would merge the automatically supplied proxy
|
|
|
|
configuration (from DHCP's WPAD option) with user-provided overrides from the
|
|
|
|
NMSettingProxy and send the results to the system. The 'default' connection's
|
|
|
|
proxy configuration would be preferred, so we'd have to update proxy
|
|
|
|
configuration from nm-policy.c the same time we update DNS information and the
|
|
|
|
default route.
|
|
|
|
|
|
|
|
The merged proxy configuration would then be sent to the system. There is no
|
|
|
|
canonical proxy daemon in-use, so we should have plugins (if not separate
|
|
|
|
shared libraries, then certainly encapsulated source files that implement a
|
|
|
|
common glib GInterface or are subclasses of eg a parent NMProxyHandler class)
|
|
|
|
that handle different system proxy handlers. Some of the proxy handlers are:
|
|
|
|
|
|
|
|
libproxy: need to figure out how it gets proxy info and have NM write merged
|
|
|
|
proxy config out to that location
|
|
|
|
pacrunner: a D-Bus enabled daemon, NM would call D-Bus methods of the
|
|
|
|
pacrunner service with the proxy information
|
|
|
|
GNOME/KDE: how do these desktop environments retrieve proxy configuration?
|
|
|
|
|
|
|
|
|
2011-05-24 22:21:15 +00:00
|
|
|
* Bridging and Bonding Support
|
|
|
|
|
|
|
|
The largest complication here is that NetworkManager normally operates on
|
|
|
|
physical interfaces, while bridging and bonding involve tying multiple physical
|
|
|
|
interfaces together into a logical interface. This has interesting implications
|
|
|
|
for the D-Bus API and the NM device model. The first complication is that
|
|
|
|
we may need to do 802.1x port authentication on an interface before it can
|
|
|
|
communicate with the other side of the link, and those credentials may be
|
|
|
|
different for each interface; thus we may need to do separate 802.1x
|
|
|
|
operations on each interface that is part of a bridge/bond before adding each
|
|
|
|
one to the master bridge/bond interface.
|
|
|
|
|
|
|
|
In this way bridge/bond interfaces may be treated the same way as NetworkManager
|
|
|
|
treats VPN interfaces already; one or more physical interface NMConnections must
|
|
|
|
be activated before the master bridge/bond interface's NMConnection can be
|
|
|
|
activated, though this all happens internally.
|
|
|
|
|
|
|
|
To enable bridging and bonding in the NMConnection itself, we should create
|
|
|
|
new NMSettingBridge and NMSettingBond classes that contain information specific
|
|
|
|
to each. Both settings would contain a 'components' property with an
|
|
|
|
'array of string' type which would contain the UUIDs of the Connections of
|
|
|
|
physical interfaces that compose the bridge or bond. Thus NetworkManager would
|
|
|
|
have the necessary information to tie lower-level interface configuration
|
|
|
|
(802.1x, MTU, MAC address locking, duplex mode, speed, etc) to each physical
|
|
|
|
interface that will be part of the bridge/bond, configure the interface with
|
|
|
|
it, and then configure the master bridge/bond interface at upper layers using
|
|
|
|
configuration specific for the bridge/bond interface (like IP details). Thus
|
|
|
|
for a single active bridge, two or more NMConnections would be activated; one
|
|
|
|
for each physical interface component of the bridge/bond, and one for the master
|
|
|
|
bridge/bond interface itself.
|
|
|
|
|
|
|
|
NMSettingBridge would contain at least the following keys:
|
|
|
|
|
|
|
|
components: (array of string) UUIDs of component connections
|
|
|
|
stp: (boolean) on to enable STP, off to disable
|
|
|
|
|
|
|
|
NMSettingBond would contain at least the following keys:
|
|
|
|
|
|
|
|
components: (array of string) UUIDs of component connections
|
|
|
|
mode: (string) one of "balance-rr", "active-backup", "balance-xor",
|
|
|
|
"broadcast", "802.3ad", "balance-tlb", or "balance-alb"
|
|
|
|
monitor-interval: (uint) Specifies link monitoring interval (in milliseconds);
|
|
|
|
NM will always enable netlink carrier monitoring if this
|
|
|
|
value is non-zero so this property only affects speed and
|
|
|
|
duplex checking
|
|
|
|
|
|
|
|
In the future we may consider adding other bonding parameters like "up-delay"
|
|
|
|
and "down-delay".
|
|
|
|
|
|
|
|
Then we'd add a 'component' (boolean) property to NMSettingConnection to
|
|
|
|
indicate that the component interface connections were in fact components of
|
|
|
|
a bridge or bond and shouldn't be automatically started by NetworkManager or
|
|
|
|
displayed as separate connections in the user interface.
|
|
|
|
|
|
|
|
TO BE CONTINUED
|