todo: update VPN IP Method item with more details
[NetworkManager.git] / TODO
1 So you're interested in hacking on NetworkManager?  Here's some cool
2 stuff you could do...
3
4 * Internet Connectivity Detection
5
6 This feature would consist of attempting to make an HTTP request to a known
7 DNS address and compare the response to a well-known string, like Windows does.
8 This feature and the server address should be configurable via an option in the
9 /etc/NetworkManager/NetworkManager.conf config file.
10
11 Once the device has successfully gotten an IPv4 or IPv6 address, it should
12 enter the state NM_DEVICE_STATE_IP_CHECK, where this HTTP request would be
13 performed.  After the check was done, the device would set a property in
14 NMDevicePrivate to indicate whether Internet access was successful or not, and
15 advance to the NM_DEVICE_STATE_ACTIVATED state.
16
17 The NMManager object, when determining the overall NM_STATE_* state in the
18 nm_manager_update_state() function, would query this property and set
19 NM_STATE_CONNECTED_LOCAL, NM_STATE_CONNECTED_SITE, or NM_STATE_CONNECTED_GLOBAL
20 based on it and the device's state.
21
22 Ideally this feature would not require linking to an HTTP library like libcurl,
23 but would use open-coded simple HTTP or libsoup for the request.  The request
24 must be done asynchronously, of course.
25
26
27 * ADSL support
28
29 NetworkManager should natively support ADSL modems using one of the 3 main
30 connection methods, PPP over ATM (pppoa), PPP over Ethernet (pppoe), or
31 IP over ATM (ipoatm).  Initial support could be targeted at just pppoa and
32 pppoe, and there is some code in NetworkManager already for pppoe.  More info
33 about ADSL configuration on Linux in general is here:
34
35 http://atm.eagle-usb.org/wakka.php?wiki=UeagleAtmDoc
36
37 hicham started code for the configuration settings here:
38
39 https://github.com/hicham-haouari/NetworkManager-ADSL-Support/commits/adsl
40
41 After the libnm-util pieces, internally NM needs to be modified for ADSL
42 support, of course.  That involves adding a new NM_DEVICE_TYPE_ADSL in
43 NetworkManager.h, and then creating a new NMDeviceAdsl subclass in src/.  It's
44 probably easiest to copy the nm-device-ethernet.c file and strip out stuff
45 that's not required.  Like the nm-device-ethernet.c file handles the 'carrier'
46 state though, the ADSL code should periodically poll the sysfs 'carrier'
47 attribute of the DSL modem to detect when the modem has a link with the remote
48 DSL concentrator, and only activate connections when the link is present.
49
50 Detection of ADSL modems should be handled in nm-udev-manager.c checking for
51 the "atm" subsystem.
52
53 Code to manage br2684ctl will likely be required to be written for the PPPoE
54 case before PPPoE is started on the bridge-created link "nasX".  There are
55 quite a few examples of daemon management code in NetworkManager (dnsmasq,
56 avahi-autoipd, ppp, dhclient, etc) so there should be a lot of code to
57 copy and paste from.
58
59
60 * Convert WEXT code to nl80211
61
62 There's still some WEXT code in NetworkManager for signal strength reporting,
63 mode, frequency, BSSID, etc.  This should all get converted to nl80211 code,
64 possibly using libnl as a base.  It's not particularly hard, but some
65 investigation on how to talk to netlink and how to use nl80211 and netlink
66 attributes will need to be done.  Tools like 'iw' already do much of this work,
67 but we *cannot* copy & paste code from them since the 'iw' license is not
68 compatible with NetworkManager's GPL license.  For exmaple, the following code
69 does the job, but should be reworked a bit to use the internal synchronous
70 netlink connection from src/nm-netlink-manager.c instead of doing the
71 netlink communication on its own with genl_connect() and such:
72
73 http://mail.gnome.org/archives/networkmanager-list/2009-September/msg00214.html
74
75 The same approach should be taken for signal strength reporting, etc.
76
77
78 * Real Access Point mode support
79
80 Now that NetworkManager requires wpa_supplicant 0.7.x or later, we can add
81 full Access Point (AP) mode support.  NetworkManager currently implements
82 connection sharing via AdHoc mode support, which has some limitations.  Instead,
83 we should check whether the wifi device supports AP mode, and if so, use
84 that mode instead.  wpa_supplicant has support for a "lightweight AP" mode which
85 we should use.  Witold Sowa started this support a while ago and wrote the new
86 D-Bus API for wpa_supplicant that makes all this possible, but some NM pieces
87 are still missing.  If the wifi driver supports AP mode, then in
88 src/supplicant-manager/ NM should send an AP-mode config instead of sending
89 the adhoc config.
90
91 Note that some devices (airo, ipw2100, ipw2200, iwl3945, iwl4965, atmel, zd1201)
92 will never support AP mode due to firmware limitations, so we clearly must still
93 provide Ad-Hoc connection sharing support for those devices and switch between
94 Ad-Hoc and AP mode depending on device capabilities.
95
96
97 * On-Demand WiFi Scan support
98
99 Single-user and embedded devices often use a continuous wifi scan when the
100 networking configuration interface is open to quickly allow users to find their
101 wifi network.  NM periodically scans, but this could take as long as 2 mintues
102 to update the list.  Note that WiFi scans require 2 - 10 seconds to complete,
103 and during this time normal traffic (video, VOIP, streaming music, downloads,
104 etc) is not transmitted, so a WiFi scan is a disruptive operation to the user.
105
106 A D-Bus method should be added to the NMDeviceWifi device to allow user
107 applications to request a scan.  This request should be rate-limited to no
108 more than once every 10 seconds to give time for traffic to resume when the
109 scan is done, and to lessen the effect of any DDoS by malicious user
110 applications.  This request should also be restricted by one or more PolicyKit
111 permissions like org.freedesktop.NetworkManager.network-control.
112
113 To begin, a new method definition should be added to the
114 introspection/nm-device-wifi.xml for a method called "RequestScan" which takes
115 an argument called "options" of type of "a{sv}".  This argument will be used
116 later.  An annotation (like the other functions have) should be added so that
117 the method will be called "impl_device_request_scan".
118
119 Next, the corresponding method implementation should be added to
120 src/nm-device-wifi.c by adding the prototype for impl_device_request_scan
121 near the top of the file, and implementing it below.  The implementation will
122 recieve a GHashTable corresponding to the "a{sv}" argument list from the XML
123 file, but we can ignore that for now.
124
125 The incoming request should be authenticated using nm_auth_get_caller_uid()
126 and additionally starting a PolicyKit authentication check with
127 with nm_auth_chain_new().  See the function manager_device_disconnect_request()
128 in src/nm-manager.c for an example of this.
129
130 Only after the caller is authorized to scan should the request be checked
131 against the last scan timestamp, and if the last scan was 10 seconds or more
132 ago, a new scan should be requested.
133
134
135 * Implement NM_DEVICE_STATE_DISCONNECTING
136
137 To allow for "pre-down" scenarios, this state should be implemented before a
138 device is taken down while it still has connectivity.  If the device is
139 taken down because it's ethernet carrier was dropped, or because the WiFi
140 connection was terminated by the supplicant, this state is pointless and should
141 be skipped.  But if the user requested a manual "disconnect", or NM is dropping
142 connections on exit, etc, then this state should be entered.  In the future
143 this state should hook into a new dispatcher action in src/NetworkManagerUtils.c
144 to exectue dispatcher scripts during the disconnection, and to wait a limited
145 amount of time for each script to complete before allowing the device to
146 proceed to the NM_DEVICE_STATE_DISCONNECTED state, fully implementing pre-down.
147
148
149 * VPN re-connect
150
151 NM should remember whether a VPN was connected if a connection disconnects
152 (like WiFi drops out or short carrier drop) or if the laptop goes to sleep.
153 Upon reconnect, if the same Connection is again active, the previously
154 connected VPN should be activated again as well.  Basically, don't just drop
155 the VPN because WiFi choked for 10 seconds, but reconnect the VPN if it was
156 connected before the drop.
157
158
159 * VPN autoconnect
160
161 We should add a property to the NMSettingConnection object in
162 libnm-util/nm-setting-connection.c called "vpns" that is a string list,
163 containing a list of Connection UUIDs that should be activated when the base
164 connection itself is activated.  This will allow a VPN connection to be
165 started every time another connection is started, so that if you choose you're
166 always on the VPN in your favorite coffee shop.
167
168 The NM_DEVICE_STATE_SECONDARIES state was added specifically for cases like
169 this.  Thus, after the base device has IP connectivity, but before it has
170 signaled that it's fully activated, the device should enter the SECONDARIES
171 state and kick off activation of the given VPN connection.  Only after this
172 VPN connection has successfully connected should the base device to the
173 NM_DEVICE_STATE_ACTIVATED state.
174
175
176 * VPN and IPv6
177
178 The internal VPN capability should support IPv6.  Essentially, the D-Bus
179 interface between NetworkManager and the VPN service daemons should be extended
180 with an IP6Config signal that passes up the IPv6 addressing and routing details
181 if the VPN daemon is IPv6 capable.  NM should then process those details like it
182 does with IPv4.  include/NetworkManagerVPN.h should be updated with key/value
183 pairs defining the various IPv6 attributes much like the IPv4 ones are defined.
184
185
186 * VPN IP Methods
187
188 Some VPNs (openvpn with TAP for example) require that DHCP is run on a
189 pseudo-ethernet device to obtain addressing information.  This is not currently
190 possible, but NM already has all the code for DHCP.  Thus, a new "method"
191 key should be defined in include/NetworkManagerVPN.h to allow for DHCP to
192 be performed if the VPN service daemon requests it in the IP4Config or IP6Config
193 signals.  A patch here:
194
195 http://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?h=vpn-ip-method
196
197 shows that.  In nm-vpn-connection.c, upon receipt of the D-Bus Ip4Config signal
198 from the VPN plugin, NetworkManager would inspect the "method" property of the
199 ip4 config dictionary.  If that property was present and set to "auto" then
200 DHCP would be started using the network interface returned in the dict.  The
201 nm_vpn_connection_ip4_config_get() function should be split up into two
202 functions, one containing the existing code for static configuration, and a
203 second for handling DHCP kickoff.  Minimal parsing of the response should be
204 handled in the newly reduced nm_vpn_connection_ip4_config_get() function.
205
206 To handle DHCP, the NMVPNConnectionPrivate structure should have two members
207 added:
208
209     NMDHCPManager *dhcp_manager;
210     NMDHCPClient  *dhcp4_client;
211
212 which would be initialized in the new DHCP handler code split off from
213 nm_vpn_connection_ip4_config_get().  These new members would be disposed of in
214 both vpn_cleanup() and dispose(), though remember to stop any ongoing DHCP
215 transaction when doing so (see dhcp4_cleanup() in nm-device.c for example code).
216 For basic code to start the DHCP transaction, see dhcp4_start() in nm-device.c
217 as well.  After calling nm_dhcp_manager_start_ip4() and connecting the signals
218 to monitor success and failure, the VPN IP4 config handler would simply return
219 without changing VPN state, unless a failure occurred.
220
221 Then, when the DHCP transaction succeeds, which we'd know by checking the
222 DHCP client state changes in the "state-changed" signal handler we attached to
223 the DHCP client object returned from nm_dhcp_manager_start_ip4(), the code
224 would retrieve the completed NMIP4Config object from the DHCP client using the
225 nm_dhcp_client_get_ip4_config() function, and then proceed to execute
226 essentially the bottom-half of the existing nm_vpn_connection_ip4_config_get()
227 function to merge that config with user overrides and apply it to the VPN
228 tunnel interface.  Other state changes from the DHCP client might trigger a
229 failure of the VPN connection, just like DHCP timeouts and lease-renewal
230 failures do for other devices (see dhcp_state_changed() in nm-device.c).
231
232
233 * WPS
234
235 wpa_supplicant has support for WPS (Wifi Protected Setup, basically Bluetooth-
236 like PIN codes for setting up a wifi connection) and we should add support for
237 this to NetworkManager too.  APs that support WPS will say so in their beacon
238 IEs which are contained in the "WPA" and "RSN" properties of the BSS object
239 exported by the supplicant, and can be processed in src/nm-wifi-ap.c's
240 foreach_property_cb() function.  We should add some private fields to the
241 NMAccessPoint object (defined in nm-wifi-ap.c) to remember whether a specific
242 AP supports WPS and what WPS methods it supports, and expose that over D-Bus to
243 GUI clients as well.
244
245 There are two common WPS setup methods: PIN and button.  For PIN, the router
246 either displays a random PIN on an LCD or the router's web UI, or a static PIN
247 is printed on the router itself.  The user enters that PIN instead of a PSK
248 when connecting.  For the "button" method, the router has a physical button that
249 when pushed, allows any client to connect for a short period of time.
250
251 We'll then need to add some properties to the NMSettingWirelessSecurity setting
252 for the WPS PIN code so that when the user enters it through the GUI, it can
253 be passed back to NM.  And we'll need to figure out some mechanism for passing
254 back an indication that the user pushed the button on the router for the
255 pushbutton method.
256
257 When connecting to a new access point that supports WPS, the GUI client would
258 call the AddAndActivateConnection method and wait for NM to request secrets.
259 NM would determine that the AP supports WPS, and request WPS secrets from the
260 applet.  The applet would ask the user for a PIN, or to push the button on the
261 AP, instead of asking for a passphrase or PSK.  When the user has entered the
262 PIN or pushed the button, the applet returns this information to NM, which
263 proceeds with the connection.
264
265 NM sends the correct wpa_supplicant config for WPS to the supplicant, and waits
266 for the connection to occur.  WPS can only be used the *first* time, so after a
267 first successfull connection, NM must request the actual hexadecimal PSK from 
268 wpa_supplicant via D-Bus, and store that PSK in the connection, clear any WPS
269 PIN code from the connection, and save the connection to backing storage.
270
271 Any applet GUI should also allow the user to enter the PSK instead of completing
272 association using WPS, since quite a few routers out there are broken, or
273 because the user has no physical access to the router itself, but has been given
274 as passphrase/PSK instead.
275
276
277 * Proxies
278
279 HTTP and other proxies are per-connection configuration.  It's highly unlikely
280 that the same proxy you need to use at work is used at home or in a coffee shop.
281 Thus, it makes sense that which proxy settings to use should be updated when
282 network connections change.  NetworkManager is a perfect place to do this since
283 it tracks which network connections are active, and it already queries the
284 network for automatic proxy configuration via DHCP and WPAD.
285
286 We should add a new NMSetting subclass called NMSettingProxy that holds
287 necessary proxy configuration.  The properties of this setting should be a
288 superset of what is provided in the Firefox proxy configuration screen and the
289 various desktop environment proxy configuration tools like the GNOME Network
290 Proxy control panel; this should include at a minimum:
291
292   method: "auto", "manual", "none"
293   default-proxy: string
294   default-proxy-port: uint
295   default-always: boolean (use default proxy for all protocols)
296   ssl-proxy: string
297   ssl-proxy-port: uint
298   ftp-proxy: string
299   ftp-proxy-port: uint
300   socks-proxy: string
301   socks-proxy-port: uint
302   socks-version: uint, either 4 or 5
303   no-proxy-for: array of strings (things not to use the proxy for, ie ".foobar.com",
304                  "192.168.0.1/24", an IPv6 address, etc)
305   pac-url: string (URL of PAC file, overrides DHCP-provided WPAD value)
306   (FIXME: proxy authentication?  do we need separate user/pass properties for
307     each protocol type?  should NM handle proxy auth or should it be punted
308     to each application?)
309
310 After completing IP configuration but still during the NM_DEVICE_STATE_IP_CONFIG
311 activation stage, NetworkManager would merge the automatically supplied proxy
312 configuration (from DHCP's WPAD option) with user-provided overrides from the
313 NMSettingProxy and send the results to the system.  The 'default' connection's
314 proxy configuration would be preferred, so we'd have to update proxy
315 configuration from nm-policy.c the same time we update DNS information and the
316 default route.
317
318 The merged proxy configuration would then be sent to the system.  There is no
319 canonical proxy daemon in-use, so we should have plugins (if not separate
320 shared libraries, then certainly encapsulated source files that implement a
321 common glib GInterface or are subclasses of eg a parent NMProxyHandler class)
322 that handle different system proxy handlers.  Some of the proxy handlers are:
323
324   libproxy: need to figure out how it gets proxy info and have NM write merged
325              proxy config out to that location
326   pacrunner: a D-Bus enabled daemon, NM would call D-Bus methods of the
327                pacrunner service with the proxy information
328   GNOME/KDE: how do these desktop environments retrieve proxy configuration?
329
330
331 * Bridging and Bonding Support
332
333 The largest complication here is that NetworkManager normally operates on
334 physical interfaces, while bridging and bonding involve tying multiple physical
335 interfaces together into a logical interface.  This has interesting implications
336 for the D-Bus API and the NM device model.  The first complication is that
337 we may need to do 802.1x port authentication on an interface before it can
338 communicate with the other side of the link, and those credentials may be
339 different for each interface; thus we may need to do separate 802.1x
340 operations on each interface that is part of a bridge/bond before adding each
341 one to the master bridge/bond interface.
342
343 In this way bridge/bond interfaces may be treated the same way as NetworkManager
344 treats VPN interfaces already; one or more physical interface NMConnections must
345 be activated before the master bridge/bond interface's NMConnection can be
346 activated, though this all happens internally.
347
348 To enable bridging and bonding in the NMConnection itself, we should create
349 new NMSettingBridge and NMSettingBond classes that contain information specific
350 to each.  Both settings would contain a 'components' property with an
351 'array of string' type which would contain the UUIDs of the Connections of
352 physical interfaces that compose the bridge or bond.  Thus NetworkManager would
353 have the necessary information to tie lower-level interface configuration
354 (802.1x, MTU, MAC address locking, duplex mode, speed, etc) to each physical
355 interface that will be part of the bridge/bond, configure the interface with
356 it, and then configure the master bridge/bond interface at upper layers using
357 configuration specific for the bridge/bond interface (like IP details).  Thus
358 for a single active bridge, two or more NMConnections would be activated; one
359 for each physical interface component of the bridge/bond, and one for the master
360 bridge/bond interface itself.
361
362 NMSettingBridge would contain at least the following keys:
363
364   components: (array of string) UUIDs of component connections
365   stp:        (boolean) on to enable STP, off to disable
366
367 NMSettingBond would contain at least the following keys:
368
369   components: (array of string) UUIDs of component connections
370   mode:       (string) one of "balance-rr", "active-backup", "balance-xor",
371                   "broadcast", "802.3ad", "balance-tlb", or "balance-alb"
372   monitor-interval: (uint) Specifies link monitoring interval (in milliseconds);
373                        NM will always enable netlink carrier monitoring if this
374                        value is non-zero so this property only affects speed and
375                        duplex checking
376
377 In the future we may consider adding other bonding parameters like "up-delay"
378 and "down-delay".
379
380 Then we'd add a 'component' (boolean) property to NMSettingConnection to
381 indicate that the component interface connections were in fact components of
382 a bridge or bond and shouldn't be automatically started by NetworkManager or
383 displayed as separate connections in the user interface.
384
385 TO BE CONTINUED